diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..da4dfd4 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,104 @@ +version: 2.1 +jobs: + build: + docker: + - image: cimg/ruby:3.3.0-browsers + working_directory: ~/app + environment: + RAILS_ENV: test + steps: + - checkout + - restore_cache: + keys: + - ruby-dependencies-v8-{{ checksum "Gemfile.lock" }} + - ruby-dependencies-v8 + - run: + name: Set bundle path + command: bundle config --local path vendor/bundle + - run: + name: Bundle Install + command: | + bundle check || bundle install --deployment + - run: + name: Clean old gem versions + command: bundle clean --force + - save_cache: + paths: + - vendor/bundle + key: ruby-dependencies-v8-{{ checksum "Gemfile.lock" }} + + run_tests: + docker: + - image: cimg/ruby:3.3.0-browsers + - image: cimg/postgres:16.2 + environment: + POSTGRES_HOST_AUTH_METHOD: trust + POSTGRES_USER: postgres + POSTGRES_PASSWORD: password + environment: + RAILS_ENV: test + SECRET_KEY_BASE: dummy + MAIL_FROM_ADDRESS: support@mystore.com + CIRCLE_TEST_REPORTS: /tmp/test-results + CIRCLE_ARTIFACTS: /tmp/test-artifacts + working_directory: ~/app + steps: + - checkout + - restore_cache: + keys: + - ruby-dependencies-v8-{{ checksum "Gemfile.lock" }} + - ruby-dependencies-v8 + - run: + name: Set bundle path + command: bundle config --local path vendor/bundle + - run: + name: Wait for DB + command: dockerize -wait tcp://localhost:5432 + - run: + name: Setup DB + command: bundle exec rails db:create db:schema:load + - run: + name: Precompile assets + command: SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile + - run: + name: Run Rspec + command: | + mkdir -p /tmp/test-results + circleci tests glob "spec/**/*_spec.rb" | circleci tests run --command="xargs bundle exec rspec --format documentation --format RspecJunitFormatter -o /tmp/test-results/rspec.xml" --verbose --split-by=timings + - store_test_results: + path: /tmp/test-results + - store_artifacts: + path: /tmp/test-artifacts + + run_brakeman: + docker: + - image: cimg/ruby:3.3.0-browsers + environment: + RAILS_ENV: test + working_directory: ~/app + steps: + - checkout + - restore_cache: + keys: + - ruby-dependencies-v8-{{ checksum "Gemfile.lock" }} + - ruby-dependencies-v8 + - run: + name: Set bundle path + command: bundle config --local path vendor/bundle + - run: + name: Run Brakeman + command: bundle exec brakeman -f html -o /tmp/brakeman.html + - store_artifacts: + path: /tmp/brakeman.html + +workflows: + version: 2 + main: + jobs: + - build + - run_tests: + requires: + - build + - run_brakeman: + requires: + - build diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9612375 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,37 @@ +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. + +# Ignore git directory. +/.git/ + +# Ignore bundler config. +/.bundle + +# Ignore all environment files (except templates). +/.env* +!/.env*.erb + +# Ignore all default key files. +/config/master.key +/config/credentials/*.key + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/.keep + +# Ignore assets. +/node_modules/ +/app/assets/builds/* +!/app/assets/builds/.keep +/public/assets diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8dc4323 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +# See https://git-scm.com/docs/gitattributes for more about git attribute files. + +# Mark the database schema as having been generated. +db/schema.rb linguist-generated + +# Mark any vendored files as having been vendored. +vendor/* linguist-vendored +config/credentials/*.yml.enc diff=rails_credentials +config/credentials.yml.enc diff=rails_credentials diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..c496bc7 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "bundler" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..45b63cf --- /dev/null +++ b/.gitignore @@ -0,0 +1,49 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore all environment files (except templates). +/.env* +!/.env*.erb + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/ +!/tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/ +!/tmp/storage/.keep + +/public/assets + +# Ignore master key for decrypting credentials and more. +/config/master.key + +/app/assets/builds/* +!/app/assets/builds/.keep + +.DS_Store + +# Ignore all environment files. +.env +.env.local +.env.development +.env.test +.env.production + +coverage \ No newline at end of file diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..049490a --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--require spec_helper -f documentation diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..7c216a1 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,124 @@ +AllCops: + # Default formatter will be used if no `-f/--format` option is given. + DefaultFormatter: progress + + # Enables the result cache if `true`. Can be overridden by the `--cache` command + # line option. + UseCache: true + + TargetRubyVersion: 3.3 + + NewCops: enable + + SuggestExtensions: false + + Exclude: + - db/schema.rb + - db/migrate/**/* + - vendor/bundle/**/* + - bin/**/* + - Rakefile + - config.ru + - config/environments/**/* + - spec/support/**/* + - config/initializers/**/* + - config/application.rb + +Layout/MultilineOperationIndentation: + EnforcedStyle: indented + +Layout/ParameterAlignment: + Enabled: false + +Metrics/ClassLength: + Enabled: false + +Metrics/ModuleLength: + Enabled: false + +Style/Documentation: + Enabled: false + +Layout/LineLength: + Max: 150 + +Metrics/MethodLength: + Enabled: false + +Metrics/BlockLength: + Enabled: false + +Metrics/AbcSize: + Enabled: false + +Style/StringLiterals: + Enabled: false + +Layout/DotPosition: + EnforcedStyle: trailing + Enabled: true + +Layout/SpaceInsidePercentLiteralDelimiters: + Enabled: false + +Style/FrozenStringLiteralComment: + Enabled: false + +Style/RegexpLiteral: + Enabled: false + +Style/WordArray: + Enabled: false + +Style/SymbolArray: + Enabled: false + +Style/GuardClause: + Enabled: false + +Style/TrailingCommaInArrayLiteral: + Enabled: false + +Style/TrailingCommaInHashLiteral: + Enabled: false + +Style/BarePercentLiterals: + Enabled: false + +Style/MutableConstant: + Enabled: false + +Style/PercentLiteralDelimiters: + Enabled: false + +Naming/VariableNumber: + Enabled: false + +Style/RedundantPercentQ: + Enabled: false + +Lint/ParenthesesAsGroupedExpression: + Enabled: false + +Metrics/PerceivedComplexity: + Max: 20 + +Metrics/CyclomaticComplexity: + Max: 20 + +Style/ClassAndModuleChildren: + Enabled: false + +Style/AndOr: + Exclude: + - '**/*controller.rb' + +Bundler/OrderedGems: + Enabled: false + +Lint/MissingSuper: + Enabled: false + +Lint/UnusedMethodArgument: + Exclude: + - 'app/services/**/*' \ No newline at end of file diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..15a2799 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.3.0 diff --git a/.solargraph.yml b/.solargraph.yml new file mode 100644 index 0000000..c7ba1fb --- /dev/null +++ b/.solargraph.yml @@ -0,0 +1,2 @@ +plugins: + - solargraph-rails \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1dbd4bb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,61 @@ +# syntax = docker/dockerfile:1 + +# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand: +# docker build -t my-app . +# docker run -d -p 80:80 -p 443:443 --name my-app -e SECRET_KEY_BASE= my-app + +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version +ARG RUBY_VERSION=3.3.0 +FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base + +# Rails app lives here +WORKDIR /rails + +# Install base packages +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y curl libjemalloc2 postgresql-client libpq-dev libvips redis-tools && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +ENV RAILS_ENV="production" \ + BUNDLE_DEPLOYMENT="1" \ + BUNDLE_PATH="/usr/local/bundle" + +# Throw-away build stage to reduce size of final image +FROM base AS build + +# Install packages needed to build gems +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential git pkg-config && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +# Install application gems +COPY Gemfile Gemfile.lock ./ +RUN bundle install && \ + rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git + +# Copy application code +COPY . . + +# Precompiling assets for production without requiring secret RAILS_MASTER_KEY +RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile + + +# Final stage for app image +FROM base + +# Copy built artifacts: gems, application +COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" +COPY --from=build /rails /rails + +# Run and own only the runtime files as a non-root user for security +RUN groupadd --system --gid 1000 rails && \ + useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ + chown -R rails:rails db log storage tmp +USER 1000:1000 + +# Entrypoint prepares the database. +ENTRYPOINT ["/rails/bin/docker-entrypoint"] + +# Start the server by default, this can be overwritten at runtime +EXPOSE 3000 +CMD ["./bin/rails", "server", "-b", "0.0.0.0"] diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..915e17b --- /dev/null +++ b/Gemfile @@ -0,0 +1,111 @@ +source "https://rubygems.org" + +ruby '3.3.0' + +# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" +gem 'rails', '~> 8.0.0' + +# Use pg as the database for Active Record +gem "pg", "~> 1.6" + +# Use the Puma web server [https://github.com/puma/puma] +gem "puma", ">= 5.0" + +# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] +gem "importmap-rails" + +# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] +gem "turbo-rails" + +# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] +gem "stimulus-rails" + +# Build JSON APIs with ease [https://github.com/rails/jbuilder] +gem "jbuilder" + +# Use Mini Racer for JavaScript runtime (required for asset precompilation) +gem 'mini_racer', platforms: :ruby + +# Use Redis adapter to run Action Cable in production +gem "redis", ">= 4.0.1" + +# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] +# gem "kredis" + +# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] +# gem "bcrypt", "~> 3.1.7" + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem "tzinfo-data", platforms: %i[ windows jruby ] + +# Reduces boot times through caching; required in config/boot.rb +gem "bootsnap", require: false + +# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] +gem "image_processing", "~> 1.13" + +group :development, :test do + # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem + gem "debug", platforms: %i[ mri windows ] + + gem 'brakeman' + gem 'dotenv-rails', '~> 3.1' + gem 'rubocop', '~> 1.23' + gem 'rubocop-performance' + gem 'rubocop-rails' + + # monitoring + gem 'pry' + gem 'pry-remote' +end + +group :development do + gem "foreman" + + # Use console on exceptions pages [https://github.com/rails/web-console] + gem "web-console" + + # Preview emails in the browser [https://github.com/plataformatec/letter_opener] + gem "letter_opener" + + # LSP support for Ruby + gem 'solargraph' + gem 'solargraph-rails' + gem 'ruby-lsp' + gem 'ruby-lsp-rails' + + # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] + # gem "rack-mini-profiler" + + # Speed up commands on slow machines / big apps [https://github.com/rails/spring] + # gem "spring" +end + +group :test do + gem 'spree_dev_tools' + gem 'rails-controller-testing' +end + +# Use Sidekiq for background jobs +gem 'sidekiq' + +# Use Devise for authentication +gem "devise" + +# Sentry for error/performance monitoring +gem 'sentry-ruby' +gem 'sentry-rails' +gem 'sentry-sidekiq' + +# Spree gems +spree_opts = '~> 5.1' +gem "spree", spree_opts +gem "spree_emails", spree_opts +gem "spree_sample", spree_opts +gem "spree_admin", spree_opts +gem "spree_storefront", spree_opts +gem "spree_i18n" +gem "spree_stripe" +gem "spree_google_analytics", "~> 1.0" +gem "spree_klaviyo", "~> 1.0" +gem "spree_paypal_checkout", "~> 0.5" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..1a6316b --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,1029 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (8.0.3) + actionpack (= 8.0.3) + activesupport (= 8.0.3) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (8.0.3) + actionpack (= 8.0.3) + activejob (= 8.0.3) + activerecord (= 8.0.3) + activestorage (= 8.0.3) + activesupport (= 8.0.3) + mail (>= 2.8.0) + actionmailer (8.0.3) + actionpack (= 8.0.3) + actionview (= 8.0.3) + activejob (= 8.0.3) + activesupport (= 8.0.3) + mail (>= 2.8.0) + rails-dom-testing (~> 2.2) + actionpack (8.0.3) + actionview (= 8.0.3) + activesupport (= 8.0.3) + nokogiri (>= 1.8.5) + rack (>= 2.2.4) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + useragent (~> 0.16) + actiontext (8.0.3) + actionpack (= 8.0.3) + activerecord (= 8.0.3) + activestorage (= 8.0.3) + activesupport (= 8.0.3) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (8.0.3) + activesupport (= 8.0.3) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + active_link_to (1.0.5) + actionpack + addressable + active_storage_validations (1.3.0) + activejob (>= 6.1.4) + activemodel (>= 6.1.4) + activestorage (>= 6.1.4) + activesupport (>= 6.1.4) + activejob (8.0.3) + activesupport (= 8.0.3) + globalid (>= 0.3.6) + activemerchant (1.137.0) + activesupport (>= 4.2) + builder (>= 2.1.2, < 4.0.0) + i18n (>= 0.6.9) + nokogiri (~> 1.4) + rexml (~> 3.3, >= 3.3.4) + activemodel (8.0.3) + activesupport (= 8.0.3) + activerecord (8.0.3) + activemodel (= 8.0.3) + activesupport (= 8.0.3) + timeout (>= 0.4.0) + activestorage (8.0.3) + actionpack (= 8.0.3) + activejob (= 8.0.3) + activerecord (= 8.0.3) + activesupport (= 8.0.3) + marcel (~> 1.0) + activesupport (8.0.3) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + acts-as-taggable-on (12.0.0) + activerecord (>= 7.1, < 8.1) + zeitwerk (>= 2.4, < 3.0) + acts_as_list (1.2.6) + activerecord (>= 6.1) + activesupport (>= 6.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + any_ascii (0.3.3) + apimatic_core (0.3.20) + apimatic_core_interfaces (~> 0.2.0) + certifi (~> 2018.1, >= 2018.01.18) + faraday-multipart (~> 1.0) + nokogiri (~> 1.13, >= 1.13.10) + apimatic_core_interfaces (0.2.3) + apimatic_faraday_client_adapter (0.1.6) + apimatic_core_interfaces (~> 0.2.0) + certifi (~> 2018.1, >= 2018.01.18) + faraday (~> 2.0, >= 2.0.1) + faraday-follow_redirects (~> 0.2) + faraday-gzip (>= 1, < 4) + faraday-http-cache (~> 2.2) + faraday-multipart (~> 1.0) + faraday-net_http_persistent (~> 2.0) + faraday-retry (~> 2.0) + appraisal (2.5.0) + bundler + rake + thor (>= 0.14.0) + ast (2.4.3) + async (2.34.0) + console (~> 1.29) + fiber-annotation + io-event (~> 1.11) + metrics (~> 0.12) + traces (~> 0.18) + async-http (0.92.1) + async (>= 2.10.2) + async-pool (~> 0.11) + io-endpoint (~> 0.14) + io-stream (~> 0.6) + metrics (~> 0.12) + protocol-http (~> 0.49) + protocol-http1 (~> 0.30) + protocol-http2 (~> 0.22) + protocol-url (~> 0.2) + traces (~> 0.10) + async-http-faraday (0.22.1) + async-http (~> 0.42) + faraday + async-pool (0.11.0) + async (>= 2.0) + auto_strip_attributes (2.6.0) + activerecord (>= 4.0) + autoprefixer-rails (10.4.21.0) + execjs (~> 2) + awesome_nested_set (3.8.0) + activerecord (>= 4.0.0, < 8.1) + awesome_print (1.9.2) + backport (1.2.0) + base64 (0.3.0) + bcrypt (3.1.20) + benchmark (0.5.0) + bigdecimal (3.3.1) + bindex (0.8.1) + bootsnap (1.18.6) + msgpack (~> 1.2) + bootstrap (4.6.2.1) + autoprefixer-rails (>= 9.1.0) + popper_js (>= 1.16.1, < 2) + brakeman (7.1.0) + racc + breadcrumbs_on_rails (4.1.0) + railties (>= 5.0) + builder (3.3.0) + cancancan (3.6.1) + canonical-rails (0.2.17) + actionview (>= 4.1, < 8.1) + capybara (3.40.0) + addressable + matrix + mini_mime (>= 0.1.3) + nokogiri (~> 1.11) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + capybara-screenshot (1.0.26) + capybara (>= 1.0, < 4) + launchy + capybara-select-2 (0.5.1) + carmen (1.1.3) + activesupport (>= 3.0.0) + certifi (2018.01.18) + chartkick (5.2.1) + childprocess (5.1.0) + logger (~> 1.5) + coderay (1.1.3) + concurrent-ruby (1.3.5) + connection_pool (2.5.4) + console (1.34.2) + fiber-annotation + fiber-local (~> 1.1) + json + countries (8.0.4) + unaccent (~> 0.3) + crass (1.0.6) + csv (3.3.5) + dartsass-rails (0.5.1) + railties (>= 6.0.0) + sass-embedded (~> 1.63) + database_cleaner (2.1.0) + database_cleaner-active_record (>= 2, < 3) + database_cleaner-active_record (2.2.2) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0) + database_cleaner-core (2.0.1) + date (3.4.1) + debug (1.11.0) + irb (~> 1.10) + reline (>= 0.3.8) + devise (4.9.4) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 4.1.0) + responders + warden (~> 1.2.3) + diff-lcs (1.6.2) + docile (1.4.1) + doorkeeper (5.8.2) + railties (>= 5) + dotenv (3.1.8) + dotenv-rails (3.1.8) + dotenv (= 3.1.8) + railties (>= 6.1) + drb (2.2.3) + erb (5.1.1) + erubi (1.13.1) + execjs (2.10.0) + factory_bot (6.5.5) + activesupport (>= 6.1.0) + faraday (2.14.0) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-follow_redirects (0.4.0) + faraday (>= 1, < 3) + faraday-gzip (3.0.4) + faraday (>= 2.0, < 3) + zlib (~> 3.0) + faraday-http-cache (2.5.1) + faraday (>= 0.8) + faraday-multipart (1.1.1) + multipart-post (~> 2.0) + faraday-net_http (3.4.1) + net-http (>= 0.5.0) + faraday-net_http_persistent (2.3.1) + faraday (~> 2.5) + net-http-persistent (>= 4.0.4, < 5) + faraday-retry (2.3.2) + faraday (~> 2.0) + ffaker (2.25.0) + ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-aarch64-linux-musl) + ffi (1.17.2-arm-linux-gnu) + ffi (1.17.2-arm-linux-musl) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x86_64-darwin) + ffi (1.17.2-x86_64-linux-gnu) + ffi (1.17.2-x86_64-linux-musl) + fiber-annotation (0.2.0) + fiber-local (1.1.0) + fiber-storage + fiber-storage (1.0.1) + foreman (0.90.0) + thor (~> 1.4) + friendly_id (5.4.2) + activerecord (>= 4.0.0) + friendly_id-mobility (1.0.4) + friendly_id (>= 5.0.0, < 5.5) + mobility (>= 1.0.1, < 2.0) + frozen_record (0.27.4) + activemodel + gem-release (2.2.4) + geocoder (1.8.6) + base64 (>= 0.1.0) + csv (>= 3.0.0) + github_changelog_generator (1.16.4) + activesupport + async (>= 1.25.0) + async-http-faraday + faraday-http-cache + multi_json + octokit (~> 4.6) + rainbow (>= 2.2.1) + rake (>= 10.0) + globalid (1.3.0) + activesupport (>= 6.1) + google-protobuf (4.33.0) + bigdecimal + rake (>= 13) + google-protobuf (4.33.0-aarch64-linux-gnu) + bigdecimal + rake (>= 13) + google-protobuf (4.33.0-aarch64-linux-musl) + bigdecimal + rake (>= 13) + google-protobuf (4.33.0-arm64-darwin) + bigdecimal + rake (>= 13) + google-protobuf (4.33.0-x86_64-darwin) + bigdecimal + rake (>= 13) + google-protobuf (4.33.0-x86_64-linux-gnu) + bigdecimal + rake (>= 13) + google-protobuf (4.33.0-x86_64-linux-musl) + bigdecimal + rake (>= 13) + groupdate (6.7.0) + activesupport (>= 7.1) + heroicon (1.0.0) + rails (>= 5.2) + highline (3.1.2) + reline + hightop (0.6.0) + activesupport (>= 7.1) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + i18n-tasks (1.0.15) + activesupport (>= 4.0.2) + ast (>= 2.1.0) + erubi + highline (>= 2.0.0) + i18n + parser (>= 3.2.2.1) + rails-i18n + rainbow (>= 2.2.2, < 4.0) + ruby-progressbar (~> 1.8, >= 1.8.1) + terminal-table (>= 1.5.1) + i18n_data (1.1.0) + simple_po_parser (~> 1.1) + image_processing (1.14.0) + mini_magick (>= 4.9.5, < 6) + ruby-vips (>= 2.0.17, < 3) + importmap-rails (2.2.2) + actionpack (>= 6.0.0) + activesupport (>= 6.0.0) + railties (>= 6.0.0) + io-console (0.8.1) + io-endpoint (0.15.2) + io-event (1.14.0) + io-stream (0.11.0) + irb (1.15.2) + pp (>= 0.6.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + jaro_winkler (1.6.1) + jbuilder (2.14.1) + actionview (>= 7.0.0) + activesupport (>= 7.0.0) + json (2.15.1) + jsonapi-rspec (0.0.11) + rspec-core + rspec-expectations + jsonapi-serializer (2.2.0) + activesupport (>= 4.2) + kaminari (1.2.2) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.2.2) + kaminari-activerecord (= 1.2.2) + kaminari-core (= 1.2.2) + kaminari-actionview (1.2.2) + actionview + kaminari-core (= 1.2.2) + kaminari-activerecord (1.2.2) + activerecord + kaminari-core (= 1.2.2) + kaminari-core (1.2.2) + kaminari-i18n (0.5.0) + kaminari + rails + kramdown (2.5.1) + rexml (>= 3.3.9) + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + language_server-protocol (3.17.0.5) + launchy (3.1.1) + addressable (~> 2.8) + childprocess (~> 5.0) + logger (~> 1.6) + letter_opener (1.10.0) + launchy (>= 2.2, < 4) + libv8-node (24.1.0.0) + libv8-node (24.1.0.0-aarch64-linux) + libv8-node (24.1.0.0-arm64-darwin) + libv8-node (24.1.0.0-x86_64-darwin) + libv8-node (24.1.0.0-x86_64-linux) + libv8-node (24.1.0.0-x86_64-linux-musl) + lint_roller (1.1.0) + local_time (3.0.3) + logger (1.7.0) + loofah (2.24.1) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.9.0) + logger + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + mail_form (1.11.0) + actionpack (>= 7.0) + activemodel (>= 7.0) + mapkick-rb (0.2.0) + marcel (1.1.0) + matrix (0.4.3) + method_source (1.1.0) + metrics (0.15.0) + mini_magick (5.3.1) + logger + mini_mime (1.1.5) + mini_racer (0.19.1) + libv8-node (~> 24.1.0.0) + minitest (5.26.0) + mobility (1.3.2) + i18n (>= 0.6.10, < 2) + request_store (~> 1.0) + mobility-actiontext (1.1.1) + actiontext (>= 6.0) + mobility (~> 1.2) + mobility-ransack (1.2.2) + mobility (>= 1.0.1, < 2.0) + ransack (>= 1.8.0, < 5.0) + monetize (1.13.0) + money (~> 6.12) + money (6.19.0) + i18n (>= 0.6.4, <= 2) + msgpack (1.8.0) + multi_json (1.17.0) + multipart-post (2.4.1) + name_of_person (1.1.3) + activesupport (>= 5.2.0) + net-http (0.6.0) + uri + net-http-persistent (4.0.6) + connection_pool (~> 2.2, >= 2.2.4) + net-imap (0.5.12) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.5.1) + net-protocol + nio4r (2.7.4) + nokogiri (1.18.10-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.10-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.18.10-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.10-arm-linux-musl) + racc (~> 1.4) + nokogiri (1.18.10-arm64-darwin) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-linux-musl) + racc (~> 1.4) + observer (0.1.2) + octokit (4.25.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) + orm_adapter (0.5.0) + ostruct (0.6.3) + parallel (1.27.0) + paranoia (3.0.1) + activerecord (>= 6, < 8.1) + parser (3.3.9.0) + ast (~> 2.4.1) + racc + payment_icons (1.7.59) + frozen_record + railties (>= 5.0) + sassc-rails + paypal-server-sdk (1.1.0) + apimatic_core (~> 0.3.11) + apimatic_core_interfaces (~> 0.2.1) + apimatic_faraday_client_adapter (~> 0.1.4) + pg (1.6.2) + pg (1.6.2-aarch64-linux) + pg (1.6.2-aarch64-linux-musl) + pg (1.6.2-arm64-darwin) + pg (1.6.2-x86_64-darwin) + pg (1.6.2-x86_64-linux) + pg (1.6.2-x86_64-linux-musl) + phonelib (0.10.12) + popper_js (1.16.1) + pp (0.6.3) + prettyprint + prettyprint (0.2.0) + prism (1.6.0) + protocol-hpack (1.5.1) + protocol-http (0.55.0) + protocol-http1 (0.35.2) + protocol-http (~> 0.22) + protocol-http2 (0.23.0) + protocol-hpack (~> 1.4) + protocol-http (~> 0.47) + protocol-url (0.4.0) + pry (0.15.2) + coderay (~> 1.1) + method_source (~> 1.0) + pry-remote (0.1.8) + pry (~> 0.9) + slop (~> 3.0) + psych (5.2.6) + date + stringio + public_suffix (6.0.2) + puma (7.1.0) + nio4r (~> 2.0) + racc (1.8.1) + rack (3.2.3) + rack-session (2.1.1) + base64 (>= 0.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) + rack (>= 1.3) + rackup (2.2.1) + rack (>= 3) + rails (8.0.3) + actioncable (= 8.0.3) + actionmailbox (= 8.0.3) + actionmailer (= 8.0.3) + actionpack (= 8.0.3) + actiontext (= 8.0.3) + actionview (= 8.0.3) + activejob (= 8.0.3) + activemodel (= 8.0.3) + activerecord (= 8.0.3) + activestorage (= 8.0.3) + activesupport (= 8.0.3) + bundler (>= 1.15.0) + railties (= 8.0.3) + rails-controller-testing (1.0.5) + actionpack (>= 5.0.1.rc1) + actionview (>= 5.0.1.rc1) + activesupport (>= 5.0.1.rc1) + rails-dom-testing (2.3.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.2) + loofah (~> 2.21) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + rails-i18n (8.0.2) + i18n (>= 0.7, < 2) + railties (>= 8.0.0, < 9) + railties (8.0.3) + actionpack (= 8.0.3) + activesupport (= 8.0.3) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + tsort (>= 0.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) + rake (13.3.0) + ransack (4.4.1) + activerecord (>= 7.2) + activesupport (>= 7.2) + i18n + rbs (3.9.5) + logger + rdoc (6.15.0) + erb + psych (>= 4.0.0) + tsort + redis (5.4.1) + redis-client (>= 0.22.0) + redis-client (0.26.1) + connection_pool + regexp_parser (2.11.3) + reline (0.6.2) + io-console (~> 0.5) + request_store (1.7.0) + rack (>= 1.4) + responders (3.2.0) + actionpack (>= 7.0) + railties (>= 7.0) + reverse_markdown (3.0.0) + nokogiri + rexml (3.4.4) + rspec-activemodel-mocks (1.3.0) + activemodel (>= 3.0) + activesupport (>= 3.0) + rspec-mocks (>= 2.99, < 4.0) + rspec-core (3.13.6) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.6) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-rails (8.0.2) + actionpack (>= 7.2) + activesupport (>= 7.2) + railties (>= 7.2) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) + rspec-retry (0.6.2) + rspec-core (> 3.3) + rspec-support (3.13.6) + rspec_junit_formatter (0.6.0) + rspec-core (>= 2, < 4, != 2.12.0) + rubocop (1.81.6) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.47.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.47.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-performance (1.26.1) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.47.1, < 2.0) + rubocop-rails (2.33.4) + activesupport (>= 4.2.0) + lint_roller (~> 1.1) + rack (>= 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + ruby-lsp (0.26.1) + language_server-protocol (~> 3.17.0) + prism (>= 1.2, < 2.0) + rbs (>= 3, < 5) + ruby-lsp-rails (0.4.8) + ruby-lsp (>= 0.26.0, < 0.27.0) + ruby-oembed (0.18.1) + ruby-progressbar (1.13.0) + ruby-vips (2.2.5) + ffi (~> 1.12) + logger + rubyzip (2.4.1) + safely_block (0.5.0) + sass-embedded (1.93.2-aarch64-linux-gnu) + google-protobuf (~> 4.31) + sass-embedded (1.93.2-aarch64-linux-musl) + google-protobuf (~> 4.31) + sass-embedded (1.93.2-arm-linux-gnueabihf) + google-protobuf (~> 4.31) + sass-embedded (1.93.2-arm-linux-musleabihf) + google-protobuf (~> 4.31) + sass-embedded (1.93.2-arm64-darwin) + google-protobuf (~> 4.31) + sass-embedded (1.93.2-x86_64-darwin) + google-protobuf (~> 4.31) + sass-embedded (1.93.2-x86_64-linux-gnu) + google-protobuf (~> 4.31) + sass-embedded (1.93.2-x86_64-linux-musl) + google-protobuf (~> 4.31) + sass-rails (6.0.0) + sassc-rails (~> 2.1, >= 2.1.1) + sassc (2.4.0) + ffi (~> 1.9) + sassc-rails (2.1.2) + railties (>= 4.0.0) + sassc (>= 2.0) + sprockets (> 3.0) + sprockets-rails + tilt + sawyer (0.9.3) + addressable (>= 2.3.5) + faraday (>= 0.17.3, < 3) + securerandom (0.4.1) + selenium-webdriver (4.10.0) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) + sentry-rails (6.0.0) + railties (>= 5.2.0) + sentry-ruby (~> 6.0.0) + sentry-ruby (6.0.0) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + sentry-sidekiq (6.0.0) + sentry-ruby (~> 6.0.0) + sidekiq (>= 5.0) + sidekiq (8.0.8) + connection_pool (>= 2.5.0) + json (>= 2.9.0) + logger (>= 1.6.2) + rack (>= 3.1.0) + redis-client (>= 0.23.2) + simple_po_parser (1.1.6) + simplecov (0.22.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-html (0.13.2) + simplecov_json_formatter (0.1.4) + slop (3.6.0) + solargraph (0.57.0) + backport (~> 1.2) + benchmark (~> 0.4) + bundler (~> 2.0) + diff-lcs (~> 1.4) + jaro_winkler (~> 1.6, >= 1.6.1) + kramdown (~> 2.3) + kramdown-parser-gfm (~> 1.1) + logger (~> 1.6) + observer (~> 0.1) + ostruct (~> 0.6) + parser (~> 3.0) + prism (~> 1.4) + rbs (>= 3.6.1, <= 4.0.0.dev.4) + reverse_markdown (~> 3.0) + rubocop (~> 1.76) + thor (~> 1.0) + tilt (~> 2.0) + yard (~> 0.9, >= 0.9.24) + yard-activesupport-concern (~> 0.0) + yard-solargraph (~> 0.1) + solargraph-rails (1.2.4) + activesupport + solargraph (>= 0.48.0, <= 0.57) + spree (5.1.7) + spree_api (= 5.1.7) + spree_cli (= 5.1.7) + spree_core (= 5.1.7) + spree_admin (5.1.7) + active_link_to + bootstrap (~> 4.6, >= 4.6.2.1) + breadcrumbs_on_rails (~> 4.1) + chartkick (~> 5.0) + dartsass-rails (~> 0.5) + groupdate (~> 6.2) + hightop (~> 0.3) + importmap-rails + local_time (~> 3.0) + mapkick-rb (~> 0.1) + payment_icons + spree_api (>= 5.1.7) + spree_core (>= 5.1.7) + sprockets (>= 4.0) + stimulus-rails + tinymce-rails (~> 6.8.5) + turbo-rails + spree_api (5.1.7) + bcrypt (~> 3.1) + doorkeeper (~> 5.3) + jsonapi-serializer (~> 2.1) + spree_core (= 5.1.7) + spree_cli (5.1.7) + thor (~> 1.0) + spree_core (5.1.7) + active_storage_validations (= 1.3.0) + activemerchant (~> 1.67) + acts-as-taggable-on + acts_as_list (>= 0.8) + any_ascii (~> 0.3.2) + auto_strip_attributes (~> 2.6) + awesome_nested_set (~> 3.3, >= 3.3.1) + cancancan (~> 3.2) + carmen (>= 1.0) + countries + friendly_id (~> 5.2, >= 5.2.1) + friendly_id-mobility (~> 1.0) + geocoder + highline (>= 2, < 4) + image_processing (~> 1.2) + kaminari (~> 1.2) + mobility (~> 1.3, >= 1.3.2) + mobility-actiontext (~> 1.1) + mobility-ransack (~> 1.2) + monetize (~> 1.9) + money (~> 6.13) + name_of_person (~> 1.1) + paranoia (>= 2.4) + phonelib (~> 0.10) + rails (>= 7.2, < 8.1) + ransack (>= 4.1) + request_store (~> 1.7) + rexml + ruby-oembed (~> 0.18) + safely_block (~> 0.4) + state_machines-activemodel (~> 0.10) + state_machines-activerecord (~> 0.10) + stringex + tracking_number + validates_zipcode + wannabe_bool + spree_dev_tools (0.3.1) + appraisal + awesome_print + brakeman + capybara + capybara-screenshot + capybara-select-2 + database_cleaner + dotenv + factory_bot (~> 6.2) + ffaker + gem-release + github_changelog_generator + i18n-tasks + jsonapi-rspec + pry + puma + rails-controller-testing + rspec-activemodel-mocks + rspec-rails + rspec-retry + rspec_junit_formatter + rubocop + rubocop-rails + sass-rails + selenium-webdriver (>= 4.10) + simplecov + spree (>= 5.0) + timecop + webdrivers + spree_emails (5.1.7) + spree_core (>= 5.1.7) + sprockets (>= 4.0) + spree_extension (0.1.0) + activerecord (>= 4.2) + spree_core + spree_google_analytics (1.0.1) + spree (>= 5.1.0.beta) + spree_admin (>= 5.1.0.beta) + spree_extension + spree_storefront (>= 5.1.0.beta) + spree_i18n (5.3.1) + i18n_data + kaminari-i18n + rails-i18n + spree_core (>= 4.2.0.rc3) + spree_extension + spree_klaviyo (1.0.3) + spree (>= 5.1.0.beta2) + spree_admin (>= 5.1.0.beta2) + spree_extension + spree_storefront (>= 5.1.0.beta2) + spree_paypal_checkout (0.5.3) + paypal-server-sdk (~> 1.1) + spree (>= 5.1.0.beta4) + spree_admin (>= 5.1.0.beta4) + spree_extension + spree_storefront (>= 5.1.0.beta4) + spree_sample (5.1.7) + ffaker (~> 2.9) + spree_core (>= 5.1.7) + spree_storefront (5.1.7) + active_link_to + canonical-rails (~> 0.2.14) + heroicon + importmap-rails + local_time (~> 3.0) + mail_form + payment_icons + spree_core (>= 5.1.7) + sprockets (>= 4.0) + stimulus-rails + tailwindcss-rails + tailwindcss-ruby (~> 3.4.17) + turbo-rails + spree_stripe (1.2.8) + importmap-rails + spree (>= 5.0.0.alpha) + spree_admin (>= 5.0.0.alpha) + spree_extension + spree_storefront (>= 5.0.0.alpha) + stripe (~> 10.1.0) + stripe_event (~> 2.11) + sprockets (4.2.2) + concurrent-ruby (~> 1.0) + logger + rack (>= 2.2.4, < 4) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) + sprockets (>= 3.0.0) + state_machines (0.100.4) + state_machines-activemodel (0.100.0) + activemodel (>= 7.2) + state_machines (>= 0.100.0) + state_machines-activerecord (0.100.0) + activerecord (>= 7.2) + state_machines-activemodel (>= 0.100.0) + stimulus-rails (1.3.4) + railties (>= 6.0.0) + stringex (2.8.6) + stringio (3.1.7) + stripe (10.1.0) + stripe_event (2.12.0) + activesupport (>= 3.1) + stripe (>= 2.8, < 16) + tailwindcss-rails (3.3.2) + railties (>= 7.0.0) + tailwindcss-ruby (~> 3.0) + tailwindcss-ruby (3.4.17-aarch64-linux) + tailwindcss-ruby (3.4.17-arm-linux) + tailwindcss-ruby (3.4.17-arm64-darwin) + tailwindcss-ruby (3.4.17-x86_64-darwin) + tailwindcss-ruby (3.4.17-x86_64-linux) + terminal-table (4.0.0) + unicode-display_width (>= 1.1.1, < 4) + thor (1.4.0) + tilt (2.6.1) + timecop (0.9.10) + timeout (0.4.3) + tinymce-rails (6.8.6.1) + railties (>= 3.1.1) + traces (0.18.2) + tracking_number (2.4.0) + activesupport (>= 4.2.5) + json (>= 1.8.3) + tsort (0.2.0) + turbo-rails (2.0.17) + actionpack (>= 7.1.0) + railties (>= 7.1.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unaccent (0.4.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.1.0) + uri (1.0.4) + useragent (0.16.11) + validates_zipcode (0.5.4) + activemodel (>= 4.2.0) + wannabe_bool (0.7.1) + warden (1.2.9) + rack (>= 2.0.9) + web-console (4.2.1) + actionview (>= 6.0.0) + activemodel (>= 6.0.0) + bindex (>= 0.4.0) + railties (>= 6.0.0) + webdrivers (5.3.1) + nokogiri (~> 1.6) + rubyzip (>= 1.3.0) + selenium-webdriver (~> 4.0, < 4.11) + websocket (1.2.11) + websocket-driver (0.8.0) + base64 + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + xpath (3.2.0) + nokogiri (~> 1.8) + yard (0.9.37) + yard-activesupport-concern (0.0.1) + yard (>= 0.8) + yard-solargraph (0.1.0) + yard (~> 0.9) + zeitwerk (2.7.3) + zlib (3.2.1) + +PLATFORMS + aarch64-linux + aarch64-linux-gnu + aarch64-linux-musl + arm-linux + arm-linux-gnu + arm-linux-gnueabihf + arm-linux-musl + arm-linux-musleabihf + arm64-darwin + x86_64-darwin + x86_64-linux + x86_64-linux-gnu + x86_64-linux-musl + +DEPENDENCIES + bootsnap + brakeman + debug + devise + dotenv-rails (~> 3.1) + foreman + image_processing (~> 1.13) + importmap-rails + jbuilder + letter_opener + mini_racer + pg (~> 1.6) + pry + pry-remote + puma (>= 5.0) + rails (~> 8.0.0) + rails-controller-testing + redis (>= 4.0.1) + rubocop (~> 1.23) + rubocop-performance + rubocop-rails + ruby-lsp + ruby-lsp-rails + sentry-rails + sentry-ruby + sentry-sidekiq + sidekiq + solargraph + solargraph-rails + spree (~> 5.1) + spree_admin (~> 5.1) + spree_dev_tools + spree_emails (~> 5.1) + spree_google_analytics (~> 1.0) + spree_i18n + spree_klaviyo (~> 1.0) + spree_paypal_checkout (~> 0.5) + spree_sample (~> 5.1) + spree_storefront (~> 5.1) + spree_stripe + stimulus-rails + turbo-rails + tzinfo-data + web-console + +RUBY VERSION + ruby 3.3.0p0 + +BUNDLED WITH + 2.6.5 diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..65ed922 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,26 @@ +Copyright (c) 2015-2024 Spark Solutions Sp. z o.o., Vendo Connect Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name Spree nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..b3c7a9a --- /dev/null +++ b/Procfile @@ -0,0 +1,4 @@ +release: bin/rails db:migrate +web: bundle exec puma -C config/puma.rb +worker: bin/rake sidekiq +cache: bin/rails cache:clear diff --git a/Procfile.dev b/Procfile.dev new file mode 100644 index 0000000..e0b022c --- /dev/null +++ b/Procfile.dev @@ -0,0 +1,4 @@ +web: bin/rails server -p 3000 +worker: bundle exec sidekiq +admin_css: bin/rails dartsass:watch +storefront_css: bin/rails tailwindcss:watch \ No newline at end of file diff --git a/README.md b/README.md index 8f6e21e..e0bdb88 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,110 @@ -# Fab-store +# Spree Starter +This is a starter kit for [Spree Commerce](https://spreecommerce.org) - the [open-source eCommerce platform](https://spreecommerce.org) for [Rails](https://spreecommerce.org/category/ruby-on-rails/). +It is a great starting point for any Rails developer to quickly build an eCommerce application. -## Getting started +This starter uses: -To make it easy for you to get started with GitLab, here's a list of recommended next steps. +* **[Spree Commerce 5](https://spreecommerce.org/announcing-spree-5-the-biggest-open-source-release-ever/)**, the biggest release ever, which includes Admin Dashboard, API and Storefront - everything you need to start developing your new eCommerce application/store/marketeplace +* Stripe for payment processing, thanks to the official [Spree Stripe gem](https://github.com/spree/spree_stripe) +* Google Analytics 4 integration, thanks to the official [Spree Google Analytics gem](https://github.com/spree/spree_google_analytics) +* Klaviyo integration, thanks to the official [Spree Klaviyo gem](https://github.com/spree/spree_klaviyo) +* [Devise](https://github.com/heartcombo/devise) for authentication +* [Sidekiq](https://github.com/mperham/sidekiq) for background jobs +* PostgreSQL as a database +* Redis for caching +* (Optional) [Sentry](https://sentry.io) for error/performance monitoring +* (Optional) [SendGrid](https://sendgrid.com) for transactional email notifications -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! +You don't need to install additional tools or libraries to start developing with Spree Starter. Everything is already set up for you. -## Add your files +If you like what you see, consider giving this repo a GitHub star :star: -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command: +Thank you for supporting Spree open-source :heart: -``` -cd existing_repo -git remote add origin https://gitlab.com/code2lab/fab-store.git -git branch -M main -git push -uf origin main +## Local Installation + +Please follow [Spree Quickstart guide](https://spreecommerce.org/docs/developer/getting-started/quickstart) to setup your Spree application using the Spree starter. + +## Deployment + +Please follow [Deployment guide](https://spreecommerce.org/docs/developer/deployment/render) to quickly deploy your production-ready Spree application. + +## Customizing + +Please follow [Customization guide](https://spreecommerce.org/docs/developer/customization/quickstart) to learn how to customize and extend your Spree application. + +## Running tests + +This repository is pre-configured for running tests of your Spree customizations. To run the full test suite, just type: + +```bash +bundle exec rspec ``` -## Integrate with your tools +## Spree 5 Announcement & Demo -- [ ] [Set up project integrations](https://gitlab.com/code2lab/fab-store/-/settings/integrations) +[![Spree Commerce 5 version](https://vendo-production-res.cloudinary.com/image/upload/w_2000/q_auto/v1742985405/docs/github/Spree_Commerce_open-source_eCommerce_myzurl.jpg)](https://spreecommerce.org/announcing-spree-5-the-biggest-open-source-release-ever/) -## Collaborate with your team +We’re thrilled to unveil [Spree 5](https://spreecommerce.org/announcing-spree-5-the-biggest-open-source-release-ever/ +) — the most powerful and feature-packed open-source release in Spree Commerce’s history, including: +- A completely revamped Admin Dashboard experience: boost your team's productivity +- A Mobile-First, No-code Customizable Storefront: raise conversions and loyalty +- New integrations: a native [Stripe integration](https://github.com/spree/spree_stripe), and also Stripe Connect, Klaviyo integrations available with the Enterprise Edition +- Enterprise Edition Admin Features: Audit Log, [Multi-Vendor Marketplace](https://spreecommerce.org/marketplace-ecommerce/), [Multi-tenant / White-label SaaS eCommerce](https://spreecommerce.org/multi-tenant-white-label-ecommerce/) -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/) +Read the [full Spree 5 announcement here](https://spreecommerce.org/announcing-spree-5-the-biggest-open-source-release-ever/). -## Test and Deploy +Check out the [Spree 5 demo](https://demo.spreecommerce.org/) for yourself. -Use the built-in continuous integration in GitLab. +## Troubleshooting -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) +### libvips error -*** +If you encounter an error like the following: -# Editing this README +```bash +LoadError: Could not open library 'vips.so.42' +``` -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. +Please check that libvips is installed with `vips -v`, and if it is not installed, follow [installation instructions here](https://www.libvips.org/install.html). -## Suggestions for a good README +## Join the Community -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. +[Join our Slack](https://slack.spreecommerce.org) to meet other 6k+ community members and get some support. -## Name -Choose a self-explaining name for your project. +## Need more support? -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. +[Contact us](https://spreecommerce.org/contact/) for enterprise support and custom development services. We offer: + * migrations and upgrades, + * delivering your Spree application, + * optimizing your Spree stack. -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. +## Enterprise Edition -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. +Besides enterprise support we also offer the Spree Commerce [Enterprise Edition](https://spreecommerce.org/spree-commerce-version-comparison-community-edition-vs-enterprise-edition/) that gives you all the tools you need to launch your store or marketplace and provides you with ready-to-use integrations that will reduce your project's development time and cost. -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. +With the Enterprise Edition you could build: -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. +### A [B2B eCommerce](https://spreecommerce.org/use-cases/headless-b2b-ecommerce/) +With support for customer segmentation, per customer or segment pricing logic, organizational user roles, and gated storefronts, Spree enables you to deliver tailored experiences across many storefronts, all with a single admin panel. +- [B2B eCommerce Capabilities](https://spreecommerce.org/docs/use-case/b2b/b2b-capabilities) +- [B2B eCommerce Admin Capabilities](https://spreecommerce.org/docs/use-case/b2b/b2b-admin-capabilities) +- [B2B eCommerce Buyer Experience](https://spreecommerce.org/docs/use-case/b2b/b2b-buyer-capabilities) +Spree Commerce - B2B eCommerce -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. +### A [white-label SaaS or multi-tenant eCommerce](https://spreecommerce.org/multi-tenant-white-label-ecommerce/) platform +Launch a [multi-tenant eCommerce platform](https://spreecommerce.org/multi-tenant-white-label-ecommerce/) for your customers, resellers, affiliates in any configuration, eg. B2B2B, B2B2C, B2B2E +- [Multi-Tenant Capabilities](https://spreecommerce.org/docs/use-case/multi-tenant/multi-tenant-capabilities) +- [Multi-Tenant Super Admin Capabilities](https://spreecommerce.org/docs/use-case/multi-tenant/super-admin-capabilities) +- [Tenant Capabilities](https://spreecommerce.org/docs/use-case/multi-tenant/tenant-capabilities) +Spree Commerce - Multi-store -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +### A [Multi-vendor marketplace](https://spreecommerce.org/marketplace-ecommerce/) +Run your own marketplace with multiple suppliers, each with a dedicated supplier dashboard +- [Marketplace eCommerce Capabilities](https://spreecommerce.org/docs/use-case/marketplace/capabilities) +- [Marketplace eCommerce Admin Panel](https://spreecommerce.org/docs/use-case/marketplace/admin-dashboard) +- [Marketplace eCommerce Vendor Panel](https://spreecommerce.org/docs/use-case/marketplace/vendor-dashboard) +- [Marketplace eCommerce Customer Experience](https://spreecommerce.org/docs/use-case/marketplace/customer-ux) +Spree Commerce - Marketplace diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..9a5ea73 --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require_relative "config/application" + +Rails.application.load_tasks diff --git a/app.json b/app.json new file mode 100644 index 0000000..1b0de2d --- /dev/null +++ b/app.json @@ -0,0 +1,45 @@ +{ + "name": "Spree Commerce Demo", + "description": "Spree is a is a open-source e-commerce platform for Rails. It is a great starting point for any Rails developer to quickly build an e-commerce store.", + "keywords": [ + "spree commerce", + "spree", + "e-commerce", + "global commerce" + ], + "logo": "https://spreecommerce.org/wp-content/uploads/2019/09/spree-60x60@2x.png", + "website": "https://spreecommerce.org", + "repository": "https://github.com/spree/spree_starter", + "env": { + "ADMIN_EMAIL": { + "description": "We will create an admin user with this email.", + "value": "spree@example.com" + }, + "ADMIN_PASSWORD": { + "description": "We will create an admin user with this password.", + "value": "spree123" + }, + "SECRET_KEY_BASE": { + "description": "A secret key for verifying the integrity of signed cookies.", + "generator": "secret" + } + }, + "formation": { + "web": { + "quantity": 1, + "size": "standard-2x" + } + }, + "scripts": { + "postdeploy": "bundle exec rails db:seed" + }, + "addons": [ + "heroku-postgresql", + "heroku-redis" + ], + "buildpacks": [ + { + "url": "heroku/ruby" + } + ] +} diff --git a/app/assets/builds/.keep b/app/assets/builds/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js new file mode 100644 index 0000000..f167895 --- /dev/null +++ b/app/assets/config/manifest.js @@ -0,0 +1,5 @@ +//= link_tree ../images +//= link_tree ../../javascript .js +//= link_tree ../../../vendor/javascript .js +//= link_tree ../builds +//= link application.css \ No newline at end of file diff --git a/app/assets/images/.keep b/app/assets/images/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/assets/images/homepage/products.jpg b/app/assets/images/homepage/products.jpg new file mode 100644 index 0000000..12f3f04 Binary files /dev/null and b/app/assets/images/homepage/products.jpg differ diff --git a/app/assets/images/noimage/large.png b/app/assets/images/noimage/large.png new file mode 100644 index 0000000..246d3d1 Binary files /dev/null and b/app/assets/images/noimage/large.png differ diff --git a/app/assets/images/noimage/mini.png b/app/assets/images/noimage/mini.png new file mode 100644 index 0000000..c91b4de Binary files /dev/null and b/app/assets/images/noimage/mini.png differ diff --git a/app/assets/images/noimage/plp.png b/app/assets/images/noimage/plp.png new file mode 100644 index 0000000..a5fa866 Binary files /dev/null and b/app/assets/images/noimage/plp.png differ diff --git a/app/assets/images/noimage/plp.svg b/app/assets/images/noimage/plp.svg new file mode 100644 index 0000000..838ba6d --- /dev/null +++ b/app/assets/images/noimage/plp.svg @@ -0,0 +1,16 @@ + + + + + + + + NO IMAGE + AVAILABLE + + + diff --git a/app/assets/images/noimage/product.png b/app/assets/images/noimage/product.png new file mode 100644 index 0000000..246d3d1 Binary files /dev/null and b/app/assets/images/noimage/product.png differ diff --git a/app/assets/images/noimage/small.png b/app/assets/images/noimage/small.png new file mode 100644 index 0000000..0407e9f Binary files /dev/null and b/app/assets/images/noimage/small.png differ diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css new file mode 100644 index 0000000..288b9ab --- /dev/null +++ b/app/assets/stylesheets/application.css @@ -0,0 +1,15 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's + * vendor/assets/stylesheets directory can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any other CSS + * files in this directory. Styles in this file should be added after the last require_* statement. + * It is generally better to create a new file per style scope. + * + *= require_tree . + *= require_self + */ diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css new file mode 100644 index 0000000..cf19b4c --- /dev/null +++ b/app/assets/stylesheets/application.tailwind.css @@ -0,0 +1,1761 @@ +@import url("https://esm.sh/photoswipe@5.4.4/dist/photoswipe.css"); +@import url("https://esm.sh/swiper@11.2.2/swiper-bundle.min.css"); +@import url("https://esm.sh/flag-icons@7.3.2/css/flag-icons.min.css"); + +@tailwind base; +@tailwind components; +@tailwind utilities; +@tailwind forms; + +/* + This is the storefront CSS +*/ + +.container, +.page-container { + max-width: 90rem; + padding-left: 1rem; + padding-right: 1rem; + margin-left: auto; + margin-right: auto; +} +@media (min-width: 1024px) { + .page-container { + padding-left: 3.75rem; + padding-right: 3.75rem; + } +} + +@media (min-width: 1024px) { + header.header-logo-centered.headroom--not-top + > nav + > .page-container + > .flex { + align-items: center !important; + } +} + +html { + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +.trix-content a { + text-decoration: underline; +} + +.trix-content ul { + list-style-type: revert; + list-style-position: inside; + + @apply pl-8; + + &:not(ul ul) { + @apply mt-2 mb-6; + } +} + +.trix-content li:last-child { + @apply mb-2; +} + +.trix-content ol { + list-style: decimal; + list-style-position: inside; + + @apply pl-8; + + &:not(ol ol) { + @apply mt-2 mb-6; + } +} + +.text-input { + max-width: 100%; + border-radius: var(--input-border-radius); + border-color: var(--input); + background-color: var(--input-bg); + color: var(--input-text); + height: 3rem; +} + +textarea.text-input { + height: auto; + min-height: 3rem; + border-radius: 0; +} + +.text-input:disabled { + background-color: var(--neutral-50); + border-color: var(--input); + color: var(--neutral-400); +} + +.text-input:focus { + border-color: var(--primary); + background-color: var(--input-focus-bg); + --tw-ring-color: var(--primary); +} +.invalid { + border-color: var(--danger); + --tw-ring-color: var(--danger); +} + +.turbo-frame button { + background-color: transparent; + cursor: pointer; +} + +.select-input { + cursor: pointer; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: var(--input-border-radius); + border-color: var(--input); + background-color: var(--input-bg); + color: var(--input-text); + height: 3rem; +} + +.select-input:focus { + border-color: var(--primary); + background-color: var(--input-focus-bg); + --tw-ring-color: var(--primary); +} + +.checkbox-input { + cursor: pointer; + border-radius: var(--input-border-radius) / 2; + border-color: var(--input); + background-color: transparent; +} + +.checkbox-input:checked { + background-color: var(--primary); +} + +.radio-input { + cursor: pointer; +} + +.checkbox-input:focus, +.checkbox-input:checked, +.radio-input:focus, +.radio-input:checked { + outline: none !important; + box-shadow: none !important; +} + +.menu-item { + font-weight: 400; + line-height: 0.875rem; + letter-spacing: 0.06rem; + text-transform: uppercase; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + border: 1.5px solid transparent; +} +.menu-item:hover span { + border-bottom: 1.5px solid var(--accent); +} +.menu-item:active span, +.menu-item--active span { + border-bottom: 1.5px solid var(--text); +} +.menu-item:focus { + outline: none; + padding-left: 0.5rem; + padding-right: 0.5rem; + margin-left: -0.5rem; + margin-right: -0.5rem; + border-radius: var(--button-border-radius); +} + +@media (min-width: 1024px) { + .menu-item { + font-size: 0.875rem; + line-height: 1.375rem; + letter-spacing: 0.07rem; + padding-top: 0px; + padding-bottom: 0px; + } +} + +.btn-primary, +.btn-secondary { + position: relative; + font-size: 0.875rem; + font-weight: 600; + line-height: 1.25rem; + letter-spacing: 0.07rem; + text-transform: uppercase; + text-align: center; + cursor: pointer; + border-radius: var(--button-border-radius); + background-color: var(--button-background-color, var(--button)); + padding-left: 1.25rem; + padding-right: 1.25rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + color: var(--button-text-color, var(--button-text)); + outline-offset: 0.5rem; + transition-property: + color, + background-color, + border-color, + text-decoration-color, + fill, + stroke, + -webkit-text-decoration-color; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} +.btn-primary { + border: var(--button-border-width) solid + var(--button-border-color, var(--button)); +} + +.btn-primary:focus-visible, +.btn-secondary:focus-visible, +.btn-icon:not(.btn-primary, .btn-secondary):focus-visible { + outline: none; +} + +.btn-primary:not(:disabled):focus::after, +.btn-primary:not(:disabled):active::after, +.btn-secondary:not(:disabled):focus::after, +.btn-secondary:not(:disabled):active::after { + content: ""; + border-radius: var(--button-border-radius); + position: absolute; + top: -8px; + left: -8px; + width: calc(100% + 16px); + height: calc(100% + 16px); + background-color: transparent; + display: inherit; +} + +.btn-primary:disabled, +.btn-primary.btn-disabled { + cursor: not-allowed; +} + +.btn-primary:hover:not(:disabled, .btn-disabled), +.btn-secondary:hover:not(:disabled, .btn-disabled) { + cursor: pointer; +} + +.btn-primary:hover:not(:disabled, .btn-disabled) { + color: var(--button-background-color, var(--primary)); + background-color: var(--button-text-color, var(--button-text)); +} + +.btn-primary:hover:not(:disabled) svg path { + stroke: var(--button-background-color, var(--primary)); +} + +.btn-secondary { + color: var(--secondary-button-text); + background-color: var(--secondary-button); + border: var(--button-border-width) solid + var(--button-border-color, var(--secondary-button-text)); +} + +.btn-secondary:hover:not(:disabled) { + color: var(--secondary-button); + background-color: var(--secondary-button-text); +} + +.btn-secondary:hover:not(:disabled) svg path { + stroke: var(--secondary-button); +} + +@media (hover: none) { + .btn-primary:hover:not(:disabled, .btn-disabled) { + color: var(--button-text); + background-color: var(--button); + } + .btn-secondary:hover:not(:disabled) { + color: var(--secondary-button-text); + background-color: var(--secondary-button); + } +} + +.btn-secondary:focus, +.btn-secondary:active { + outline-color: var(--secondary-button); +} + +.btn-primary.btn-icon, +.btn-secondary.btn-icon, +.link-icon { + display: flex; + justify-content: center; + align-items: center; + gap: 0.5rem; +} + +.btn-primary.btn-icon > svg .btn-secondary.btn-icon > svg { + height: 1.25rem; +} + +.btn-icon:not(.btn-primary, .btn-secondary) { + position: relative; + padding: 0.5rem; + border-radius: var(--button-border-radius); + outline-offset: 1px; +} + +.btn-icon:not(.btn-primary, .btn-secondary):hover { + background: var(--accent-100); +} + +.btn-icon:not(.btn-primary, .btn-secondary):active { + background: var(--accent); +} + +.btn-icon:not(.btn-primary, .btn-secondary):focus::after { + content: ""; + border-radius: var(--button-border-radius); + position: absolute; + top: -1px; + left: -1px; + width: calc(100% + 2px); + height: calc(100% + 2px); + background-color: transparent; + display: inherit; +} + +.link { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.375; + letter-spacing: 0.07rem; + text-transform: uppercase; + color: var(--text); + border-bottom: 1px solid transparent; +} + +.link:hover { + border-bottom-color: var(--text); +} + +.link:focus-visible { + outline-offset: 0.25rem; + padding: 0 0.25rem; + border-radius: 0.25rem; +} + +.link > svg { + height: 1.5rem; +} + +.link-disabled { + opacity: 0.3; +} + +#checkout-page .btn-primary { + border-radius: var(--button-border-radius); + border: var(--button-border-width) solid + var(--button-border-color, var(--button)); + font-size: 1rem; + font-weight: 400; + text-transform: none; + letter-spacing: initial; +} + +#checkout-page .btn-primary:focus, +#checkout-page .btn-primary:active { + outline: none; +} + +#checkout-page .btn-primary:hover:not(:disabled) { + opacity: 0.8; + background-color: var(--button); + color: var(--button-text); +} + +#checkout-page .btn-primary:disabled { + opacity: 0.5; + background-color: var(--button); + border-color: var(--button); +} + +#checkout-page .text-input, +#checkout-page .select-input { + border-radius: 0.375rem; + height: 46.8px; +} + +#checkout-page #flashes .fixed { + position: fixed; + left: 0; +} + +#checkout-page #checkout_payment_methods[busy] { + opacity: 0.5; + cursor: wait; + pointer-events: none; +} + +#checkout-page #checkout-message { + h1, + h2, + h3, + h4, + h5, + h6 { + @apply text-xl pb-1; + } +} + +.field_with_errors .text-input, +.field_with_errors .select-input { + --tw-border-opacity: 1; + border-color: rgb(220 38 38 / var(--tw-border-opacity)); +} + +.StripeElement iframe:focus-visible { + outline: none; +} + +.breadcrumb-item { + font-size: 12px; + margin-top: -1px; +} + +.breadcrumb-item::before { + content: url("data:image/svg+xml;utf8,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23ccc' class='bi bi-chevron-right' viewBox='0 0 16 16'%3e%3cpath fill-rule='evenodd' d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + padding-right: 0.5rem; + position: relative; + top: 0.25rem; +} + +.breadcrumb-item:first-child::before { + content: none; +} + +.breadcrumb-item:first-child { + margin-top: 0.1rem; +} + +.breadcrumb-square { + width: 0.25rem; + height: 0.25rem; + margin: 0.6rem 0; + background-color: var(--text); +} + +a:hover { +} + +.delivery-list-item:last-child { + border-radius: 0.375rem !important; +} + +.has-float-label { + position: relative; +} + +.has-float-label label { + color: var(--input-text); + font-size: 11px; + position: absolute; + left: 10px; + cursor: text; + top: 3px; + padding: 0 4px; + opacity: 0.8; + transition: transform 0.2s ease-in-out; + white-space: nowrap; + pointer-events: none; +} + +.has-float-label input, +.has-float-label select { + padding-top: 1rem; + padding-bottom: 0.3rem; +} + +.has-float-label input:-moz-placeholder-shown + label, +.has-float-label select:-moz-placeholder-shown + label { + opacity: 0; + transform: translateY(5px); +} + +.has-float-label input:-ms-input-placeholder + label, +.has-float-label select:-ms-input-placeholder + label { + opacity: 0; + transform: translateY(5px); +} + +.has-float-label input:placeholder-shown + label, +.has-float-label select:placeholder-shown + label { + opacity: 0; + transform: translateY(5px); +} + +.has-float-label input:-moz-placeholder-shown, +.has-float-label select:-moz-placeholder-shown { + padding-top: 0.45rem; + padding-bottom: 0.45rem; +} + +.has-float-label input:-ms-input-placeholder, +.has-float-label select:-ms-input-placeholder { + padding-top: 0.45rem; + padding-bottom: 0.45rem; +} + +.has-float-label input:placeholder-shown, +.has-float-label select:placeholder-shown { + padding-top: 0.45rem; + padding-bottom: 0.45rem; +} + +.badge, +.badge-success, +.badge-paid, +.badge-warning, +.badge-canceled, +.badge-failed, +.badge-refunded, +.badge-void, +.badge-pending, +.badge-ready, +.badge-partial, +.badge-active, +.badge-inactive { + margin-right: 0.25rem; + display: inline-block; + border-radius: var(--badge-border-radius); + padding-top: 0.125rem; + padding-bottom: 0.125rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + font-size: 0.875rem; + line-height: 1.375rem; + font-weight: 400; +} + +.badge:last-child, +.badge-success:last-child, +.badge-paid:last-child, +.badge-warning:last-child, +.badge-canceled:last-child, +.badge-failed:last-child, +.badge-refunded:last-child, +.badge-void:last-child, +.badge-pending:last-child, +.badge-ready:last-child, +.badge-partial:last-child { + margin-right: 0px; +} + +.badge-success, +.badge-paid, +.badge-active { + background-color: #d9f7ea; +} + +.badge-warning, +.badge-canceled, +.badge-failed { + background-color: #f8e7e5; +} + +.badge, +.badge-refunded, +.badge-pending, +.badge-void, +.badge-ready, +.badge-inactive { + background-color: #f3f3f3; +} + +.badge-partial { + background-color: rgb(186 230 253); +} + +address { + font-style: normal; +} + +button:focus { + outline: none; +} + +.summary-folded .summary { + height: 0px !important; +} + +.summary-folded .show-summary { + display: block; +} + +.summary-folded .hide-summary { + display: none; +} + +.chevron-summary::after { + content: url("data:image/svg+xml;utf8,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' class='bi bi-chevron-right' viewBox='0 0 16 16'%3e%3cpath fill-rule='evenodd' d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + color: var(--sidebar-divider); + transform: rotate(-90deg); + margin-left: 0.07rem; +} + +.summary-folded .chevron-summary::after { + transform: rotate(90deg); +} + +@media (min-width: 1024px) { + .summary-folded .summary { + pointer-events: auto; + height: 100% !important; + } +} + +/* .address-form { + grid-template-columns: repeat(1, minmax(0, 1fr)); +} + +@media (min-width: 768px) { + .address-form { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .address-form.cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .address-form.col-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); + } +} */ + +.field_with_errors { + display: contents; +} + +.turbo-progress-bar { + background-color: var(--primary); +} +.modal .turbo-frame-error { + display: flex; + width: 100%; + height: 100%; + align-items: center; + justify-content: center; + font-weight: normal; +} + +.card-dialog { + margin-bottom: 1.25rem; +} + +.border-default, +.border-sidebar { + border-color: var(--border-default-color); +} + +.card-dialog { + border-radius: var(--border-default-radius); + box-shadow: var(--border-default-shadow); +} + +.border-default.border-t { + border-width: 0; + border-radius: 0; + border-top-width: var(--border-default-width); +} + +.border-default.border-b { + border-width: 0; + border-radius: 0; + border-bottom-width: var(--border-default-width); +} + +.border-default.border-b.border-t { + border-width: 0; + border-radius: 0; + border-top-width: var(--border-default-width); + border-bottom-width: var(--border-default-width); +} + +.border-default.border-b-0 { + border-bottom-width: 0; +} + +.logo { + max-height: 60px; +} + +.checkout-mobile-header .logo { + display: inline; +} + +.product-image-container { + text-indent: 100%; + white-space: nowrap; + overflow: hidden; +} + +.product-image-container img { + max-width: 100%; + max-height: 100%; + margin: auto; + position: relative; + left: 50%; + transform: translateX(-50%); +} + +@media (max-width: 1024px) { + .line-items { + max-height: none !important; + } +} + +.alert-notice { + background-color: var(--success); +} + +.alert-error { + background-color: #f8e7e5; +} + +.alert-success { + background-color: var(--success); +} + +.alert-warning { + --tw-bg-opacity: 1; + background-color: rgb(254 249 195 / var(--tw-bg-opacity)); +} + +@media (min-width: 1024px) { + .background { + background: linear-gradient( + 90deg, + var(--background) 50%, + var(--accent) 50% + ); + } +} + +.quantity-picker { + display: inline-flex; + align-items: center; + gap: 8px; + border-radius: var(--input-border-radius); + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + border: var(--border-default-width) solid var(--border-default-color); +} + +.quantity-picker.border-t { + border-width: 0; + border-radius: 0; + border-top-width: var(--border-default-width); +} + +.quantity-picker.border-b { + border-width: 0; + border-radius: 0; + border-bottom-width: var(--border-default-width); +} + +.quantity-picker.border-b-0 { + border-bottom-width: 0; +} + +.quantity-picker button:not(.hidden) { + cursor: pointer; + background-color: transparent; + display: inline-flex; + width: 36px; + height: 36px; + justify-content: center; + align-items: center; + border-radius: var(--input-border-radius); +} +.quantity-picker button svg { + width: 18px; + height: 18px; +} + +.quantity-picker button:disabled { + cursor: not-allowed; + opacity: 0.5; +} + +.quantity-picker input { + width: 1.5rem; + height: 100%; + border-width: 0px; + padding: 0px 0px; + text-align: center; + background-color: transparent; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + margin: 0; +} + +.quantity-picker input::-webkit-inner-spin-button, +.quantity-picker input::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +.quantity-picker input:focus { + border-width: 0px; + outline: none; + border-color: transparent; + box-shadow: none; +} + +.quantity-picker input[type="number"]::-webkit-inner-spin-button, +.quantity-picker input[type="number"]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +.quantity-picker input[type="number"] { + -moz-appearance: textfield; +} + +.swiper-pagination-bullet { + border: 1px solid var(--primary); + background: none; + opacity: 1; + margin: 0px 0.375rem !important; + width: 10px; + height: 10px; +} + +input.without-arrows[type="number"]::-webkit-outer-spin-button, +input.without-arrows[type="number"]::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +input.without-arrows[type="number"] { + -moz-appearance: textfield; +} + +.swiper-pagination-bullet-active { + background: var(--primary) !important; +} + +.swiper-pagination-current { + color: var(--text); +} + +.swiper-pagination-lock { + display: none; +} + +.swiper-notification { + display: none; +} + +.pswp { + --pswp-bg: var(--accent) !important; + --pswp-placeholder-bg: var(--accent) !important; +} + +.pswp__button--close { + margin: 0; + width: 4rem; + height: 4rem; + background: var(--background); + opacity: 1; + display: flex; + justify-content: center; + align-items: center; +} +.pswp__button--close:hover { + background: var(--background); +} + +.pswp__button--close .pswp__icn { + position: static; + width: 1.5rem; + height: 1.5rem; +} + +.pswp__button--arrow .pswp__icn { + width: 2rem; + height: 2rem; + top: 0; + margin: 0; + left: 0; +} + +.pswp__button--arrow--next .pswp__icn { + transform: rotate(0deg) !important; +} + +.pswp__button--arrow { + width: 2rem; + height: 2rem; + bottom: 2rem; + top: auto; + visibility: visible !important; +} + +.pswp__button--arrow--prev { + left: 1rem; +} + +.pswp__button--arrow--next { + right: 1rem; +} + +.pswp__button--zoom { + display: none !important; +} + +.pswp__counter { + display: none; +} + +.pswp__bullets-indicator { + display: flex; + flex-direction: row; + align-items: center; + bottom: 2rem; + height: 2rem; + position: absolute; + left: 50%; + transform: translate(-50%, 0); +} + +.pswp__bullet { + width: 0.5rem; + height: 0.5rem; + padding: 0.25rem; + margin: 0 0.25rem; + border-radius: 50%; + border: 1px solid var(--primary); +} + +.pswp__bullet--active { + background: var(--primary); +} +.pswp__pagination { + display: none; +} + +@media (min-width: 1024px) { + .pswp__button--close { + margin-right: 3.75rem; + margin-top: 3.75rem; + } + .pswp__button--arrow { + top: 50%; + } + .pswp__button--arrow--prev { + left: 3.75rem; + } + .pswp__button--arrow--next { + right: 3.75rem; + } + .pswp__bullets-indicator { + display: none; + } + .pswp__pagination { + display: block; + position: absolute; + top: 5rem; + left: 3.75rem; + font-size: 1.5rem; + line-height: 2rem; + font-weight: 400; + color: var(--neutral); + } + .pswp__pagination--current { + color: var(--text); + } +} + +#pinch-to-zoom { + left: 50%; + z-index: 100001; + top: 50%; + transform: translate(-50%, -50%); + pointer-events: none; + display: none; +} + +.product-image :hover .zoom-icon { + display: block; +} + +.flyout-menu:hover .flyout-button button { + border-color: var(--primary); + color: var(--primary); +} + +.flyout-menu:hover .flyout-menu-container { + display: block; + z-index: 9999; +} + +.product-description p { + margin-bottom: 1rem; +} + +.swipe-slide { + -webkit-backface-visibility: hidden; + -webkit-transform: translate3d(0, 0, 0); +} + +.swiper-wrapper { + -webkit-transform-style: preserve-3d; +} + +.word-break { + word-break: break-word; +} + +.tailwind-container { + width: 100%; +} + +@media (min-width: 640px) { + .tailwind-container { + max-width: 640px; + } +} + +@media (min-width: 768px) { + .tailwind-container { + max-width: 768px; + } +} + +@media (min-width: 1024px) { + .tailwind-container { + max-width: 1024px; + } +} + +@media (min-width: 1280px) { + .tailwind-container { + max-width: 1280px; + } +} + +@media (min-width: 1536px) { + .tailwind-container { + max-width: 1536px; + } +} + +.hamburger-visible, +.search-visible { + opacity: 1; + pointer-events: auto; +} + +.hamburger-visible .body { + transform: translateX(0); +} + +.menu-open div:first-of-type { + opacity: 0; +} + +.menu-open div:last-of-type { + opacity: 1; +} + +html[aria-busy="true"] .hide-on-load { + pointer-events: none; + opacity: 0; +} + +.label { + position: absolute; + width: fit-content; + height: fit-content; + overflow-wrap: anywhere; +} + +@media (max-width: 768px) { + *[width-desktop="true"] { + width: 100% !important; + } +} + +@media (min-width: 1024px) { + .flex-centered { + position: absolute; + flex: 0 1 auto; + left: 50%; + transform: translateX(-50%); + } +} + +/* kanety/stimulus-accordion */ + +.st-accordion .st-accordion__icon svg { + transition: transform 0.2s; +} + +.st-accordion .st-accordion__icon--opened svg { + transform: rotate(-180deg); +} + +.st-accordion .st-accordion__content:not(.st-accordion__content--visible) { + height: 0; + opacity: 0; + overflow: hidden; + transition: all 0.2s; + visibility: hidden; + padding: 0; +} + +.st-accordion .st-accordion__content.st-accordion__content--visible { + opacity: 1; + transition: all 0.2s; + visibility: visible; +} + +.st-accordion button { + width: 100%; + text-align: left; +} + +.fixed-pdp-button { + transition: all 0.2s ease; +} + +@media (min-width: 1024px) { + .fixed-pdp-button { + display: none !important; + } +} + +.sidebar-pane { + max-width: 420px; +} + +#slideover-cart .line-item-total-amount { + display: none; +} + +#slideover-cart #cart_contents { + display: flex; + flex-direction: column; + height: 100%; +} +#slideover-cart #line-items { + flex-grow: 1; + overflow: auto; +} +#slideover-cart .cart-line-item { +} +.cart-line-item .delete svg { + width: 1rem !important; + height: 1rem !important; +} +#slideover-cart .cart-summary-container { + background-color: var(--accent); +} +#slideover-cart .cart-summary-container * { + text-align: left !important; +} +#slideover-cart .shopping-cart-total-text { + display: flex; + justify-content: space-between; +} +#slideover-cart .btn-primary { + width: 100%; + margin-top: 1rem; + text-align: center !important; + margin-bottom: 0; +} +#slideover-cart turbo-frame[busy] { + opacity: 0.5; + cursor: wait; +} +.line-item-overlay { + display: none; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +#slideover-cart turbo-frame[busy] .line-item-overlay { + display: block; +} + +.headroom--unpinned:not(.headroom--frozen) { + pointer-events: none; +} + +.headroom--unpinned:not([data-toggle-menu-open-value="true"]):not( + [data-slideover-open-value="true"] + ) + nav { + transform: translateY(-100%); +} +/*#region noUiSlider functional */ +.noUi-target, +.noUi-target * { + -webkit-touch-callout: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + -webkit-user-select: none; + -ms-touch-action: none; + touch-action: none; + -ms-user-select: none; + -moz-user-select: none; + user-select: none; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.noUi-target { + position: relative; +} +.noUi-base, +.noUi-connects { + width: 100%; + height: 100%; + position: relative; + z-index: 1; +} +.noUi-connects { + overflow: hidden; + z-index: 0; +} +.noUi-connect, +.noUi-origin { + will-change: transform; + position: absolute; + z-index: 1; + top: 0; + right: 0; + height: 100%; + width: 100%; + -ms-transform-origin: 0 0; + -webkit-transform-origin: 0 0; + -webkit-transform-style: preserve-3d; + transform-origin: 0 0; + transform-style: flat; +} +.noUi-txt-dir-rtl.noUi-horizontal .noUi-origin { + left: 0; + right: auto; +} +.noUi-vertical .noUi-origin { + top: -100%; + width: 0; +} +.noUi-horizontal .noUi-origin { + height: 0; +} +.noUi-handle { + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + position: absolute; +} +.noUi-touch-area { + height: 100%; + width: 100%; +} +.noUi-state-tap .noUi-connect, +.noUi-state-tap .noUi-origin { + -webkit-transition: transform 0.3s; + transition: transform 0.3s; +} +.noUi-state-drag * { + cursor: inherit !important; +} +.noUi-horizontal { + height: 18px; +} +.noUi-vertical { + width: 18px; +} +.noUi-txt-dir-rtl.noUi-horizontal .noUi-handle { + left: -17px; + right: auto; +} +/*#endregion*/ + +.noUi-target { + background: var(--border-default-color); + height: 2px; + width: calc(100% - 24px); + margin-left: 12px; +} +.noUi-connect { + background: var(--primary); + height: 2px; +} +.noUi-handle { + border: 3px solid #fff; + width: 24px; + height: 24px; + right: -12px; + top: -12px; + border-radius: 50%; + background: var(--primary); + cursor: pointer; +} + +.input-checkbox { + width: 1.5rem; + height: 1.5rem; + cursor: pointer; + border-color: var(--border-default-color); + background-color: transparent; + color: transparent; +} + +.input-checkbox:checked { + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); + border-color: var(--primary); +} +.input-checkbox:hover { + border-color: var(--primary); +} +.input-checkbox:checked:hover { + border-color: var(--primary); +} +.input-checkbox:focus, +.input-checkbox:checked:focus { + outline-color: var(--primary); + outline: none; + box-shadow: none; +} + +#search-suggestions { + z-index: 50; + width: 100%; + background-color: var(--background); + top: 0; + left: 0; + display: none; + position: absolute; +} +#search-suggestions::before { + content: ""; + position: fixed; + top: 0; + left: 0; + height: 100%; + width: 100%; + background-color: var(--background); + opacity: 0.75; + z-index: -1; + animation: fadeInTo75 0.5s ease-in-out; +} + +@keyframes fadeInTo75 { + 0% { + opacity: 0; + } + 100% { + opacity: 0.75; + } +} + +.no-scrollbar::-webkit-scrollbar { + display: none; +} + +.no-scrollbar { + -ms-overflow-style: none; + scrollbar-width: none; +} +@media (min-width: 768px) { + .custom-desktop-height { + height: var(--desktop-height); + } +} +@media (max-width: 768px) { + .custom-mobile-height { + height: var(--mobile-height); + } +} + +.rounded-input { + border-radius: var(--input-border-radius); +} + +.rounded-button { + border-radius: var(--button-border-radius); +} + +.modal { + position: fixed; + overflow-y: auto; + inset: 0px; + align-items: center; + justify-content: center; + z-index: 9999; + /* https://stackoverflow.com/questions/32082121/why-is-fixed-position-elements-being-cut-off-on-full-screen-iphone-experience-wh */ + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.modal .page-container, +.modal .main-product-container { + padding: 0 !important; + margin: 0 !important; + border: 0 none !important; +} + +.product-modal #breadcrumbs { + display: none; +} + +.product-modal .add-to-wishlist { + display: none; +} + +.media-gallery-desktop .swiper-slide-thumb-active { + position: relative; +} +.media-gallery-desktop .swiper-slide-thumb-active::after { + position: absolute; + width: 100%; + height: 100%; + border: 1px solid black; + display: block; + left: 0px; + top: 0px; + content: ""; +} + +.media-gallery-desktop .swiper-button-lock { + display: none; +} +.media-gallery-desktop { + container-name: media-gallery-desktop; + container-type: inline-size; +} +@supports (container-type: inline-size) { + .media-gallery-desktop { + --arrows-display: none; + } +} +@container media-gallery-desktop (max-width: calc(108px * 6 + 104px + 0.5rem)) { + .media-gallery-desktop:has(.swiper-slide:nth-child(6)) + > .media-gallery-desktop__wrapper { + --arrows-display: flex; + } +} +@container media-gallery-desktop (max-width: calc(108px * 5 + 104px + 0.5rem)) { + .media-gallery-desktop:has(.swiper-slide:nth-child(5)) + > .media-gallery-desktop__wrapper { + --arrows-display: flex; + } +} +@container media-gallery-desktop (max-width: calc(108px * 4 + 104px + 0.5rem)) { + .media-gallery-desktop:has(.swiper-slide:nth-child(4)) + > .media-gallery-desktop__wrapper { + --arrows-display: flex; + } +} +@container media-gallery-desktop (max-width: calc(108px * 3 + 104px + 0.5rem)) { + .media-gallery-desktop:has(.swiper-slide:nth-child(3)) + > .media-gallery-desktop__wrapper { + --arrows-display: flex; + } +} +@container media-gallery-desktop (max-width: calc(108px * 2 + 104px + 0.5rem)) { + .media-gallery-desktop:has(.swiper-slide:nth-child(2)) + > .media-gallery-desktop__wrapper { + --arrows-display: flex; + } +} + +.media-gallery-desktop-arrow { + display: var(--arrows-display, flex); +} + +#floating-cart-icon { + bottom: 1rem; + right: 1rem; + z-index: 9998; +} + +.custom-height { + height: var(--mobile-height, var(--height)); +} +@media (min-width: 501px) { + .custom-height { + height: var(--desktop-height, var(--height)); + } +} +@media (min-width: 768px) { + .desktop-max-width { + max-width: var(--desktop-max-width); + } +} + +.checkout-container { + --main-container-width: 650px; + --summary-container-width: 455px; + grid-template-rows: min-content auto; + grid-template-columns: 1fr; + grid-template-areas: + "summary" + "main"; +} + +@media (min-width: 768px) { + .checkout-container { + grid-template-rows: 1fr; + grid-template-columns: + minmax(0, 1fr) + minmax(0, var(--main-container-width)) + minmax(0, var(--summary-container-width)) + minmax(0, 1fr); + grid-template-areas: "main main summary summary"; + } +} + +#checkout-main #flashes { + --flashes-container-width: var(--main-container-width) + + var(--summary-container-width); + grid-template-columns: + minmax(0, 1fr) + minmax(0, calc(var(--flashes-container-width))) + minmax(0, 1fr); + grid-template-areas: ". flash ."; + display: grid; + left: 0; +} + +#checkout-main #flashes > div { + grid-area: flash; +} + +#checkout-main { + background: var(--background); + grid-area: main; +} + +#checkout-summary { + background: var(--accent); + grid-area: summary; +} + +#checkout-main > .checkout-main-container, +#checkout-footer { + max-width: var(--main-container-width); + width: 100%; + inline-size: 100%; + padding: 0px 21px; +} +#checkout-footer { + padding: 16px 21px; + padding-top: 0; +} +#checkout-summary > .checkout-summary-container { + max-width: var(--summary-container-width); + width: 100%; + inline-size: 100%; + padding: 21px; +} + +@media (min-width: 768px) { + #checkout-main > .checkout-main-container { + padding: 42px; + flex-grow: 1; + } + #checkout-footer { + padding: 16px 42px; + padding-top: 0; + } + #checkout-summary > .checkout-summary-container { + padding: 42px; + position: sticky; + top: 0; + } +} + +.size-chart-table table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; +} +.size-chart-table tr th { + border: 1px solid var(--border-default-color); + padding: 0.25rem; + text-align: center; + font-weight: 600; +} +.size-chart-table tr td { + border: 1px solid var(--border-default-color); + padding: 0.25rem; + text-align: center; +} + +.dropdown-button:focus svg { + rotate: 180deg; + transition: 200ms; +} + +/* PDP properties */ +.product-property { + ul { + list-style: disc; + padding-left: 2rem; + } + + ol { + list-style: decimal; + padding-left: 2rem; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + font-size: 1.5rem; + line-height: 2rem; + } + + a { + font-weight: 600; + line-height: 1.375; + letter-spacing: 0.07rem; + color: var(--text); + border-bottom: 1px solid transparent; + + &:hover { + border-bottom-color: var(--text); + } + + &:focus-visible { + outline-offset: 0.25rem; + padding: 0 0.25rem; + border-radius: 0.25rem; + } + } +} +.product-description-truncated { + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: var(--read-more-line-clamp, 3); +} +.header--nav-item .menu-item:focus:not(.header--mega-nav-container *) { + outline: none; + padding-left: 1rem; + padding-right: 1rem; + margin-left: 0rem; + margin-right: 0rem; +} + +.post-details-content { + h1, + h2, + h3, + h4, + h5, + h6 { + @apply text-xl font-medium my-4; + } + + li { + b, + strong { + @apply font-semibold; + } + } + + pre { + @apply mb-4; + } + + p { + @apply my-4; + } + + p:first-child { + margin-top: 0; + } + + img { + width: 100%; + } + + hr { + @apply mt-4 mb-6; + } + + .attachment { + @apply my-6; + } + + .attachment__caption { + @apply text-center text-neutral-600 italic; + } +} + +.prose:not(:has(h1)) { + h2:first-of-type { + margin-top: 0; + } +} + +.pagination { + .pagination-link { + border: 1.5px solid transparent; + } + + .pagination-link:hover { + border-bottom: 1.5px solid var(--accent); + } + + .pagination-link:active, + .pagination-link--active { + border-bottom: 1.5px solid var(--text); + } + + .pagination-link--disabled { + color: var(--neutral); + pointer-events: none; + } +} + +label:has(.input-address-default:disabled) { + color: var(--neutral); +} + +.input-address-default:disabled { + @apply cursor-not-allowed; + + border-color: var(--neutral); + background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='#999999' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); + + &:hover { + border-color: var(--neutral); + } +} + +body:has(.currency-and-locale-modal:not(.hidden)) .page-contents { + position: relative; + z-index: 1; +} + +.video-embed-container { + iframe { + width: 100%; + height: auto; + aspect-ratio: 1.77; + } +} diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb new file mode 100644 index 0000000..d672697 --- /dev/null +++ b/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb new file mode 100644 index 0000000..0ff5442 --- /dev/null +++ b/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000..09705d1 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < ActionController::Base +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/controllers/spree/user_passwords_controller.rb b/app/controllers/spree/user_passwords_controller.rb new file mode 100644 index 0000000..fde1908 --- /dev/null +++ b/app/controllers/spree/user_passwords_controller.rb @@ -0,0 +1,17 @@ +module Spree + class UserPasswordsController < ::Devise::PasswordsController + include Spree::Storefront::DeviseConcern + + protected + + def translation_scope + 'devise.user_passwords' + end + + private + + def title + Spree.t(:forgot_password) + end + end +end diff --git a/app/controllers/spree/user_registrations_controller.rb b/app/controllers/spree/user_registrations_controller.rb new file mode 100644 index 0000000..af11a91 --- /dev/null +++ b/app/controllers/spree/user_registrations_controller.rb @@ -0,0 +1,17 @@ +module Spree + class UserRegistrationsController < ::Devise::RegistrationsController + include Spree::Storefront::DeviseConcern + + protected + + def translation_scope + 'devise.user_registrations' + end + + private + + def title + Spree.t(:sign_up) + end + end +end diff --git a/app/controllers/spree/user_sessions_controller.rb b/app/controllers/spree/user_sessions_controller.rb new file mode 100644 index 0000000..956d455 --- /dev/null +++ b/app/controllers/spree/user_sessions_controller.rb @@ -0,0 +1,17 @@ +module Spree + class UserSessionsController < ::Devise::SessionsController + include Spree::Storefront::DeviseConcern + + protected + + def translation_scope + 'devise.user_sessions' + end + + private + + def title + Spree.t(:login) + end + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 0000000..de6be79 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/app/javascript/application.js b/app/javascript/application.js new file mode 100644 index 0000000..d33bbbc --- /dev/null +++ b/app/javascript/application.js @@ -0,0 +1,4 @@ +// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails +import "@hotwired/turbo-rails" +import "controllers" +import "@rails/request.js" diff --git a/app/javascript/controllers/application.js b/app/javascript/controllers/application.js new file mode 100644 index 0000000..1213e85 --- /dev/null +++ b/app/javascript/controllers/application.js @@ -0,0 +1,9 @@ +import { Application } from "@hotwired/stimulus" + +const application = Application.start() + +// Configure Stimulus development experience +application.debug = false +window.Stimulus = application + +export { application } diff --git a/app/javascript/controllers/hello_controller.js b/app/javascript/controllers/hello_controller.js new file mode 100644 index 0000000..5975c07 --- /dev/null +++ b/app/javascript/controllers/hello_controller.js @@ -0,0 +1,7 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + connect() { + this.element.textContent = "Hello World!" + } +} diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js new file mode 100644 index 0000000..54ad4ca --- /dev/null +++ b/app/javascript/controllers/index.js @@ -0,0 +1,11 @@ +// Import and register all your controllers from the importmap under controllers/* + +import { application } from "controllers/application" + +// Eager load all controllers defined in the import map under controllers/**/*_controller +import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" +eagerLoadControllersFrom("controllers", application) + +// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!) +// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading" +// lazyLoadControllersFrom("controllers", application) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb new file mode 100644 index 0000000..d394c3d --- /dev/null +++ b/app/jobs/application_job.rb @@ -0,0 +1,7 @@ +class ApplicationJob < ActiveJob::Base + # Automatically retry jobs that encountered a deadlock + # retry_on ActiveRecord::Deadlocked + + # Most jobs are safe to ignore if the underlying records are no longer available + # discard_on ActiveJob::DeserializationError +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100644 index 0000000..3c34c81 --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: "from@example.com" + layout "mailer" +end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 0000000..b63caeb --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + primary_abstract_class +end diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/spree/admin_user.rb b/app/models/spree/admin_user.rb new file mode 100644 index 0000000..86f67ef --- /dev/null +++ b/app/models/spree/admin_user.rb @@ -0,0 +1,8 @@ +class Spree::AdminUser < ApplicationRecord + # Include default devise modules. Others available are: + # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable + devise :database_authenticatable, :registerable, + :recoverable, :rememberable, :validatable, :trackable + + include Spree::UserMethods +end diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb new file mode 100644 index 0000000..913ee61 --- /dev/null +++ b/app/models/spree/user.rb @@ -0,0 +1,11 @@ +class Spree::User < Spree.base_class + # Include default devise modules. Others available are: + # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable + devise :database_authenticatable, :registerable, + :recoverable, :rememberable, :validatable + + # Spree modules + include Spree::UserAddress + include Spree::UserMethods + include Spree::UserPaymentSource +end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100644 index 0000000..9c7396e --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,16 @@ + + + + SpreeStarter + + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + + <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> + <%= javascript_importmap_tags %> + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100644 index 0000000..3aac900 --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 0000000..37f0bdd --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/bin/brakeman b/bin/brakeman new file mode 100755 index 0000000..ace1c9b --- /dev/null +++ b/bin/brakeman @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +ARGV.unshift("--ensure-latest") + +load Gem.bin_path("brakeman", "brakeman") diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 0000000..50da5fd --- /dev/null +++ b/bin/bundle @@ -0,0 +1,109 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'bundle' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "rubygems" + +m = Module.new do + module_function + + def invoked_as_script? + File.expand_path($0) == File.expand_path(__FILE__) + end + + def env_var_version + ENV["BUNDLER_VERSION"] + end + + def cli_arg_version + return unless invoked_as_script? # don't want to hijack other binstubs + return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` + bundler_version = nil + update_index = nil + ARGV.each_with_index do |a, i| + if update_index && update_index.succ == i && a.match?(Gem::Version::ANCHORED_VERSION_PATTERN) + bundler_version = a + end + next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/ + bundler_version = $1 + update_index = i + end + bundler_version + end + + def gemfile + gemfile = ENV["BUNDLE_GEMFILE"] + return gemfile if gemfile && !gemfile.empty? + + File.expand_path("../Gemfile", __dir__) + end + + def lockfile + lockfile = + case File.basename(gemfile) + when "gems.rb" then gemfile.sub(/\.rb$/, ".locked") + else "#{gemfile}.lock" + end + File.expand_path(lockfile) + end + + def lockfile_version + return unless File.file?(lockfile) + lockfile_contents = File.read(lockfile) + return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/ + Regexp.last_match(1) + end + + def bundler_requirement + @bundler_requirement ||= + env_var_version || + cli_arg_version || + bundler_requirement_for(lockfile_version) + end + + def bundler_requirement_for(version) + return "#{Gem::Requirement.default}.a" unless version + + bundler_gem_version = Gem::Version.new(version) + + bundler_gem_version.approximate_recommendation + end + + def load_bundler! + ENV["BUNDLE_GEMFILE"] ||= gemfile + + activate_bundler + end + + def activate_bundler + gem_error = activation_error_handling do + gem "bundler", bundler_requirement + end + return if gem_error.nil? + require_error = activation_error_handling do + require "bundler/version" + end + return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) + 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}'`" + exit 42 + end + + def activation_error_handling + yield + nil + rescue StandardError, LoadError => e + e + end +end + +m.load_bundler! + +if m.invoked_as_script? + load Gem.bin_path("bundler", "bundle") +end diff --git a/bin/dev b/bin/dev new file mode 100755 index 0000000..e4a2331 --- /dev/null +++ b/bin/dev @@ -0,0 +1,7 @@ +#!/usr/bin/env sh +if ! gem list foreman -i --silent; then + echo "Installing foreman..." + gem install foreman +fi + +exec foreman start -f Procfile.dev "$@" diff --git a/bin/docker-entrypoint b/bin/docker-entrypoint new file mode 100755 index 0000000..3176d2c --- /dev/null +++ b/bin/docker-entrypoint @@ -0,0 +1,8 @@ +#!/bin/bash -e + +# If running the rails server then create or migrate existing database +if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then + AUTO_ACCEPT=1 ./bin/rails db:prepare +fi + +exec "${@}" diff --git a/bin/importmap b/bin/importmap new file mode 100755 index 0000000..36502ab --- /dev/null +++ b/bin/importmap @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby + +require_relative "../config/application" +require "importmap/commands" diff --git a/bin/rails b/bin/rails new file mode 100755 index 0000000..efc0377 --- /dev/null +++ b/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path("../config/application", __dir__) +require_relative "../config/boot" +require "rails/commands" diff --git a/bin/rake b/bin/rake new file mode 100755 index 0000000..4fbf10b --- /dev/null +++ b/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative "../config/boot" +require "rake" +Rake.application.run diff --git a/bin/render-build.sh b/bin/render-build.sh new file mode 100755 index 0000000..269c97a --- /dev/null +++ b/bin/render-build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +# exit on error +set -o errexit + +bundle install --deployment +bin/rails assets:precompile +bin/rails assets:clean \ No newline at end of file diff --git a/bin/rubocop b/bin/rubocop new file mode 100755 index 0000000..40330c0 --- /dev/null +++ b/bin/rubocop @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +# explicit rubocop config increases performance slightly while avoiding config confusion. +ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) + +load Gem.bin_path("rubocop", "rubocop") diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..05b87ef --- /dev/null +++ b/bin/setup @@ -0,0 +1,54 @@ +#!/usr/bin/env ruby +require "fileutils" + +APP_ROOT = File.expand_path("..", __dir__) + +def system!(*args) + system(*args, exception: true) +end + +FileUtils.chdir APP_ROOT do + # This script is a way to set up or update your development environment automatically. + # This script is idempotent, so that you can run it at any time and get an expectable outcome. + # Add necessary setup steps to this file. + + puts "== Installing dependencies ==" + system("bundle check") || system!("bundle install") + + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # FileUtils.cp "config/database.yml.sample", "config/database.yml" + # end + + puts "\n== Preparing database ==" + system! "bin/rails db:prepare" + + puts "\n== Seeding database ==" + system! "bin/rails db:seed" + + puts "\n== Setup ENVs ==" + unless File.exist?(".env") + puts "Creating .env file..." + FileUtils.cp ".env.example", ".env" if File.exist?(".env.example") + + # If .env.example doesn't exist, create a basic .env file + unless File.exist?(".env") + File.open(".env", "w") do |f| + f.puts "SECRET_KEY_BASE=#{`bin/rails secret`.strip}" + end + end + + puts "Created .env file" + else + puts ".env file already exists" + end + + puts "\n== Removing old logs and tempfiles ==" + system! "bin/rails log:clear tmp:clear" + + unless ARGV.include?("--skip-server") + puts "\n== Starting development server ==" + STDOUT.flush # flush the output before exec(2) so that it displays + exec "bin/dev" + end +end diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..4a3c09a --- /dev/null +++ b/config.ru @@ -0,0 +1,6 @@ +# This file is used by Rack-based servers to start the application. + +require_relative "config/environment" + +run Rails.application +Rails.application.load_server diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 0000000..0bd5c2e --- /dev/null +++ b/config/application.rb @@ -0,0 +1,37 @@ +require_relative "boot" + +require "rails/all" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module SpreeStarter + class Application < Rails::Application + config.to_prepare do + # Load application's model / class decorators + Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c| + Rails.configuration.cache_classes ? require(c) : load(c) + end + end + + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 8.0 + + # Please, add to the `ignore` list any other `lib` subdirectories that do + # not contain `.rb` files, or that should not be reloaded or eager loaded. + # Common ones are `templates`, `generators`, or `middleware`, for example. + config.autoload_lib(ignore: %w[assets tasks]) + + # Configuration for the application, engines, and railties goes here. + # + # These settings can be overridden in specific environments using the files + # in config/environments, which are processed later. + # + # config.time_zone = "Central Time (US & Canada)" + # config.eager_load_paths << Rails.root.join("extras") + + # https://github.com/rails/rails/issues/45826 + config.active_record.yaml_column_permitted_classes = [Symbol, BigDecimal, Date, Time, ActiveSupport::TimeWithZone, ActiveSupport::TimeZone, ActiveSupport::HashWithIndifferentAccess] + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000..988a5dd --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,4 @@ +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "bundler/setup" # Set up gems listed in the Gemfile. +require "bootsnap/setup" # Speed up boot time by caching expensive operations. diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 0000000..11182f9 --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,11 @@ +development: + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + +test: + adapter: test + +production: + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + channel_prefix: spree_production \ No newline at end of file diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000..9badaa6 --- /dev/null +++ b/config/database.yml @@ -0,0 +1,100 @@ +# PostgreSQL. Versions 9.3 and up are supported. +# +# Install the pg driver: +# gem install pg +# On macOS with Homebrew: +# gem install pg -- --with-pg-config=/usr/local/bin/pg_config +# On Windows: +# gem install pg +# Choose the win32 build. +# Install PostgreSQL and put its /bin directory on your path. +# +# Configure Using Gemfile +# gem "pg" +# +default: &default + adapter: postgresql + encoding: unicode + # For details on connection pooling, see Rails configuration guide + # https://guides.rubyonrails.org/configuring.html#database-pooling + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + +development: &development + <<: *default + database: spree_starter_development + host: <%= ENV.fetch('DB_HOST', 'localhost') %> + username: <%= ENV.fetch('DB_USER', 'postgres') %> + password: <%= ENV.fetch('DB_PASSWORD', 'password') %> + port: <%= ENV.fetch('DB_PORT', 5432) %> + # On MacOS some users are reporting crashes when first trying to access + # the database. This workaround was suggested in this issue on `ruby-pg`: + # https://github.com/ged/ruby-pg/issues/538 + gssencmode: disable + + + # The specified database role being used to connect to PostgreSQL. + # To create additional roles in PostgreSQL see `$ createuser --help`. + # When left blank, PostgreSQL will use the default role. This is + # the same name as the operating system user running Rails. + #username: spree_starter + + # The password associated with the PostgreSQL role (username). + #password: + + # Connect on a TCP socket. Omitted by default since the client uses a + # domain socket that doesn't need configuration. Windows does not have + # domain sockets, so uncomment these lines. + #host: localhost + + # The TCP port the server listens on. Defaults to 5432. + # If your server runs on a different port number, change accordingly. + #port: 5432 + + # Schema search path. The server defaults to $user,public + #schema_search_path: myapp,sharedapp,public + + # Minimum log levels, in increasing order: + # debug5, debug4, debug3, debug2, debug1, + # log, notice, warning, error, fatal, and panic + # Defaults to warning. + #min_messages: notice + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: spree_starter_test + host: <%= ENV.fetch('DB_HOST', 'localhost') %> + username: <%= ENV.fetch('DB_USER', 'postgres') %> + password: <%= ENV.fetch('DB_PASSWORD', 'password') %> + port: <%= ENV.fetch('DB_PORT', 5432) %> + # On MacOS some users are reporting crashes when first trying to access + # the database. This workaround was suggested in this issue on `ruby-pg`: + # https://github.com/ged/ruby-pg/issues/538 + gssencmode: disable + + +# As with config/credentials.yml, you never want to store sensitive information, +# like your database password, in your source code. If your source code is +# ever seen by anyone, they now have access to your database. +# +# Instead, provide the password or a full connection URL as an environment +# variable when you boot the app. For example: +# +# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" +# +# If the connection URL is provided in the special DATABASE_URL environment +# variable, Rails will automatically merge its configuration values on top of +# the values provided in this file. Alternatively, you can specify a connection +# URL environment variable explicitly: +# +# production: +# url: <%= ENV["MY_APP_DATABASE_URL"] %> +# +# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database +# for a full overview on how database connection configuration can be specified. +# +production: + <<: *default + url: <%= ENV['DATABASE_URL'] %> diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000..cac5315 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative "application" + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000..2c78164 --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,83 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Make code changes take effect immediately without server restart. + config.enable_reloading = true + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable server timing. + config.server_timing = true + + # Enable/disable Action Controller caching. By default Action Controller caching is disabled. + # Run rails dev:cache to toggle Action Controller caching. + if Rails.root.join("tmp/caching-dev.txt").exist? + config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true + config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" } + else + config.action_controller.perform_caching = false + end + + # Change to :null_store to avoid any caching. + config.cache_store = :memory_store + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + # Make template changes take effect immediately. + config.action_mailer.perform_caching = false + + # Set localhost to be used by links generated in mailer templates. + config.action_mailer.default_url_options = { host: "localhost", port: 3000 } + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + + # Append comments with runtime information tags to SQL queries in logs. + config.active_record.query_log_tags_enabled = true + + # Highlight code that enqueued background job in logs. + config.active_job.verbose_enqueue_logs = true + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + config.action_view.annotate_rendered_view_with_filenames = true + + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true + + # Raise error when a before_action's only/except options reference missing actions. + config.action_controller.raise_on_missing_callback_actions = true + + # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. + # config.generators.apply_rubocop_autocorrect_after_generate! + + # sidekiq + config.active_job.queue_adapter = :sidekiq + + # letter opener + config.action_mailer.delivery_method = :letter_opener + config.action_mailer.perform_deliveries = true + + config.hosts << "18.141.239.213" + config.action_controller.default_url_options = { host: "18.141.239.213", protocol: "http" } + +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000..339955a --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,111 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.enable_reloading = false + + # Eager load code on boot for better performance and memory savings (ignored by Rake tasks). + config.eager_load = true + + # Full error reports are disabled. + config.consider_all_requests_local = false + + # Turn on fragment caching in view templates. + config.action_controller.perform_caching = true + + # Cache assets for far-future expiry since they are all digest stamped. + config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" } + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.asset_host = "http://assets.example.com" + + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = :local + + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + config.assume_ssl = true + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + config.force_ssl = true + + # Skip http-to-https redirect for the default health check endpoint. + # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } + + # Log to STDOUT with the current request id as a default log tag. + config.log_tags = [ :request_id ] + config.logger = ActiveSupport::TaggedLogging.logger(STDOUT) + + # Change to "debug" to log everything (including potentially personally-identifiable information!) + config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") + + # Prevent health checks from clogging up the logs. + config.silence_healthcheck_path = "/up" + + # Don't log any deprecations. + config.active_support.report_deprecations = false + + # Replace the default in-process memory cache store with a durable alternative. + # https://guides.rubyonrails.org/caching_with_rails.html#activesupport-cache-rediscachestore + if ENV['REDIS_CACHE_URL'].present? + cache_servers = ENV['REDIS_CACHE_URL'].split(',') # if multiple instances are provided + config.cache_store = :redis_cache_store, { + url: cache_servers, + connect_timeout: 30, # Defaults to 1 second + read_timeout: 0.2, # Defaults to 1 second + write_timeout: 0.2, # Defaults to 1 second + reconnect_attempts: 2, # Defaults to 1 + } + else + config.cache_store = :memory_store + end + + # Replace the default in-process and non-durable queuing backend for Active Job. + config.active_job.queue_adapter = :sidekiq + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Set host to be used by links generated in mailer templates. + # config.action_mailer.default_url_options = { host: "example.com" } + + # Specify outgoing SMTP server. Remember to add smtp/* credentials via rails credentials:edit. + if ENV['SENDGRID_API_KEY'].present? + config.action_mailer.smtp_settings = { + user_name: 'apikey', # This is the string literal 'apikey', NOT the ID of your API key + password: ENV['SENDGRID_API_KEY'], # This is the secret sendgrid API key which was issued during API key creation + domain: ENV.fetch('SENDGRID_DOMAIN', Rails.application.routes.default_url_options[:host]), + address: 'smtp.sendgrid.net', + port: 587, + authentication: :plain, + enable_starttls_auto: true + } + end + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false + + # Only use :id for inspections in production. + config.active_record.attributes_for_inspect = [ :id ] + + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } + + # Fix for Render deployment + # this will set the store URL to the render external URL during db:seeds for the first time + if ENV['RENDER_EXTERNAL_URL'].present? + Rails.application.routes.default_url_options[:host] = ENV['RENDER_EXTERNAL_URL'] + end +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000..c2095b1 --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,53 @@ +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # While tests run files are not watched, reloading is not necessary. + config.enable_reloading = false + + # Eager loading loads your entire application. When running a single test locally, + # this is usually not necessary, and can slow down your test suite. However, it's + # recommended that you enable it in continuous integration systems to ensure eager + # loading is working properly before deploying your code. + config.eager_load = ENV["CI"].present? + + # Configure public file server for tests with cache-control for performance. + config.public_file_server.headers = { "cache-control" => "public, max-age=3600" } + + # Show full error reports. + config.consider_all_requests_local = true + config.cache_store = :null_store + + # Render exception templates for rescuable exceptions and raise for other exceptions. + config.action_dispatch.show_exceptions = :rescuable + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + config.active_storage.service = :test + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Set host to be used by links generated in mailer templates. + config.action_mailer.default_url_options = { host: "example.com" } + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + + # Raise error when a before_action's only/except options reference missing actions. + config.action_controller.raise_on_missing_callback_actions = true +end diff --git a/config/importmap.rb b/config/importmap.rb new file mode 100644 index 0000000..909dfc5 --- /dev/null +++ b/config/importmap.rb @@ -0,0 +1,7 @@ +# Pin npm packages by running ./bin/importmap + +pin "application" +pin "@hotwired/turbo-rails", to: "turbo.min.js" +pin "@hotwired/stimulus", to: "stimulus.min.js" +pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" +pin_all_from "app/javascript/controllers", under: "controllers" diff --git a/config/initializers/active_storage.rb b/config/initializers/active_storage.rb new file mode 100644 index 0000000..ed34f86 --- /dev/null +++ b/config/initializers/active_storage.rb @@ -0,0 +1,2 @@ +Rails.application.config.active_storage.resolve_model_to_route = :rails_storage_proxy +Rails.application.config.active_storage.variant_processor = :vips diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100644 index 0000000..4873244 --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = "1.0" + +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb new file mode 100644 index 0000000..b3076b3 --- /dev/null +++ b/config/initializers/content_security_policy.rb @@ -0,0 +1,25 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy. +# See the Securing Rails Applications Guide for more information: +# https://guides.rubyonrails.org/security.html#content-security-policy-header + +# Rails.application.configure do +# config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end +# +# # Generate session nonces for permitted importmap, inline scripts, and inline styles. +# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } +# config.content_security_policy_nonce_directives = %w(script-src style-src) +# +# # Report violations without enforcing the policy. +# # config.content_security_policy_report_only = true +# end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb new file mode 100644 index 0000000..615d76c --- /dev/null +++ b/config/initializers/devise.rb @@ -0,0 +1,313 @@ +# frozen_string_literal: true + +# Assuming you have not yet modified this file, each configuration option below +# is set to its default value. Note that some are commented out while others +# are not: uncommented lines are intended to protect your configuration from +# breaking changes in upgrades (i.e., in the event that future versions of +# Devise change the default values for those options). +# +# Use this hook to configure devise mailer, warden hooks and so forth. +# Many of these configuration options can be set straight in your model. +Devise.setup do |config| + # The secret key used by Devise. Devise uses this key to generate + # random tokens. Changing this key will render invalid all existing + # confirmation, reset password and unlock tokens in the database. + # Devise will use the `secret_key_base` as its `secret_key` + # by default. You can change it below and use your own secret key. + config.secret_key = Rails.application.credentials.secret_key_base || ENV['SECRET_KEY_BASE'] + + # ==> Controller configuration + # Configure the parent class to the devise controllers. + config.parent_controller = 'Spree::BaseController' + + # ==> Mailer Configuration + # Configure the e-mail address which will be shown in Devise::Mailer, + # note that it will be overwritten if you use your own mailer class + # with default "from" parameter. + config.mailer_sender = ENV.fetch('MAIL_FROM_ADDRESS', "support@mystore.com") + + # Configure the class responsible to send e-mails. + # config.mailer = 'Spree::DeviseMailer' + + # Configure the parent class responsible to send e-mails. + config.parent_mailer = 'Spree::BaseMailer' + + # ==> ORM configuration + # Load and configure the ORM. Supports :active_record (default) and + # :mongoid (bson_ext recommended) by default. Other ORMs may be + # available as additional gems. + require 'devise/orm/active_record' + + # ==> Configuration for any authentication mechanism + # Configure which keys are used when authenticating a user. The default is + # just :email. You can configure it to use [:username, :subdomain], so for + # authenticating a user, both parameters are required. Remember that those + # parameters are used only when authenticating and not when retrieving from + # session. If you need permissions, you should implement that in a before filter. + # You can also supply a hash where the value is a boolean determining whether + # or not authentication should be aborted when the value is not present. + # config.authentication_keys = [:email] + + # Configure parameters from the request object used for authentication. Each entry + # given should be a request method and it will automatically be passed to the + # find_for_authentication method and considered in your model lookup. For instance, + # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. + # The same considerations mentioned for authentication_keys also apply to request_keys. + # config.request_keys = [] + + # Configure which authentication keys should be case-insensitive. + # These keys will be downcased upon creating or modifying a user and when used + # to authenticate or find a user. Default is :email. + config.case_insensitive_keys = [:email] + + # Configure which authentication keys should have whitespace stripped. + # These keys will have whitespace before and after removed upon creating or + # modifying a user and when used to authenticate or find a user. Default is :email. + config.strip_whitespace_keys = [:email] + + # Tell if authentication through request.params is enabled. True by default. + # It can be set to an array that will enable params authentication only for the + # given strategies, for example, `config.params_authenticatable = [:database]` will + # enable it only for database (email + password) authentication. + # config.params_authenticatable = true + + # Tell if authentication through HTTP Auth is enabled. False by default. + # It can be set to an array that will enable http authentication only for the + # given strategies, for example, `config.http_authenticatable = [:database]` will + # enable it only for database authentication. + # For API-only applications to support authentication "out-of-the-box", you will likely want to + # enable this with :database unless you are using a custom strategy. + # The supported strategies are: + # :database = Support basic authentication with authentication key + password + # config.http_authenticatable = false + + # If 401 status code should be returned for AJAX requests. True by default. + # config.http_authenticatable_on_xhr = true + + # The realm used in Http Basic Authentication. 'Application' by default. + config.http_authentication_realm = 'Spree Application' + + # It will change confirmation, password recovery and other workflows + # to behave the same regardless if the e-mail provided was right or wrong. + # Does not affect registerable. + # config.paranoid = true + + # By default Devise will store the user in session. You can skip storage for + # particular strategies by setting this option. + # Notice that if you are skipping storage for all authentication paths, you + # may want to disable generating routes to Devise's sessions controller by + # passing skip: :sessions to `devise_for` in your config/routes.rb + config.skip_session_storage = [:http_auth] + + # By default, Devise cleans up the CSRF token on authentication to + # avoid CSRF token fixation attacks. This means that, when using AJAX + # requests for sign in and sign up, you need to get a new CSRF token + # from the server. You can disable this option at your own risk. + # config.clean_up_csrf_token_on_authentication = true + + # When false, Devise will not attempt to reload routes on eager load. + # This can reduce the time taken to boot the app but if your application + # requires the Devise mappings to be loaded during boot time the application + # won't boot properly. + # config.reload_routes = true + + # ==> Configuration for :database_authenticatable + # For bcrypt, this is the cost for hashing the password and defaults to 12. If + # using other algorithms, it sets how many times you want the password to be hashed. + # The number of stretches used for generating the hashed password are stored + # with the hashed password. This allows you to change the stretches without + # invalidating existing passwords. + # + # Limiting the stretches to just one in testing will increase the performance of + # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use + # a value less than 10 in other environments. Note that, for bcrypt (the default + # algorithm), the cost increases exponentially with the number of stretches (e.g. + # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). + config.stretches = Rails.env.test? ? 1 : 12 + + # Set up a pepper to generate the hashed password. + # config.pepper = 'c15d8d05f7bc89ed79d15ae9004c7ed6ca207358cc79f37daee6ac122752197c7ed3235d7d444901997fae450cc02f278399ef6423e3658b5ff1ab6e01188edf' + + # Send a notification to the original email when the user's email is changed. + # config.send_email_changed_notification = false + + # Send a notification email when the user's password is changed. + # config.send_password_change_notification = false + + # ==> Configuration for :confirmable + # A period that the user is allowed to access the website even without + # confirming their account. For instance, if set to 2.days, the user will be + # able to access the website for two days without confirming their account, + # access will be blocked just in the third day. + # You can also set it to nil, which will allow the user to access the website + # without confirming their account. + # Default is 0.days, meaning the user cannot access the website without + # confirming their account. + # config.allow_unconfirmed_access_for = 2.days + + # A period that the user is allowed to confirm their account before their + # token becomes invalid. For example, if set to 3.days, the user can confirm + # their account within 3 days after the mail was sent, but on the fourth day + # their account can't be confirmed with the token any more. + # Default is nil, meaning there is no restriction on how long a user can take + # before confirming their account. + # config.confirm_within = 3.days + + # If true, requires any email changes to be confirmed (exactly the same way as + # initial account confirmation) to be applied. Requires additional unconfirmed_email + # db field (see migrations). Until confirmed, new email is stored in + # unconfirmed_email column, and copied to email column on successful confirmation. + config.reconfirmable = true + + # Defines which key will be used when confirming an account + # config.confirmation_keys = [:email] + + # ==> Configuration for :rememberable + # The time the user will be remembered without asking for credentials again. + # config.remember_for = 2.weeks + + # Invalidates all the remember me tokens when the user signs out. + config.expire_all_remember_me_on_sign_out = true + + # If true, extends the user's remember period when remembered via cookie. + # config.extend_remember_period = false + + # Options to be passed to the created cookie. For instance, you can set + # secure: true in order to force SSL only cookies. + # config.rememberable_options = {} + + # ==> Configuration for :validatable + # Range for password length. + config.password_length = 6..128 + + # Email regex used to validate email formats. It simply asserts that + # one (and only one) @ exists in the given string. This is mainly + # to give user feedback and not to assert the e-mail validity. + config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ + + # ==> Configuration for :timeoutable + # The time you want to timeout the user session without activity. After this + # time the user will be asked for credentials again. Default is 30 minutes. + config.timeout_in = ENV.fetch('DEVISE_SESSION_TIMEOUT', 14).to_i.days + + # ==> Configuration for :lockable + # Defines which strategy will be used to lock an account. + # :failed_attempts = Locks an account after a number of failed attempts to sign in. + # :none = No lock strategy. You should handle locking by yourself. + # config.lock_strategy = :failed_attempts + + # Defines which key will be used when locking and unlocking an account + # config.unlock_keys = [:email] + + # Defines which strategy will be used to unlock an account. + # :email = Sends an unlock link to the user email + # :time = Re-enables login after a certain amount of time (see :unlock_in below) + # :both = Enables both strategies + # :none = No unlock strategy. You should handle unlocking by yourself. + # config.unlock_strategy = :both + + # Number of authentication tries before locking an account if lock_strategy + # is failed attempts. + # config.maximum_attempts = 20 + + # Time interval to unlock the account if :time is enabled as unlock_strategy. + # config.unlock_in = 1.hour + + # Warn on the last attempt before the account is locked. + # config.last_attempt_warning = true + + # ==> Configuration for :recoverable + # + # Defines which key will be used when recovering the password for an account + # config.reset_password_keys = [:email] + + # Time interval you can reset your password with a reset password key. + # Don't put a too small interval or your users won't have the time to + # change their passwords. + config.reset_password_within = 6.hours + + # When set to false, does not sign a user in automatically after their password is + # reset. Defaults to true, so a user is signed in automatically after a reset. + # config.sign_in_after_reset_password = true + + # ==> Configuration for :encryptable + # Allow you to use another hashing or encryption algorithm besides bcrypt (default). + # You can use :sha1, :sha512 or algorithms from others authentication tools as + # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20 + # for default behavior) and :restful_authentication_sha1 (then you should set + # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper). + # + # Require the `devise-encryptable` gem when using anything other than bcrypt + # config.encryptor = :sha512 + + # ==> Scopes configuration + # Turn scoped views on. Before rendering "sessions/new", it will first check for + # "users/sessions/new". It's turned off by default because it's slower if you + # are using only default views. + # config.scoped_views = true + + # Configure the default scope given to Warden. By default it's the first + # devise role declared in your routes (usually :user). + # config.default_scope = :user + + # Set this configuration to false if you want /users/sign_out to sign out + # only the current scope. By default, Devise signs out all scopes. + # config.sign_out_all_scopes = true + + # ==> Navigation configuration + # Lists the formats that should be treated as navigational. Formats like + # :html should redirect to the sign in page when the user does not have + # access, but formats like :xml or :json, should return 401. + # + # If you have any extra navigational formats, like :iphone or :mobile, you + # should add them to the navigational formats lists. + # + # The "*/*" below is required to match Internet Explorer requests. + config.navigational_formats = ['*/*', :html, :turbo_stream] + + # The default HTTP method used to sign out a resource. Default is :delete. + config.sign_out_via = :delete + + # ==> OmniAuth + # Add a new OmniAuth provider. Check the wiki for more information on setting + # up on your models and hooks. + # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' + + # ==> Warden configuration + # If you want to use other strategies, that are not supported by Devise, or + # change the failure app, you can configure them inside the config.warden block. + # + # config.warden do |manager| + # manager.intercept_401 = false + # manager.default_strategies(scope: :user).unshift :some_external_strategy + # end + + # ==> Mountable engine configurations + # When using Devise inside an engine, let's call it `MyEngine`, and this engine + # is mountable, there are some extra configurations to be taken into account. + # The following options are available, assuming the engine is mounted as: + # + # mount MyEngine, at: '/my_engine' + # + # The router that invoked `devise_for`, in the example above, would be: + # config.router_name = :spree + # + # When using OmniAuth, Devise cannot automatically set OmniAuth path, + # so you need to do it manually. For the users scope, it would be: + # config.omniauth_path_prefix = '/my_engine/users/auth' + + # ==> Hotwire/Turbo configuration + # When using Devise with Hotwire/Turbo, the http status for error responses + # and some redirects must match the following. The default in Devise for existing + # apps is `200 OK` and `302 Found` respectively, but new apps are generated with + # these new defaults that match Hotwire/Turbo behavior. + # Note: These might become the new default in future versions of Devise. + config.responder.error_status = :unprocessable_entity + config.responder.redirect_status = :see_other + + # ==> Configuration for :registerable + + # When set to false, does not sign a user in automatically after their password is + # changed. Defaults to true, so a user is signed in automatically after changing a password. + # config.sign_in_after_change_password = true +end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000..c0b717f --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. +# Use this to limit dissemination of sensitive information. +# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. +Rails.application.config.filter_parameters += [ + :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc +] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000..3860f65 --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, "\\1en" +# inflect.singular /^(ox)en/i, "\\1" +# inflect.irregular "person", "people" +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym "RESTful" +# end diff --git a/config/initializers/new_framework_defaults_8_0.rb b/config/initializers/new_framework_defaults_8_0.rb new file mode 100644 index 0000000..92efa95 --- /dev/null +++ b/config/initializers/new_framework_defaults_8_0.rb @@ -0,0 +1,30 @@ +# Be sure to restart your server when you modify this file. +# +# This file eases your Rails 8.0 framework defaults upgrade. +# +# Uncomment each configuration one by one to switch to the new default. +# Once your application is ready to run with all new defaults, you can remove +# this file and set the `config.load_defaults` to `8.0`. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. +# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html + +### +# Specifies whether `to_time` methods preserve the UTC offset of their receivers or preserves the timezone. +# If set to `:zone`, `to_time` methods will use the timezone of their receivers. +# If set to `:offset`, `to_time` methods will use the UTC offset. +# If `false`, `to_time` methods will convert to the local system UTC offset instead. +#++ +# Rails.application.config.active_support.to_time_preserves_timezone = :zone + +### +# When both `If-Modified-Since` and `If-None-Match` are provided by the client +# only consider `If-None-Match` as specified by RFC 7232 Section 6. +# If set to `false` both conditions need to be satisfied. +#++ +# Rails.application.config.action_dispatch.strict_freshness = true + +### +# Set `Regexp.timeout` to `1`s by default to improve security over Regexp Denial-of-Service attacks. +#++ +# Regexp.timeout = 1 diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb new file mode 100644 index 0000000..7db3b95 --- /dev/null +++ b/config/initializers/permissions_policy.rb @@ -0,0 +1,13 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide HTTP permissions policy. For further +# information see: https://developers.google.com/web/updates/2018/06/feature-policy + +# Rails.application.config.permissions_policy do |policy| +# policy.camera :none +# policy.gyroscope :none +# policy.microphone :none +# policy.usb :none +# policy.fullscreen :self +# policy.payment :self, "https://secure.example.com" +# end diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb new file mode 100644 index 0000000..b1ecab4 --- /dev/null +++ b/config/initializers/sentry.rb @@ -0,0 +1,30 @@ +if defined?(Sentry) && ENV['SENTRY_DSN'].present? + Sentry.init do |config| + config.dsn = ENV['SENTRY_DSN'] + config.breadcrumbs_logger = %i[active_support_logger http_logger] + + # Set tracesSampleRate to 1.0 to capture 100% + # of transactions for performance monitoring. + # We recommend adjusting this value in production + config.traces_sample_rate = 0.5 + + config.enabled_environments = %w[production staging] + config.enabled_environments << 'development' if ENV['SENTRY_REPORT_ON_DEVELOPMENT'].present? + + config.release = "spree@#{ENV['RENDER_GIT_COMMIT']}" if ENV['RENDER_GIT_COMMIT'].present? + + config.excluded_exceptions = [ + 'ActionController::RoutingError', + 'ActiveRecord::RecordNotFound', + 'Sidekiq::JobRetry::Skip', + 'Sidekiq::JobRetry::SilentRetry', + 'Aws::S3::Errors::NoSuchKey', + 'Aws::S3::Errors::NotFound', + 'ActiveStorage::FileNotFoundError' + ] + + # Use native Rails error subscriber + # https://guides.rubyonrails.org/error_reporting.html + config.rails.register_error_subscriber = true + end +end diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb new file mode 100644 index 0000000..8a5dec4 --- /dev/null +++ b/config/initializers/sidekiq.rb @@ -0,0 +1,5 @@ +Sidekiq.strict_args!(:warn) # https://github.com/sidekiq/sidekiq/blob/main/docs/7.0-Upgrade.md#strict-arguments + +Sidekiq.configure_server do |config| + config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') } +end diff --git a/config/initializers/spree.rb b/config/initializers/spree.rb new file mode 100644 index 0000000..9fab508 --- /dev/null +++ b/config/initializers/spree.rb @@ -0,0 +1,94 @@ +# Configure Spree Preferences +# +# Note: Initializing preferences available within the Admin will overwrite any changes that were made through the user interface when you restart. +# If you would like users to be able to update a setting with the Admin it should NOT be set here. +# +# Note: If a preference is set here it will be stored within the cache & database upon initialization. +# Just removing an entry from this initializer will not make the preference value go away. +# Instead you must either set a new value or remove entry, clear cache, and remove database entry. +# +# In order to initialize a setting do: +# config.setting_name = 'new value' +# +# More on configuring Spree preferences can be found at: +# https://docs.spreecommerce.org/developer/customization +Spree.config do |config| + # Example: + # Uncomment to stop tracking inventory levels in the application + # config.track_inventory_levels = false +end + +# Background job queue names +# Spree.queues.default = :default +# Spree.queues.variants = :default +# Spree.queues.stock_location_stock_items = :default +# Spree.queues.coupon_codes = :default + +# Use a CDN host for images, eg. Cloudfront +# This is used in the frontend to generate absolute URLs to images +# Default is nil and your application host will be used +# Spree.cdn_host = 'cdn.example.com' + +# Use a different service for storage (S3, google, etc) +# unless Rails.env.test? +# Spree.private_storage_service_name = :amazon_public # public assets, such as product images +# Spree.public_storage_service_name = :amazon_private # private assets, such as invoices, etc +# end + +# Configure Spree Dependencies +# +# Note: If a dependency is set here it will NOT be stored within the cache & database upon initialization. +# Just removing an entry from this initializer will make the dependency value go away. +# +# More on how to use Spree dependencies can be found at: +# https://docs.spreecommerce.org/customization/dependencies +Spree.dependencies do |dependencies| + # Example: + # Uncomment to change the default Service handling adding Items to Cart + # dependencies.cart_add_item_service = 'MyNewAwesomeService' +end + +# Spree::Api::Dependencies.storefront_cart_serializer = 'MyRailsApp::CartSerializer' + +# uncomment lines below to add your own custom business logic +# such as promotions, shipping methods, etc +Rails.application.config.after_initialize do + # Rails.application.config.spree.shipping_methods << Spree::ShippingMethods::SuperExpensiveNotVeryFastShipping + # Rails.application.config.spree.payment_methods << Spree::PaymentMethods::VerySafeAndReliablePaymentMethod + + # Rails.application.config.spree.calculators.tax_rates << Spree::TaxRates::FinanceTeamForcedMeToCodeThis + + # Rails.application.config.spree.stock_splitters << Spree::Stock::Splitters::SecretLogicSplitter + + # Rails.application.config.spree.adjusters << Spree::Adjustable::Adjuster::TaxTheRich + + # Custom promotions + # Rails.application.config.spree.calculators.promotion_actions_create_adjustments << Spree::Calculators::PromotionActions::CreateAdjustments::AddDiscountForFriends + # Rails.application.config.spree.calculators.promotion_actions_create_item_adjustments << Spree::Calculators::PromotionActions::CreateItemAdjustments::FinanceTeamForcedMeToCodeThis + # Rails.application.config.spree.promotions.rules << Spree::Promotions::Rules::OnlyForVIPCustomers + # Rails.application.config.spree.promotions.actions << Spree::Promotions::Actions::GiftWithPurchase + + # Rails.application.config.spree.taxon_rules << Spree::TaxonRules::ProductsWithColor + + # Rails.application.config.spree.exports << Spree::Exports::Payments + # Rails.application.config.spree.reports << Spree::Reports::MassivelyOvercomplexReportForCfo + + # Themes and page builder + # Rails.application.config.spree.themes << Spree::Themes::NewShinyTheme + # Rails.application.config.spree.theme_layout_sections << Spree::PageSections::SuperImportantCeoBio + # Rails.application.config.spree.page_sections << Spree::PageSections::ContactFormToGetInTouch + # Rails.application.config.spree.page_blocks << Spree::PageBlocks::BigRedButtonToCallSales + + # Rails.application.config.spree_storefront.head_partials << 'spree/shared/that_js_snippet_that_marketing_forced_me_to_include' +end + +Spree.user_class = 'Spree::User' +# Use a different class for admin users +Spree.admin_user_class = 'Spree::AdminUser' + +Spree.google_places_api_key = ENV['GOOGLE_PLACES_API_KEY'] if ENV['GOOGLE_PLACES_API_KEY'].present? +Spree.screenshot_api_token = ENV['SCREENSHOT_API_TOKEN'] if ENV['SCREENSHOT_API_TOKEN'].present? + +Rails.application.config.to_prepare do + require_dependency 'spree/authentication_helpers' +end diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml new file mode 100644 index 0000000..260e1c4 --- /dev/null +++ b/config/locales/devise.en.yml @@ -0,0 +1,65 @@ +# Additional translations at https://github.com/heartcombo/devise/wiki/I18n + +en: + devise: + confirmations: + confirmed: "Your email address has been successfully confirmed." + send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes." + failure: + already_authenticated: "You are already signed in." + inactive: "Your account is not activated yet." + invalid: "Invalid %{authentication_keys} or password." + locked: "Your account is locked." + last_attempt: "You have one more attempt before your account is locked." + not_found_in_database: "Invalid %{authentication_keys} or password." + timeout: "Your session expired. Please sign in again to continue." + unauthenticated: "You need to sign in or sign up before continuing." + unconfirmed: "You have to confirm your email address before continuing." + mailer: + confirmation_instructions: + subject: "Confirmation instructions" + reset_password_instructions: + subject: "Reset password instructions" + unlock_instructions: + subject: "Unlock instructions" + email_changed: + subject: "Email Changed" + password_change: + subject: "Password Changed" + omniauth_callbacks: + failure: "Could not authenticate you from %{kind} because \"%{reason}\"." + success: "Successfully authenticated from %{kind} account." + passwords: + no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided." + send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." + updated: "Your password has been changed successfully. You are now signed in." + updated_not_active: "Your password has been changed successfully." + registrations: + destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon." + signed_up: "Welcome! You have signed up successfully." + signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." + signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." + signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account." + update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address." + updated: "Your account has been updated successfully." + updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again." + sessions: + signed_in: "Signed in successfully." + signed_out: "Signed out successfully." + already_signed_out: "Signed out successfully." + unlocks: + send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes." + send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes." + unlocked: "Your account has been unlocked successfully. Please sign in to continue." + errors: + messages: + already_confirmed: "was already confirmed, please try signing in" + confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" + expired: "has expired, please request a new one" + not_found: "not found" + not_locked: "was not locked" + not_saved: + one: "1 error prohibited this %{resource} from being saved:" + other: "%{count} errors prohibited this %{resource} from being saved:" diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..6c349ae --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,31 @@ +# Files in the config/locales directory are used for internationalization and +# are automatically loaded by Rails. If you want to use locales other than +# English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t "hello" +# +# In views, this is aliased to just `t`: +# +# <%= t("hello") %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more about the API, please read the Rails Internationalization guide +# at https://guides.rubyonrails.org/i18n.html. +# +# Be aware that YAML interprets the following case-insensitive strings as +# booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings +# must be quoted to be interpreted as strings. For example: +# +# en: +# "yes": yup +# enabled: "ON" + +en: + hello: "Hello world" diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 0000000..a248513 --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,41 @@ +# This configuration file will be evaluated by Puma. The top-level methods that +# are invoked here are part of Puma's configuration DSL. For more information +# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html. +# +# Puma starts a configurable number of processes (workers) and each process +# serves each request in a thread from an internal thread pool. +# +# You can control the number of workers using ENV["WEB_CONCURRENCY"]. You +# should only set this value when you want to run 2 or more workers. The +# default is already 1. +# +# The ideal number of threads per worker depends both on how much time the +# application spends waiting for IO operations and on how much you wish to +# prioritize throughput over latency. +# +# As a rule of thumb, increasing the number of threads will increase how much +# traffic a given process can handle (throughput), but due to CRuby's +# Global VM Lock (GVL) it has diminishing returns and will degrade the +# response time (latency) of the application. +# +# The default is set to 3 threads as it's deemed a decent compromise between +# throughput and latency for the average Rails application. +# +# Any libraries that use a connection pool or another resource pool should +# be configured to provide at least as many connections as the number of +# threads. This includes Active Record's `pool` parameter in `database.yml`. +threads_count = ENV.fetch("RAILS_MAX_THREADS", 3) +threads threads_count, threads_count + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +port ENV.fetch("PORT", 3000) + +# Allow puma to be restarted by `bin/rails restart` command. +plugin :tmp_restart + +# Run the Solid Queue supervisor inside of Puma for single-server deployments +plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"] + +# Specify the PID file. Defaults to tmp/pids/server.pid in development. +# In other environments, only set the PID file if requested. +pidfile ENV["PIDFILE"] if ENV["PIDFILE"] diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..3036b05 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,53 @@ +require "sidekiq/web" # require the web UI + +Rails.application.routes.draw do + Spree::Core::Engine.add_routes do + # Storefront routes + scope '(:locale)', locale: /#{Spree.available_locales.join('|')}/, defaults: { locale: nil } do + devise_for( + Spree.user_class.model_name.singular_route_key, + class_name: Spree.user_class.to_s, + path: :user, + controllers: { + sessions: 'spree/user_sessions', + passwords: 'spree/user_passwords', + registrations: 'spree/user_registrations' + }, + router_name: :spree + ) + end + + # Admin authentication + devise_for( + Spree.admin_user_class.model_name.singular_route_key, + class_name: Spree.admin_user_class.to_s, + controllers: { + sessions: 'spree/admin/user_sessions', + passwords: 'spree/admin/user_passwords' + }, + skip: :registrations, + path: :admin_user, + router_name: :spree + ) + end + # This line mounts Spree's routes at the root of your application. + # This means, any requests to URLs such as /products, will go to + # Spree::ProductsController. + # If you would like to change where this engine is mounted, simply change the + # :at option to something different. + # + # We ask that you don't use the :as option here, as Spree relies on it being + # the default of "spree". + mount Spree::Core::Engine, at: '/' + + mount Sidekiq::Web => "/sidekiq" # access it at http://localhost:3000/sidekiq + + # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html + + # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. + # Can be used by load balancers and uptime monitors to verify that the app is live. + get "up" => "rails/health#show", as: :rails_health_check + + # Defines the root path route ("/") + root "spree/home#index" +end diff --git a/config/storage.yml b/config/storage.yml new file mode 100644 index 0000000..a94d75c --- /dev/null +++ b/config/storage.yml @@ -0,0 +1,44 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket-<%= Rails.env %> + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket-<%= Rails.env %> + +# Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name-<%= Rails.env %> + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] + +cloudflare: + service: S3 + endpoint: <%= ENV.fetch("CLOUDFLARE_ENDPOINT", "") %> + access_key_id: <%= ENV.fetch("CLOUDFLARE_ACCESS_KEY_ID", "") %> + secret_access_key: <%= ENV.fetch("CLOUDFLARE_SECRET_ACCESS_KEY", "") %> + region: auto + bucket: <%= ENV.fetch("CLOUDFLARE_BUCKET", "spree-#{Rails.env}") %> + request_checksum_calculation: "when_required" + response_checksum_validation: "when_required" diff --git a/config/tailwind.config.js b/config/tailwind.config.js new file mode 100644 index 0000000..6998060 --- /dev/null +++ b/config/tailwind.config.js @@ -0,0 +1,128 @@ +const defaultTheme = require("tailwindcss/defaultTheme"); + +module.exports = { + content: [ + 'public/*.html', + 'app/helpers/**/*.rb', + 'app/javascript/**/*.js', + 'app/views/spree/**/*.erb', + 'app/views/devise/**/*.erb', + 'app/views/themes/**/*.erb', + process.env.SPREE_STOREFRONT_PATH + '/app/helpers/**/*.rb', + process.env.SPREE_STOREFRONT_PATH + '/app/javascript/**/*.js', + process.env.SPREE_STOREFRONT_PATH + '/app/views/themes/**/*.erb', + process.env.SPREE_STOREFRONT_PATH + '/app/views/spree/**/*.erb', + process.env.SPREE_STOREFRONT_PATH + '/app/views/devise/**/*.erb' + ], + plugins: [ + require("@tailwindcss/typography"), + require("@tailwindcss/forms"), + require("@tailwindcss/aspect-ratio"), + ], + variants: { + scrollbar: ["rounded"], + }, + safelist: [ + "hidden", + "lg:grid", + "grid", + "text-xs", + "text-sm", + "text-base", + "text-lg", + "text-xl", + "text-2xl", + "text-3xl", + "text-4xl", + "text-left", + "text-right", + "text-center", + "cursor-wait", + "lg:sr-only", + ], + theme: { + extend: { + fontFamily: { + body: ["var(--font-body)", ...defaultTheme.fontFamily.sans], + }, + screens: { + lg: { raw: "(min-width: 1024px) { &:not(.force-mobile-view *) }" }, + }, + animation: { + fadeIn: "fadeIn 0.5s ease-in-out", + }, + keyframes: { + fadeIn: { + "0%": { opacity: 0 }, + "100%": { opacity: 1 }, + }, + }, + colors: { + primary: "var(--primary)", + accent: "var(--accent)", + neutral: "var(--neutral)", + danger: "var(--danger)", + success: "var(--success)", + + "accent-100": "var(--accent-100)", + "neutral-50": "var(--neutral-50)", + "neutral-100": "var(--neutral-100)", + "neutral-200": "var(--neutral-200)", + "neutral-300": "var(--neutral-300)", + "neutral-400": "var(--neutral-400)", + "neutral-500": "var(--neutral-500)", + "neutral-600": "var(--neutral-600)", + "neutral-700": "var(--neutral-700)", + "neutral-800": "var(--neutral-800)", + "neutral-900": "var(--neutral-900)", + + background: "var(--background)", + "section-background": "var(--section-background, var(--background))", + text: "var(--text)", + + button: "rgba(var(--button-rgb), )", + "button-text": "var(--button-text)", + "button-hover": "var(--button-hover)", + "button-hover-text": "var(--button-hover-text)", + + "secondary-button": "var(--secondary-button)", + "secondary-button-text": "var(--secondary-button-text)", + "secondary-button-hover": "var(--secondary-button-hover)", + "secondary-button-hover-text": "var(--secondary-button-hover-text)", + + "button-light": "var(--button-light)", + "button-light-text": "var(--button-light-text)", + "button-light-hover": "var(--button-light-hover)", + "button-light-hover-text": "var(--button-light-hover-text)", + + input: "var(--input)", + "input-bg": "var(--input-bg)", + "input-text": "var(--input-text)", + "input-focus": "var(--input-focus)", + "input-focus-bg": "var(--input-focus-bg)", + "input-focus-text": "var(--input-focus-text)", + }, + letterSpacing: { + widest: "0.07rem", + }, + typography: { + DEFAULT: { + css: { + "--tw-prose-body": "var(--text)", + "--tw-prose-headings": "var(--text)", + "--tw-prose-bold": "var(--text)", + "--tw-prose-links": "var(--text)", + "--tw-prose-counters": "var(--text)", + "--tw-prose-bullets": "var(--text)", + "--tw-prose-lead": "var(--text)", + "--tw-prose-hr": "var(--border-default-color)", + "--tw-prose-th-borders": "var(--border-default-color)", + "--tw-prose-td-borders": "var(--border-default-color)", + "--tw-prose-quote-borders": "var(--border-default-color)", + "--tw-prose-quotes": "var(--text)", + }, + }, + }, + }, + }, +}; diff --git a/db/migrate/20240523142421_devise_create_spree_users.rb b/db/migrate/20240523142421_devise_create_spree_users.rb new file mode 100644 index 0000000..1862abc --- /dev/null +++ b/db/migrate/20240523142421_devise_create_spree_users.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +class DeviseCreateSpreeUsers < ActiveRecord::Migration[7.1] + def change + create_table :spree_users do |t| + ## Database authenticatable + t.string :email, null: false, default: "" + t.string :encrypted_password, null: false, default: "" + + ## Recoverable + t.string :reset_password_token + t.datetime :reset_password_sent_at + + ## Rememberable + t.datetime :remember_created_at + + ## Trackable + t.integer :sign_in_count, default: 0, null: false + t.datetime :current_sign_in_at + t.datetime :last_sign_in_at + t.string :current_sign_in_ip + t.string :last_sign_in_ip + + ## Confirmable + t.string :confirmation_token + t.datetime :confirmed_at + t.datetime :confirmation_sent_at + t.string :unconfirmed_email # Only if using reconfirmable + + ## Lockable + t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts + t.string :unlock_token # Only if unlock strategy is :email or :both + t.datetime :locked_at + + + t.timestamps null: false + end + + add_index :spree_users, :email, unique: true + add_index :spree_users, :reset_password_token, unique: true + add_index :spree_users, :confirmation_token, unique: true + add_index :spree_users, :unlock_token, unique: true + end +end diff --git a/db/migrate/20240523142422_create_active_storage_tables.active_storage.rb b/db/migrate/20240523142422_create_active_storage_tables.active_storage.rb new file mode 100644 index 0000000..e4706aa --- /dev/null +++ b/db/migrate/20240523142422_create_active_storage_tables.active_storage.rb @@ -0,0 +1,57 @@ +# This migration comes from active_storage (originally 20170806125915) +class CreateActiveStorageTables < ActiveRecord::Migration[7.0] + def change + # Use Active Record's configured type for primary and foreign keys + primary_key_type, foreign_key_type = primary_and_foreign_key_types + + create_table :active_storage_blobs, id: primary_key_type do |t| + t.string :key, null: false + t.string :filename, null: false + t.string :content_type + t.text :metadata + t.string :service_name, null: false + t.bigint :byte_size, null: false + t.string :checksum + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :key ], unique: true + end + + create_table :active_storage_attachments, id: primary_key_type do |t| + t.string :name, null: false + t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type + t.references :blob, null: false, type: foreign_key_type + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + + create_table :active_storage_variant_records, id: primary_key_type do |t| + t.belongs_to :blob, null: false, index: false, type: foreign_key_type + t.string :variation_digest, null: false + + t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + def primary_and_foreign_key_types + config = Rails.configuration.generators + setting = config.options[config.orm][:primary_key_type] + primary_key_type = setting || :primary_key + foreign_key_type = setting || :bigint + [primary_key_type, foreign_key_type] + end +end diff --git a/db/migrate/20240523142423_create_action_mailbox_tables.action_mailbox.rb b/db/migrate/20240523142423_create_action_mailbox_tables.action_mailbox.rb new file mode 100644 index 0000000..7b2b807 --- /dev/null +++ b/db/migrate/20240523142423_create_action_mailbox_tables.action_mailbox.rb @@ -0,0 +1,20 @@ +# This migration comes from action_mailbox (originally 20180917164000) +class CreateActionMailboxTables < ActiveRecord::Migration[6.0] + def change + create_table :action_mailbox_inbound_emails, id: primary_key_type do |t| + t.integer :status, default: 0, null: false + t.string :message_id, null: false + t.string :message_checksum, null: false + + t.timestamps + + t.index [ :message_id, :message_checksum ], name: "index_action_mailbox_inbound_emails_uniqueness", unique: true + end + end + + private + def primary_key_type + config = Rails.configuration.generators + config.options[config.orm][:primary_key_type] || :primary_key + end +end diff --git a/db/migrate/20240523142424_create_action_text_tables.action_text.rb b/db/migrate/20240523142424_create_action_text_tables.action_text.rb new file mode 100644 index 0000000..1be48d7 --- /dev/null +++ b/db/migrate/20240523142424_create_action_text_tables.action_text.rb @@ -0,0 +1,26 @@ +# This migration comes from action_text (originally 20180528164100) +class CreateActionTextTables < ActiveRecord::Migration[6.0] + def change + # Use Active Record's configured type for primary and foreign keys + primary_key_type, foreign_key_type = primary_and_foreign_key_types + + create_table :action_text_rich_texts, id: primary_key_type do |t| + t.string :name, null: false + t.text :body, size: :long + t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type + + t.timestamps + + t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true + end + end + + private + def primary_and_foreign_key_types + config = Rails.configuration.generators + setting = config.options[config.orm][:primary_key_type] + primary_key_type = setting || :primary_key + foreign_key_type = setting || :bigint + [primary_key_type, foreign_key_type] + end +end diff --git a/db/migrate/20240523142425_devise_create_spree_admin_users.rb b/db/migrate/20240523142425_devise_create_spree_admin_users.rb new file mode 100644 index 0000000..423036d --- /dev/null +++ b/db/migrate/20240523142425_devise_create_spree_admin_users.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +class DeviseCreateSpreeAdminUsers < ActiveRecord::Migration[8.0] + def change + create_table :spree_admin_users do |t| + ## Database authenticatable + t.string :email, null: false, default: "" + t.string :encrypted_password, null: false, default: "" + + ## Recoverable + t.string :reset_password_token + t.datetime :reset_password_sent_at + + ## Rememberable + t.datetime :remember_created_at + + ## Trackable + t.integer :sign_in_count, default: 0, null: false + t.datetime :current_sign_in_at + t.datetime :last_sign_in_at + t.string :current_sign_in_ip + t.string :last_sign_in_ip + + ## Confirmable + t.string :confirmation_token + t.datetime :confirmed_at + t.datetime :confirmation_sent_at + t.string :unconfirmed_email # Only if using reconfirmable + + ## Lockable + t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts + t.string :unlock_token # Only if unlock strategy is :email or :both + t.datetime :locked_at + + + t.timestamps null: false + end + + add_index :spree_admin_users, :email, unique: true + add_index :spree_admin_users, :reset_password_token, unique: true + add_index :spree_admin_users, :confirmation_token, unique: true + add_index :spree_admin_users, :unlock_token, unique: true + end +end diff --git a/db/migrate/20250210131634_spree_four_three.spree.rb b/db/migrate/20250210131634_spree_four_three.spree.rb new file mode 100644 index 0000000..5746b12 --- /dev/null +++ b/db/migrate/20250210131634_spree_four_three.spree.rb @@ -0,0 +1,1127 @@ +# This migration comes from spree (originally 20210914000000) +class SpreeFourThree < ActiveRecord::Migration[5.2] + def up + # This migration is just a compressed version of all the previous + # migrations for spree_core. Do not run it if one of the core tables + # already exists. Assume the best. + return if data_source_exists?(:spree_addresses) + + create_table "friendly_id_slugs", force: :cascade do |t| + t.string "slug", null: false + t.bigint "sluggable_id", null: false + t.string "sluggable_type", limit: 50 + t.string "scope" + t.datetime "created_at" + t.datetime "deleted_at" + t.index ["deleted_at"], name: "index_friendly_id_slugs_on_deleted_at" + t.index ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true + t.index ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type" + t.index ["sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_id" + t.index ["sluggable_type"], name: "index_friendly_id_slugs_on_sluggable_type" + end + + create_table "spree_addresses", force: :cascade do |t| + t.string "firstname" + t.string "lastname" + t.string "address1" + t.string "address2" + t.string "city" + t.string "zipcode" + t.string "phone" + t.string "state_name" + t.string "alternative_phone" + t.string "company" + t.bigint "state_id" + t.bigint "country_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.bigint "user_id" + t.datetime "deleted_at" + t.string "label" + t.index ["country_id"], name: "index_spree_addresses_on_country_id" + t.index ["deleted_at"], name: "index_spree_addresses_on_deleted_at" + t.index ["firstname"], name: "index_addresses_on_firstname" + t.index ["lastname"], name: "index_addresses_on_lastname" + t.index ["state_id"], name: "index_spree_addresses_on_state_id" + t.index ["user_id"], name: "index_spree_addresses_on_user_id" + end + + create_table "spree_adjustments", force: :cascade do |t| + t.string "source_type" + t.bigint "source_id" + t.string "adjustable_type" + t.bigint "adjustable_id" + t.decimal "amount", precision: 10, scale: 2 + t.string "label" + t.boolean "mandatory" + t.boolean "eligible", default: true + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "state" + t.bigint "order_id", null: false + t.boolean "included", default: false + t.index ["adjustable_id", "adjustable_type"], name: "index_spree_adjustments_on_adjustable_id_and_adjustable_type" + t.index ["eligible"], name: "index_spree_adjustments_on_eligible" + t.index ["order_id"], name: "index_spree_adjustments_on_order_id" + t.index ["source_id", "source_type"], name: "index_spree_adjustments_on_source_id_and_source_type" + end + + create_table "spree_assets", force: :cascade do |t| + t.string "viewable_type" + t.bigint "viewable_id" + t.integer "attachment_width" + t.integer "attachment_height" + t.integer "attachment_file_size" + t.integer "position" + t.string "attachment_content_type" + t.string "attachment_file_name" + t.string "type", limit: 75 + t.datetime "attachment_updated_at" + t.text "alt" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["position"], name: "index_spree_assets_on_position" + t.index ["viewable_id"], name: "index_assets_on_viewable_id" + t.index ["viewable_type", "type"], name: "index_assets_on_viewable_type_and_type" + end + + create_table "spree_calculators", force: :cascade do |t| + t.string "type" + t.string "calculable_type" + t.bigint "calculable_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.text "preferences" + t.datetime "deleted_at" + t.index ["calculable_id", "calculable_type"], name: "index_spree_calculators_on_calculable_id_and_calculable_type" + t.index ["deleted_at"], name: "index_spree_calculators_on_deleted_at" + t.index ["id", "type"], name: "index_spree_calculators_on_id_and_type" + end + + create_table "spree_countries", force: :cascade do |t| + t.string "iso_name" + t.string "iso", null: false + t.string "iso3", null: false + t.string "name" + t.integer "numcode" + t.boolean "states_required", default: false + t.datetime "updated_at" + t.boolean "zipcode_required", default: true + t.datetime "created_at" + t.index ["iso_name"], name: "index_spree_countries_on_iso_name", unique: true + t.index ["name"], name: "index_spree_countries_on_name", unique: true + t.index ["iso"], name: "index_spree_countries_on_iso", unique: true + t.index ["iso3"], name: "index_spree_countries_on_iso3", unique: true + end + + create_table "spree_credit_cards", force: :cascade do |t| + t.string "month" + t.string "year" + t.string "cc_type" + t.string "last_digits" + t.bigint "address_id" + t.string "gateway_customer_profile_id" + t.string "gateway_payment_profile_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "name" + t.bigint "user_id" + t.bigint "payment_method_id" + t.boolean "default", default: false, null: false + t.datetime "deleted_at" + t.index ["address_id"], name: "index_spree_credit_cards_on_address_id" + t.index ["deleted_at"], name: "index_spree_credit_cards_on_deleted_at" + t.index ["payment_method_id"], name: "index_spree_credit_cards_on_payment_method_id" + t.index ["user_id"], name: "index_spree_credit_cards_on_user_id" + end + + create_table "spree_customer_returns", force: :cascade do |t| + t.string "number" + t.bigint "stock_location_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.bigint "store_id" + t.index ["number"], name: "index_spree_customer_returns_on_number", unique: true + t.index ["stock_location_id"], name: "index_spree_customer_returns_on_stock_location_id" + t.index ["store_id"], name: "index_spree_customer_returns_on_store_id" + end + + create_table "spree_gateways", force: :cascade do |t| + t.string "type" + t.string "name" + t.text "description" + t.boolean "active", default: true + t.string "environment", default: "development" + t.string "server", default: "test" + t.boolean "test_mode", default: true + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.text "preferences" + t.index ["active"], name: "index_spree_gateways_on_active" + t.index ["test_mode"], name: "index_spree_gateways_on_test_mode" + end + + create_table "spree_inventory_units", force: :cascade do |t| + t.string "state" + t.bigint "variant_id" + t.bigint "order_id" + t.bigint "shipment_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.boolean "pending", default: true + t.bigint "line_item_id" + t.integer "quantity", default: 1 + t.bigint "original_return_item_id" + t.index ["line_item_id"], name: "index_spree_inventory_units_on_line_item_id" + t.index ["order_id"], name: "index_inventory_units_on_order_id" + t.index ["original_return_item_id"], name: "index_spree_inventory_units_on_original_return_item_id" + t.index ["shipment_id"], name: "index_inventory_units_on_shipment_id" + t.index ["variant_id"], name: "index_inventory_units_on_variant_id" + end + + create_table "spree_line_items", force: :cascade do |t| + t.bigint "variant_id" + t.bigint "order_id" + t.integer "quantity", null: false + t.decimal "price", precision: 10, scale: 2, null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "currency" + t.decimal "cost_price", precision: 10, scale: 2 + t.bigint "tax_category_id" + t.decimal "adjustment_total", precision: 10, scale: 2, default: "0.0" + t.decimal "additional_tax_total", precision: 10, scale: 2, default: "0.0" + t.decimal "promo_total", precision: 10, scale: 2, default: "0.0" + t.decimal "included_tax_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "pre_tax_amount", precision: 12, scale: 4, default: "0.0", null: false + t.decimal "taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "non_taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.index ["order_id"], name: "index_spree_line_items_on_order_id" + t.index ["tax_category_id"], name: "index_spree_line_items_on_tax_category_id" + t.index ["variant_id"], name: "index_spree_line_items_on_variant_id" + end + + create_table "spree_log_entries", force: :cascade do |t| + t.string "source_type" + t.bigint "source_id" + t.text "details" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["source_id", "source_type"], name: "index_spree_log_entries_on_source_id_and_source_type" + end + + create_table "spree_option_type_prototypes", force: :cascade do |t| + t.bigint "prototype_id" + t.bigint "option_type_id" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["option_type_id"], name: "index_spree_option_type_prototypes_on_option_type_id" + t.index ["prototype_id", "option_type_id"], name: "spree_option_type_prototypes_prototype_id_option_type_id", unique: true + t.index ["prototype_id"], name: "index_spree_option_type_prototypes_on_prototype_id" + end + + create_table "spree_option_types", force: :cascade do |t| + t.string "name", limit: 100 + t.string "presentation", limit: 100 + t.integer "position", default: 0, null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.boolean "filterable", default: true, null: false + t.index ["filterable"], name: "index_spree_option_types_on_filterable" + t.index ["name"], name: "index_spree_option_types_on_name" + t.index ["position"], name: "index_spree_option_types_on_position" + end + + create_table "spree_option_value_variants", force: :cascade do |t| + t.bigint "variant_id" + t.bigint "option_value_id" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["option_value_id"], name: "index_spree_option_value_variants_on_option_value_id" + t.index ["variant_id", "option_value_id"], name: "index_option_values_variants_on_variant_id_and_option_value_id", unique: true + t.index ["variant_id"], name: "index_spree_option_value_variants_on_variant_id" + end + + create_table "spree_option_values", force: :cascade do |t| + t.integer "position" + t.string "name" + t.string "presentation" + t.bigint "option_type_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["name"], name: "index_spree_option_values_on_name" + t.index ["option_type_id"], name: "index_spree_option_values_on_option_type_id" + t.index ["position"], name: "index_spree_option_values_on_position" + end + + create_table "spree_order_promotions", force: :cascade do |t| + t.bigint "order_id" + t.bigint "promotion_id" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["order_id"], name: "index_spree_order_promotions_on_order_id" + t.index ["promotion_id", "order_id"], name: "index_spree_order_promotions_on_promotion_id_and_order_id" + t.index ["promotion_id"], name: "index_spree_order_promotions_on_promotion_id" + end + + create_table "spree_orders", force: :cascade do |t| + t.string "number", limit: 32 + t.decimal "item_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "total", precision: 10, scale: 2, default: "0.0", null: false + t.string "state" + t.decimal "adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.bigint "user_id" + t.datetime "completed_at" + t.bigint "bill_address_id" + t.bigint "ship_address_id" + t.decimal "payment_total", precision: 10, scale: 2, default: "0.0" + t.string "shipment_state" + t.string "payment_state" + t.string "email" + t.text "special_instructions" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "currency" + t.string "last_ip_address" + t.bigint "created_by_id" + t.decimal "shipment_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "additional_tax_total", precision: 10, scale: 2, default: "0.0" + t.decimal "promo_total", precision: 10, scale: 2, default: "0.0" + t.string "channel", default: "spree" + t.decimal "included_tax_total", precision: 10, scale: 2, default: "0.0", null: false + t.integer "item_count", default: 0 + t.bigint "approver_id" + t.datetime "approved_at" + t.boolean "confirmation_delivered", default: false + t.boolean "considered_risky", default: false + t.string "token" + t.datetime "canceled_at" + t.bigint "canceler_id" + t.bigint "store_id" + t.integer "state_lock_version", default: 0, null: false + t.decimal "taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "non_taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.boolean "store_owner_notification_delivered" + t.index ["approver_id"], name: "index_spree_orders_on_approver_id" + t.index ["bill_address_id"], name: "index_spree_orders_on_bill_address_id" + t.index ["canceler_id"], name: "index_spree_orders_on_canceler_id" + t.index ["completed_at"], name: "index_spree_orders_on_completed_at" + t.index ["confirmation_delivered"], name: "index_spree_orders_on_confirmation_delivered" + t.index ["considered_risky"], name: "index_spree_orders_on_considered_risky" + t.index ["created_by_id"], name: "index_spree_orders_on_created_by_id" + t.index ["number"], name: "index_spree_orders_on_number", unique: true + t.index ["ship_address_id"], name: "index_spree_orders_on_ship_address_id" + t.index ["store_id"], name: "index_spree_orders_on_store_id" + t.index ["token"], name: "index_spree_orders_on_token" + t.index ["user_id", "created_by_id"], name: "index_spree_orders_on_user_id_and_created_by_id" + end + + create_table "spree_payment_capture_events", force: :cascade do |t| + t.decimal "amount", precision: 10, scale: 2, default: "0.0" + t.bigint "payment_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["payment_id"], name: "index_spree_payment_capture_events_on_payment_id" + end + + create_table "spree_payment_methods", force: :cascade do |t| + t.string "type" + t.string "name" + t.text "description" + t.boolean "active", default: true + t.datetime "deleted_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "display_on", default: "both" + t.boolean "auto_capture" + t.text "preferences" + t.integer "position", default: 0 + t.index ["id", "type"], name: "index_spree_payment_methods_on_id_and_type" + end + + create_table "spree_payment_methods_stores", id: false, force: :cascade do |t| + t.bigint "payment_method_id" + t.bigint "store_id" + t.index ["payment_method_id", "store_id"], name: "payment_mentod_id_store_id_unique_index", unique: true + t.index ["payment_method_id"], name: "index_spree_payment_methods_stores_on_payment_method_id" + t.index ["store_id"], name: "index_spree_payment_methods_stores_on_store_id" + end + + create_table "spree_payments", force: :cascade do |t| + t.decimal "amount", precision: 10, scale: 2, default: "0.0", null: false + t.bigint "order_id" + t.string "source_type" + t.bigint "source_id" + t.bigint "payment_method_id" + t.string "state" + t.string "response_code" + t.string "avs_response" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "number" + t.string "cvv_response_code" + t.string "cvv_response_message" + t.index ["number"], name: "index_spree_payments_on_number", unique: true + t.index ["order_id"], name: "index_spree_payments_on_order_id" + t.index ["payment_method_id"], name: "index_spree_payments_on_payment_method_id" + t.index ["source_id", "source_type"], name: "index_spree_payments_on_source_id_and_source_type" + end + + create_table "spree_preferences", force: :cascade do |t| + t.text "value" + t.string "key" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["key"], name: "index_spree_preferences_on_key", unique: true + end + + create_table "spree_prices", force: :cascade do |t| + t.bigint "variant_id", null: false + t.decimal "amount", precision: 10, scale: 2 + t.string "currency" + t.datetime "deleted_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.decimal "compare_at_amount", precision: 10, scale: 2 + t.index ["deleted_at"], name: "index_spree_prices_on_deleted_at" + t.index ["variant_id", "currency"], name: "index_spree_prices_on_variant_id_and_currency" + t.index ["variant_id"], name: "index_spree_prices_on_variant_id" + end + + create_table "spree_product_option_types", force: :cascade do |t| + t.integer "position" + t.bigint "product_id" + t.bigint "option_type_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["option_type_id"], name: "index_spree_product_option_types_on_option_type_id" + t.index ["position"], name: "index_spree_product_option_types_on_position" + t.index ["product_id"], name: "index_spree_product_option_types_on_product_id" + end + + create_table "spree_product_promotion_rules", force: :cascade do |t| + t.bigint "product_id" + t.bigint "promotion_rule_id" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["product_id"], name: "index_products_promotion_rules_on_product_id" + t.index ["promotion_rule_id", "product_id"], name: "index_products_promotion_rules_on_promotion_rule_and_product" + end + + create_table "spree_product_properties", force: :cascade do |t| + t.string "value" + t.bigint "product_id" + t.bigint "property_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.integer "position", default: 0 + t.boolean "show_property", default: true + t.string "filter_param" + t.index ["filter_param"], name: "index_spree_product_properties_on_filter_param" + t.index ["position"], name: "index_spree_product_properties_on_position" + t.index ["product_id"], name: "index_product_properties_on_product_id" + t.index ["property_id", "product_id"], name: "index_spree_product_properties_on_property_id_and_product_id", unique: true + t.index ["property_id"], name: "index_spree_product_properties_on_property_id" + end + + create_table "spree_products", force: :cascade do |t| + t.string "name", default: "", null: false + t.text "description" + t.datetime "available_on" + t.datetime "deleted_at" + t.string "slug" + t.text "meta_description" + t.string "meta_keywords" + t.bigint "tax_category_id" + t.bigint "shipping_category_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.boolean "promotionable", default: true + t.string "meta_title" + t.datetime "discontinue_on" + t.index ["available_on"], name: "index_spree_products_on_available_on" + t.index ["deleted_at"], name: "index_spree_products_on_deleted_at" + t.index ["discontinue_on"], name: "index_spree_products_on_discontinue_on" + t.index ["name"], name: "index_spree_products_on_name" + t.index ["shipping_category_id"], name: "index_spree_products_on_shipping_category_id" + t.index ["slug"], name: "index_spree_products_on_slug", unique: true + t.index ["tax_category_id"], name: "index_spree_products_on_tax_category_id" + end + + create_table "spree_products_stores", force: :cascade do |t| + t.bigint "product_id" + t.bigint "store_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["product_id", "store_id"], name: "index_spree_products_stores_on_product_id_and_store_id", unique: true + t.index ["product_id"], name: "index_spree_products_stores_on_product_id" + t.index ["store_id"], name: "index_spree_products_stores_on_store_id" + end + + create_table "spree_products_taxons", force: :cascade do |t| + t.bigint "product_id" + t.bigint "taxon_id" + t.integer "position" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["position"], name: "index_spree_products_taxons_on_position" + t.index ["product_id", "taxon_id"], name: "index_spree_products_taxons_on_product_id_and_taxon_id", unique: true + t.index ["product_id"], name: "index_spree_products_taxons_on_product_id" + t.index ["taxon_id"], name: "index_spree_products_taxons_on_taxon_id" + end + + create_table "spree_promotion_action_line_items", force: :cascade do |t| + t.bigint "promotion_action_id" + t.bigint "variant_id" + t.integer "quantity", default: 1 + t.datetime "created_at" + t.datetime "updated_at" + t.index ["promotion_action_id"], name: "index_spree_promotion_action_line_items_on_promotion_action_id" + t.index ["variant_id"], name: "index_spree_promotion_action_line_items_on_variant_id" + end + + create_table "spree_promotion_actions", force: :cascade do |t| + t.bigint "promotion_id" + t.integer "position" + t.string "type" + t.datetime "deleted_at" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["deleted_at"], name: "index_spree_promotion_actions_on_deleted_at" + t.index ["id", "type"], name: "index_spree_promotion_actions_on_id_and_type" + t.index ["promotion_id"], name: "index_spree_promotion_actions_on_promotion_id" + end + + create_table "spree_promotion_categories", force: :cascade do |t| + t.string "name" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "code" + end + + create_table "spree_promotion_rule_taxons", force: :cascade do |t| + t.bigint "taxon_id" + t.bigint "promotion_rule_id" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["promotion_rule_id"], name: "index_spree_promotion_rule_taxons_on_promotion_rule_id" + t.index ["taxon_id"], name: "index_spree_promotion_rule_taxons_on_taxon_id" + end + + create_table "spree_promotion_rule_users", force: :cascade do |t| + t.bigint "user_id" + t.bigint "promotion_rule_id" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["promotion_rule_id"], name: "index_promotion_rules_users_on_promotion_rule_id" + t.index ["user_id", "promotion_rule_id"], name: "index_promotion_rules_users_on_user_id_and_promotion_rule_id" + end + + create_table "spree_promotion_rules", force: :cascade do |t| + t.bigint "promotion_id" + t.bigint "user_id" + t.bigint "product_group_id" + t.string "type" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "code" + t.text "preferences" + t.index ["product_group_id"], name: "index_promotion_rules_on_product_group_id" + t.index ["promotion_id"], name: "index_spree_promotion_rules_on_promotion_id" + t.index ["user_id"], name: "index_promotion_rules_on_user_id" + end + + create_table "spree_promotions", force: :cascade do |t| + t.string "description" + t.datetime "expires_at" + t.datetime "starts_at" + t.string "name" + t.string "type" + t.integer "usage_limit" + t.string "match_policy", default: "all" + t.string "code" + t.boolean "advertise", default: false + t.string "path" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.bigint "promotion_category_id" + t.index ["advertise"], name: "index_spree_promotions_on_advertise" + t.index ["code"], name: "index_spree_promotions_on_code" + t.index ["expires_at"], name: "index_spree_promotions_on_expires_at" + t.index ["id", "type"], name: "index_spree_promotions_on_id_and_type" + t.index ["path"], name: "index_spree_promotions_on_path" + t.index ["promotion_category_id"], name: "index_spree_promotions_on_promotion_category_id" + t.index ["starts_at"], name: "index_spree_promotions_on_starts_at" + end + + create_table "spree_promotions_stores", force: :cascade do |t| + t.bigint "promotion_id" + t.bigint "store_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["promotion_id", "store_id"], name: "index_spree_promotions_stores_on_promotion_id_and_store_id", unique: true + t.index ["promotion_id"], name: "index_spree_promotions_stores_on_promotion_id" + t.index ["store_id"], name: "index_spree_promotions_stores_on_store_id" + end + + create_table "spree_properties", force: :cascade do |t| + t.string "name" + t.string "presentation", null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.boolean "filterable", default: false, null: false + t.string "filter_param" + t.index ["filter_param"], name: "index_spree_properties_on_filter_param" + t.index ["filterable"], name: "index_spree_properties_on_filterable" + t.index ["name"], name: "index_spree_properties_on_name" + end + + create_table "spree_property_prototypes", force: :cascade do |t| + t.bigint "prototype_id" + t.bigint "property_id" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["property_id"], name: "index_spree_property_prototypes_on_property_id" + t.index ["prototype_id", "property_id"], name: "index_property_prototypes_on_prototype_id_and_property_id", unique: true + t.index ["prototype_id"], name: "index_spree_property_prototypes_on_prototype_id" + end + + create_table "spree_prototype_taxons", force: :cascade do |t| + t.bigint "taxon_id" + t.bigint "prototype_id" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["prototype_id", "taxon_id"], name: "index_spree_prototype_taxons_on_prototype_id_and_taxon_id" + t.index ["prototype_id"], name: "index_spree_prototype_taxons_on_prototype_id" + t.index ["taxon_id"], name: "index_spree_prototype_taxons_on_taxon_id" + end + + create_table "spree_prototypes", force: :cascade do |t| + t.string "name" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + + create_table "spree_refund_reasons", force: :cascade do |t| + t.string "name" + t.boolean "active", default: true + t.boolean "mutable", default: true + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["name"], name: "index_spree_refund_reasons_on_name", unique: true + end + + create_table "spree_refunds", force: :cascade do |t| + t.bigint "payment_id" + t.decimal "amount", precision: 10, scale: 2, default: "0.0", null: false + t.string "transaction_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.bigint "refund_reason_id" + t.bigint "reimbursement_id" + t.index ["payment_id"], name: "index_spree_refunds_on_payment_id" + t.index ["refund_reason_id"], name: "index_refunds_on_refund_reason_id" + t.index ["reimbursement_id"], name: "index_spree_refunds_on_reimbursement_id" + end + + create_table "spree_reimbursement_credits", force: :cascade do |t| + t.decimal "amount", precision: 10, scale: 2, default: "0.0", null: false + t.bigint "reimbursement_id" + t.bigint "creditable_id" + t.string "creditable_type" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["creditable_id", "creditable_type"], name: "index_reimbursement_credits_on_creditable_id_and_type" + t.index ["reimbursement_id"], name: "index_spree_reimbursement_credits_on_reimbursement_id" + end + + create_table "spree_reimbursement_types", force: :cascade do |t| + t.string "name" + t.boolean "active", default: true + t.boolean "mutable", default: true + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "type" + t.index ["name"], name: "index_spree_reimbursement_types_on_name", unique: true + t.index ["type"], name: "index_spree_reimbursement_types_on_type" + end + + create_table "spree_reimbursements", force: :cascade do |t| + t.string "number" + t.string "reimbursement_status" + t.bigint "customer_return_id" + t.bigint "order_id" + t.decimal "total", precision: 10, scale: 2 + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["customer_return_id"], name: "index_spree_reimbursements_on_customer_return_id" + t.index ["number"], name: "index_spree_reimbursements_on_number", unique: true + t.index ["order_id"], name: "index_spree_reimbursements_on_order_id" + end + + create_table "spree_return_authorization_reasons", force: :cascade do |t| + t.string "name" + t.boolean "active", default: true + t.boolean "mutable", default: true + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["name"], name: "index_spree_return_authorization_reasons_on_name", unique: true + end + + create_table "spree_return_authorizations", force: :cascade do |t| + t.string "number" + t.string "state" + t.bigint "order_id" + t.text "memo" + t.datetime "created_at" + t.datetime "updated_at" + t.bigint "stock_location_id" + t.bigint "return_authorization_reason_id" + t.index ["number"], name: "index_spree_return_authorizations_on_number", unique: true + t.index ["order_id"], name: "index_spree_return_authorizations_on_order_id" + t.index ["return_authorization_reason_id"], name: "index_return_authorizations_on_return_authorization_reason_id" + t.index ["stock_location_id"], name: "index_spree_return_authorizations_on_stock_location_id" + end + + create_table "spree_return_items", force: :cascade do |t| + t.bigint "return_authorization_id" + t.bigint "inventory_unit_id" + t.bigint "exchange_variant_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.decimal "pre_tax_amount", precision: 12, scale: 4, default: "0.0", null: false + t.decimal "included_tax_total", precision: 12, scale: 4, default: "0.0", null: false + t.decimal "additional_tax_total", precision: 12, scale: 4, default: "0.0", null: false + t.string "reception_status" + t.string "acceptance_status" + t.bigint "customer_return_id" + t.bigint "reimbursement_id" + t.text "acceptance_status_errors" + t.bigint "preferred_reimbursement_type_id" + t.bigint "override_reimbursement_type_id" + t.boolean "resellable", default: true, null: false + t.index ["customer_return_id"], name: "index_return_items_on_customer_return_id" + t.index ["exchange_variant_id"], name: "index_spree_return_items_on_exchange_variant_id" + t.index ["inventory_unit_id"], name: "index_spree_return_items_on_inventory_unit_id" + t.index ["override_reimbursement_type_id"], name: "index_spree_return_items_on_override_reimbursement_type_id" + t.index ["preferred_reimbursement_type_id"], name: "index_spree_return_items_on_preferred_reimbursement_type_id" + t.index ["reimbursement_id"], name: "index_spree_return_items_on_reimbursement_id" + t.index ["return_authorization_id"], name: "index_spree_return_items_on_return_authorization_id" + end + + create_table "spree_role_users", force: :cascade do |t| + t.bigint "role_id" + t.bigint "user_id" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["role_id"], name: "index_spree_role_users_on_role_id" + t.index ["user_id"], name: "index_spree_role_users_on_user_id" + end + + create_table "spree_roles", force: :cascade do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["name"], name: "index_spree_roles_on_name", unique: true + end + + create_table "spree_shipments", force: :cascade do |t| + t.string "tracking" + t.string "number" + t.decimal "cost", precision: 10, scale: 2, default: "0.0" + t.datetime "shipped_at" + t.bigint "order_id" + t.bigint "address_id" + t.string "state" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.bigint "stock_location_id" + t.decimal "adjustment_total", precision: 10, scale: 2, default: "0.0" + t.decimal "additional_tax_total", precision: 10, scale: 2, default: "0.0" + t.decimal "promo_total", precision: 10, scale: 2, default: "0.0" + t.decimal "included_tax_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "pre_tax_amount", precision: 12, scale: 4, default: "0.0", null: false + t.decimal "taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "non_taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.index ["address_id"], name: "index_spree_shipments_on_address_id" + t.index ["number"], name: "index_spree_shipments_on_number", unique: true + t.index ["order_id"], name: "index_spree_shipments_on_order_id" + t.index ["stock_location_id"], name: "index_spree_shipments_on_stock_location_id" + end + + create_table "spree_shipping_categories", force: :cascade do |t| + t.string "name" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["name"], name: "index_spree_shipping_categories_on_name" + end + + create_table "spree_shipping_method_categories", force: :cascade do |t| + t.bigint "shipping_method_id", null: false + t.bigint "shipping_category_id", null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["shipping_category_id", "shipping_method_id"], name: "unique_spree_shipping_method_categories", unique: true + t.index ["shipping_category_id"], name: "index_spree_shipping_method_categories_on_shipping_category_id" + t.index ["shipping_method_id"], name: "index_spree_shipping_method_categories_on_shipping_method_id" + end + + create_table "spree_shipping_method_zones", force: :cascade do |t| + t.bigint "shipping_method_id" + t.bigint "zone_id" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["shipping_method_id"], name: "index_spree_shipping_method_zones_on_shipping_method_id" + t.index ["zone_id"], name: "index_spree_shipping_method_zones_on_zone_id" + end + + create_table "spree_shipping_methods", force: :cascade do |t| + t.string "name" + t.string "display_on" + t.datetime "deleted_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "tracking_url" + t.string "admin_name" + t.bigint "tax_category_id" + t.string "code" + t.index ["deleted_at"], name: "index_spree_shipping_methods_on_deleted_at" + t.index ["tax_category_id"], name: "index_spree_shipping_methods_on_tax_category_id" + end + + create_table "spree_shipping_rates", force: :cascade do |t| + t.bigint "shipment_id" + t.bigint "shipping_method_id" + t.boolean "selected", default: false + t.decimal "cost", precision: 8, scale: 2, default: "0.0" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.bigint "tax_rate_id" + t.index ["selected"], name: "index_spree_shipping_rates_on_selected" + t.index ["shipment_id", "shipping_method_id"], name: "spree_shipping_rates_join_index", unique: true + t.index ["shipment_id"], name: "index_spree_shipping_rates_on_shipment_id" + t.index ["shipping_method_id"], name: "index_spree_shipping_rates_on_shipping_method_id" + t.index ["tax_rate_id"], name: "index_spree_shipping_rates_on_tax_rate_id" + end + + create_table "spree_state_changes", force: :cascade do |t| + t.string "name" + t.string "previous_state" + t.bigint "stateful_id" + t.bigint "user_id" + t.string "stateful_type" + t.string "next_state" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["stateful_id", "stateful_type"], name: "index_spree_state_changes_on_stateful_id_and_stateful_type" + end + + create_table "spree_states", force: :cascade do |t| + t.string "name" + t.string "abbr" + t.bigint "country_id" + t.datetime "updated_at" + t.datetime "created_at" + t.index ["country_id"], name: "index_spree_states_on_country_id" + end + + create_table "spree_stock_items", force: :cascade do |t| + t.bigint "stock_location_id" + t.bigint "variant_id" + t.integer "count_on_hand", default: 0, null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.boolean "backorderable", default: false + t.datetime "deleted_at" + t.index ["backorderable"], name: "index_spree_stock_items_on_backorderable" + t.index ["deleted_at"], name: "index_spree_stock_items_on_deleted_at" + t.index ["stock_location_id", "variant_id"], name: "stock_item_by_loc_and_var_id" + t.index ["stock_location_id"], name: "index_spree_stock_items_on_stock_location_id" + t.index ["variant_id"], name: "index_spree_stock_items_on_variant_id" + end + + create_table "spree_stock_locations", force: :cascade do |t| + t.string "name" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.boolean "default", default: false, null: false + t.string "address1" + t.string "address2" + t.string "city" + t.bigint "state_id" + t.string "state_name" + t.bigint "country_id" + t.string "zipcode" + t.string "phone" + t.boolean "active", default: true + t.boolean "backorderable_default", default: false + t.boolean "propagate_all_variants", default: true + t.string "admin_name" + t.index ["active"], name: "index_spree_stock_locations_on_active" + t.index ["backorderable_default"], name: "index_spree_stock_locations_on_backorderable_default" + t.index ["country_id"], name: "index_spree_stock_locations_on_country_id" + t.index ["propagate_all_variants"], name: "index_spree_stock_locations_on_propagate_all_variants" + t.index ["state_id"], name: "index_spree_stock_locations_on_state_id" + end + + create_table "spree_stock_movements", force: :cascade do |t| + t.bigint "stock_item_id" + t.integer "quantity", default: 0 + t.string "action" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "originator_type" + t.bigint "originator_id" + t.index ["originator_id", "originator_type"], name: "index_stock_movements_on_originator_id_and_originator_type" + t.index ["stock_item_id"], name: "index_spree_stock_movements_on_stock_item_id" + end + + create_table "spree_stock_transfers", force: :cascade do |t| + t.string "type" + t.string "reference" + t.bigint "source_location_id" + t.bigint "destination_location_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "number" + t.index ["destination_location_id"], name: "index_spree_stock_transfers_on_destination_location_id" + t.index ["number"], name: "index_spree_stock_transfers_on_number", unique: true + t.index ["source_location_id"], name: "index_spree_stock_transfers_on_source_location_id" + end + + create_table "spree_store_credit_categories", force: :cascade do |t| + t.string "name" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + + create_table "spree_store_credit_events", force: :cascade do |t| + t.bigint "store_credit_id", null: false + t.string "action", null: false + t.decimal "amount", precision: 8, scale: 2 + t.string "authorization_code", null: false + t.decimal "user_total_amount", precision: 8, scale: 2, default: "0.0", null: false + t.bigint "originator_id" + t.string "originator_type" + t.datetime "deleted_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["originator_id", "originator_type"], name: "spree_store_credit_events_originator" + t.index ["store_credit_id"], name: "index_spree_store_credit_events_on_store_credit_id" + end + + create_table "spree_store_credit_types", force: :cascade do |t| + t.string "name" + t.integer "priority" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["priority"], name: "index_spree_store_credit_types_on_priority" + end + + create_table "spree_store_credits", force: :cascade do |t| + t.bigint "user_id" + t.bigint "category_id" + t.bigint "created_by_id" + t.decimal "amount", precision: 8, scale: 2, default: "0.0", null: false + t.decimal "amount_used", precision: 8, scale: 2, default: "0.0", null: false + t.text "memo" + t.datetime "deleted_at" + t.string "currency" + t.decimal "amount_authorized", precision: 8, scale: 2, default: "0.0", null: false + t.bigint "originator_id" + t.string "originator_type" + t.bigint "type_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.bigint "store_id" + t.index ["deleted_at"], name: "index_spree_store_credits_on_deleted_at" + t.index ["originator_id", "originator_type"], name: "spree_store_credits_originator" + t.index ["store_id"], name: "index_spree_store_credits_on_store_id" + t.index ["type_id"], name: "index_spree_store_credits_on_type_id" + t.index ["user_id"], name: "index_spree_store_credits_on_user_id" + end + + create_table "spree_stores", force: :cascade do |t| + t.string "name" + t.string "url" + t.text "meta_description" + t.text "meta_keywords" + t.string "seo_title" + t.string "mail_from_address" + t.string "default_currency" + t.string "code" + t.boolean "default", default: false, null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "supported_currencies" + t.string "facebook" + t.string "twitter" + t.string "instagram" + t.string "default_locale" + t.string "customer_support_email" + t.bigint "default_country_id" + t.text "description" + t.text "address" + t.string "contact_phone" + t.string "new_order_notifications_email" + t.bigint "checkout_zone_id" + t.string "seo_robots" + t.string "supported_locales" + t.index ["code"], name: "index_spree_stores_on_code", unique: true + t.index ["default"], name: "index_spree_stores_on_default" + t.index ["url"], name: "index_spree_stores_on_url" + end + + create_table "spree_tax_categories", force: :cascade do |t| + t.string "name" + t.string "description" + t.boolean "is_default", default: false + t.datetime "deleted_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "tax_code" + t.index ["deleted_at"], name: "index_spree_tax_categories_on_deleted_at" + t.index ["is_default"], name: "index_spree_tax_categories_on_is_default" + end + + create_table "spree_tax_rates", force: :cascade do |t| + t.decimal "amount", precision: 8, scale: 5 + t.bigint "zone_id" + t.bigint "tax_category_id" + t.boolean "included_in_price", default: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "name" + t.boolean "show_rate_in_label", default: true + t.datetime "deleted_at" + t.index ["deleted_at"], name: "index_spree_tax_rates_on_deleted_at" + t.index ["included_in_price"], name: "index_spree_tax_rates_on_included_in_price" + t.index ["show_rate_in_label"], name: "index_spree_tax_rates_on_show_rate_in_label" + t.index ["tax_category_id"], name: "index_spree_tax_rates_on_tax_category_id" + t.index ["zone_id"], name: "index_spree_tax_rates_on_zone_id" + end + + create_table "spree_taxonomies", force: :cascade do |t| + t.string "name", null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.integer "position", default: 0 + t.bigint "store_id" + t.index ["name", "store_id"], name: "index_spree_taxonomies_on_name_and_store_id", unique: true + t.index ["position"], name: "index_spree_taxonomies_on_position" + t.index ["store_id"], name: "index_spree_taxonomies_on_store_id" + end + + create_table "spree_taxons", force: :cascade do |t| + t.bigint "parent_id" + t.integer "position", default: 0 + t.string "name", null: false + t.string "permalink" + t.bigint "taxonomy_id" + t.bigint "lft" + t.bigint "rgt" + t.text "description" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "meta_title" + t.string "meta_description" + t.string "meta_keywords" + t.integer "depth" + t.boolean "hide_from_nav", default: false + t.index ["lft"], name: "index_spree_taxons_on_lft" + t.index ["name", "parent_id", "taxonomy_id"], name: "index_spree_taxons_on_name_and_parent_id_and_taxonomy_id", unique: true + t.index ["name"], name: "index_spree_taxons_on_name" + t.index ["parent_id"], name: "index_taxons_on_parent_id" + t.index ["permalink", "parent_id", "taxonomy_id"], name: "index_spree_taxons_on_permalink_and_parent_id_and_taxonomy_id", unique: true + t.index ["permalink"], name: "index_taxons_on_permalink" + t.index ["position"], name: "index_spree_taxons_on_position" + t.index ["rgt"], name: "index_spree_taxons_on_rgt" + t.index ["taxonomy_id"], name: "index_taxons_on_taxonomy_id" + end + + create_table "spree_trackers", force: :cascade do |t| + t.string "analytics_id" + t.boolean "active", default: true + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.integer "engine", default: 0, null: false + t.index ["active"], name: "index_spree_trackers_on_active" + end + + create_table "spree_users", force: :cascade do |t| + t.string "encrypted_password", limit: 128 + t.string "password_salt", limit: 128 + t.string "email" + t.string "remember_token" + t.string "persistence_token" + t.string "reset_password_token" + t.string "perishable_token" + t.integer "sign_in_count", default: 0, null: false + t.integer "failed_attempts", default: 0, null: false + t.datetime "last_request_at" + t.datetime "current_sign_in_at" + t.datetime "last_sign_in_at" + t.string "current_sign_in_ip" + t.string "last_sign_in_ip" + t.string "login" + t.bigint "ship_address_id" + t.bigint "bill_address_id" + t.string "authentication_token" + t.string "unlock_token" + t.datetime "locked_at" + t.datetime "remember_created_at" + t.datetime "reset_password_sent_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + + create_table "spree_variants", force: :cascade do |t| + t.string "sku", default: "", null: false + t.decimal "weight", precision: 8, scale: 2, default: "0.0" + t.decimal "height", precision: 8, scale: 2 + t.decimal "width", precision: 8, scale: 2 + t.decimal "depth", precision: 8, scale: 2 + t.datetime "deleted_at" + t.boolean "is_master", default: false + t.bigint "product_id" + t.decimal "cost_price", precision: 10, scale: 2 + t.integer "position" + t.string "cost_currency" + t.boolean "track_inventory", default: true + t.bigint "tax_category_id" + t.datetime "updated_at", null: false + t.datetime "discontinue_on" + t.datetime "created_at", null: false + t.index ["deleted_at"], name: "index_spree_variants_on_deleted_at" + t.index ["discontinue_on"], name: "index_spree_variants_on_discontinue_on" + t.index ["is_master"], name: "index_spree_variants_on_is_master" + t.index ["position"], name: "index_spree_variants_on_position" + t.index ["product_id"], name: "index_spree_variants_on_product_id" + t.index ["sku"], name: "index_spree_variants_on_sku" + t.index ["tax_category_id"], name: "index_spree_variants_on_tax_category_id" + t.index ["track_inventory"], name: "index_spree_variants_on_track_inventory" + end + + create_table "spree_zone_members", force: :cascade do |t| + t.string "zoneable_type" + t.bigint "zoneable_id" + t.bigint "zone_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["zone_id"], name: "index_spree_zone_members_on_zone_id" + t.index ["zoneable_id", "zoneable_type"], name: "index_spree_zone_members_on_zoneable_id_and_zoneable_type" + end + + create_table "spree_zones", force: :cascade do |t| + t.string "name" + t.string "description" + t.boolean "default_tax", default: false + t.integer "zone_members_count", default: 0 + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "kind", default: "state" + t.index ["default_tax"], name: "index_spree_zones_on_default_tax" + t.index ["kind"], name: "index_spree_zones_on_kind" + end + end +end diff --git a/db/migrate/20250210131635_add_metadata_to_spree_orders.spree.rb b/db/migrate/20250210131635_add_metadata_to_spree_orders.spree.rb new file mode 100644 index 0000000..52d4e34 --- /dev/null +++ b/db/migrate/20250210131635_add_metadata_to_spree_orders.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20210915064321) +class AddMetadataToSpreeOrders < ActiveRecord::Migration[5.2] + def change + change_table :spree_orders do |t| + if t.respond_to? :jsonb + add_column :spree_orders, :public_metadata, :jsonb + add_column :spree_orders, :private_metadata, :jsonb + else + add_column :spree_orders, :public_metadata, :json + add_column :spree_orders, :private_metadata, :json + end + end + end +end diff --git a/db/migrate/20250210131636_add_metadata_to_spree_products.spree.rb b/db/migrate/20250210131636_add_metadata_to_spree_products.spree.rb new file mode 100644 index 0000000..f536e3c --- /dev/null +++ b/db/migrate/20250210131636_add_metadata_to_spree_products.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20210915064322) +class AddMetadataToSpreeProducts < ActiveRecord::Migration[5.2] + def change + change_table :spree_products do |t| + if t.respond_to? :jsonb + add_column :spree_products, :public_metadata, :jsonb + add_column :spree_products, :private_metadata, :jsonb + else + add_column :spree_products, :public_metadata, :json + add_column :spree_products, :private_metadata, :json + end + end + end +end diff --git a/db/migrate/20250210131637_add_metadata_to_spree_variants.spree.rb b/db/migrate/20250210131637_add_metadata_to_spree_variants.spree.rb new file mode 100644 index 0000000..6db507f --- /dev/null +++ b/db/migrate/20250210131637_add_metadata_to_spree_variants.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20210915064323) +class AddMetadataToSpreeVariants < ActiveRecord::Migration[5.2] + def change + change_table :spree_variants do |t| + if t.respond_to? :jsonb + add_column :spree_variants, :public_metadata, :jsonb + add_column :spree_variants, :private_metadata, :jsonb + else + add_column :spree_variants, :public_metadata, :json + add_column :spree_variants, :private_metadata, :json + end + end + end +end diff --git a/db/migrate/20250210131638_add_metadata_to_spree_line_items.spree.rb b/db/migrate/20250210131638_add_metadata_to_spree_line_items.spree.rb new file mode 100644 index 0000000..86103f6 --- /dev/null +++ b/db/migrate/20250210131638_add_metadata_to_spree_line_items.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20210915064324) +class AddMetadataToSpreeLineItems < ActiveRecord::Migration[5.2] + def change + change_table :spree_line_items do |t| + if t.respond_to? :jsonb + add_column :spree_line_items, :public_metadata, :jsonb + add_column :spree_line_items, :private_metadata, :jsonb + else + add_column :spree_line_items, :public_metadata, :json + add_column :spree_line_items, :private_metadata, :json + end + end + end +end diff --git a/db/migrate/20250210131639_add_metadata_to_spree_shipments.spree.rb b/db/migrate/20250210131639_add_metadata_to_spree_shipments.spree.rb new file mode 100644 index 0000000..e56973b --- /dev/null +++ b/db/migrate/20250210131639_add_metadata_to_spree_shipments.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20210915064325) +class AddMetadataToSpreeShipments < ActiveRecord::Migration[5.2] + def change + change_table :spree_shipments do |t| + if t.respond_to? :jsonb + add_column :spree_shipments, :public_metadata, :jsonb + add_column :spree_shipments, :private_metadata, :jsonb + else + add_column :spree_shipments, :public_metadata, :json + add_column :spree_shipments, :private_metadata, :json + end + end + end +end diff --git a/db/migrate/20250210131640_add_metadata_to_spree_payments.spree.rb b/db/migrate/20250210131640_add_metadata_to_spree_payments.spree.rb new file mode 100644 index 0000000..42dd39d --- /dev/null +++ b/db/migrate/20250210131640_add_metadata_to_spree_payments.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20210915064326) +class AddMetadataToSpreePayments < ActiveRecord::Migration[5.2] + def change + change_table :spree_payments do |t| + if t.respond_to? :jsonb + add_column :spree_payments, :public_metadata, :jsonb + add_column :spree_payments, :private_metadata, :jsonb + else + add_column :spree_payments, :public_metadata, :json + add_column :spree_payments, :private_metadata, :json + end + end + end +end diff --git a/db/migrate/20250210131641_add_metadata_to_spree_taxons_and_taxonomies.spree.rb b/db/migrate/20250210131641_add_metadata_to_spree_taxons_and_taxonomies.spree.rb new file mode 100644 index 0000000..efa9153 --- /dev/null +++ b/db/migrate/20250210131641_add_metadata_to_spree_taxons_and_taxonomies.spree.rb @@ -0,0 +1,19 @@ +# This migration comes from spree (originally 20210915064327) +class AddMetadataToSpreeTaxonsAndTaxonomies < ActiveRecord::Migration[5.2] + def change + %i[ + spree_taxons + spree_taxonomies + ].each do |table_name| + change_table table_name do |t| + if t.respond_to? :jsonb + add_column table_name, :public_metadata, :jsonb + add_column table_name, :private_metadata, :jsonb + else + add_column table_name, :public_metadata, :json + add_column table_name, :private_metadata, :json + end + end + end + end +end diff --git a/db/migrate/20250210131642_add_metadata_to_spree_stock_transfers.spree.rb b/db/migrate/20250210131642_add_metadata_to_spree_stock_transfers.spree.rb new file mode 100644 index 0000000..3143291 --- /dev/null +++ b/db/migrate/20250210131642_add_metadata_to_spree_stock_transfers.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20210915064328) +class AddMetadataToSpreeStockTransfers < ActiveRecord::Migration[5.2] + def change + change_table :spree_stock_transfers do |t| + if t.respond_to? :jsonb + add_column :spree_stock_transfers, :public_metadata, :jsonb + add_column :spree_stock_transfers, :private_metadata, :jsonb + else + add_column :spree_stock_transfers, :public_metadata, :json + add_column :spree_stock_transfers, :private_metadata, :json + end + end + end +end diff --git a/db/migrate/20250210131643_add_metadata_to_spree_multiple_tables.spree.rb b/db/migrate/20250210131643_add_metadata_to_spree_multiple_tables.spree.rb new file mode 100644 index 0000000..732328d --- /dev/null +++ b/db/migrate/20250210131643_add_metadata_to_spree_multiple_tables.spree.rb @@ -0,0 +1,31 @@ +# This migration comes from spree (originally 20210915064329) +class AddMetadataToSpreeMultipleTables < ActiveRecord::Migration[5.2] + def change + %i[ + spree_assets + spree_option_types + spree_option_values + spree_properties + spree_promotions + spree_payment_methods + spree_shipping_methods + spree_prototypes + spree_refunds + spree_customer_returns + spree_users + spree_addresses + spree_credit_cards + spree_store_credits + ].each do |table_name| + change_table table_name do |t| + if t.respond_to? :jsonb + add_column table_name, :public_metadata, :jsonb + add_column table_name, :private_metadata, :jsonb + else + add_column table_name, :public_metadata, :json + add_column table_name, :private_metadata, :json + end + end + end + end +end diff --git a/db/migrate/20250210131644_add_deleted_at_to_spree_stores.spree.rb b/db/migrate/20250210131644_add_deleted_at_to_spree_stores.spree.rb new file mode 100644 index 0000000..5ee5ac0 --- /dev/null +++ b/db/migrate/20250210131644_add_deleted_at_to_spree_stores.spree.rb @@ -0,0 +1,9 @@ +# This migration comes from spree (originally 20210920090344) +class AddDeletedAtToSpreeStores < ActiveRecord::Migration[5.2] + def change + unless column_exists?(:spree_stores, :deleted_at) + add_column :spree_stores, :deleted_at, :datetime + add_index :spree_stores, :deleted_at + end + end +end diff --git a/db/migrate/20250210131645_rename_column_access_hash_to_token.spree.rb b/db/migrate/20250210131645_rename_column_access_hash_to_token.spree.rb new file mode 100644 index 0000000..44d49c9 --- /dev/null +++ b/db/migrate/20250210131645_rename_column_access_hash_to_token.spree.rb @@ -0,0 +1,9 @@ +# This migration comes from spree (originally 20210921070812) +class RenameColumnAccessHashToToken < ActiveRecord::Migration[5.2] + def change + if table_exists?(:spree_wishlists) + rename_column(:spree_wishlists, :access_hash, :token) if column_exists?(:spree_wishlists, :access_hash) + add_reference(:spree_wishlists, :store, index: true) unless column_exists?(:spree_wishlists, :store_id) + end + end +end diff --git a/db/migrate/20250210131646_create_spree_wishlists.spree.rb b/db/migrate/20250210131646_create_spree_wishlists.spree.rb new file mode 100644 index 0000000..a84edd9 --- /dev/null +++ b/db/migrate/20250210131646_create_spree_wishlists.spree.rb @@ -0,0 +1,19 @@ +# This migration comes from spree (originally 20210921070813) +class CreateSpreeWishlists < ActiveRecord::Migration[5.2] + def change + create_table :spree_wishlists, if_not_exists: true do |t| + t.belongs_to :user + t.belongs_to :store + + t.column :name, :string + t.column :token, :string, null: false + t.column :is_private, :boolean, default: true, null: false + t.column :is_default, :boolean, default: false, null: false + + t.timestamps + end + + add_index :spree_wishlists, :token, unique: true + add_index :spree_wishlists, [:user_id, :is_default] unless index_exists?(:spree_wishlists, [:user_id, :is_default]) + end +end diff --git a/db/migrate/20250210131647_create_spree_wished_products.spree.rb b/db/migrate/20250210131647_create_spree_wished_products.spree.rb new file mode 100644 index 0000000..5811a48 --- /dev/null +++ b/db/migrate/20250210131647_create_spree_wished_products.spree.rb @@ -0,0 +1,17 @@ +# This migration comes from spree (originally 20210921070814) +class CreateSpreeWishedProducts < ActiveRecord::Migration[5.2] + def change + create_table :spree_wished_products, if_not_exists: true do |t| + t.references :variant + t.belongs_to :wishlist + + t.column :quantity, :integer, default: 1, null: false + + t.timestamps + end + + add_index :spree_wished_products, [:variant_id, :wishlist_id], unique: true unless index_exists?(:spree_wished_products, [:variant_id, :wishlist_id]) + add_index :spree_wished_products, :variant_id unless index_exists?(:spree_wished_products, :variant_id) + add_index :spree_wished_products, :wishlist_id unless index_exists?(:spree_wished_products, :wishlist_id) + end +end diff --git a/db/migrate/20250210131648_rename_spree_wished_products_to_spree_wished_items.spree.rb b/db/migrate/20250210131648_rename_spree_wished_products_to_spree_wished_items.spree.rb new file mode 100644 index 0000000..a38e498 --- /dev/null +++ b/db/migrate/20250210131648_rename_spree_wished_products_to_spree_wished_items.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20210921070815) +class RenameSpreeWishedProductsToSpreeWishedItems < ActiveRecord::Migration[5.2] + def change + rename_table :spree_wished_products, :spree_wished_items + end +end diff --git a/db/migrate/20250210131649_add_unique_stock_item_stock_location_variant_deleted_at_index.spree.rb b/db/migrate/20250210131649_add_unique_stock_item_stock_location_variant_deleted_at_index.spree.rb new file mode 100644 index 0000000..24337f5 --- /dev/null +++ b/db/migrate/20250210131649_add_unique_stock_item_stock_location_variant_deleted_at_index.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20210921090344) +class AddUniqueStockItemStockLocationVariantDeletedAtIndex < ActiveRecord::Migration[5.2] + def change + add_index :spree_stock_items, [:stock_location_id, :variant_id, :deleted_at], name: 'stock_item_by_loc_var_id_deleted_at', unique: true + end +end diff --git a/db/migrate/20250210131650_create_stock_item_stock_location_id_variant_id_coalesce_deleted_at_unique_index.spree.rb b/db/migrate/20250210131650_create_stock_item_stock_location_id_variant_id_coalesce_deleted_at_unique_index.spree.rb new file mode 100644 index 0000000..0749478 --- /dev/null +++ b/db/migrate/20250210131650_create_stock_item_stock_location_id_variant_id_coalesce_deleted_at_unique_index.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20210929090344) +class CreateStockItemStockLocationIdVariantIdCoalesceDeletedAtUniqueIndex < ActiveRecord::Migration[5.2] + def change + # this migration was broken and is fixed in the following migration + end +end diff --git a/db/migrate/20250210131651_create_spree_digital_links.spree.rb b/db/migrate/20250210131651_create_spree_digital_links.spree.rb new file mode 100644 index 0000000..2340667 --- /dev/null +++ b/db/migrate/20250210131651_create_spree_digital_links.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20210929091444) +class CreateSpreeDigitalLinks < ActiveRecord::Migration[5.2] + def change + create_table :spree_digital_links, if_not_exists: true do |t| + t.belongs_to :digital + t.belongs_to :line_item + t.string :secret + t.integer :access_counter + + t.timestamps + end + add_index :spree_digital_links, :secret, unique: true unless index_exists?(:spree_digital_links, :secret) + end +end diff --git a/db/migrate/20250210131652_create_spree_digitals.spree.rb b/db/migrate/20250210131652_create_spree_digitals.spree.rb new file mode 100644 index 0000000..f6ae40b --- /dev/null +++ b/db/migrate/20250210131652_create_spree_digitals.spree.rb @@ -0,0 +1,10 @@ +# This migration comes from spree (originally 20210929093238) +class CreateSpreeDigitals < ActiveRecord::Migration[5.2] + def change + create_table :spree_digitals, if_not_exists: true do |t| + t.belongs_to :variant + + t.timestamps + end + end +end diff --git a/db/migrate/20250210131653_rename_secret_to_token_on_spree_digital_links.spree.rb b/db/migrate/20250210131653_rename_secret_to_token_on_spree_digital_links.spree.rb new file mode 100644 index 0000000..7c42f77 --- /dev/null +++ b/db/migrate/20250210131653_rename_secret_to_token_on_spree_digital_links.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20210930143043) +class RenameSecretToTokenOnSpreeDigitalLinks < ActiveRecord::Migration[5.2] + def change + rename_column :spree_digital_links, :secret, :token + end +end diff --git a/db/migrate/20250210131654_add_settings_to_spree_stores.spree.rb b/db/migrate/20250210131654_add_settings_to_spree_stores.spree.rb new file mode 100644 index 0000000..1dcb13f --- /dev/null +++ b/db/migrate/20250210131654_add_settings_to_spree_stores.spree.rb @@ -0,0 +1,12 @@ +# This migration comes from spree (originally 20210930155649) +class AddSettingsToSpreeStores < ActiveRecord::Migration[5.2] + def change + change_table :spree_stores do |t| + if t.respond_to? :jsonb + add_column :spree_stores, :settings, :jsonb + else + add_column :spree_stores, :settings, :json + end + end + end +end diff --git a/db/migrate/20250210131655_add_settings_to_payment_methods.spree.rb b/db/migrate/20250210131655_add_settings_to_payment_methods.spree.rb new file mode 100644 index 0000000..5c68a97 --- /dev/null +++ b/db/migrate/20250210131655_add_settings_to_payment_methods.spree.rb @@ -0,0 +1,12 @@ +# This migration comes from spree (originally 20211203082008) +class AddSettingsToPaymentMethods < ActiveRecord::Migration[5.2] + def change + change_table :spree_payment_methods do |t| + if t.respond_to? :jsonb + add_column :spree_payment_methods, :settings, :jsonb + else + add_column :spree_payment_methods, :settings, :json + end + end + end +end diff --git a/db/migrate/20250210131656_disable_propagate_all_variants_by_default.spree.rb b/db/migrate/20250210131656_disable_propagate_all_variants_by_default.spree.rb new file mode 100644 index 0000000..f859380 --- /dev/null +++ b/db/migrate/20250210131656_disable_propagate_all_variants_by_default.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20211229162122) +class DisablePropagateAllVariantsByDefault < ActiveRecord::Migration[5.2] + def change + change_column_default :spree_stock_locations, :propagate_all_variants, false + end +end diff --git a/db/migrate/20250210131657_add_status_and_make_active_at_to_spree_products.spree.rb b/db/migrate/20250210131657_add_status_and_make_active_at_to_spree_products.spree.rb new file mode 100644 index 0000000..763beb2 --- /dev/null +++ b/db/migrate/20250210131657_add_status_and_make_active_at_to_spree_products.spree.rb @@ -0,0 +1,8 @@ +# This migration comes from spree (originally 20220103082046) +class AddStatusAndMakeActiveAtToSpreeProducts < ActiveRecord::Migration[5.2] + def change + add_column :spree_products, :status, :string, null: false, default: 'draft' + add_index :spree_products, :status + add_index :spree_products, %i[status deleted_at] + end +end diff --git a/db/migrate/20250210131658_add_internal_note_to_spree_orders.spree.rb b/db/migrate/20250210131658_add_internal_note_to_spree_orders.spree.rb new file mode 100644 index 0000000..1efb621 --- /dev/null +++ b/db/migrate/20250210131658_add_internal_note_to_spree_orders.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20220106230929) +class AddInternalNoteToSpreeOrders < ActiveRecord::Migration[5.2] + def change + add_column :spree_orders, :internal_note, :text + end +end diff --git a/db/migrate/20250210131659_create_payment_sources.spree.rb b/db/migrate/20250210131659_create_payment_sources.spree.rb new file mode 100644 index 0000000..5b7322b --- /dev/null +++ b/db/migrate/20250210131659_create_payment_sources.spree.rb @@ -0,0 +1,23 @@ +# This migration comes from spree (originally 20220113052823) +class CreatePaymentSources < ActiveRecord::Migration[5.2] + def change + create_table :spree_payment_sources do |t| + t.string :gateway_payment_profile_id + t.string :type, index: true + + t.references :payment_method, index: true, foreign_key: { to_table: :spree_payment_methods } + t.references :user, index: true, foreign_key: { to_table: :spree_users } + + if t.respond_to? :jsonb + t.jsonb :public_metadata + t.jsonb :private_metadata + else + t.json :public_metadata + t.json :private_metadata + end + + t.index [:type, :gateway_payment_profile_id], unique: true, name: 'index_payment_sources_on_type_and_gateway_payment_profile_id' + t.timestamps + end + end +end diff --git a/db/migrate/20250210131660_add_make_active_at_to_spree_products.spree.rb b/db/migrate/20250210131660_add_make_active_at_to_spree_products.spree.rb new file mode 100644 index 0000000..c841893 --- /dev/null +++ b/db/migrate/20250210131660_add_make_active_at_to_spree_products.spree.rb @@ -0,0 +1,18 @@ +# This migration comes from spree (originally 20220117100333) +class AddMakeActiveAtToSpreeProducts < ActiveRecord::Migration[5.2] + def change + add_column :spree_products, :make_active_at, :datetime + add_index :spree_products, :make_active_at + + Spree::Product. + where('discontinue_on IS NULL or discontinue_on > ?', Time.current). + where('available_on <= ?', Time.current). + where(status: 'draft'). + update_all(status: 'active', updated_at: Time.current) + + Spree::Product. + where('discontinue_on <= ?', Time.current). + where.not(status: 'archived'). + update_all(status: 'archived', updated_at: Time.current) + end +end diff --git a/db/migrate/20250210131661_add_metadata_to_spree_tax_rates.spree.rb b/db/migrate/20250210131661_add_metadata_to_spree_tax_rates.spree.rb new file mode 100644 index 0000000..eed16c0 --- /dev/null +++ b/db/migrate/20250210131661_add_metadata_to_spree_tax_rates.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20220120092821) +class AddMetadataToSpreeTaxRates < ActiveRecord::Migration[5.2] + def change + change_table :spree_tax_rates do |t| + if t.respond_to? :jsonb + add_column :spree_tax_rates, :public_metadata, :jsonb + add_column :spree_tax_rates, :private_metadata, :jsonb + else + add_column :spree_tax_rates, :public_metadata, :json + add_column :spree_tax_rates, :private_metadata, :json + end + end + end +end diff --git a/db/migrate/20250210131662_add_first_name_and_last_name_to_spree_users.spree.rb b/db/migrate/20250210131662_add_first_name_and_last_name_to_spree_users.spree.rb new file mode 100644 index 0000000..33151ad --- /dev/null +++ b/db/migrate/20250210131662_add_first_name_and_last_name_to_spree_users.spree.rb @@ -0,0 +1,10 @@ +# This migration comes from spree (originally 20220201103922) +class AddFirstNameAndLastNameToSpreeUsers < ActiveRecord::Migration[5.2] + def change + if Spree.user_class.present? + users_table_name = Spree.user_class.table_name + add_column users_table_name, :first_name, :string unless column_exists?(users_table_name, :first_name) + add_column users_table_name, :last_name, :string unless column_exists?(users_table_name, :last_name) + end + end +end diff --git a/db/migrate/20250210131663_add_barcode_to_spree_variants.spree.rb b/db/migrate/20250210131663_add_barcode_to_spree_variants.spree.rb new file mode 100644 index 0000000..ab7c464 --- /dev/null +++ b/db/migrate/20250210131663_add_barcode_to_spree_variants.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20220222083546) +class AddBarcodeToSpreeVariants < ActiveRecord::Migration[5.2] + def change + add_column :spree_variants, :barcode, :string + add_index :spree_variants, :barcode + end +end diff --git a/db/migrate/20250210131664_add_metadata_to_spree_stock_items.spree.rb b/db/migrate/20250210131664_add_metadata_to_spree_stock_items.spree.rb new file mode 100644 index 0000000..3a6c650 --- /dev/null +++ b/db/migrate/20250210131664_add_metadata_to_spree_stock_items.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20220613133029) +class AddMetadataToSpreeStockItems < ActiveRecord::Migration[5.2] + def change + change_table :spree_stock_items do |t| + if t.respond_to? :jsonb + add_column :spree_stock_items, :public_metadata, :jsonb + add_column :spree_stock_items, :private_metadata, :jsonb + else + add_column :spree_stock_items, :public_metadata, :json + add_column :spree_stock_items, :private_metadata, :json + end + end + end +end diff --git a/db/migrate/20250210131665_create_product_name_and_description_translations_for_mobility_table_backend.spree.rb b/db/migrate/20250210131665_create_product_name_and_description_translations_for_mobility_table_backend.spree.rb new file mode 100644 index 0000000..da045d6 --- /dev/null +++ b/db/migrate/20250210131665_create_product_name_and_description_translations_for_mobility_table_backend.spree.rb @@ -0,0 +1,28 @@ +# This migration comes from spree (originally 20220706112554) +class CreateProductNameAndDescriptionTranslationsForMobilityTableBackend < ActiveRecord::Migration[6.1] + def change + # create translation table only if spree_globalize has not already created it + if ActiveRecord::Base.connection.table_exists? 'spree_product_translations' + # manually check for index since Rails if_exists does not always work correctly + if ActiveRecord::Migration.connection.index_exists?(:spree_product_translations, :spree_product_id) + remove_index :spree_product_translations, name: "index_spree_product_translations_on_spree_product_id", if_exists: true + end + else + create_table :spree_product_translations do |t| + + # Translated attribute(s) + t.string :name + t.text :description + + t.string :locale, null: false + t.references :spree_product, null: false, foreign_key: true, index: false + + t.timestamps null: false + end + + add_index :spree_product_translations, :locale, name: :index_spree_product_translations_on_locale + end + + add_index :spree_product_translations, [:spree_product_id, :locale], name: :unique_product_id_per_locale, unique: true + end +end diff --git a/db/migrate/20250210131666_create_spree_product_translations_for_mobility.spree.rb b/db/migrate/20250210131666_create_spree_product_translations_for_mobility.spree.rb new file mode 100644 index 0000000..d6de3a3 --- /dev/null +++ b/db/migrate/20250210131666_create_spree_product_translations_for_mobility.spree.rb @@ -0,0 +1,8 @@ +# This migration comes from spree (originally 20220715083542) +class CreateSpreeProductTranslationsForMobility < ActiveRecord::Migration[6.1] + def change + add_column :spree_product_translations, :meta_description, :text, if_not_exists: true + add_column :spree_product_translations, :meta_keywords, :string, if_not_exists: true + add_column :spree_product_translations, :meta_title, :string, if_not_exists: true + end +end diff --git a/db/migrate/20250210131667_create_spree_taxon_name_and_description_translations_for_mobility_table_backend.spree.rb b/db/migrate/20250210131667_create_spree_taxon_name_and_description_translations_for_mobility_table_backend.spree.rb new file mode 100644 index 0000000..ef48a1d --- /dev/null +++ b/db/migrate/20250210131667_create_spree_taxon_name_and_description_translations_for_mobility_table_backend.spree.rb @@ -0,0 +1,28 @@ +# This migration comes from spree (originally 20220718100743) +class CreateSpreeTaxonNameAndDescriptionTranslationsForMobilityTableBackend < ActiveRecord::Migration[6.1] + def change + # create translation table only if spree_globalize has not already created it + if ActiveRecord::Base.connection.table_exists? 'spree_taxon_translations' + # manually check for index since Rails if_exists does not always work correctly + if ActiveRecord::Migration.connection.index_exists?(:spree_taxon_translations, :spree_taxon_id) + # replacing this with index on spree_taxon_id and locale + remove_index :spree_taxon_translations, name: "index_spree_taxon_translations_on_spree_taxon_id", if_exists: true + end + else + create_table :spree_taxon_translations do |t| + # Translated attribute(s) + t.string :name + t.text :description + + t.string :locale, null: false + t.references :spree_taxon, null: false, foreign_key: true, index: false + + t.timestamps null: false + end + + add_index :spree_taxon_translations, :locale, name: :index_spree_taxon_translations_on_locale + end + + add_index :spree_taxon_translations, [:spree_taxon_id, :locale], name: :index_spree_taxon_translations_on_spree_taxon_id_and_locale, unique: true + end +end diff --git a/db/migrate/20250210131668_add_locale_to_friendly_id_slugs.spree.rb b/db/migrate/20250210131668_add_locale_to_friendly_id_slugs.spree.rb new file mode 100644 index 0000000..fad7ed6 --- /dev/null +++ b/db/migrate/20250210131668_add_locale_to_friendly_id_slugs.spree.rb @@ -0,0 +1,12 @@ +# This migration comes from spree (originally 20220802070609) +class AddLocaleToFriendlyIdSlugs < ActiveRecord::Migration[6.1] + def change + add_column :friendly_id_slugs, :locale, :string, null: :false, after: :scope + + remove_index :friendly_id_slugs, [:slug, :sluggable_type] + add_index :friendly_id_slugs, [:slug, :sluggable_type, :locale], length: { slug: 140, sluggable_type: 50, locale: 2 } + remove_index :friendly_id_slugs, [:slug, :sluggable_type, :scope] + add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope, :locale], length: { slug: 70, sluggable_type: 50, scope: 70, locale: 2 }, unique: true, name: :index_friendly_id_slugs_unique + add_index :friendly_id_slugs, :locale + end +end diff --git a/db/migrate/20250210131669_create_spree_product_slug_translations_for_mobility_table_backend.spree.rb b/db/migrate/20250210131669_create_spree_product_slug_translations_for_mobility_table_backend.spree.rb new file mode 100644 index 0000000..ba7afce --- /dev/null +++ b/db/migrate/20250210131669_create_spree_product_slug_translations_for_mobility_table_backend.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20220802073225) +class CreateSpreeProductSlugTranslationsForMobilityTableBackend < ActiveRecord::Migration[6.1] + def change + add_column :spree_product_translations, :slug, :string + end +end diff --git a/db/migrate/20250210131670_add_selected_locale_to_spree_users.spree.rb b/db/migrate/20250210131670_add_selected_locale_to_spree_users.spree.rb new file mode 100644 index 0000000..c97a247 --- /dev/null +++ b/db/migrate/20250210131670_add_selected_locale_to_spree_users.spree.rb @@ -0,0 +1,9 @@ +# This migration comes from spree (originally 20221215151408) +class AddSelectedLocaleToSpreeUsers < ActiveRecord::Migration[6.1] + def change + if Spree.user_class.present? + users_table_name = Spree.user_class.table_name + add_column users_table_name, :selected_locale, :string unless column_exists?(users_table_name, :selected_locale) + end + end +end diff --git a/db/migrate/20250210131671_add_deleted_at_to_product_translations.spree.rb b/db/migrate/20250210131671_add_deleted_at_to_product_translations.spree.rb new file mode 100644 index 0000000..d173526 --- /dev/null +++ b/db/migrate/20250210131671_add_deleted_at_to_product_translations.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20221219123957) +class AddDeletedAtToProductTranslations < ActiveRecord::Migration[6.1] + def change + add_column :spree_product_translations, :deleted_at, :datetime + add_index :spree_product_translations, :deleted_at + end +end diff --git a/db/migrate/20250210131672_add_uniqueness_constraint_to_product_translations.spree.rb b/db/migrate/20250210131672_add_uniqueness_constraint_to_product_translations.spree.rb new file mode 100644 index 0000000..cce1f04 --- /dev/null +++ b/db/migrate/20250210131672_add_uniqueness_constraint_to_product_translations.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20221220133432) +class AddUniquenessConstraintToProductTranslations < ActiveRecord::Migration[6.1] + def change + add_index :spree_product_translations, [:locale, :slug], unique: true, name: 'unique_slug_per_locale' + end +end diff --git a/db/migrate/20250210131673_create_spree_data_feed_settings.spree.rb b/db/migrate/20250210131673_create_spree_data_feed_settings.spree.rb new file mode 100644 index 0000000..1d67237 --- /dev/null +++ b/db/migrate/20250210131673_create_spree_data_feed_settings.spree.rb @@ -0,0 +1,15 @@ +# This migration comes from spree (originally 20221229132350) +class CreateSpreeDataFeedSettings < ActiveRecord::Migration[6.0] + def change + create_table :spree_data_feed_settings do |t| + t.references :spree_store + + t.string :name + t.string :provider + t.string :uuid, unique: true + t.boolean :enabled, default: true + + t.timestamps + end + end +end diff --git a/db/migrate/20250210131674_create_option_type_translations.spree.rb b/db/migrate/20250210131674_create_option_type_translations.spree.rb new file mode 100644 index 0000000..89c06ef --- /dev/null +++ b/db/migrate/20250210131674_create_option_type_translations.spree.rb @@ -0,0 +1,26 @@ +# This migration comes from spree (originally 20230103144439) +class CreateOptionTypeTranslations < ActiveRecord::Migration[6.1] + def change + if ActiveRecord::Base.connection.table_exists? 'spree_option_type_translations' + # manually check for index since Rails if_exists does not always work correctly + if ActiveRecord::Migration.connection.index_exists?(:spree_option_type_translations, :spree_option_type_id) + remove_index :spree_option_type_translations, name: "index_spree_option_type_translations_on_spree_option_type_id", if_exists: true + end + else + create_table :spree_option_type_translations do |t| + + # Translated attribute(s) + t.string :presentation + + t.string :locale, null: false + t.references :spree_option_type, null: false, foreign_key: true, index: false + + t.timestamps + end + + add_index :spree_option_type_translations, :locale, name: :index_spree_option_type_translations_on_locale + end + + add_index :spree_option_type_translations, [:spree_option_type_id, :locale], name: :unique_option_type_id_per_locale, unique: true + end +end diff --git a/db/migrate/20250210131675_create_option_value_translations.spree.rb b/db/migrate/20250210131675_create_option_value_translations.spree.rb new file mode 100644 index 0000000..11fc495 --- /dev/null +++ b/db/migrate/20250210131675_create_option_value_translations.spree.rb @@ -0,0 +1,26 @@ +# This migration comes from spree (originally 20230103151034) +class CreateOptionValueTranslations < ActiveRecord::Migration[6.1] + def change + if ActiveRecord::Base.connection.table_exists? 'spree_option_value_translations' + # manually check for index since Rails if_exists does not always work correctly + if ActiveRecord::Migration.connection.index_exists?(:spree_option_value_translations, :spree_option_value_id) + remove_index :spree_option_value_translations, column: :spree_option_value_id, if_exists: true + end + else + create_table :spree_option_value_translations do |t| + + # Translated attribute(s) + t.string :presentation + + t.string :locale, null: false + t.references :spree_option_value, null: false, foreign_key: true, index: false + + t.timestamps + end + + add_index :spree_option_value_translations, :locale, name: :index_spree_option_value_translations_on_locale + end + + add_index :spree_option_value_translations, [:spree_option_value_id, :locale], name: :unique_option_value_id_per_locale, unique: true + end +end diff --git a/db/migrate/20250210131676_create_product_property_translations.spree.rb b/db/migrate/20250210131676_create_product_property_translations.spree.rb new file mode 100644 index 0000000..e5869f9 --- /dev/null +++ b/db/migrate/20250210131676_create_product_property_translations.spree.rb @@ -0,0 +1,25 @@ +# This migration comes from spree (originally 20230109084253) +class CreateProductPropertyTranslations < ActiveRecord::Migration[6.1] + def change + if ActiveRecord::Base.connection.table_exists? 'spree_product_property_translations' + # manually check for index since Rails if_exists does not always work correctly + if ActiveRecord::Migration.connection.index_exists?(:spree_product_property_translations, :spree_product_property_id) + remove_index :spree_product_property_translations, column: :spree_product_property_id, if_exists: true + end + else + create_table :spree_product_property_translations do |t| + # Translated attribute(s) + t.string :value + + t.string :locale, null: false + t.references :spree_product_property, null: false, foreign_key: true, index: false + + t.timestamps + end + + add_index :spree_product_property_translations, :locale, name: :index_spree_product_property_translations_on_locale + end + + add_index :spree_product_property_translations, [:spree_product_property_id, :locale], name: :unique_product_property_id_per_locale, unique: true + end +end diff --git a/db/migrate/20250210131677_create_property_translations.spree.rb b/db/migrate/20250210131677_create_property_translations.spree.rb new file mode 100644 index 0000000..38e0525 --- /dev/null +++ b/db/migrate/20250210131677_create_property_translations.spree.rb @@ -0,0 +1,25 @@ +# This migration comes from spree (originally 20230109105943) +class CreatePropertyTranslations < ActiveRecord::Migration[6.1] + def change + if ActiveRecord::Base.connection.table_exists?('spree_property_translations') + # manually check for index since Rails if_exists does not always work correctly + if ActiveRecord::Migration.connection.index_exists?(:spree_property_translations, :spree_property_id) + remove_index :spree_property_translations, column: :spree_property_id, if_exists: true + end + else + create_table :spree_property_translations do |t| + # Translated attribute(s) + t.string :presentation + + t.string :locale, null: false + t.references :spree_property, null: false, foreign_key: true, index: false + + t.timestamps + end + + add_index :spree_property_translations, :locale, name: :index_spree_property_translations_on_locale + end + + add_index :spree_property_translations, [:spree_property_id, :locale], name: :unique_property_id_per_locale, unique: true + end +end diff --git a/db/migrate/20250210131678_backfill_friendly_id_slug_locale.spree.rb b/db/migrate/20250210131678_backfill_friendly_id_slug_locale.spree.rb new file mode 100644 index 0000000..6a30443 --- /dev/null +++ b/db/migrate/20250210131678_backfill_friendly_id_slug_locale.spree.rb @@ -0,0 +1,12 @@ +# This migration comes from spree (originally 20230110142344) +class BackfillFriendlyIdSlugLocale < ActiveRecord::Migration[6.1] + def up + if Spree::Store.default.present? + FriendlyId::Slug.unscoped.update_all(locale: Spree::Store.default.default_locale) + end + end + + def down + FriendlyId::Slug.unscoped.update_all(locale: nil) + end +end diff --git a/db/migrate/20250210131679_add_additional_taxon_translation_fields.spree.rb b/db/migrate/20250210131679_add_additional_taxon_translation_fields.spree.rb new file mode 100644 index 0000000..4d29836 --- /dev/null +++ b/db/migrate/20250210131679_add_additional_taxon_translation_fields.spree.rb @@ -0,0 +1,9 @@ +# This migration comes from spree (originally 20230111121534) +class AddAdditionalTaxonTranslationFields < ActiveRecord::Migration[6.1] + def change + add_column :spree_taxon_translations, :meta_title, :string, if_not_exists: true + add_column :spree_taxon_translations, :meta_description, :string, if_not_exists: true + add_column :spree_taxon_translations, :meta_keywords, :string, if_not_exists: true + add_column :spree_taxon_translations, :permalink, :string, if_not_exists: true + end +end diff --git a/db/migrate/20250210131680_create_taxonomy_translations.spree.rb b/db/migrate/20250210131680_create_taxonomy_translations.spree.rb new file mode 100644 index 0000000..c58202d --- /dev/null +++ b/db/migrate/20250210131680_create_taxonomy_translations.spree.rb @@ -0,0 +1,25 @@ +# This migration comes from spree (originally 20230117115531) +class CreateTaxonomyTranslations < ActiveRecord::Migration[6.1] + def change + if ActiveRecord::Base.connection.table_exists?('spree_taxonomy_translations') + # manually check for index since Rails if_exists does not always work correctly + if ActiveRecord::Migration.connection.index_exists?(:spree_taxonomy_translations, :spree_taxonomy_id) + remove_index :spree_taxonomy_translations, column: :spree_taxonomy_id, if_exists: true + end + else + create_table :spree_taxonomy_translations do |t| + # Translated attribute(s) + t.string :name + + t.string :locale, null: false + t.references :spree_taxonomy, null: false, foreign_key: true, index: false + + t.timestamps null: false + end + + add_index :spree_taxonomy_translations, :locale, name: :index_spree_taxonomy_translations_on_locale + end + + add_index :spree_taxonomy_translations, [:spree_taxonomy_id, :locale], name: :index_spree_taxonomy_translations_on_spree_taxonomy_id_locale, unique: true + end +end diff --git a/db/migrate/20250210131681_create_store_translations.spree.rb b/db/migrate/20250210131681_create_store_translations.spree.rb new file mode 100644 index 0000000..fbb3a54 --- /dev/null +++ b/db/migrate/20250210131681_create_store_translations.spree.rb @@ -0,0 +1,51 @@ +# This migration comes from spree (originally 20230210142732) +class CreateStoreTranslations < ActiveRecord::Migration[6.1] + def change + if ActiveRecord::Base.connection.table_exists?('spree_store_translations') + add_new_translation_columns_to_globalize_table + else + create_table :spree_store_translations do |t| + # Translated attribute(s) + t.string :name + t.text :meta_description + t.text :meta_keywords + t.string :seo_title + t.string :facebook + t.string :twitter + t.string :instagram + t.string :customer_support_email + t.text :description + t.text :address + t.string :contact_phone + t.string :new_order_notifications_email + + t.string :locale, null: false + t.references :spree_store, null: false, foreign_key: true, index: false + + t.timestamps null: false + end + + add_index :spree_store_translations, :locale, name: :index_spree_store_translations_on_locale + end + + add_index :spree_store_translations, [:spree_store_id, :locale], name: :index_spree_store_translations_on_spree_store_id_locale, unique: true + end + + private + + def add_new_translation_columns_to_globalize_table + # manually check for index since Rails if_exists does not always work correctly + if ActiveRecord::Migration.connection.index_exists?(:spree_store_translations, :spree_store_id) + remove_index :spree_store_translations, column: :spree_store_id, if_exists: true + end + + add_column :spree_store_translations, :facebook, :string + add_column :spree_store_translations, :twitter, :string + add_column :spree_store_translations, :instagram, :string + add_column :spree_store_translations, :customer_support_email, :string + add_column :spree_store_translations, :description, :text + add_column :spree_store_translations, :address, :text + add_column :spree_store_translations, :contact_phone, :string + add_column :spree_store_translations, :new_order_notifications_email, :string + end +end diff --git a/db/migrate/20250210131682_add_deleted_at_to_store_translations.spree.rb b/db/migrate/20250210131682_add_deleted_at_to_store_translations.spree.rb new file mode 100644 index 0000000..9750211 --- /dev/null +++ b/db/migrate/20250210131682_add_deleted_at_to_store_translations.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20230210230434) +class AddDeletedAtToStoreTranslations < ActiveRecord::Migration[6.1] + def change + add_column :spree_store_translations, :deleted_at, :datetime + add_index :spree_store_translations, :deleted_at + end +end diff --git a/db/migrate/20250210131683_rename_data_feed_settings_table.spree.rb b/db/migrate/20250210131683_rename_data_feed_settings_table.spree.rb new file mode 100644 index 0000000..21df59d --- /dev/null +++ b/db/migrate/20250210131683_rename_data_feed_settings_table.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20230415155958) +class RenameDataFeedSettingsTable < ActiveRecord::Migration[6.1] + def change + rename_table :spree_data_feed_settings, :spree_data_feeds + end +end diff --git a/db/migrate/20250210131684_rename_data_feed_table_columns.spree.rb b/db/migrate/20250210131684_rename_data_feed_table_columns.spree.rb new file mode 100644 index 0000000..ad3ea23 --- /dev/null +++ b/db/migrate/20250210131684_rename_data_feed_table_columns.spree.rb @@ -0,0 +1,8 @@ +# This migration comes from spree (originally 20230415160828) +class RenameDataFeedTableColumns < ActiveRecord::Migration[6.1] + def change + rename_column :spree_data_feeds, :spree_store_id, :store_id + rename_column :spree_data_feeds, :enabled, :active + rename_column :spree_data_feeds, :uuid, :slug + end +end diff --git a/db/migrate/20250210131685_add_indexes_to_data_feeds_table.spree.rb b/db/migrate/20250210131685_add_indexes_to_data_feeds_table.spree.rb new file mode 100644 index 0000000..82b3065 --- /dev/null +++ b/db/migrate/20250210131685_add_indexes_to_data_feeds_table.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20230415161226) +class AddIndexesToDataFeedsTable < ActiveRecord::Migration[6.1] + def change + add_index :spree_data_feeds, [:store_id, :slug, :provider] + end +end diff --git a/db/migrate/20250210131686_rename_data_feeds_column_provider_to_type.spree.rb b/db/migrate/20250210131686_rename_data_feeds_column_provider_to_type.spree.rb new file mode 100644 index 0000000..913bb91 --- /dev/null +++ b/db/migrate/20250210131686_rename_data_feeds_column_provider_to_type.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20230512094803) +class RenameDataFeedsColumnProviderToType < ActiveRecord::Migration[6.1] + def change + rename_column :spree_data_feeds, :provider, :type + end +end diff --git a/db/migrate/20250210131687_fix_spree_stock_item_unique_index.spree.rb b/db/migrate/20250210131687_fix_spree_stock_item_unique_index.spree.rb new file mode 100644 index 0000000..9bd845b --- /dev/null +++ b/db/migrate/20250210131687_fix_spree_stock_item_unique_index.spree.rb @@ -0,0 +1,36 @@ +# This migration comes from spree (originally 20240303174340) +class FixSpreeStockItemUniqueIndex < ActiveRecord::Migration[6.1] + def change + remove_index :spree_stock_items, name: 'stock_item_by_loc_var_id_deleted_at' if index_exists?(:spree_stock_items, [:stock_location_id, :variant_id], name: 'stock_item_by_loc_var_id_deleted_at') + + unless index_exists?(:spree_stock_items, ['variant_id', 'stock_location_id'], name: 'index_spree_stock_items_unique_without_deleted_at') + # MySQL doesn't support partial indexes + if ActiveRecord::Base.connection.adapter_name == 'Mysql2' + reversible do |dir| + dir.up do + execute <<-SQL + CREATE UNIQUE INDEX index_spree_stock_items_unique_without_deleted_at + ON spree_stock_items( + stock_location_id, + variant_id, + (COALESCE(deleted_at, CAST('1970-01-01' AS DATETIME))) + ); + SQL + end + + dir.down do + remove_index :spree_stock_items, name: :index_spree_stock_items_unique_without_deleted_at + end + end + else + add_index( + :spree_stock_items, + ['variant_id', 'stock_location_id'], + name: 'index_spree_stock_items_unique_without_deleted_at', + unique: true, + where: 'deleted_at IS NULL', + ) + end + end + end +end diff --git a/db/migrate/20250210131688_add_weight_and_dimension_units_to_spree_variants.spree.rb b/db/migrate/20250210131688_add_weight_and_dimension_units_to_spree_variants.spree.rb new file mode 100644 index 0000000..e7e405b --- /dev/null +++ b/db/migrate/20250210131688_add_weight_and_dimension_units_to_spree_variants.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20240514105216) +class AddWeightAndDimensionUnitsToSpreeVariants < ActiveRecord::Migration[6.1] + def change + add_column :spree_variants, :weight_unit, :string, if_not_exists: true + add_column :spree_variants, :dimensions_unit, :string, if_not_exists: true + end +end diff --git a/db/migrate/20250210131689_add_deleted_at_to_spree_stock_locations.spree.rb b/db/migrate/20250210131689_add_deleted_at_to_spree_stock_locations.spree.rb new file mode 100644 index 0000000..d353f3d --- /dev/null +++ b/db/migrate/20250210131689_add_deleted_at_to_spree_stock_locations.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20240623172111) +class AddDeletedAtToSpreeStockLocations < ActiveRecord::Migration[6.1] + def change + add_column :spree_stock_locations, :deleted_at, :datetime, if_not_exists: true + add_index :spree_stock_locations, :deleted_at, if_not_exists: true + end +end diff --git a/db/migrate/20250210131690_add_refunder_to_spree_refunds.spree.rb b/db/migrate/20250210131690_add_refunder_to_spree_refunds.spree.rb new file mode 100644 index 0000000..2ac2b5d --- /dev/null +++ b/db/migrate/20250210131690_add_refunder_to_spree_refunds.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20240725124530) +class AddRefunderToSpreeRefunds < ActiveRecord::Migration[6.1] + def change + add_column :spree_refunds, :refunder_id, :bigint, if_not_exists: true + add_index :spree_refunds, :refunder_id, if_not_exists: true + end +end diff --git a/db/migrate/20250210131691_add_pretty_name_to_spree_taxons.spree.rb b/db/migrate/20250210131691_add_pretty_name_to_spree_taxons.spree.rb new file mode 100644 index 0000000..72b25b9 --- /dev/null +++ b/db/migrate/20250210131691_add_pretty_name_to_spree_taxons.spree.rb @@ -0,0 +1,10 @@ +# This migration comes from spree (originally 20240822163534) +class AddPrettyNameToSpreeTaxons < ActiveRecord::Migration[6.1] + def change + add_column :spree_taxons, :pretty_name, :string, null: true, if_not_exists: true + add_index :spree_taxons, :pretty_name, if_not_exists: true + + add_column :spree_taxon_translations, :pretty_name, :string, null: true, if_not_exists: true + add_index :spree_taxon_translations, :pretty_name, if_not_exists: true + end +end diff --git a/db/migrate/20250210131692_change_default_value_of_spree_option_types_filterable.spree.rb b/db/migrate/20250210131692_change_default_value_of_spree_option_types_filterable.spree.rb new file mode 100644 index 0000000..6942c2b --- /dev/null +++ b/db/migrate/20250210131692_change_default_value_of_spree_option_types_filterable.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20240913143518) +class ChangeDefaultValueOfSpreeOptionTypesFilterable < ActiveRecord::Migration[6.1] + def change + change_column_default :spree_option_types, :filterable, from: false, to: true + end +end diff --git a/db/migrate/20250210131693_add_display_on_to_spree_properties.spree.rb b/db/migrate/20250210131693_add_display_on_to_spree_properties.spree.rb new file mode 100644 index 0000000..d5933a8 --- /dev/null +++ b/db/migrate/20250210131693_add_display_on_to_spree_properties.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20240914153106) +class AddDisplayOnToSpreeProperties < ActiveRecord::Migration[6.1] + def change + add_column :spree_properties, :display_on, :string, default: 'both', if_not_exists: true + end +end diff --git a/db/migrate/20250210131694_add_position_to_spree_properties.spree.rb b/db/migrate/20250210131694_add_position_to_spree_properties.spree.rb new file mode 100644 index 0000000..c1adad5 --- /dev/null +++ b/db/migrate/20250210131694_add_position_to_spree_properties.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20240915144935) +class AddPositionToSpreeProperties < ActiveRecord::Migration[6.1] + def change + add_column :spree_properties, :position, :integer, default: 0, if_not_exists: true + add_index :spree_properties, :position, if_not_exists: true + end +end diff --git a/db/migrate/20250210131695_create_spree_coupon_codes.spree.rb b/db/migrate/20250210131695_create_spree_coupon_codes.spree.rb new file mode 100644 index 0000000..df22a92 --- /dev/null +++ b/db/migrate/20250210131695_create_spree_coupon_codes.spree.rb @@ -0,0 +1,16 @@ +# This migration comes from spree (originally 20241004181911) +class CreateSpreeCouponCodes < ActiveRecord::Migration[6.1] + def change + return if table_exists?(:spree_coupon_codes) + + create_table :spree_coupon_codes do |t| + t.string :code, index: { unique: true, where: 'deleted_at IS NULL' } + t.references :promotion, index: true + t.references :order, index: true + t.integer :state, default: 0, null: false, index: true + t.datetime :deleted_at, index: true + + t.timestamps + end + end +end diff --git a/db/migrate/20250210131696_add_multi_code_to_spree_promotions.spree.rb b/db/migrate/20250210131696_add_multi_code_to_spree_promotions.spree.rb new file mode 100644 index 0000000..73d6669 --- /dev/null +++ b/db/migrate/20250210131696_add_multi_code_to_spree_promotions.spree.rb @@ -0,0 +1,15 @@ +# This migration comes from spree (originally 20241005093437) +class AddMultiCodeToSpreePromotions < ActiveRecord::Migration[6.1] + def change + add_column :spree_promotions, :code_prefix, :string, if_not_exists: true + add_column :spree_promotions, :number_of_codes, :integer, if_not_exists: true + add_column :spree_promotions, :kind, :integer, default: 0, if_not_exists: true + add_column :spree_promotions, :multi_codes, :boolean, default: false, if_not_exists: true + + add_index :spree_promotions, :kind, if_not_exists: true + + Spree::Promotion.reset_column_information + # set all promotions without a code to automatic + Spree::Promotion.where(code: [nil, '']).update_all(kind: 1) + end +end diff --git a/db/migrate/20250210131697_translate_rich_texts.spree.rb b/db/migrate/20250210131697_translate_rich_texts.spree.rb new file mode 100644 index 0000000..5f4399b --- /dev/null +++ b/db/migrate/20250210131697_translate_rich_texts.spree.rb @@ -0,0 +1,18 @@ +# This migration comes from spree (originally 20241014140140) +class TranslateRichTexts < ActiveRecord::Migration[6.1] + def change + if table_exists?(:action_text_rich_texts) + add_column :action_text_rich_texts, :locale, :string, null: false + + remove_index :action_text_rich_texts, + column: [:record_type, :record_id, :name], + name: :index_action_text_rich_texts_uniqueness, + unique: true + + add_index :action_text_rich_texts, + [:record_type, :record_id, :name, :locale], + name: :index_action_text_rich_texts_uniqueness, + unique: true + end + end +end diff --git a/db/migrate/20250210131698_create_spree_exports.spree.rb b/db/migrate/20250210131698_create_spree_exports.spree.rb new file mode 100644 index 0000000..cca54a9 --- /dev/null +++ b/db/migrate/20250210131698_create_spree_exports.spree.rb @@ -0,0 +1,24 @@ +# This migration comes from spree (originally 20241030134309) +class CreateSpreeExports < ActiveRecord::Migration[6.1] + def change + return if table_exists?(:spree_exports) + + create_table :spree_exports do |t| + t.references :user + t.references :store, null: false + + t.string :number, limit: 32, null: false, index: { unique: true } + t.string :type, null: false + + if t.respond_to? :jsonb + t.jsonb :search_params + else + t.json :search_params + end + + t.integer :format, index: true, null: false + + t.timestamps + end + end +end diff --git a/db/migrate/20250210131699_migrate_spree_promotion_rules_option_value_eligible_values.spree.rb b/db/migrate/20250210131699_migrate_spree_promotion_rules_option_value_eligible_values.spree.rb new file mode 100644 index 0000000..e01026f --- /dev/null +++ b/db/migrate/20250210131699_migrate_spree_promotion_rules_option_value_eligible_values.spree.rb @@ -0,0 +1,17 @@ +# This migration comes from spree (originally 20241104083457) +class MigrateSpreePromotionRulesOptionValueEligibleValues < ActiveRecord::Migration[6.1] + def change + Spree::Promotion::Rules::OptionValue.find_each do |option_value| + new_eligible_values = option_value.preferred_eligible_values.flat_map do |product_id, option_value_ids| + value_ids = option_value_ids.is_a?(String) ? option_value_ids.split(',') : option_value_ids + + Spree::OptionValueVariant. + joins(:variant). + where(option_value_id: value_ids, "#{Spree::Variant.table_name}.product_id" => product_id). + pluck(:id) + end + + option_value.update!(preferred_eligible_values: new_eligible_values) + end + end +end diff --git a/db/migrate/20250210131700_add_estimated_transit_fields_to_spree_shipping_methods.spree.rb b/db/migrate/20250210131700_add_estimated_transit_fields_to_spree_shipping_methods.spree.rb new file mode 100644 index 0000000..88e1c95 --- /dev/null +++ b/db/migrate/20250210131700_add_estimated_transit_fields_to_spree_shipping_methods.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20241123110646) +class AddEstimatedTransitFieldsToSpreeShippingMethods < ActiveRecord::Migration[6.1] + def change + add_column :spree_shipping_methods, :estimated_transit_business_days_min, :integer + add_column :spree_shipping_methods, :estimated_transit_business_days_max, :integer + end +end diff --git a/db/migrate/20250210131701_create_spree_taxon_rules.spree.rb b/db/migrate/20250210131701_create_spree_taxon_rules.spree.rb new file mode 100644 index 0000000..1ed36d6 --- /dev/null +++ b/db/migrate/20250210131701_create_spree_taxon_rules.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20241127193411) +class CreateSpreeTaxonRules < ActiveRecord::Migration[6.1] + def change + create_table :spree_taxon_rules do |t| + t.belongs_to :taxon, null: false, index: true + + t.string :type, null: false + t.string :value, null: false + t.string :match_policy, null: false, default: 'is_equal_to' + + t.timestamps + end + end +end diff --git a/db/migrate/20250210131702_add_rules_match_policy_and_sort_order_to_spree_taxons.spree.rb b/db/migrate/20250210131702_add_rules_match_policy_and_sort_order_to_spree_taxons.spree.rb new file mode 100644 index 0000000..11a8d43 --- /dev/null +++ b/db/migrate/20250210131702_add_rules_match_policy_and_sort_order_to_spree_taxons.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20241127223627) +class AddRulesMatchPolicyAndSortOrderToSpreeTaxons < ActiveRecord::Migration[6.1] + def change + add_column :spree_taxons, :rules_match_policy, :string, default: 'all', null: false + add_column :spree_taxons, :sort_order, :string, default: 'manual', null: false + end +end diff --git a/db/migrate/20250210131703_add_automatic_to_spree_taxons.spree.rb b/db/migrate/20250210131703_add_automatic_to_spree_taxons.spree.rb new file mode 100644 index 0000000..0a0050f --- /dev/null +++ b/db/migrate/20250210131703_add_automatic_to_spree_taxons.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20241128103947) +class AddAutomaticToSpreeTaxons < ActiveRecord::Migration[6.1] + def change + add_column :spree_taxons, :automatic, :boolean, default: false, null: false + end +end diff --git a/db/migrate/20250210131704_add_gateway_customer_profile_id_to_spree_payment_sources.spree.rb b/db/migrate/20250210131704_add_gateway_customer_profile_id_to_spree_payment_sources.spree.rb new file mode 100644 index 0000000..373fb16 --- /dev/null +++ b/db/migrate/20250210131704_add_gateway_customer_profile_id_to_spree_payment_sources.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20241218183905) +class AddGatewayCustomerProfileIdToSpreePaymentSources < ActiveRecord::Migration[6.1] + def change + add_column :spree_payment_sources, :gateway_customer_profile_id, :string + end +end diff --git a/db/migrate/20250210131705_add_accept_marketing_and_signup_for_an_account_to_spree_orders.spree.rb b/db/migrate/20250210131705_add_accept_marketing_and_signup_for_an_account_to_spree_orders.spree.rb new file mode 100644 index 0000000..d085d9a --- /dev/null +++ b/db/migrate/20250210131705_add_accept_marketing_and_signup_for_an_account_to_spree_orders.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20250107220432) +class AddAcceptMarketingAndSignupForAnAccountToSpreeOrders < ActiveRecord::Migration[6.1] + def change + add_column :spree_orders, :accept_marketing, :boolean, default: false, if_not_exists: true + add_column :spree_orders, :signup_for_an_account, :boolean, default: false, if_not_exists: true + end +end diff --git a/db/migrate/20250210131706_add_quick_checkout_to_spree_addresses.spree.rb b/db/migrate/20250210131706_add_quick_checkout_to_spree_addresses.spree.rb new file mode 100644 index 0000000..94a28aa --- /dev/null +++ b/db/migrate/20250210131706_add_quick_checkout_to_spree_addresses.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20250110171203) +class AddQuickCheckoutToSpreeAddresses < ActiveRecord::Migration[6.1] + def change + add_column :spree_addresses, :quick_checkout, :boolean, default: false, if_not_exists: true + add_index :spree_addresses, :quick_checkout, if_not_exists: true + end +end diff --git a/db/migrate/20250210131707_add_preferences_to_spree_stores.spree.rb b/db/migrate/20250210131707_add_preferences_to_spree_stores.spree.rb new file mode 100644 index 0000000..3441373 --- /dev/null +++ b/db/migrate/20250210131707_add_preferences_to_spree_stores.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20250113180019) +class AddPreferencesToSpreeStores < ActiveRecord::Migration[6.1] + def change + add_column :spree_stores, :preferences, :text, if_not_exists: true + end +end diff --git a/db/migrate/20250210131708_add_metadata_to_spree_stores.spree.rb b/db/migrate/20250210131708_add_metadata_to_spree_stores.spree.rb new file mode 100644 index 0000000..3b1ec2b --- /dev/null +++ b/db/migrate/20250210131708_add_metadata_to_spree_stores.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20250114193857) +class AddMetadataToSpreeStores < ActiveRecord::Migration[6.1] + def change + change_table :spree_stores do |t| + if t.respond_to? :jsonb + add_column :spree_stores, :public_metadata, :jsonb + add_column :spree_stores, :private_metadata, :jsonb + else + add_column :spree_stores, :public_metadata, :json + add_column :spree_stores, :private_metadata, :json + end + end + end +end diff --git a/db/migrate/20250210131709_create_spree_custom_domains.spree.rb b/db/migrate/20250210131709_create_spree_custom_domains.spree.rb new file mode 100644 index 0000000..a0de0b2 --- /dev/null +++ b/db/migrate/20250210131709_create_spree_custom_domains.spree.rb @@ -0,0 +1,23 @@ +# This migration comes from spree (originally 20250119165904) +class CreateSpreeCustomDomains < ActiveRecord::Migration[6.1] + def change + return if table_exists?(:spree_custom_domains) + + create_table :spree_custom_domains do |t| + t.references :store, null: false, index: true + t.string :url, null: false, index: { unique: true } + t.boolean :status, default: false + t.boolean :default, default: false, null: false + + if t.respond_to? :jsonb + t.jsonb :public_metadata + t.jsonb :private_metadata + else + t.json :public_metadata + t.json :private_metadata + end + + t.timestamps + end + end +end diff --git a/db/migrate/20250210131710_create_page_builder_models.spree.rb b/db/migrate/20250210131710_create_page_builder_models.spree.rb new file mode 100644 index 0000000..aae1208 --- /dev/null +++ b/db/migrate/20250210131710_create_page_builder_models.spree.rb @@ -0,0 +1,81 @@ +# This migration comes from spree (originally 20250120094216) +class CreatePageBuilderModels < ActiveRecord::Migration[6.1] + def change + if !table_exists?(:spree_themes) + create_table :spree_themes do |t| + t.string :name + t.references :store, null: false, index: true + t.boolean :default, default: false, null: false + t.boolean :ready, default: true + t.string :type, default: 'Spree::Themes::Default', null: false + t.references :parent + t.text :preferences + + t.timestamps + t.datetime :deleted_at + + t.index ['deleted_at'], name: 'index_spree_themes_on_deleted_at' + t.index ['store_id', 'default'], name: 'index_spree_themes_on_store_id_and_default', unique: true, where: "((deleted_at IS NULL) AND (\"default\" = true))" + end + + create_table :spree_pages do |t| + t.references :pageable, polymorphic: true, null: false + t.string :type, null: false + t.string :slug + t.string :name, null: false + t.string :meta_title + t.string :meta_description + t.string :meta_keywords + t.references :parent + t.text :preferences + + t.timestamps + t.datetime :deleted_at + + t.index ['pageable_id', 'name'], name: 'index_spree_pages_on_pageable_id_and_name' + t.index ['pageable_id', 'pageable_type', 'slug'], name: 'index_spree_pages_on_pageable_id_and_pageable_type_and_slug', unique: true, where: '((deleted_at IS NULL) AND (slug IS NOT NULL))' + t.index ['pageable_id', 'pageable_type', 'type'], name: 'index_spree_pages_on_pageable_id_and_pageable_type_and_type' + t.index ['pageable_id', 'pageable_type'], name: 'index_spree_pages_on_pageable_id_and_pageable_type' + end + + create_table :spree_page_sections do |t| + t.references :pageable, polymorphic: true, null: false, index: true + t.string :type, null: false + t.string :name, null: false + t.integer :position, default: 1, null: false + t.integer :page_links_count, default: 0 + t.text :preferences + + t.timestamps + t.datetime :deleted_at + + t.index ['pageable_id', 'pageable_type', 'position'], name: 'index_spree_page_sections_on_pageable_w_position' + end + + create_table :spree_page_blocks do |t| + t.references :section, null: false, index: true + t.string :name, null: false + t.integer :position, default: 1, null: false + t.string :type, null: false + t.integer :page_links_count, default: 0 + t.text :preferences + + t.timestamps + t.datetime :deleted_at + + t.index ['section_id', 'position'], name: 'index_spree_page_blocks_on_section_w_position' + end + + create_table :spree_page_links do |t| + t.references :parent, polymorphic: true, index: true + t.references :linkable, polymorphic: true, index: true + t.string :label + t.string :url + t.boolean :open_in_new_tab, default: false + t.integer :position, default: 1, null: false + + t.timestamps + end + end + end +end diff --git a/db/migrate/20250210131711_add_default_locale_to_action_text_rich_texts.spree.rb b/db/migrate/20250210131711_add_default_locale_to_action_text_rich_texts.spree.rb new file mode 100644 index 0000000..03d0263 --- /dev/null +++ b/db/migrate/20250210131711_add_default_locale_to_action_text_rich_texts.spree.rb @@ -0,0 +1,8 @@ +# This migration comes from spree (originally 20250120152208) +class AddDefaultLocaleToActionTextRichTexts < ActiveRecord::Migration[6.1] + def change + if ActionText::RichText.column_defaults['locale'].nil? + change_column_default :action_text_rich_texts, :locale, from: nil, to: :en + end + end +end diff --git a/db/migrate/20250210131712_create_spree_posts_and_spree_post_categories.spree.rb b/db/migrate/20250210131712_create_spree_posts_and_spree_post_categories.spree.rb new file mode 100644 index 0000000..1200762 --- /dev/null +++ b/db/migrate/20250210131712_create_spree_posts_and_spree_post_categories.spree.rb @@ -0,0 +1,35 @@ +# This migration comes from spree (originally 20250121160028) +class CreateSpreePostsAndSpreePostCategories < ActiveRecord::Migration[6.1] + def change + if !table_exists?(:spree_post_categories) + create_table :spree_post_categories do |t| + t.references :store, null: false, index: true + t.string :title, null: false + t.string :slug, null: false + + t.timestamps + + t.index ['slug', 'store_id'], name: 'index_spree_post_categories_on_slug_and_store_id', unique: true + end + end + + if !table_exists?(:spree_posts) + create_table :spree_posts do |t| + t.references :author, index: true + t.datetime :published_at + t.string :title, null: false + t.string :slug, null: false + t.references :post_category, index: true + t.references :store, index: true + t.string :meta_title + t.string :meta_description + + t.timestamps + t.datetime :deleted_at + + t.index ['slug', 'store_id'], name: 'index_spree_posts_on_slug_and_store_id', unique: true, where: '(deleted_at IS NULL)' + t.index ['title'], name: 'index_spree_posts_on_title' + end + end + end +end diff --git a/db/migrate/20250210131713_add_first_and_last_name_to_spree_admin_class.spree.rb b/db/migrate/20250210131713_add_first_and_last_name_to_spree_admin_class.spree.rb new file mode 100644 index 0000000..8cc1b67 --- /dev/null +++ b/db/migrate/20250210131713_add_first_and_last_name_to_spree_admin_class.spree.rb @@ -0,0 +1,10 @@ +# This migration comes from spree (originally 20250122113708) +class AddFirstAndLastNameToSpreeAdminClass < ActiveRecord::Migration[6.1] + def change + if Spree.admin_user_class.present? + admin_users_table_name = Spree.admin_user_class.table_name + add_column admin_users_table_name, :first_name, :string unless column_exists?(admin_users_table_name, :first_name) + add_column admin_users_table_name, :last_name, :string unless column_exists?(admin_users_table_name, :last_name) + end + end +end diff --git a/db/migrate/20250210131714_add_custom_code_fields_to_spree_store.spree.rb b/db/migrate/20250210131714_add_custom_code_fields_to_spree_store.spree.rb new file mode 100644 index 0000000..fc8f8d6 --- /dev/null +++ b/db/migrate/20250210131714_add_custom_code_fields_to_spree_store.spree.rb @@ -0,0 +1,8 @@ +# This migration comes from spree (originally 20250123135358) +class AddCustomCodeFieldsToSpreeStore < ActiveRecord::Migration[6.1] + def change + add_column :spree_stores, :storefront_custom_code_head, :text + add_column :spree_stores, :storefront_custom_code_body_start, :text + add_column :spree_stores, :storefront_custom_code_body_end, :text + end +end diff --git a/db/migrate/20250210131715_add_kind_to_spree_properties.spree.rb b/db/migrate/20250210131715_add_kind_to_spree_properties.spree.rb new file mode 100644 index 0000000..a8a4bc2 --- /dev/null +++ b/db/migrate/20250210131715_add_kind_to_spree_properties.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20250127083740) +class AddKindToSpreeProperties < ActiveRecord::Migration[6.1] + def change + add_column :spree_properties, :kind, :integer, default: 0, if_not_exists: true + end +end diff --git a/db/migrate/20250210131716_add_latitude_and_longitude_to_spree_addresses.spree.rb b/db/migrate/20250210131716_add_latitude_and_longitude_to_spree_addresses.spree.rb new file mode 100644 index 0000000..efa8671 --- /dev/null +++ b/db/migrate/20250210131716_add_latitude_and_longitude_to_spree_addresses.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20250127112758) +class AddLatitudeAndLongitudeToSpreeAddresses < ActiveRecord::Migration[6.1] + def change + add_column :spree_addresses, :latitude, :decimal, if_not_exists: true + add_column :spree_addresses, :longitude, :decimal, if_not_exists: true + end +end diff --git a/db/migrate/20250210131717_add_phone_to_spree_users.spree.rb b/db/migrate/20250210131717_add_phone_to_spree_users.spree.rb new file mode 100644 index 0000000..4e549a9 --- /dev/null +++ b/db/migrate/20250210131717_add_phone_to_spree_users.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20250127151258) +class AddPhoneToSpreeUsers < ActiveRecord::Migration[6.1] + def change + add_column Spree.user_class.table_name, :phone, :string, if_not_exists: true + end +end diff --git a/db/migrate/20250210131718_create_spree_reports.spree.rb b/db/migrate/20250210131718_create_spree_reports.spree.rb new file mode 100644 index 0000000..d4218ac --- /dev/null +++ b/db/migrate/20250210131718_create_spree_reports.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20250204162453) +class CreateSpreeReports < ActiveRecord::Migration[6.1] + def change + create_table :spree_reports do |t| + t.references :store, null: false + t.references :user + t.string 'type' + t.string 'currency' + t.datetime 'date_from' + t.datetime 'date_to' + t.timestamps + end + end +end diff --git a/db/migrate/20250210131719_add_accepts_email_marketing_field_to_spree_users_table.spree.rb b/db/migrate/20250210131719_add_accepts_email_marketing_field_to_spree_users_table.spree.rb new file mode 100644 index 0000000..fd40e16 --- /dev/null +++ b/db/migrate/20250210131719_add_accepts_email_marketing_field_to_spree_users_table.spree.rb @@ -0,0 +1,7 @@ +# This migration comes from spree (originally 20250207084000) +class AddAcceptsEmailMarketingFieldToSpreeUsersTable < ActiveRecord::Migration[6.1] + def change + add_column Spree.user_class.table_name, :accepts_email_marketing, :boolean, default: false, null: false, if_not_exists: true + add_index Spree.user_class.table_name, :accepts_email_marketing, if_not_exists: true + end +end diff --git a/db/migrate/20250210131720_add_api_key_to_spree_users.spree_api.rb b/db/migrate/20250210131720_add_api_key_to_spree_users.spree_api.rb new file mode 100644 index 0000000..87d38cc --- /dev/null +++ b/db/migrate/20250210131720_add_api_key_to_spree_users.spree_api.rb @@ -0,0 +1,8 @@ +# This migration comes from spree_api (originally 20100107141738) +class AddApiKeyToSpreeUsers < ActiveRecord::Migration[4.2] + def change + unless defined?(User) + add_column :spree_users, :api_key, :string, limit: 40 + end + end +end diff --git a/db/migrate/20250210131721_resize_api_key_field.spree_api.rb b/db/migrate/20250210131721_resize_api_key_field.spree_api.rb new file mode 100644 index 0000000..4282004 --- /dev/null +++ b/db/migrate/20250210131721_resize_api_key_field.spree_api.rb @@ -0,0 +1,8 @@ +# This migration comes from spree_api (originally 20120411123334) +class ResizeApiKeyField < ActiveRecord::Migration[4.2] + def change + unless defined?(User) + change_column :spree_users, :api_key, :string, limit: 48 + end + end +end diff --git a/db/migrate/20250210131722_rename_api_key_to_spree_api_key.spree_api.rb b/db/migrate/20250210131722_rename_api_key_to_spree_api_key.spree_api.rb new file mode 100644 index 0000000..60747db --- /dev/null +++ b/db/migrate/20250210131722_rename_api_key_to_spree_api_key.spree_api.rb @@ -0,0 +1,8 @@ +# This migration comes from spree_api (originally 20120530054546) +class RenameApiKeyToSpreeApiKey < ActiveRecord::Migration[4.2] + def change + unless defined?(User) + rename_column :spree_users, :api_key, :spree_api_key + end + end +end diff --git a/db/migrate/20250210131723_add_index_to_user_spree_api_key.spree_api.rb b/db/migrate/20250210131723_add_index_to_user_spree_api_key.spree_api.rb new file mode 100644 index 0000000..ab7b732 --- /dev/null +++ b/db/migrate/20250210131723_add_index_to_user_spree_api_key.spree_api.rb @@ -0,0 +1,8 @@ +# This migration comes from spree_api (originally 20131017162334) +class AddIndexToUserSpreeApiKey < ActiveRecord::Migration[4.2] + def change + unless defined?(User) + add_index :spree_users, :spree_api_key + end + end +end diff --git a/db/migrate/20250210131724_create_doorkeeper_tables.spree_api.rb b/db/migrate/20250210131724_create_doorkeeper_tables.spree_api.rb new file mode 100644 index 0000000..2494d8e --- /dev/null +++ b/db/migrate/20250210131724_create_doorkeeper_tables.spree_api.rb @@ -0,0 +1,70 @@ +# This migration comes from spree_api (originally 20180320110726) +class CreateDoorkeeperTables < ActiveRecord::Migration[5.1] + def change + create_table :spree_oauth_applications do |t| + t.string :name, null: false + t.string :uid, null: false + t.string :secret, null: false + t.text :redirect_uri, null: false + t.string :scopes, null: false, default: '' + t.boolean :confidential, null: false, default: true + t.timestamps null: false + end + + add_index :spree_oauth_applications, :uid, unique: true + + create_table :spree_oauth_access_grants do |t| + t.integer :resource_owner_id, null: false + t.references :application, null: false + t.string :token, null: false + t.integer :expires_in, null: false + t.text :redirect_uri, null: false + t.datetime :created_at, null: false + t.datetime :revoked_at + t.string :scopes + end + + add_index :spree_oauth_access_grants, :token, unique: true + add_foreign_key( + :spree_oauth_access_grants, + :spree_oauth_applications, + column: :application_id + ) + + create_table :spree_oauth_access_tokens do |t| + t.integer :resource_owner_id + t.references :application + + # If you use a custom token generator you may need to change this column + # from string to text, so that it accepts tokens larger than 255 + # characters. More info on custom token generators in: + # https://github.com/doorkeeper-gem/doorkeeper/tree/v3.0.0.rc1#custom-access-token-generator + # + # t.text :token, null: false + t.string :token, null: false + + t.string :refresh_token + t.integer :expires_in + t.datetime :revoked_at + t.datetime :created_at, null: false + t.string :scopes + + # If there is a previous_refresh_token column, + # refresh tokens will be revoked after a related access token is used. + # If there is no previous_refresh_token column, + # previous tokens are revoked as soon as a new access token is created. + # Comment out this line if you'd rather have refresh tokens + # instantly revoked. + t.string :previous_refresh_token, null: false, default: "" + end + + add_index :spree_oauth_access_tokens, :token, unique: true + add_index :spree_oauth_access_tokens, :resource_owner_id + add_index :spree_oauth_access_tokens, :refresh_token, unique: true + add_foreign_key( + :spree_oauth_access_tokens, + :spree_oauth_applications, + column: :application_id + ) + end +end diff --git a/db/migrate/20250210131725_change_integer_id_columns_type.spree_api.rb b/db/migrate/20250210131725_change_integer_id_columns_type.spree_api.rb new file mode 100644 index 0000000..e225743 --- /dev/null +++ b/db/migrate/20250210131725_change_integer_id_columns_type.spree_api.rb @@ -0,0 +1,10 @@ +# This migration comes from spree_api (originally 20210727102516) +class ChangeIntegerIdColumnsType < ActiveRecord::Migration[5.2] + def change + change_column :spree_oauth_access_grants, :resource_owner_id, :bigint + change_column :spree_oauth_access_grants, :application_id, :bigint + + change_column :spree_oauth_access_tokens, :resource_owner_id, :bigint + change_column :spree_oauth_access_tokens, :application_id, :bigint + end +end diff --git a/db/migrate/20250210131726_create_spree_webhooks_tables.spree_api.rb b/db/migrate/20250210131726_create_spree_webhooks_tables.spree_api.rb new file mode 100644 index 0000000..a18b5e4 --- /dev/null +++ b/db/migrate/20250210131726_create_spree_webhooks_tables.spree_api.rb @@ -0,0 +1,17 @@ +# This migration comes from spree_api (originally 20210902162826) +class CreateSpreeWebhooksTables < ActiveRecord::Migration[5.2] + def change + create_table :spree_webhooks_subscribers do |t| + t.string :url, null: false + t.boolean :active, default: false, index: true + + if t.respond_to? :jsonb + t.jsonb :subscriptions + else + t.json :subscriptions + end + + t.timestamps + end + end +end diff --git a/db/migrate/20250210131727_enable_polymorphic_resource_owner.spree_api.rb b/db/migrate/20250210131727_enable_polymorphic_resource_owner.spree_api.rb new file mode 100644 index 0000000..539122c --- /dev/null +++ b/db/migrate/20250210131727_enable_polymorphic_resource_owner.spree_api.rb @@ -0,0 +1,22 @@ +# This migration comes from spree_api (originally 20210919183228) +class EnablePolymorphicResourceOwner < ActiveRecord::Migration[5.2] + def change + add_column :spree_oauth_access_tokens, :resource_owner_type, :string + add_column :spree_oauth_access_grants, :resource_owner_type, :string + change_column_null :spree_oauth_access_grants, :resource_owner_type, false + + add_index :spree_oauth_access_tokens, + [:resource_owner_id, :resource_owner_type], + name: 'polymorphic_owner_oauth_access_tokens' + + add_index :spree_oauth_access_grants, + [:resource_owner_id, :resource_owner_type], + name: 'polymorphic_owner_oauth_access_grants' + + Spree::OauthAccessToken.reset_column_information + Spree::OauthAccessToken.update_all(resource_owner_type: Spree.user_class) + + Spree::OauthAccessGrant.reset_column_information + Spree::OauthAccessGrant.update_all(resource_owner_type: Spree.user_class) + end +end diff --git a/db/migrate/20250210131728_create_spree_webhooks_events.spree_api.rb b/db/migrate/20250210131728_create_spree_webhooks_events.spree_api.rb new file mode 100644 index 0000000..6f4de51 --- /dev/null +++ b/db/migrate/20250210131728_create_spree_webhooks_events.spree_api.rb @@ -0,0 +1,15 @@ +# This migration comes from spree_api (originally 20211025162826) +class CreateSpreeWebhooksEvents < ActiveRecord::Migration[5.2] + def change + create_table :spree_webhooks_events do |t| + t.integer "execution_time" + t.string "name", null: false + t.string "request_errors" + t.string "response_code", index: true + t.belongs_to "subscriber", null: false, index: true + t.boolean "success", index: true + t.string "url", null: false + t.timestamps + end + end +end diff --git a/db/migrate/20250210131729_add_secret_key_to_spree_webhooks_subscribers.spree_api.rb b/db/migrate/20250210131729_add_secret_key_to_spree_webhooks_subscribers.spree_api.rb new file mode 100644 index 0000000..ac03bdd --- /dev/null +++ b/db/migrate/20250210131729_add_secret_key_to_spree_webhooks_subscribers.spree_api.rb @@ -0,0 +1,6 @@ +# This migration comes from spree_api (originally 20221221122100) +class AddSecretKeyToSpreeWebhooksSubscribers < ActiveRecord::Migration[6.1] + def change + add_column :spree_webhooks_subscribers, :secret_key, :string, null: true + end +end diff --git a/db/migrate/20250210131730_backfill_secret_key_for_spree_webhooks_subscribers.spree_api.rb b/db/migrate/20250210131730_backfill_secret_key_for_spree_webhooks_subscribers.spree_api.rb new file mode 100644 index 0000000..199a71e --- /dev/null +++ b/db/migrate/20250210131730_backfill_secret_key_for_spree_webhooks_subscribers.spree_api.rb @@ -0,0 +1,6 @@ +# This migration comes from spree_api (originally 20230116204600) +class BackfillSecretKeyForSpreeWebhooksSubscribers < ActiveRecord::Migration[6.1] + def change + Spree::Webhooks::Subscriber.where(secret_key: nil).find_each(&:regenerate_secret_key) + end +end diff --git a/db/migrate/20250210131731_change_secret_key_to_non_null_column.spree_api.rb b/db/migrate/20250210131731_change_secret_key_to_non_null_column.spree_api.rb new file mode 100644 index 0000000..b83d876 --- /dev/null +++ b/db/migrate/20250210131731_change_secret_key_to_non_null_column.spree_api.rb @@ -0,0 +1,6 @@ +# This migration comes from spree_api (originally 20230116205000) +class ChangeSecretKeyToNonNullColumn < ActiveRecord::Migration[6.1] + def change + change_column_null :spree_webhooks_subscribers, :secret_key, false + end +end diff --git a/db/migrate/20250222135707_add_service_name_to_active_storage_blobs.active_storage.rb b/db/migrate/20250222135707_add_service_name_to_active_storage_blobs.active_storage.rb new file mode 100644 index 0000000..a15c6ce --- /dev/null +++ b/db/migrate/20250222135707_add_service_name_to_active_storage_blobs.active_storage.rb @@ -0,0 +1,22 @@ +# This migration comes from active_storage (originally 20190112182829) +class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0] + def up + return unless table_exists?(:active_storage_blobs) + + unless column_exists?(:active_storage_blobs, :service_name) + add_column :active_storage_blobs, :service_name, :string + + if configured_service = ActiveStorage::Blob.service.name + ActiveStorage::Blob.unscoped.update_all(service_name: configured_service) + end + + change_column :active_storage_blobs, :service_name, :string, null: false + end + end + + def down + return unless table_exists?(:active_storage_blobs) + + remove_column :active_storage_blobs, :service_name + end +end diff --git a/db/migrate/20250222135708_create_active_storage_variant_records.active_storage.rb b/db/migrate/20250222135708_create_active_storage_variant_records.active_storage.rb new file mode 100644 index 0000000..94ac83a --- /dev/null +++ b/db/migrate/20250222135708_create_active_storage_variant_records.active_storage.rb @@ -0,0 +1,27 @@ +# This migration comes from active_storage (originally 20191206030411) +class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0] + def change + return unless table_exists?(:active_storage_blobs) + + # Use Active Record's configured type for primary key + create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t| + t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type + t.string :variation_digest, null: false + + t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + def primary_key_type + config = Rails.configuration.generators + config.options[config.orm][:primary_key_type] || :primary_key + end + + def blobs_primary_key_type + pkey_name = connection.primary_key(:active_storage_blobs) + pkey_column = connection.columns(:active_storage_blobs).find { |c| c.name == pkey_name } + pkey_column.bigint? ? :bigint : pkey_column.type + end +end diff --git a/db/migrate/20250222135709_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb b/db/migrate/20250222135709_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb new file mode 100644 index 0000000..93c8b85 --- /dev/null +++ b/db/migrate/20250222135709_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb @@ -0,0 +1,8 @@ +# This migration comes from active_storage (originally 20211119233751) +class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[6.0] + def change + return unless table_exists?(:active_storage_blobs) + + change_column_null(:active_storage_blobs, :checksum, true) + end +end diff --git a/db/migrate/20250222135729_create_action_text_video_embeds.spree.rb b/db/migrate/20250222135729_create_action_text_video_embeds.spree.rb new file mode 100644 index 0000000..8458814 --- /dev/null +++ b/db/migrate/20250222135729_create_action_text_video_embeds.spree.rb @@ -0,0 +1,12 @@ +# This migration comes from spree (originally 20250217171018) +class CreateActionTextVideoEmbeds < ActiveRecord::Migration[6.1] + def change + create_table :action_text_video_embeds, if_not_exists: true do |t| + t.string :url, null: false + t.string :thumbnail_url, null: false + t.text :raw_html, null: false + + t.timestamps + end + end +end diff --git a/db/migrate/20250305135848_remove_page_builder_indices.spree.rb b/db/migrate/20250305135848_remove_page_builder_indices.spree.rb new file mode 100644 index 0000000..261dc45 --- /dev/null +++ b/db/migrate/20250305135848_remove_page_builder_indices.spree.rb @@ -0,0 +1,12 @@ +# This migration comes from spree (originally 20250305121352) +class RemovePageBuilderIndices < ActiveRecord::Migration[7.2] + def change + if index_name_exists?(:spree_pages, 'index_spree_pages_on_pageable_id_and_pageable_type_and_slug') + remove_index :spree_pages, name: 'index_spree_pages_on_pageable_id_and_pageable_type_and_slug' + end + + if index_name_exists?(:spree_themes, 'index_spree_themes_on_store_id_and_default') + remove_index :spree_themes, name: 'index_spree_themes_on_store_id_and_default' + end + end +end diff --git a/db/migrate/20250305135849_remove_spree_posts_indices.spree.rb b/db/migrate/20250305135849_remove_spree_posts_indices.spree.rb new file mode 100644 index 0000000..8ae14b9 --- /dev/null +++ b/db/migrate/20250305135849_remove_spree_posts_indices.spree.rb @@ -0,0 +1,8 @@ +# This migration comes from spree (originally 20250305121657) +class RemoveSpreePostsIndices < ActiveRecord::Migration[7.2] + def change + if index_name_exists?(:spree_posts, 'index_spree_posts_on_slug_and_store_id') + remove_index :spree_posts, name: 'index_spree_posts_on_slug_and_store_id' + end + end +end diff --git a/db/migrate/20250306141008_add_performed_by_to_spree_reimbursements.spree.rb b/db/migrate/20250306141008_add_performed_by_to_spree_reimbursements.spree.rb new file mode 100644 index 0000000..7f27462 --- /dev/null +++ b/db/migrate/20250306141008_add_performed_by_to_spree_reimbursements.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20250304115943) +class AddPerformedByToSpreeReimbursements < ActiveRecord::Migration[6.1] + def change + add_column :spree_reimbursements, :performed_by_id, :bigint, index: true, null: true, if_not_exists: true + end +end diff --git a/db/migrate/20250311134929_create_spree_gateway_customers.spree.rb b/db/migrate/20250311134929_create_spree_gateway_customers.spree.rb new file mode 100644 index 0000000..9a485f2 --- /dev/null +++ b/db/migrate/20250311134929_create_spree_gateway_customers.spree.rb @@ -0,0 +1,19 @@ +# This migration comes from spree (originally 20250311105934) +class CreateSpreeGatewayCustomers < ActiveRecord::Migration[7.2] + def change + create_table :spree_gateway_customers, if_not_exists: true do |t| + t.string :profile_id, null: false + t.bigint :payment_method_id, null: false + t.bigint :user_id, null: false + + t.timestamps + + t.index ['payment_method_id'], name: 'index_spree_gateway_customers_on_payment_method_id' + t.index ['user_id', 'payment_method_id'], name: 'index_spree_gateway_customers_on_user_id_and_payment_method_id', unique: true + t.index ['user_id'], name: 'index_spree_gateway_customers_on_user_id' + end + + add_column :spree_credit_cards, :gateway_customer_id, :bigint, if_not_exists: true + add_index :spree_credit_cards, :gateway_customer_id, if_not_exists: true + end +end diff --git a/db/migrate/20250312171228_setup_spree_stripe_models.spree_stripe.rb b/db/migrate/20250312171228_setup_spree_stripe_models.spree_stripe.rb new file mode 100644 index 0000000..cea40ba --- /dev/null +++ b/db/migrate/20250312171228_setup_spree_stripe_models.spree_stripe.rb @@ -0,0 +1,42 @@ +# This migration comes from spree_stripe (originally 20250310152812) +class SetupSpreeStripeModels < ActiveRecord::Migration[7.2] + def change + create_table :spree_stripe_payment_intents do |t| + t.decimal :amount, precision: 10, scale: 2, default: '0.0', null: false + t.bigint :order_id, null: false + t.bigint :payment_method_id, null: false + t.string :stripe_id, null: false + t.string :client_secret, null: false + t.string :customer_id + t.string :ephemeral_key_secret + t.string :stripe_payment_method_id + + t.timestamps + + t.index ['order_id', 'stripe_id'], name: 'index_spree_stripe_payment_intents_on_order_id_and_stripe_id', unique: true + t.index ['order_id'], name: 'index_spree_stripe_payment_intents_on_order_id' + t.index ['payment_method_id'], name: 'index_spree_stripe_payment_intents_on_payment_method_id' + end + + create_table :spree_stripe_webhook_keys do |t| + t.string :stripe_id, null: false + t.string :signing_secret, null: false + + t.timestamps + + t.index ['signing_secret'], name: 'index_spree_stripe_webhook_keys_on_signing_secret', unique: true + t.index ['stripe_id'], name: 'index_spree_stripe_webhook_keys_on_stripe_id', unique: true + end + + create_table :spree_stripe_payment_methods_webhook_keys do |t| + t.bigint :payment_method_id, null: false + t.bigint :webhook_key_id, null: false + + t.timestamps + + t.index ['payment_method_id', 'webhook_key_id'], name: 'index_payment_method_id_webhook_key_id_uniqueness', unique: true + t.index ['payment_method_id'], name: 'index_payment_methods_webhook_keys_on_payment_method_id' + t.index ['webhook_key_id'], name: 'index_payment_methods_webhook_keys_on_webhook_key_id' + end + end +end diff --git a/db/migrate/20250314114823_add_unique_index_on_promotion_rules_associations.spree.rb b/db/migrate/20250314114823_add_unique_index_on_promotion_rules_associations.spree.rb new file mode 100644 index 0000000..bb451c6 --- /dev/null +++ b/db/migrate/20250314114823_add_unique_index_on_promotion_rules_associations.spree.rb @@ -0,0 +1,76 @@ +# This migration comes from spree (originally 20250312202705) +class AddUniqueIndexOnPromotionRulesAssociations < ActiveRecord::Migration[7.2] + def change + if ActiveRecord::Base.connection.adapter_name == 'Mysql2' + # Remove duplicate product promotion rules + execute <<-SQL + DELETE FROM spree_product_promotion_rules + WHERE id NOT IN ( + SELECT mid FROM ( + SELECT MIN(id) AS mid + FROM spree_product_promotion_rules + GROUP BY product_id, promotion_rule_id + ) AS min_ids + ); + SQL + + # Remove duplicate taxon promotion rules + execute <<-SQL + DELETE FROM spree_promotion_rule_taxons + WHERE id NOT IN ( + SELECT mid FROM ( + SELECT MIN(id) AS mid + FROM spree_promotion_rule_taxons + GROUP BY taxon_id, promotion_rule_id + ) AS min_ids + ); + SQL + + # Remove duplicate user promotion rules + execute <<-SQL + DELETE FROM spree_promotion_rule_users + WHERE id NOT IN ( + SELECT mid FROM ( + SELECT MIN(id) AS mid + FROM spree_promotion_rule_users + GROUP BY user_id, promotion_rule_id + ) AS min_ids + ); + SQL + else + # Remove duplicate product promotion rules + execute <<-SQL + DELETE FROM spree_product_promotion_rules + WHERE id NOT IN ( + SELECT MIN(id) + FROM spree_product_promotion_rules + GROUP BY product_id, promotion_rule_id + ); + SQL + + # Remove duplicate taxon promotion rules + execute <<-SQL + DELETE FROM spree_promotion_rule_taxons + WHERE id NOT IN ( + SELECT MIN(id) + FROM spree_promotion_rule_taxons + GROUP BY taxon_id, promotion_rule_id + ); + SQL + + # Remove duplicate user promotion rules + execute <<-SQL + DELETE FROM spree_promotion_rule_users + WHERE id NOT IN ( + SELECT MIN(id) + FROM spree_promotion_rule_users + GROUP BY user_id, promotion_rule_id + ); + SQL + end + + add_index :spree_product_promotion_rules, [:product_id, :promotion_rule_id], unique: true + add_index :spree_promotion_rule_taxons, [:taxon_id, :promotion_rule_id], unique: true + add_index :spree_promotion_rule_users, [:user_id, :promotion_rule_id], unique: true + end +end diff --git a/db/migrate/20250314114824_add_user_type_to_spree_role_users.spree.rb b/db/migrate/20250314114824_add_user_type_to_spree_role_users.spree.rb new file mode 100644 index 0000000..3fbb624 --- /dev/null +++ b/db/migrate/20250314114824_add_user_type_to_spree_role_users.spree.rb @@ -0,0 +1,19 @@ +# This migration comes from spree (originally 20250313104226) +class AddUserTypeToSpreeRoleUsers < ActiveRecord::Migration[6.1] + def up + unless column_exists?(:spree_role_users, :user_type) + add_column :spree_role_users, :user_type, :string + add_index :spree_role_users, :user_type + + user_class_name = Spree.admin_user_class.to_s + Spree::RoleUser.where(user_type: nil).update_all(user_type: user_class_name) + + change_column_null :spree_role_users, :user_type, false + end + end + + def down + remove_index :spree_role_users, :user_type, if_exists: true + remove_column :spree_role_users, :user_type, if_exists: true + end +end diff --git a/db/migrate/20250314114825_add_unique_index_on_promotion_action_line_items.spree.rb b/db/migrate/20250314114825_add_unique_index_on_promotion_action_line_items.spree.rb new file mode 100644 index 0000000..fa3791d --- /dev/null +++ b/db/migrate/20250314114825_add_unique_index_on_promotion_action_line_items.spree.rb @@ -0,0 +1,30 @@ +# This migration comes from spree (originally 20250313175830) +class AddUniqueIndexOnPromotionActionLineItems < ActiveRecord::Migration[7.2] + def change + if ActiveRecord::Base.connection.adapter_name == 'Mysql2' + # Remove duplicate promotion action line items + execute <<-SQL + DELETE FROM spree_promotion_action_line_items + WHERE id NOT IN ( + SELECT mid FROM ( + SELECT MIN(id) AS mid + FROM spree_promotion_action_line_items + GROUP BY promotion_action_id, variant_id + ) AS min_ids + ); + SQL + else + # Remove duplicate promotion action line items + execute <<-SQL + DELETE FROM spree_promotion_action_line_items + WHERE id NOT IN ( + SELECT MIN(id) + FROM spree_promotion_action_line_items + GROUP BY promotion_action_id, variant_id + ); + SQL + end + + add_index :spree_promotion_action_line_items, [:promotion_action_id, :variant_id], unique: true + end +end diff --git a/db/migrate/20250319151854_create_spree_taggings_and_spree_tags.spree.rb b/db/migrate/20250319151854_create_spree_taggings_and_spree_tags.spree.rb new file mode 100644 index 0000000..14a6543 --- /dev/null +++ b/db/migrate/20250319151854_create_spree_taggings_and_spree_tags.spree.rb @@ -0,0 +1,39 @@ +# This migration comes from spree (originally 20250314144210) +class CreateSpreeTaggingsAndSpreeTags < ActiveRecord::Migration[7.2] + def change + create_table :spree_taggings do |t| + t.bigint "tag_id" + t.string "taggable_type" + t.bigint "taggable_id" + t.string "tagger_type" + t.bigint "tagger_id" + t.string "context", limit: 128 + t.datetime "created_at", precision: nil + t.string "tenant", limit: 128 + t.index ["context"], name: "index_spree_taggings_on_context" + t.index ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "spree_taggings_idx", unique: true + t.index ["tag_id"], name: "index_spree_taggings_on_tag_id" + t.index ["taggable_id", "taggable_type", "context"], name: "spree_taggings_taggable_context_idx" + t.index ["taggable_id", "taggable_type", "tagger_id", "context"], name: "spree_taggings_idy" + t.index ["taggable_id"], name: "index_spree_taggings_on_taggable_id" + t.index ["taggable_type", "taggable_id"], name: "index_spree_taggings_on_taggable_type_and_taggable_id" + t.index ["taggable_type"], name: "index_spree_taggings_on_taggable_type" + t.index ["tagger_id", "tagger_type"], name: "index_spree_taggings_on_tagger_id_and_tagger_type" + t.index ["tagger_id"], name: "index_spree_taggings_on_tagger_id" + t.index ["tagger_type", "tagger_id"], name: "index_spree_taggings_on_tagger_type_and_tagger_id" + t.index ["tenant"], name: "index_spree_taggings_on_tenant" + end + + create_table :spree_tags do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "taggings_count", default: 0 + t.index ["name"], name: "index_spree_tags_on_name", unique: true + end + + if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' + add_index :spree_tags, 'lower(name) varchar_pattern_ops', name: 'index_spree_tags_on_lower_name' + end + end +end diff --git a/db/migrate/20250520122336_create_spree_integrations.spree.rb b/db/migrate/20250520122336_create_spree_integrations.spree.rb new file mode 100644 index 0000000..32933da --- /dev/null +++ b/db/migrate/20250520122336_create_spree_integrations.spree.rb @@ -0,0 +1,13 @@ +# This migration comes from spree (originally 20250407085228) +class CreateSpreeIntegrations < ActiveRecord::Migration[7.2] + def change + create_table :spree_integrations, if_not_exists: true do |t| + t.references :store, null: false, index: true + t.string :type, null: false, index: true + t.text :preferences + t.boolean :active, default: false, null: false, index: true + + t.timestamps + end + end +end diff --git a/db/migrate/20250520122337_create_spree_invitations.spree.rb b/db/migrate/20250520122337_create_spree_invitations.spree.rb new file mode 100644 index 0000000..10c22b9 --- /dev/null +++ b/db/migrate/20250520122337_create_spree_invitations.spree.rb @@ -0,0 +1,21 @@ +# This migration comes from spree (originally 20250410061306) +class CreateSpreeInvitations < ActiveRecord::Migration[7.2] + def change + create_table :spree_invitations do |t| + t.string :email, index: true, null: false + t.string :token, index: { unique: true }, null: false + t.string :status, null: false, index: true + + t.references :resource, polymorphic: true, index: true, null: false # eg. Store, Vendor, Account + t.references :inviter, polymorphic: true, index: true, null: false + t.references :invitee, polymorphic: true, index: true + t.references :role, null: false + + t.datetime :accepted_at + t.datetime :expires_at, index: true + t.datetime :deleted_at, index: true + + t.timestamps + end + end +end diff --git a/db/migrate/20250520122338_add_resource_to_spree_role_users.spree.rb b/db/migrate/20250520122338_add_resource_to_spree_role_users.spree.rb new file mode 100644 index 0000000..963ef92 --- /dev/null +++ b/db/migrate/20250520122338_add_resource_to_spree_role_users.spree.rb @@ -0,0 +1,9 @@ +# This migration comes from spree (originally 20250418174652) +class AddResourceToSpreeRoleUsers < ActiveRecord::Migration[7.2] + def change + add_reference :spree_role_users, :resource, polymorphic: true, null: true + add_reference :spree_role_users, :invitation, null: true + + add_index :spree_role_users, [:resource_id, :resource_type, :user_id, :user_type, :role_id], unique: true + end +end diff --git a/db/migrate/20250520122339_add_selected_locale_to_spree_admin_users.spree.rb b/db/migrate/20250520122339_add_selected_locale_to_spree_admin_users.spree.rb new file mode 100644 index 0000000..c652c27 --- /dev/null +++ b/db/migrate/20250520122339_add_selected_locale_to_spree_admin_users.spree.rb @@ -0,0 +1,9 @@ +# This migration comes from spree (originally 20250508060800) +class AddSelectedLocaleToSpreeAdminUsers < ActiveRecord::Migration[7.2] + def change + if Spree.admin_user_class.present? + users_table_name = Spree.admin_user_class.table_name + add_column users_table_name, :selected_locale, :string unless column_exists?(users_table_name, :selected_locale) + end + end +end diff --git a/db/migrate/20250520122340_add_session_id_to_spree_assets.spree.rb b/db/migrate/20250520122340_add_session_id_to_spree_assets.spree.rb new file mode 100644 index 0000000..25733b7 --- /dev/null +++ b/db/migrate/20250520122340_add_session_id_to_spree_assets.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20250509143831) +class AddSessionIdToSpreeAssets < ActiveRecord::Migration[7.2] + def change + add_column :spree_assets, :session_id, :string + end +end diff --git a/db/migrate/20250529102145_add_company_to_spree_stock_locations.spree.rb b/db/migrate/20250529102145_add_company_to_spree_stock_locations.spree.rb new file mode 100644 index 0000000..a60e766 --- /dev/null +++ b/db/migrate/20250529102145_add_company_to_spree_stock_locations.spree.rb @@ -0,0 +1,6 @@ +# This migration comes from spree (originally 20250527134027) +class AddCompanyToSpreeStockLocations < ActiveRecord::Migration[7.2] + def change + add_column :spree_stock_locations, :company, :string, if_not_exists: true + end +end diff --git a/db/migrate/20250605101817_create_spree_paypal_checkout_orders.spree_paypal_checkout.rb b/db/migrate/20250605101817_create_spree_paypal_checkout_orders.spree_paypal_checkout.rb new file mode 100644 index 0000000..b842bba --- /dev/null +++ b/db/migrate/20250605101817_create_spree_paypal_checkout_orders.spree_paypal_checkout.rb @@ -0,0 +1,21 @@ +# This migration comes from spree_paypal_checkout (originally 20250528095719) +class CreateSpreePaypalCheckoutOrders < ActiveRecord::Migration[7.2] + def change + create_table :spree_paypal_checkout_orders do |t| + t.references :order, null: false + t.references :payment_method, null: false + t.string :paypal_id, null: false + t.decimal :amount, null: false, precision: 10, scale: 2 + + if t.respond_to? :jsonb + t.jsonb :data + else + t.json :data + end + + t.timestamps + end + + add_index :spree_paypal_checkout_orders, [:order_id, :paypal_id], unique: true + end +end diff --git a/db/migrate/20250623212018_enable_pg_trgm_extension.spree.rb b/db/migrate/20250623212018_enable_pg_trgm_extension.spree.rb new file mode 100644 index 0000000..a1a658d --- /dev/null +++ b/db/migrate/20250623212018_enable_pg_trgm_extension.spree.rb @@ -0,0 +1,14 @@ +# This migration comes from spree (originally 20250530101236) +class EnablePgTrgmExtension < ActiveRecord::Migration[7.2] + def up + if supports_extensions? && extension_available?('pg_trgm') && !extension_enabled?('pg_trgm') + enable_extension 'pg_trgm' + end + end + + def down + if supports_extensions? && extension_available?('pg_trgm') && extension_enabled?('pg_trgm') + disable_extension 'pg_trgm' + end + end +end diff --git a/db/migrate/20250623212019_add_missing_fields_to_users.spree.rb b/db/migrate/20250623212019_add_missing_fields_to_users.spree.rb new file mode 100644 index 0000000..4ddaafd --- /dev/null +++ b/db/migrate/20250623212019_add_missing_fields_to_users.spree.rb @@ -0,0 +1,36 @@ +# This migration comes from spree (originally 20250605131334) +# this fields were not present when someone used a custom user class +# so we need to ensure this is setup properly +class AddMissingFieldsToUsers < ActiveRecord::Migration[7.2] + def change + users_table = Spree.user_class.table_name + admin_users_table = Spree.admin_user_class.table_name + + change_table users_table do |t| + t.string :login unless column_exists?(users_table, :login) + + if t.respond_to? :jsonb + t.jsonb :public_metadata unless column_exists?(users_table, :public_metadata) + t.jsonb :private_metadata unless column_exists?(users_table, :private_metadata) + else + t.json :public_metadata unless column_exists?(users_table, :public_metadata) + t.json :private_metadata unless column_exists?(users_table, :private_metadata) + end + end + + add_reference users_table, :bill_address, if_not_exists: true + add_reference users_table, :ship_address, if_not_exists: true + + change_table admin_users_table do |t| + t.string :login unless column_exists?(admin_users_table, :login) + + if t.respond_to? :jsonb + t.jsonb :public_metadata unless column_exists?(admin_users_table, :public_metadata) + t.jsonb :private_metadata unless column_exists?(admin_users_table, :private_metadata) + else + t.json :public_metadata unless column_exists?(admin_users_table, :public_metadata) + t.json :private_metadata unless column_exists?(admin_users_table, :private_metadata) + end + end + end +end diff --git a/db/migrate/20250702154146_create_spree_gift_cards_and_spree_gift_card_batches.spree.rb b/db/migrate/20250702154146_create_spree_gift_cards_and_spree_gift_card_batches.spree.rb new file mode 100644 index 0000000..41111ac --- /dev/null +++ b/db/migrate/20250702154146_create_spree_gift_cards_and_spree_gift_card_batches.spree.rb @@ -0,0 +1,38 @@ +# This migration comes from spree (originally 20250506073057) +class CreateSpreeGiftCardsAndSpreeGiftCardBatches < ActiveRecord::Migration[7.2] + def change + create_table :spree_gift_card_batches, if_not_exists: true do |t| + t.references :store, null: false, index: true + t.references :created_by + t.integer :codes_count, default: 1, null: false + t.decimal :amount, precision: 10, scale: 2, null: false + t.string :currency, null: false + t.string :prefix + t.date :expires_at + + t.timestamps + end + + create_table :spree_gift_cards, if_not_exists: true do |t| + t.references :store, null: false, index: true + t.references :user, index: true + t.references :gift_card_batch, index: true + t.references :created_by, index: true + t.string :code, null: false + t.string :state, null: false, index: true + t.decimal :amount, precision: 10, scale: 2, null: false + t.decimal :amount_authorized, precision: 10, scale: 2, null: false, default: 0 + t.decimal :amount_used, precision: 10, scale: 2, null: false, default: 0 + t.string :currency, null: false + + t.date :expires_at, index: true + t.datetime :redeemed_at, index: true + t.timestamps + end + + add_index :spree_gift_cards, :code, unique: { scope: :store_id } + + add_column :spree_orders, :gift_card_id, :bigint, if_not_exists: true + add_index :spree_orders, :gift_card_id, if_not_exists: true + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..0e19afd --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,1962 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema[8.0].define(version: 2025_07_02_154146) do + # These are extensions that must be enabled in order to support this database + enable_extension "pg_catalog.plpgsql" + enable_extension "pg_trgm" + + create_table "action_mailbox_inbound_emails", force: :cascade do |t| + t.integer "status", default: 0, null: false + t.string "message_id", null: false + t.string "message_checksum", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["message_id", "message_checksum"], name: "index_action_mailbox_inbound_emails_uniqueness", unique: true + end + + create_table "action_text_rich_texts", force: :cascade do |t| + t.string "name", null: false + t.text "body" + t.string "record_type", null: false + t.bigint "record_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "locale", default: "en", null: false + t.index ["record_type", "record_id", "name", "locale"], name: "index_action_text_rich_texts_uniqueness", unique: true + end + + create_table "action_text_video_embeds", force: :cascade do |t| + t.string "url", null: false + t.string "thumbnail_url", null: false + t.text "raw_html", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "active_storage_attachments", force: :cascade do |t| + t.string "name", null: false + t.string "record_type", null: false + t.bigint "record_id", null: false + t.bigint "blob_id", null: false + t.datetime "created_at", null: false + t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" + t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true + end + + create_table "active_storage_blobs", force: :cascade do |t| + t.string "key", null: false + t.string "filename", null: false + t.string "content_type" + t.text "metadata" + t.string "service_name", null: false + t.bigint "byte_size", null: false + t.string "checksum" + t.datetime "created_at", null: false + t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true + end + + create_table "active_storage_variant_records", force: :cascade do |t| + t.bigint "blob_id", null: false + t.string "variation_digest", null: false + t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true + end + + create_table "friendly_id_slugs", force: :cascade do |t| + t.string "slug", null: false + t.bigint "sluggable_id", null: false + t.string "sluggable_type", limit: 50 + t.string "scope" + t.datetime "created_at", precision: nil + t.datetime "deleted_at", precision: nil + t.string "locale" + t.index ["deleted_at"], name: "index_friendly_id_slugs_on_deleted_at" + t.index ["locale"], name: "index_friendly_id_slugs_on_locale" + t.index ["slug", "sluggable_type", "locale"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_locale" + t.index ["slug", "sluggable_type", "scope", "locale"], name: "index_friendly_id_slugs_unique", unique: true + t.index ["sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_id" + t.index ["sluggable_type"], name: "index_friendly_id_slugs_on_sluggable_type" + end + + create_table "spree_addresses", force: :cascade do |t| + t.string "firstname" + t.string "lastname" + t.string "address1" + t.string "address2" + t.string "city" + t.string "zipcode" + t.string "phone" + t.string "state_name" + t.string "alternative_phone" + t.string "company" + t.bigint "state_id" + t.bigint "country_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "user_id" + t.datetime "deleted_at", precision: nil + t.string "label" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.boolean "quick_checkout", default: false + t.decimal "latitude" + t.decimal "longitude" + t.index ["country_id"], name: "index_spree_addresses_on_country_id" + t.index ["deleted_at"], name: "index_spree_addresses_on_deleted_at" + t.index ["firstname"], name: "index_addresses_on_firstname" + t.index ["lastname"], name: "index_addresses_on_lastname" + t.index ["quick_checkout"], name: "index_spree_addresses_on_quick_checkout" + t.index ["state_id"], name: "index_spree_addresses_on_state_id" + t.index ["user_id"], name: "index_spree_addresses_on_user_id" + end + + create_table "spree_adjustments", force: :cascade do |t| + t.string "source_type" + t.bigint "source_id" + t.string "adjustable_type" + t.bigint "adjustable_id" + t.decimal "amount", precision: 10, scale: 2 + t.string "label" + t.boolean "mandatory" + t.boolean "eligible", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "state" + t.bigint "order_id", null: false + t.boolean "included", default: false + t.index ["adjustable_id", "adjustable_type"], name: "index_spree_adjustments_on_adjustable_id_and_adjustable_type" + t.index ["eligible"], name: "index_spree_adjustments_on_eligible" + t.index ["order_id"], name: "index_spree_adjustments_on_order_id" + t.index ["source_id", "source_type"], name: "index_spree_adjustments_on_source_id_and_source_type" + end + + create_table "spree_admin_users", force: :cascade do |t| + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false + t.string "reset_password_token" + t.datetime "reset_password_sent_at" + t.datetime "remember_created_at" + t.integer "sign_in_count", default: 0, null: false + t.datetime "current_sign_in_at" + t.datetime "last_sign_in_at" + t.string "current_sign_in_ip" + t.string "last_sign_in_ip" + t.string "confirmation_token" + t.datetime "confirmed_at" + t.datetime "confirmation_sent_at" + t.string "unconfirmed_email" + t.integer "failed_attempts", default: 0, null: false + t.string "unlock_token" + t.datetime "locked_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "first_name" + t.string "last_name" + t.string "selected_locale" + t.string "login" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["confirmation_token"], name: "index_spree_admin_users_on_confirmation_token", unique: true + t.index ["email"], name: "index_spree_admin_users_on_email", unique: true + t.index ["reset_password_token"], name: "index_spree_admin_users_on_reset_password_token", unique: true + t.index ["unlock_token"], name: "index_spree_admin_users_on_unlock_token", unique: true + end + + create_table "spree_assets", force: :cascade do |t| + t.string "viewable_type" + t.bigint "viewable_id" + t.integer "attachment_width" + t.integer "attachment_height" + t.integer "attachment_file_size" + t.integer "position" + t.string "attachment_content_type" + t.string "attachment_file_name" + t.string "type", limit: 75 + t.datetime "attachment_updated_at", precision: nil + t.text "alt" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.string "session_id" + t.index ["position"], name: "index_spree_assets_on_position" + t.index ["viewable_id"], name: "index_assets_on_viewable_id" + t.index ["viewable_type", "type"], name: "index_assets_on_viewable_type_and_type" + end + + create_table "spree_calculators", force: :cascade do |t| + t.string "type" + t.string "calculable_type" + t.bigint "calculable_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "preferences" + t.datetime "deleted_at", precision: nil + t.index ["calculable_id", "calculable_type"], name: "index_spree_calculators_on_calculable_id_and_calculable_type" + t.index ["deleted_at"], name: "index_spree_calculators_on_deleted_at" + t.index ["id", "type"], name: "index_spree_calculators_on_id_and_type" + end + + create_table "spree_countries", force: :cascade do |t| + t.string "iso_name" + t.string "iso", null: false + t.string "iso3", null: false + t.string "name" + t.integer "numcode" + t.boolean "states_required", default: false + t.datetime "updated_at", precision: nil + t.boolean "zipcode_required", default: true + t.datetime "created_at", precision: nil + t.index ["iso"], name: "index_spree_countries_on_iso", unique: true + t.index ["iso3"], name: "index_spree_countries_on_iso3", unique: true + t.index ["iso_name"], name: "index_spree_countries_on_iso_name", unique: true + t.index ["name"], name: "index_spree_countries_on_name", unique: true + end + + create_table "spree_coupon_codes", force: :cascade do |t| + t.string "code" + t.bigint "promotion_id" + t.bigint "order_id" + t.integer "state", default: 0, null: false + t.datetime "deleted_at", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["code"], name: "index_spree_coupon_codes_on_code", unique: true, where: "(deleted_at IS NULL)" + t.index ["deleted_at"], name: "index_spree_coupon_codes_on_deleted_at" + t.index ["order_id"], name: "index_spree_coupon_codes_on_order_id" + t.index ["promotion_id"], name: "index_spree_coupon_codes_on_promotion_id" + t.index ["state"], name: "index_spree_coupon_codes_on_state" + end + + create_table "spree_credit_cards", force: :cascade do |t| + t.string "month" + t.string "year" + t.string "cc_type" + t.string "last_digits" + t.bigint "address_id" + t.string "gateway_customer_profile_id" + t.string "gateway_payment_profile_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name" + t.bigint "user_id" + t.bigint "payment_method_id" + t.boolean "default", default: false, null: false + t.datetime "deleted_at", precision: nil + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.bigint "gateway_customer_id" + t.index ["address_id"], name: "index_spree_credit_cards_on_address_id" + t.index ["deleted_at"], name: "index_spree_credit_cards_on_deleted_at" + t.index ["gateway_customer_id"], name: "index_spree_credit_cards_on_gateway_customer_id" + t.index ["payment_method_id"], name: "index_spree_credit_cards_on_payment_method_id" + t.index ["user_id"], name: "index_spree_credit_cards_on_user_id" + end + + create_table "spree_custom_domains", force: :cascade do |t| + t.bigint "store_id", null: false + t.string "url", null: false + t.boolean "status", default: false + t.boolean "default", default: false, null: false + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["store_id"], name: "index_spree_custom_domains_on_store_id" + t.index ["url"], name: "index_spree_custom_domains_on_url", unique: true + end + + create_table "spree_customer_returns", force: :cascade do |t| + t.string "number" + t.bigint "stock_location_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "store_id" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["number"], name: "index_spree_customer_returns_on_number", unique: true + t.index ["stock_location_id"], name: "index_spree_customer_returns_on_stock_location_id" + t.index ["store_id"], name: "index_spree_customer_returns_on_store_id" + end + + create_table "spree_data_feeds", force: :cascade do |t| + t.bigint "store_id" + t.string "name" + t.string "type" + t.string "slug" + t.boolean "active", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["store_id", "slug", "type"], name: "index_spree_data_feeds_on_store_id_and_slug_and_type" + t.index ["store_id"], name: "index_spree_data_feeds_on_store_id" + end + + create_table "spree_digital_links", force: :cascade do |t| + t.bigint "digital_id" + t.bigint "line_item_id" + t.string "token" + t.integer "access_counter" + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["digital_id"], name: "index_spree_digital_links_on_digital_id" + t.index ["line_item_id"], name: "index_spree_digital_links_on_line_item_id" + t.index ["token"], name: "index_spree_digital_links_on_token", unique: true + end + + create_table "spree_digitals", force: :cascade do |t| + t.bigint "variant_id" + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["variant_id"], name: "index_spree_digitals_on_variant_id" + end + + create_table "spree_exports", force: :cascade do |t| + t.bigint "user_id" + t.bigint "store_id", null: false + t.string "number", limit: 32, null: false + t.string "type", null: false + t.jsonb "search_params" + t.integer "format", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["format"], name: "index_spree_exports_on_format" + t.index ["number"], name: "index_spree_exports_on_number", unique: true + t.index ["store_id"], name: "index_spree_exports_on_store_id" + t.index ["user_id"], name: "index_spree_exports_on_user_id" + end + + create_table "spree_gateway_customers", force: :cascade do |t| + t.string "profile_id", null: false + t.bigint "payment_method_id", null: false + t.bigint "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["payment_method_id"], name: "index_spree_gateway_customers_on_payment_method_id" + t.index ["user_id", "payment_method_id"], name: "index_spree_gateway_customers_on_user_id_and_payment_method_id", unique: true + t.index ["user_id"], name: "index_spree_gateway_customers_on_user_id" + end + + create_table "spree_gateways", force: :cascade do |t| + t.string "type" + t.string "name" + t.text "description" + t.boolean "active", default: true + t.string "environment", default: "development" + t.string "server", default: "test" + t.boolean "test_mode", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "preferences" + t.index ["active"], name: "index_spree_gateways_on_active" + t.index ["test_mode"], name: "index_spree_gateways_on_test_mode" + end + + create_table "spree_gift_card_batches", force: :cascade do |t| + t.bigint "store_id", null: false + t.bigint "created_by_id" + t.integer "codes_count", default: 1, null: false + t.decimal "amount", precision: 10, scale: 2, null: false + t.string "currency", null: false + t.string "prefix" + t.date "expires_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["created_by_id"], name: "index_spree_gift_card_batches_on_created_by_id" + t.index ["store_id"], name: "index_spree_gift_card_batches_on_store_id" + end + + create_table "spree_gift_cards", force: :cascade do |t| + t.bigint "store_id", null: false + t.bigint "user_id" + t.bigint "gift_card_batch_id" + t.bigint "created_by_id" + t.string "code", null: false + t.string "state", null: false + t.decimal "amount", precision: 10, scale: 2, null: false + t.decimal "amount_authorized", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "amount_used", precision: 10, scale: 2, default: "0.0", null: false + t.string "currency", null: false + t.date "expires_at" + t.datetime "redeemed_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["code"], name: "index_spree_gift_cards_on_code", unique: true + t.index ["created_by_id"], name: "index_spree_gift_cards_on_created_by_id" + t.index ["expires_at"], name: "index_spree_gift_cards_on_expires_at" + t.index ["gift_card_batch_id"], name: "index_spree_gift_cards_on_gift_card_batch_id" + t.index ["redeemed_at"], name: "index_spree_gift_cards_on_redeemed_at" + t.index ["state"], name: "index_spree_gift_cards_on_state" + t.index ["store_id"], name: "index_spree_gift_cards_on_store_id" + t.index ["user_id"], name: "index_spree_gift_cards_on_user_id" + end + + create_table "spree_integrations", force: :cascade do |t| + t.bigint "store_id", null: false + t.string "type", null: false + t.text "preferences" + t.boolean "active", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["active"], name: "index_spree_integrations_on_active" + t.index ["store_id"], name: "index_spree_integrations_on_store_id" + t.index ["type"], name: "index_spree_integrations_on_type" + end + + create_table "spree_inventory_units", force: :cascade do |t| + t.string "state" + t.bigint "variant_id" + t.bigint "order_id" + t.bigint "shipment_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "pending", default: true + t.bigint "line_item_id" + t.integer "quantity", default: 1 + t.bigint "original_return_item_id" + t.index ["line_item_id"], name: "index_spree_inventory_units_on_line_item_id" + t.index ["order_id"], name: "index_inventory_units_on_order_id" + t.index ["original_return_item_id"], name: "index_spree_inventory_units_on_original_return_item_id" + t.index ["shipment_id"], name: "index_inventory_units_on_shipment_id" + t.index ["variant_id"], name: "index_inventory_units_on_variant_id" + end + + create_table "spree_invitations", force: :cascade do |t| + t.string "email", null: false + t.string "token", null: false + t.string "status", null: false + t.string "resource_type", null: false + t.bigint "resource_id", null: false + t.string "inviter_type", null: false + t.bigint "inviter_id", null: false + t.string "invitee_type" + t.bigint "invitee_id" + t.bigint "role_id", null: false + t.datetime "accepted_at" + t.datetime "expires_at" + t.datetime "deleted_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["deleted_at"], name: "index_spree_invitations_on_deleted_at" + t.index ["email"], name: "index_spree_invitations_on_email" + t.index ["expires_at"], name: "index_spree_invitations_on_expires_at" + t.index ["invitee_type", "invitee_id"], name: "index_spree_invitations_on_invitee" + t.index ["inviter_type", "inviter_id"], name: "index_spree_invitations_on_inviter" + t.index ["resource_type", "resource_id"], name: "index_spree_invitations_on_resource" + t.index ["role_id"], name: "index_spree_invitations_on_role_id" + t.index ["status"], name: "index_spree_invitations_on_status" + t.index ["token"], name: "index_spree_invitations_on_token", unique: true + end + + create_table "spree_line_items", force: :cascade do |t| + t.bigint "variant_id" + t.bigint "order_id" + t.integer "quantity", null: false + t.decimal "price", precision: 10, scale: 2, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "currency" + t.decimal "cost_price", precision: 10, scale: 2 + t.bigint "tax_category_id" + t.decimal "adjustment_total", precision: 10, scale: 2, default: "0.0" + t.decimal "additional_tax_total", precision: 10, scale: 2, default: "0.0" + t.decimal "promo_total", precision: 10, scale: 2, default: "0.0" + t.decimal "included_tax_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "pre_tax_amount", precision: 12, scale: 4, default: "0.0", null: false + t.decimal "taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "non_taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["order_id"], name: "index_spree_line_items_on_order_id" + t.index ["tax_category_id"], name: "index_spree_line_items_on_tax_category_id" + t.index ["variant_id"], name: "index_spree_line_items_on_variant_id" + end + + create_table "spree_log_entries", force: :cascade do |t| + t.string "source_type" + t.bigint "source_id" + t.text "details" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["source_id", "source_type"], name: "index_spree_log_entries_on_source_id_and_source_type" + end + + create_table "spree_oauth_access_grants", force: :cascade do |t| + t.bigint "resource_owner_id", null: false + t.bigint "application_id", null: false + t.string "token", null: false + t.integer "expires_in", null: false + t.text "redirect_uri", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "revoked_at", precision: nil + t.string "scopes" + t.string "resource_owner_type", null: false + t.index ["application_id"], name: "index_spree_oauth_access_grants_on_application_id" + t.index ["resource_owner_id", "resource_owner_type"], name: "polymorphic_owner_oauth_access_grants" + t.index ["token"], name: "index_spree_oauth_access_grants_on_token", unique: true + end + + create_table "spree_oauth_access_tokens", force: :cascade do |t| + t.bigint "resource_owner_id" + t.bigint "application_id" + t.string "token", null: false + t.string "refresh_token" + t.integer "expires_in" + t.datetime "revoked_at", precision: nil + t.datetime "created_at", precision: nil, null: false + t.string "scopes" + t.string "previous_refresh_token", default: "", null: false + t.string "resource_owner_type" + t.index ["application_id"], name: "index_spree_oauth_access_tokens_on_application_id" + t.index ["refresh_token"], name: "index_spree_oauth_access_tokens_on_refresh_token", unique: true + t.index ["resource_owner_id", "resource_owner_type"], name: "polymorphic_owner_oauth_access_tokens" + t.index ["resource_owner_id"], name: "index_spree_oauth_access_tokens_on_resource_owner_id" + t.index ["token"], name: "index_spree_oauth_access_tokens_on_token", unique: true + end + + create_table "spree_oauth_applications", force: :cascade do |t| + t.string "name", null: false + t.string "uid", null: false + t.string "secret", null: false + t.text "redirect_uri", null: false + t.string "scopes", default: "", null: false + t.boolean "confidential", default: true, null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["uid"], name: "index_spree_oauth_applications_on_uid", unique: true + end + + create_table "spree_option_type_prototypes", force: :cascade do |t| + t.bigint "prototype_id" + t.bigint "option_type_id" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["option_type_id"], name: "index_spree_option_type_prototypes_on_option_type_id" + t.index ["prototype_id", "option_type_id"], name: "spree_option_type_prototypes_prototype_id_option_type_id", unique: true + t.index ["prototype_id"], name: "index_spree_option_type_prototypes_on_prototype_id" + end + + create_table "spree_option_type_translations", force: :cascade do |t| + t.string "presentation" + t.string "locale", null: false + t.bigint "spree_option_type_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["locale"], name: "index_spree_option_type_translations_on_locale" + t.index ["spree_option_type_id", "locale"], name: "unique_option_type_id_per_locale", unique: true + end + + create_table "spree_option_types", force: :cascade do |t| + t.string "name", limit: 100 + t.string "presentation", limit: 100 + t.integer "position", default: 0, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "filterable", default: true, null: false + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["filterable"], name: "index_spree_option_types_on_filterable" + t.index ["name"], name: "index_spree_option_types_on_name" + t.index ["position"], name: "index_spree_option_types_on_position" + end + + create_table "spree_option_value_translations", force: :cascade do |t| + t.string "presentation" + t.string "locale", null: false + t.bigint "spree_option_value_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["locale"], name: "index_spree_option_value_translations_on_locale" + t.index ["spree_option_value_id", "locale"], name: "unique_option_value_id_per_locale", unique: true + end + + create_table "spree_option_value_variants", force: :cascade do |t| + t.bigint "variant_id" + t.bigint "option_value_id" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["option_value_id"], name: "index_spree_option_value_variants_on_option_value_id" + t.index ["variant_id", "option_value_id"], name: "index_option_values_variants_on_variant_id_and_option_value_id", unique: true + t.index ["variant_id"], name: "index_spree_option_value_variants_on_variant_id" + end + + create_table "spree_option_values", force: :cascade do |t| + t.integer "position" + t.string "name" + t.string "presentation" + t.bigint "option_type_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["name"], name: "index_spree_option_values_on_name" + t.index ["option_type_id"], name: "index_spree_option_values_on_option_type_id" + t.index ["position"], name: "index_spree_option_values_on_position" + end + + create_table "spree_order_promotions", force: :cascade do |t| + t.bigint "order_id" + t.bigint "promotion_id" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["order_id"], name: "index_spree_order_promotions_on_order_id" + t.index ["promotion_id", "order_id"], name: "index_spree_order_promotions_on_promotion_id_and_order_id" + t.index ["promotion_id"], name: "index_spree_order_promotions_on_promotion_id" + end + + create_table "spree_orders", force: :cascade do |t| + t.string "number", limit: 32 + t.decimal "item_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "total", precision: 10, scale: 2, default: "0.0", null: false + t.string "state" + t.decimal "adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.bigint "user_id" + t.datetime "completed_at", precision: nil + t.bigint "bill_address_id" + t.bigint "ship_address_id" + t.decimal "payment_total", precision: 10, scale: 2, default: "0.0" + t.string "shipment_state" + t.string "payment_state" + t.string "email" + t.text "special_instructions" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "currency" + t.string "last_ip_address" + t.bigint "created_by_id" + t.decimal "shipment_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "additional_tax_total", precision: 10, scale: 2, default: "0.0" + t.decimal "promo_total", precision: 10, scale: 2, default: "0.0" + t.string "channel", default: "spree" + t.decimal "included_tax_total", precision: 10, scale: 2, default: "0.0", null: false + t.integer "item_count", default: 0 + t.bigint "approver_id" + t.datetime "approved_at", precision: nil + t.boolean "confirmation_delivered", default: false + t.boolean "considered_risky", default: false + t.string "token" + t.datetime "canceled_at", precision: nil + t.bigint "canceler_id" + t.bigint "store_id" + t.integer "state_lock_version", default: 0, null: false + t.decimal "taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "non_taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.boolean "store_owner_notification_delivered" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.text "internal_note" + t.boolean "accept_marketing", default: false + t.boolean "signup_for_an_account", default: false + t.bigint "gift_card_id" + t.index ["approver_id"], name: "index_spree_orders_on_approver_id" + t.index ["bill_address_id"], name: "index_spree_orders_on_bill_address_id" + t.index ["canceler_id"], name: "index_spree_orders_on_canceler_id" + t.index ["completed_at"], name: "index_spree_orders_on_completed_at" + t.index ["confirmation_delivered"], name: "index_spree_orders_on_confirmation_delivered" + t.index ["considered_risky"], name: "index_spree_orders_on_considered_risky" + t.index ["created_by_id"], name: "index_spree_orders_on_created_by_id" + t.index ["gift_card_id"], name: "index_spree_orders_on_gift_card_id" + t.index ["number"], name: "index_spree_orders_on_number", unique: true + t.index ["ship_address_id"], name: "index_spree_orders_on_ship_address_id" + t.index ["store_id"], name: "index_spree_orders_on_store_id" + t.index ["token"], name: "index_spree_orders_on_token" + t.index ["user_id", "created_by_id"], name: "index_spree_orders_on_user_id_and_created_by_id" + end + + create_table "spree_page_blocks", force: :cascade do |t| + t.bigint "section_id", null: false + t.string "name", null: false + t.integer "position", default: 1, null: false + t.string "type", null: false + t.integer "page_links_count", default: 0 + t.text "preferences" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "deleted_at", precision: nil + t.index ["section_id", "position"], name: "index_spree_page_blocks_on_section_w_position" + t.index ["section_id"], name: "index_spree_page_blocks_on_section_id" + end + + create_table "spree_page_links", force: :cascade do |t| + t.string "parent_type" + t.bigint "parent_id" + t.string "linkable_type" + t.bigint "linkable_id" + t.string "label" + t.string "url" + t.boolean "open_in_new_tab", default: false + t.integer "position", default: 1, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["linkable_type", "linkable_id"], name: "index_spree_page_links_on_linkable" + t.index ["parent_type", "parent_id"], name: "index_spree_page_links_on_parent" + end + + create_table "spree_page_sections", force: :cascade do |t| + t.string "pageable_type", null: false + t.bigint "pageable_id", null: false + t.string "type", null: false + t.string "name", null: false + t.integer "position", default: 1, null: false + t.integer "page_links_count", default: 0 + t.text "preferences" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "deleted_at", precision: nil + t.index ["pageable_id", "pageable_type", "position"], name: "index_spree_page_sections_on_pageable_w_position" + t.index ["pageable_type", "pageable_id"], name: "index_spree_page_sections_on_pageable" + end + + create_table "spree_pages", force: :cascade do |t| + t.string "pageable_type", null: false + t.bigint "pageable_id", null: false + t.string "type", null: false + t.string "slug" + t.string "name", null: false + t.string "meta_title" + t.string "meta_description" + t.string "meta_keywords" + t.bigint "parent_id" + t.text "preferences" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "deleted_at", precision: nil + t.index ["pageable_id", "name"], name: "index_spree_pages_on_pageable_id_and_name" + t.index ["pageable_id", "pageable_type", "type"], name: "index_spree_pages_on_pageable_id_and_pageable_type_and_type" + t.index ["pageable_id", "pageable_type"], name: "index_spree_pages_on_pageable_id_and_pageable_type" + t.index ["pageable_type", "pageable_id"], name: "index_spree_pages_on_pageable" + t.index ["parent_id"], name: "index_spree_pages_on_parent_id" + end + + create_table "spree_payment_capture_events", force: :cascade do |t| + t.decimal "amount", precision: 10, scale: 2, default: "0.0" + t.bigint "payment_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["payment_id"], name: "index_spree_payment_capture_events_on_payment_id" + end + + create_table "spree_payment_methods", force: :cascade do |t| + t.string "type" + t.string "name" + t.text "description" + t.boolean "active", default: true + t.datetime "deleted_at", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "display_on", default: "both" + t.boolean "auto_capture" + t.text "preferences" + t.integer "position", default: 0 + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.jsonb "settings" + t.index ["id", "type"], name: "index_spree_payment_methods_on_id_and_type" + end + + create_table "spree_payment_methods_stores", id: false, force: :cascade do |t| + t.bigint "payment_method_id" + t.bigint "store_id" + t.index ["payment_method_id", "store_id"], name: "payment_mentod_id_store_id_unique_index", unique: true + t.index ["payment_method_id"], name: "index_spree_payment_methods_stores_on_payment_method_id" + t.index ["store_id"], name: "index_spree_payment_methods_stores_on_store_id" + end + + create_table "spree_payment_sources", force: :cascade do |t| + t.string "gateway_payment_profile_id" + t.string "type" + t.bigint "payment_method_id" + t.bigint "user_id" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.string "gateway_customer_profile_id" + t.index ["payment_method_id"], name: "index_spree_payment_sources_on_payment_method_id" + t.index ["type", "gateway_payment_profile_id"], name: "index_payment_sources_on_type_and_gateway_payment_profile_id", unique: true + t.index ["type"], name: "index_spree_payment_sources_on_type" + t.index ["user_id"], name: "index_spree_payment_sources_on_user_id" + end + + create_table "spree_payments", force: :cascade do |t| + t.decimal "amount", precision: 10, scale: 2, default: "0.0", null: false + t.bigint "order_id" + t.string "source_type" + t.bigint "source_id" + t.bigint "payment_method_id" + t.string "state" + t.string "response_code" + t.string "avs_response" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "number" + t.string "cvv_response_code" + t.string "cvv_response_message" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["number"], name: "index_spree_payments_on_number", unique: true + t.index ["order_id"], name: "index_spree_payments_on_order_id" + t.index ["payment_method_id"], name: "index_spree_payments_on_payment_method_id" + t.index ["source_id", "source_type"], name: "index_spree_payments_on_source_id_and_source_type" + end + + create_table "spree_paypal_checkout_orders", force: :cascade do |t| + t.bigint "order_id", null: false + t.bigint "payment_method_id", null: false + t.string "paypal_id", null: false + t.decimal "amount", precision: 10, scale: 2, null: false + t.jsonb "data" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["order_id", "paypal_id"], name: "index_spree_paypal_checkout_orders_on_order_id_and_paypal_id", unique: true + t.index ["order_id"], name: "index_spree_paypal_checkout_orders_on_order_id" + t.index ["payment_method_id"], name: "index_spree_paypal_checkout_orders_on_payment_method_id" + end + + create_table "spree_post_categories", force: :cascade do |t| + t.bigint "store_id", null: false + t.string "title", null: false + t.string "slug", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["slug", "store_id"], name: "index_spree_post_categories_on_slug_and_store_id", unique: true + t.index ["store_id"], name: "index_spree_post_categories_on_store_id" + end + + create_table "spree_posts", force: :cascade do |t| + t.bigint "author_id" + t.datetime "published_at", precision: nil + t.string "title", null: false + t.string "slug", null: false + t.bigint "post_category_id" + t.bigint "store_id" + t.string "meta_title" + t.string "meta_description" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "deleted_at", precision: nil + t.index ["author_id"], name: "index_spree_posts_on_author_id" + t.index ["post_category_id"], name: "index_spree_posts_on_post_category_id" + t.index ["store_id"], name: "index_spree_posts_on_store_id" + t.index ["title"], name: "index_spree_posts_on_title" + end + + create_table "spree_preferences", force: :cascade do |t| + t.text "value" + t.string "key" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["key"], name: "index_spree_preferences_on_key", unique: true + end + + create_table "spree_prices", force: :cascade do |t| + t.bigint "variant_id", null: false + t.decimal "amount", precision: 10, scale: 2 + t.string "currency" + t.datetime "deleted_at", precision: nil + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.decimal "compare_at_amount", precision: 10, scale: 2 + t.index ["deleted_at"], name: "index_spree_prices_on_deleted_at" + t.index ["variant_id", "currency"], name: "index_spree_prices_on_variant_id_and_currency" + t.index ["variant_id"], name: "index_spree_prices_on_variant_id" + end + + create_table "spree_product_option_types", force: :cascade do |t| + t.integer "position" + t.bigint "product_id" + t.bigint "option_type_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["option_type_id"], name: "index_spree_product_option_types_on_option_type_id" + t.index ["position"], name: "index_spree_product_option_types_on_position" + t.index ["product_id"], name: "index_spree_product_option_types_on_product_id" + end + + create_table "spree_product_promotion_rules", force: :cascade do |t| + t.bigint "product_id" + t.bigint "promotion_rule_id" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["product_id", "promotion_rule_id"], name: "idx_on_product_id_promotion_rule_id_aaea0385c9", unique: true + t.index ["product_id"], name: "index_products_promotion_rules_on_product_id" + t.index ["promotion_rule_id", "product_id"], name: "index_products_promotion_rules_on_promotion_rule_and_product" + end + + create_table "spree_product_properties", force: :cascade do |t| + t.string "value" + t.bigint "product_id" + t.bigint "property_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "position", default: 0 + t.boolean "show_property", default: true + t.string "filter_param" + t.index ["filter_param"], name: "index_spree_product_properties_on_filter_param" + t.index ["position"], name: "index_spree_product_properties_on_position" + t.index ["product_id"], name: "index_product_properties_on_product_id" + t.index ["property_id", "product_id"], name: "index_spree_product_properties_on_property_id_and_product_id", unique: true + t.index ["property_id"], name: "index_spree_product_properties_on_property_id" + end + + create_table "spree_product_property_translations", force: :cascade do |t| + t.string "value" + t.string "locale", null: false + t.bigint "spree_product_property_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["locale"], name: "index_spree_product_property_translations_on_locale" + t.index ["spree_product_property_id", "locale"], name: "unique_product_property_id_per_locale", unique: true + end + + create_table "spree_product_translations", force: :cascade do |t| + t.string "name" + t.text "description" + t.string "locale", null: false + t.bigint "spree_product_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "meta_description" + t.string "meta_keywords" + t.string "meta_title" + t.string "slug" + t.datetime "deleted_at", precision: nil + t.index ["deleted_at"], name: "index_spree_product_translations_on_deleted_at" + t.index ["locale", "slug"], name: "unique_slug_per_locale", unique: true + t.index ["locale"], name: "index_spree_product_translations_on_locale" + t.index ["spree_product_id", "locale"], name: "unique_product_id_per_locale", unique: true + end + + create_table "spree_products", force: :cascade do |t| + t.string "name", default: "", null: false + t.text "description" + t.datetime "available_on", precision: nil + t.datetime "deleted_at", precision: nil + t.string "slug" + t.text "meta_description" + t.string "meta_keywords" + t.bigint "tax_category_id" + t.bigint "shipping_category_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "promotionable", default: true + t.string "meta_title" + t.datetime "discontinue_on", precision: nil + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.string "status", default: "draft", null: false + t.datetime "make_active_at", precision: nil + t.index ["available_on"], name: "index_spree_products_on_available_on" + t.index ["deleted_at"], name: "index_spree_products_on_deleted_at" + t.index ["discontinue_on"], name: "index_spree_products_on_discontinue_on" + t.index ["make_active_at"], name: "index_spree_products_on_make_active_at" + t.index ["name"], name: "index_spree_products_on_name" + t.index ["shipping_category_id"], name: "index_spree_products_on_shipping_category_id" + t.index ["slug"], name: "index_spree_products_on_slug", unique: true + t.index ["status", "deleted_at"], name: "index_spree_products_on_status_and_deleted_at" + t.index ["status"], name: "index_spree_products_on_status" + t.index ["tax_category_id"], name: "index_spree_products_on_tax_category_id" + end + + create_table "spree_products_stores", force: :cascade do |t| + t.bigint "product_id" + t.bigint "store_id" + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["product_id", "store_id"], name: "index_spree_products_stores_on_product_id_and_store_id", unique: true + t.index ["product_id"], name: "index_spree_products_stores_on_product_id" + t.index ["store_id"], name: "index_spree_products_stores_on_store_id" + end + + create_table "spree_products_taxons", force: :cascade do |t| + t.bigint "product_id" + t.bigint "taxon_id" + t.integer "position" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["position"], name: "index_spree_products_taxons_on_position" + t.index ["product_id", "taxon_id"], name: "index_spree_products_taxons_on_product_id_and_taxon_id", unique: true + t.index ["product_id"], name: "index_spree_products_taxons_on_product_id" + t.index ["taxon_id"], name: "index_spree_products_taxons_on_taxon_id" + end + + create_table "spree_promotion_action_line_items", force: :cascade do |t| + t.bigint "promotion_action_id" + t.bigint "variant_id" + t.integer "quantity", default: 1 + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["promotion_action_id", "variant_id"], name: "idx_on_promotion_action_id_variant_id_90d181a88a", unique: true + t.index ["promotion_action_id"], name: "index_spree_promotion_action_line_items_on_promotion_action_id" + t.index ["variant_id"], name: "index_spree_promotion_action_line_items_on_variant_id" + end + + create_table "spree_promotion_actions", force: :cascade do |t| + t.bigint "promotion_id" + t.integer "position" + t.string "type" + t.datetime "deleted_at", precision: nil + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["deleted_at"], name: "index_spree_promotion_actions_on_deleted_at" + t.index ["id", "type"], name: "index_spree_promotion_actions_on_id_and_type" + t.index ["promotion_id"], name: "index_spree_promotion_actions_on_promotion_id" + end + + create_table "spree_promotion_categories", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "code" + end + + create_table "spree_promotion_rule_taxons", force: :cascade do |t| + t.bigint "taxon_id" + t.bigint "promotion_rule_id" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["promotion_rule_id"], name: "index_spree_promotion_rule_taxons_on_promotion_rule_id" + t.index ["taxon_id", "promotion_rule_id"], name: "idx_on_taxon_id_promotion_rule_id_3c91a6f5d7", unique: true + t.index ["taxon_id"], name: "index_spree_promotion_rule_taxons_on_taxon_id" + end + + create_table "spree_promotion_rule_users", force: :cascade do |t| + t.bigint "user_id" + t.bigint "promotion_rule_id" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["promotion_rule_id"], name: "index_promotion_rules_users_on_promotion_rule_id" + t.index ["user_id", "promotion_rule_id"], name: "idx_on_user_id_promotion_rule_id_ad0307a89b", unique: true + t.index ["user_id", "promotion_rule_id"], name: "index_promotion_rules_users_on_user_id_and_promotion_rule_id" + end + + create_table "spree_promotion_rules", force: :cascade do |t| + t.bigint "promotion_id" + t.bigint "user_id" + t.bigint "product_group_id" + t.string "type" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "code" + t.text "preferences" + t.index ["product_group_id"], name: "index_promotion_rules_on_product_group_id" + t.index ["promotion_id"], name: "index_spree_promotion_rules_on_promotion_id" + t.index ["user_id"], name: "index_promotion_rules_on_user_id" + end + + create_table "spree_promotions", force: :cascade do |t| + t.string "description" + t.datetime "expires_at", precision: nil + t.datetime "starts_at", precision: nil + t.string "name" + t.string "type" + t.integer "usage_limit" + t.string "match_policy", default: "all" + t.string "code" + t.boolean "advertise", default: false + t.string "path" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "promotion_category_id" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.string "code_prefix" + t.integer "number_of_codes" + t.integer "kind", default: 0 + t.boolean "multi_codes", default: false + t.index ["advertise"], name: "index_spree_promotions_on_advertise" + t.index ["code"], name: "index_spree_promotions_on_code" + t.index ["expires_at"], name: "index_spree_promotions_on_expires_at" + t.index ["id", "type"], name: "index_spree_promotions_on_id_and_type" + t.index ["kind"], name: "index_spree_promotions_on_kind" + t.index ["path"], name: "index_spree_promotions_on_path" + t.index ["promotion_category_id"], name: "index_spree_promotions_on_promotion_category_id" + t.index ["starts_at"], name: "index_spree_promotions_on_starts_at" + end + + create_table "spree_promotions_stores", force: :cascade do |t| + t.bigint "promotion_id" + t.bigint "store_id" + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["promotion_id", "store_id"], name: "index_spree_promotions_stores_on_promotion_id_and_store_id", unique: true + t.index ["promotion_id"], name: "index_spree_promotions_stores_on_promotion_id" + t.index ["store_id"], name: "index_spree_promotions_stores_on_store_id" + end + + create_table "spree_properties", force: :cascade do |t| + t.string "name" + t.string "presentation", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "filterable", default: false, null: false + t.string "filter_param" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.string "display_on", default: "both" + t.integer "position", default: 0 + t.integer "kind", default: 0 + t.index ["filter_param"], name: "index_spree_properties_on_filter_param" + t.index ["filterable"], name: "index_spree_properties_on_filterable" + t.index ["name"], name: "index_spree_properties_on_name" + t.index ["position"], name: "index_spree_properties_on_position" + end + + create_table "spree_property_prototypes", force: :cascade do |t| + t.bigint "prototype_id" + t.bigint "property_id" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["property_id"], name: "index_spree_property_prototypes_on_property_id" + t.index ["prototype_id", "property_id"], name: "index_property_prototypes_on_prototype_id_and_property_id", unique: true + t.index ["prototype_id"], name: "index_spree_property_prototypes_on_prototype_id" + end + + create_table "spree_property_translations", force: :cascade do |t| + t.string "presentation" + t.string "locale", null: false + t.bigint "spree_property_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["locale"], name: "index_spree_property_translations_on_locale" + t.index ["spree_property_id", "locale"], name: "unique_property_id_per_locale", unique: true + end + + create_table "spree_prototype_taxons", force: :cascade do |t| + t.bigint "taxon_id" + t.bigint "prototype_id" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["prototype_id", "taxon_id"], name: "index_spree_prototype_taxons_on_prototype_id_and_taxon_id" + t.index ["prototype_id"], name: "index_spree_prototype_taxons_on_prototype_id" + t.index ["taxon_id"], name: "index_spree_prototype_taxons_on_taxon_id" + end + + create_table "spree_prototypes", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.jsonb "public_metadata" + t.jsonb "private_metadata" + end + + create_table "spree_refund_reasons", force: :cascade do |t| + t.string "name" + t.boolean "active", default: true + t.boolean "mutable", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_spree_refund_reasons_on_name", unique: true + end + + create_table "spree_refunds", force: :cascade do |t| + t.bigint "payment_id" + t.decimal "amount", precision: 10, scale: 2, default: "0.0", null: false + t.string "transaction_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "refund_reason_id" + t.bigint "reimbursement_id" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.bigint "refunder_id" + t.index ["payment_id"], name: "index_spree_refunds_on_payment_id" + t.index ["refund_reason_id"], name: "index_refunds_on_refund_reason_id" + t.index ["refunder_id"], name: "index_spree_refunds_on_refunder_id" + t.index ["reimbursement_id"], name: "index_spree_refunds_on_reimbursement_id" + end + + create_table "spree_reimbursement_credits", force: :cascade do |t| + t.decimal "amount", precision: 10, scale: 2, default: "0.0", null: false + t.bigint "reimbursement_id" + t.bigint "creditable_id" + t.string "creditable_type" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["creditable_id", "creditable_type"], name: "index_reimbursement_credits_on_creditable_id_and_type" + t.index ["reimbursement_id"], name: "index_spree_reimbursement_credits_on_reimbursement_id" + end + + create_table "spree_reimbursement_types", force: :cascade do |t| + t.string "name" + t.boolean "active", default: true + t.boolean "mutable", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "type" + t.index ["name"], name: "index_spree_reimbursement_types_on_name", unique: true + t.index ["type"], name: "index_spree_reimbursement_types_on_type" + end + + create_table "spree_reimbursements", force: :cascade do |t| + t.string "number" + t.string "reimbursement_status" + t.bigint "customer_return_id" + t.bigint "order_id" + t.decimal "total", precision: 10, scale: 2 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "performed_by_id" + t.index ["customer_return_id"], name: "index_spree_reimbursements_on_customer_return_id" + t.index ["number"], name: "index_spree_reimbursements_on_number", unique: true + t.index ["order_id"], name: "index_spree_reimbursements_on_order_id" + end + + create_table "spree_reports", force: :cascade do |t| + t.bigint "store_id", null: false + t.bigint "user_id" + t.string "type" + t.string "currency" + t.datetime "date_from", precision: nil + t.datetime "date_to", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["store_id"], name: "index_spree_reports_on_store_id" + t.index ["user_id"], name: "index_spree_reports_on_user_id" + end + + create_table "spree_return_authorization_reasons", force: :cascade do |t| + t.string "name" + t.boolean "active", default: true + t.boolean "mutable", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_spree_return_authorization_reasons_on_name", unique: true + end + + create_table "spree_return_authorizations", force: :cascade do |t| + t.string "number" + t.string "state" + t.bigint "order_id" + t.text "memo" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.bigint "stock_location_id" + t.bigint "return_authorization_reason_id" + t.index ["number"], name: "index_spree_return_authorizations_on_number", unique: true + t.index ["order_id"], name: "index_spree_return_authorizations_on_order_id" + t.index ["return_authorization_reason_id"], name: "index_return_authorizations_on_return_authorization_reason_id" + t.index ["stock_location_id"], name: "index_spree_return_authorizations_on_stock_location_id" + end + + create_table "spree_return_items", force: :cascade do |t| + t.bigint "return_authorization_id" + t.bigint "inventory_unit_id" + t.bigint "exchange_variant_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.decimal "pre_tax_amount", precision: 12, scale: 4, default: "0.0", null: false + t.decimal "included_tax_total", precision: 12, scale: 4, default: "0.0", null: false + t.decimal "additional_tax_total", precision: 12, scale: 4, default: "0.0", null: false + t.string "reception_status" + t.string "acceptance_status" + t.bigint "customer_return_id" + t.bigint "reimbursement_id" + t.text "acceptance_status_errors" + t.bigint "preferred_reimbursement_type_id" + t.bigint "override_reimbursement_type_id" + t.boolean "resellable", default: true, null: false + t.index ["customer_return_id"], name: "index_return_items_on_customer_return_id" + t.index ["exchange_variant_id"], name: "index_spree_return_items_on_exchange_variant_id" + t.index ["inventory_unit_id"], name: "index_spree_return_items_on_inventory_unit_id" + t.index ["override_reimbursement_type_id"], name: "index_spree_return_items_on_override_reimbursement_type_id" + t.index ["preferred_reimbursement_type_id"], name: "index_spree_return_items_on_preferred_reimbursement_type_id" + t.index ["reimbursement_id"], name: "index_spree_return_items_on_reimbursement_id" + t.index ["return_authorization_id"], name: "index_spree_return_items_on_return_authorization_id" + end + + create_table "spree_role_users", force: :cascade do |t| + t.bigint "role_id" + t.bigint "user_id" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.string "user_type", null: false + t.string "resource_type" + t.bigint "resource_id" + t.bigint "invitation_id" + t.index ["invitation_id"], name: "index_spree_role_users_on_invitation_id" + t.index ["resource_id", "resource_type", "user_id", "user_type", "role_id"], name: "idx_on_resource_id_resource_type_user_id_user_type__5600304ec6", unique: true + t.index ["resource_type", "resource_id"], name: "index_spree_role_users_on_resource" + t.index ["role_id"], name: "index_spree_role_users_on_role_id" + t.index ["user_id"], name: "index_spree_role_users_on_user_id" + t.index ["user_type"], name: "index_spree_role_users_on_user_type" + end + + create_table "spree_roles", force: :cascade do |t| + t.string "name" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["name"], name: "index_spree_roles_on_name", unique: true + end + + create_table "spree_shipments", force: :cascade do |t| + t.string "tracking" + t.string "number" + t.decimal "cost", precision: 10, scale: 2, default: "0.0" + t.datetime "shipped_at", precision: nil + t.bigint "order_id" + t.bigint "address_id" + t.string "state" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "stock_location_id" + t.decimal "adjustment_total", precision: 10, scale: 2, default: "0.0" + t.decimal "additional_tax_total", precision: 10, scale: 2, default: "0.0" + t.decimal "promo_total", precision: 10, scale: 2, default: "0.0" + t.decimal "included_tax_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "pre_tax_amount", precision: 12, scale: 4, default: "0.0", null: false + t.decimal "taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.decimal "non_taxable_adjustment_total", precision: 10, scale: 2, default: "0.0", null: false + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["address_id"], name: "index_spree_shipments_on_address_id" + t.index ["number"], name: "index_spree_shipments_on_number", unique: true + t.index ["order_id"], name: "index_spree_shipments_on_order_id" + t.index ["stock_location_id"], name: "index_spree_shipments_on_stock_location_id" + end + + create_table "spree_shipping_categories", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_spree_shipping_categories_on_name" + end + + create_table "spree_shipping_method_categories", force: :cascade do |t| + t.bigint "shipping_method_id", null: false + t.bigint "shipping_category_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["shipping_category_id", "shipping_method_id"], name: "unique_spree_shipping_method_categories", unique: true + t.index ["shipping_category_id"], name: "index_spree_shipping_method_categories_on_shipping_category_id" + t.index ["shipping_method_id"], name: "index_spree_shipping_method_categories_on_shipping_method_id" + end + + create_table "spree_shipping_method_zones", force: :cascade do |t| + t.bigint "shipping_method_id" + t.bigint "zone_id" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil + t.index ["shipping_method_id"], name: "index_spree_shipping_method_zones_on_shipping_method_id" + t.index ["zone_id"], name: "index_spree_shipping_method_zones_on_zone_id" + end + + create_table "spree_shipping_methods", force: :cascade do |t| + t.string "name" + t.string "display_on" + t.datetime "deleted_at", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "tracking_url" + t.string "admin_name" + t.bigint "tax_category_id" + t.string "code" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.integer "estimated_transit_business_days_min" + t.integer "estimated_transit_business_days_max" + t.index ["deleted_at"], name: "index_spree_shipping_methods_on_deleted_at" + t.index ["tax_category_id"], name: "index_spree_shipping_methods_on_tax_category_id" + end + + create_table "spree_shipping_rates", force: :cascade do |t| + t.bigint "shipment_id" + t.bigint "shipping_method_id" + t.boolean "selected", default: false + t.decimal "cost", precision: 8, scale: 2, default: "0.0" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "tax_rate_id" + t.index ["selected"], name: "index_spree_shipping_rates_on_selected" + t.index ["shipment_id", "shipping_method_id"], name: "spree_shipping_rates_join_index", unique: true + t.index ["shipment_id"], name: "index_spree_shipping_rates_on_shipment_id" + t.index ["shipping_method_id"], name: "index_spree_shipping_rates_on_shipping_method_id" + t.index ["tax_rate_id"], name: "index_spree_shipping_rates_on_tax_rate_id" + end + + create_table "spree_state_changes", force: :cascade do |t| + t.string "name" + t.string "previous_state" + t.bigint "stateful_id" + t.bigint "user_id" + t.string "stateful_type" + t.string "next_state" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["stateful_id", "stateful_type"], name: "index_spree_state_changes_on_stateful_id_and_stateful_type" + end + + create_table "spree_states", force: :cascade do |t| + t.string "name" + t.string "abbr" + t.bigint "country_id" + t.datetime "updated_at", precision: nil + t.datetime "created_at", precision: nil + t.index ["country_id"], name: "index_spree_states_on_country_id" + end + + create_table "spree_stock_items", force: :cascade do |t| + t.bigint "stock_location_id" + t.bigint "variant_id" + t.integer "count_on_hand", default: 0, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "backorderable", default: false + t.datetime "deleted_at", precision: nil + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["backorderable"], name: "index_spree_stock_items_on_backorderable" + t.index ["deleted_at"], name: "index_spree_stock_items_on_deleted_at" + t.index ["stock_location_id", "variant_id", "deleted_at"], name: "stock_item_by_loc_var_id_deleted_at", unique: true + t.index ["stock_location_id", "variant_id"], name: "stock_item_by_loc_and_var_id" + t.index ["stock_location_id"], name: "index_spree_stock_items_on_stock_location_id" + t.index ["variant_id", "stock_location_id"], name: "index_spree_stock_items_unique_without_deleted_at", unique: true, where: "(deleted_at IS NULL)" + t.index ["variant_id"], name: "index_spree_stock_items_on_variant_id" + end + + create_table "spree_stock_locations", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "default", default: false, null: false + t.string "address1" + t.string "address2" + t.string "city" + t.bigint "state_id" + t.string "state_name" + t.bigint "country_id" + t.string "zipcode" + t.string "phone" + t.boolean "active", default: true + t.boolean "backorderable_default", default: false + t.boolean "propagate_all_variants", default: false + t.string "admin_name" + t.datetime "deleted_at", precision: nil + t.string "company" + t.index ["active"], name: "index_spree_stock_locations_on_active" + t.index ["backorderable_default"], name: "index_spree_stock_locations_on_backorderable_default" + t.index ["country_id"], name: "index_spree_stock_locations_on_country_id" + t.index ["deleted_at"], name: "index_spree_stock_locations_on_deleted_at" + t.index ["propagate_all_variants"], name: "index_spree_stock_locations_on_propagate_all_variants" + t.index ["state_id"], name: "index_spree_stock_locations_on_state_id" + end + + create_table "spree_stock_movements", force: :cascade do |t| + t.bigint "stock_item_id" + t.integer "quantity", default: 0 + t.string "action" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "originator_type" + t.bigint "originator_id" + t.index ["originator_id", "originator_type"], name: "index_stock_movements_on_originator_id_and_originator_type" + t.index ["stock_item_id"], name: "index_spree_stock_movements_on_stock_item_id" + end + + create_table "spree_stock_transfers", force: :cascade do |t| + t.string "type" + t.string "reference" + t.bigint "source_location_id" + t.bigint "destination_location_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "number" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["destination_location_id"], name: "index_spree_stock_transfers_on_destination_location_id" + t.index ["number"], name: "index_spree_stock_transfers_on_number", unique: true + t.index ["source_location_id"], name: "index_spree_stock_transfers_on_source_location_id" + end + + create_table "spree_store_credit_categories", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "spree_store_credit_events", force: :cascade do |t| + t.bigint "store_credit_id", null: false + t.string "action", null: false + t.decimal "amount", precision: 8, scale: 2 + t.string "authorization_code", null: false + t.decimal "user_total_amount", precision: 8, scale: 2, default: "0.0", null: false + t.bigint "originator_id" + t.string "originator_type" + t.datetime "deleted_at", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["originator_id", "originator_type"], name: "spree_store_credit_events_originator" + t.index ["store_credit_id"], name: "index_spree_store_credit_events_on_store_credit_id" + end + + create_table "spree_store_credit_types", force: :cascade do |t| + t.string "name" + t.integer "priority" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["priority"], name: "index_spree_store_credit_types_on_priority" + end + + create_table "spree_store_credits", force: :cascade do |t| + t.bigint "user_id" + t.bigint "category_id" + t.bigint "created_by_id" + t.decimal "amount", precision: 8, scale: 2, default: "0.0", null: false + t.decimal "amount_used", precision: 8, scale: 2, default: "0.0", null: false + t.text "memo" + t.datetime "deleted_at", precision: nil + t.string "currency" + t.decimal "amount_authorized", precision: 8, scale: 2, default: "0.0", null: false + t.bigint "originator_id" + t.string "originator_type" + t.bigint "type_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "store_id" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["deleted_at"], name: "index_spree_store_credits_on_deleted_at" + t.index ["originator_id", "originator_type"], name: "spree_store_credits_originator" + t.index ["store_id"], name: "index_spree_store_credits_on_store_id" + t.index ["type_id"], name: "index_spree_store_credits_on_type_id" + t.index ["user_id"], name: "index_spree_store_credits_on_user_id" + end + + create_table "spree_store_translations", force: :cascade do |t| + t.string "name" + t.text "meta_description" + t.text "meta_keywords" + t.string "seo_title" + t.string "facebook" + t.string "twitter" + t.string "instagram" + t.string "customer_support_email" + t.text "description" + t.text "address" + t.string "contact_phone" + t.string "new_order_notifications_email" + t.string "locale", null: false + t.bigint "spree_store_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "deleted_at", precision: nil + t.index ["deleted_at"], name: "index_spree_store_translations_on_deleted_at" + t.index ["locale"], name: "index_spree_store_translations_on_locale" + t.index ["spree_store_id", "locale"], name: "index_spree_store_translations_on_spree_store_id_locale", unique: true + end + + create_table "spree_stores", force: :cascade do |t| + t.string "name" + t.string "url" + t.text "meta_description" + t.text "meta_keywords" + t.string "seo_title" + t.string "mail_from_address" + t.string "default_currency" + t.string "code" + t.boolean "default", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "supported_currencies" + t.string "facebook" + t.string "twitter" + t.string "instagram" + t.string "default_locale" + t.string "customer_support_email" + t.bigint "default_country_id" + t.text "description" + t.text "address" + t.string "contact_phone" + t.string "new_order_notifications_email" + t.bigint "checkout_zone_id" + t.string "seo_robots" + t.string "supported_locales" + t.datetime "deleted_at", precision: nil + t.jsonb "settings" + t.text "preferences" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.text "storefront_custom_code_head" + t.text "storefront_custom_code_body_start" + t.text "storefront_custom_code_body_end" + t.index ["code"], name: "index_spree_stores_on_code", unique: true + t.index ["default"], name: "index_spree_stores_on_default" + t.index ["deleted_at"], name: "index_spree_stores_on_deleted_at" + t.index ["url"], name: "index_spree_stores_on_url" + end + + create_table "spree_stripe_payment_intents", force: :cascade do |t| + t.decimal "amount", precision: 10, scale: 2, default: "0.0", null: false + t.bigint "order_id", null: false + t.bigint "payment_method_id", null: false + t.string "stripe_id", null: false + t.string "client_secret", null: false + t.string "customer_id" + t.string "ephemeral_key_secret" + t.string "stripe_payment_method_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["order_id", "stripe_id"], name: "index_spree_stripe_payment_intents_on_order_id_and_stripe_id", unique: true + t.index ["order_id"], name: "index_spree_stripe_payment_intents_on_order_id" + t.index ["payment_method_id"], name: "index_spree_stripe_payment_intents_on_payment_method_id" + end + + create_table "spree_stripe_payment_methods_webhook_keys", force: :cascade do |t| + t.bigint "payment_method_id", null: false + t.bigint "webhook_key_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["payment_method_id", "webhook_key_id"], name: "index_payment_method_id_webhook_key_id_uniqueness", unique: true + t.index ["payment_method_id"], name: "index_payment_methods_webhook_keys_on_payment_method_id" + t.index ["webhook_key_id"], name: "index_payment_methods_webhook_keys_on_webhook_key_id" + end + + create_table "spree_stripe_webhook_keys", force: :cascade do |t| + t.string "stripe_id", null: false + t.string "signing_secret", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["signing_secret"], name: "index_spree_stripe_webhook_keys_on_signing_secret", unique: true + t.index ["stripe_id"], name: "index_spree_stripe_webhook_keys_on_stripe_id", unique: true + end + + create_table "spree_taggings", force: :cascade do |t| + t.bigint "tag_id" + t.string "taggable_type" + t.bigint "taggable_id" + t.string "tagger_type" + t.bigint "tagger_id" + t.string "context", limit: 128 + t.datetime "created_at", precision: nil + t.string "tenant", limit: 128 + t.index ["context"], name: "index_spree_taggings_on_context" + t.index ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "spree_taggings_idx", unique: true + t.index ["tag_id"], name: "index_spree_taggings_on_tag_id" + t.index ["taggable_id", "taggable_type", "context"], name: "spree_taggings_taggable_context_idx" + t.index ["taggable_id", "taggable_type", "tagger_id", "context"], name: "spree_taggings_idy" + t.index ["taggable_id"], name: "index_spree_taggings_on_taggable_id" + t.index ["taggable_type", "taggable_id"], name: "index_spree_taggings_on_taggable_type_and_taggable_id" + t.index ["taggable_type"], name: "index_spree_taggings_on_taggable_type" + t.index ["tagger_id", "tagger_type"], name: "index_spree_taggings_on_tagger_id_and_tagger_type" + t.index ["tagger_id"], name: "index_spree_taggings_on_tagger_id" + t.index ["tagger_type", "tagger_id"], name: "index_spree_taggings_on_tagger_type_and_tagger_id" + t.index ["tenant"], name: "index_spree_taggings_on_tenant" + end + + create_table "spree_tags", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "taggings_count", default: 0 + t.index "lower((name)::text) varchar_pattern_ops", name: "index_spree_tags_on_lower_name" + t.index ["name"], name: "index_spree_tags_on_name", unique: true + end + + create_table "spree_tax_categories", force: :cascade do |t| + t.string "name" + t.string "description" + t.boolean "is_default", default: false + t.datetime "deleted_at", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "tax_code" + t.index ["deleted_at"], name: "index_spree_tax_categories_on_deleted_at" + t.index ["is_default"], name: "index_spree_tax_categories_on_is_default" + end + + create_table "spree_tax_rates", force: :cascade do |t| + t.decimal "amount", precision: 8, scale: 5 + t.bigint "zone_id" + t.bigint "tax_category_id" + t.boolean "included_in_price", default: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name" + t.boolean "show_rate_in_label", default: true + t.datetime "deleted_at", precision: nil + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["deleted_at"], name: "index_spree_tax_rates_on_deleted_at" + t.index ["included_in_price"], name: "index_spree_tax_rates_on_included_in_price" + t.index ["show_rate_in_label"], name: "index_spree_tax_rates_on_show_rate_in_label" + t.index ["tax_category_id"], name: "index_spree_tax_rates_on_tax_category_id" + t.index ["zone_id"], name: "index_spree_tax_rates_on_zone_id" + end + + create_table "spree_taxon_rules", force: :cascade do |t| + t.bigint "taxon_id", null: false + t.string "type", null: false + t.string "value", null: false + t.string "match_policy", default: "is_equal_to", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["taxon_id"], name: "index_spree_taxon_rules_on_taxon_id" + end + + create_table "spree_taxon_translations", force: :cascade do |t| + t.string "name" + t.text "description" + t.string "locale", null: false + t.bigint "spree_taxon_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "meta_title" + t.string "meta_description" + t.string "meta_keywords" + t.string "permalink" + t.string "pretty_name" + t.index ["locale"], name: "index_spree_taxon_translations_on_locale" + t.index ["pretty_name"], name: "index_spree_taxon_translations_on_pretty_name" + t.index ["spree_taxon_id", "locale"], name: "index_spree_taxon_translations_on_spree_taxon_id_and_locale", unique: true + end + + create_table "spree_taxonomies", force: :cascade do |t| + t.string "name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "position", default: 0 + t.bigint "store_id" + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.index ["name", "store_id"], name: "index_spree_taxonomies_on_name_and_store_id", unique: true + t.index ["position"], name: "index_spree_taxonomies_on_position" + t.index ["store_id"], name: "index_spree_taxonomies_on_store_id" + end + + create_table "spree_taxonomy_translations", force: :cascade do |t| + t.string "name" + t.string "locale", null: false + t.bigint "spree_taxonomy_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["locale"], name: "index_spree_taxonomy_translations_on_locale" + t.index ["spree_taxonomy_id", "locale"], name: "index_spree_taxonomy_translations_on_spree_taxonomy_id_locale", unique: true + end + + create_table "spree_taxons", force: :cascade do |t| + t.bigint "parent_id" + t.integer "position", default: 0 + t.string "name", null: false + t.string "permalink" + t.bigint "taxonomy_id" + t.bigint "lft" + t.bigint "rgt" + t.text "description" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "meta_title" + t.string "meta_description" + t.string "meta_keywords" + t.integer "depth" + t.boolean "hide_from_nav", default: false + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.string "pretty_name" + t.string "rules_match_policy", default: "all", null: false + t.string "sort_order", default: "manual", null: false + t.boolean "automatic", default: false, null: false + t.index ["lft"], name: "index_spree_taxons_on_lft" + t.index ["name", "parent_id", "taxonomy_id"], name: "index_spree_taxons_on_name_and_parent_id_and_taxonomy_id", unique: true + t.index ["name"], name: "index_spree_taxons_on_name" + t.index ["parent_id"], name: "index_taxons_on_parent_id" + t.index ["permalink", "parent_id", "taxonomy_id"], name: "index_spree_taxons_on_permalink_and_parent_id_and_taxonomy_id", unique: true + t.index ["permalink"], name: "index_taxons_on_permalink" + t.index ["position"], name: "index_spree_taxons_on_position" + t.index ["pretty_name"], name: "index_spree_taxons_on_pretty_name" + t.index ["rgt"], name: "index_spree_taxons_on_rgt" + t.index ["taxonomy_id"], name: "index_taxons_on_taxonomy_id" + end + + create_table "spree_themes", force: :cascade do |t| + t.string "name" + t.bigint "store_id", null: false + t.boolean "default", default: false, null: false + t.boolean "ready", default: true + t.string "type", default: "Spree::Themes::Default", null: false + t.bigint "parent_id" + t.text "preferences" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "deleted_at", precision: nil + t.index ["deleted_at"], name: "index_spree_themes_on_deleted_at" + t.index ["parent_id"], name: "index_spree_themes_on_parent_id" + t.index ["store_id"], name: "index_spree_themes_on_store_id" + end + + create_table "spree_trackers", force: :cascade do |t| + t.string "analytics_id" + t.boolean "active", default: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "engine", default: 0, null: false + t.index ["active"], name: "index_spree_trackers_on_active" + end + + create_table "spree_users", force: :cascade do |t| + t.string "encrypted_password", limit: 128 + t.string "password_salt", limit: 128 + t.string "email" + t.string "remember_token" + t.string "persistence_token" + t.string "reset_password_token" + t.string "perishable_token" + t.integer "sign_in_count", default: 0, null: false + t.integer "failed_attempts", default: 0, null: false + t.datetime "last_request_at", precision: nil + t.datetime "current_sign_in_at", precision: nil + t.datetime "last_sign_in_at", precision: nil + t.string "current_sign_in_ip" + t.string "last_sign_in_ip" + t.string "login" + t.bigint "ship_address_id" + t.bigint "bill_address_id" + t.string "authentication_token" + t.string "unlock_token" + t.datetime "locked_at", precision: nil + t.datetime "remember_created_at", precision: nil + t.datetime "reset_password_sent_at", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.string "first_name" + t.string "last_name" + t.string "selected_locale" + t.string "phone" + t.boolean "accepts_email_marketing", default: false, null: false + t.string "spree_api_key", limit: 48 + t.index ["accepts_email_marketing"], name: "index_spree_users_on_accepts_email_marketing" + t.index ["bill_address_id"], name: "index_spree_users_on_bill_address_id" + t.index ["ship_address_id"], name: "index_spree_users_on_ship_address_id" + t.index ["spree_api_key"], name: "index_spree_users_on_spree_api_key" + end + + create_table "spree_variants", force: :cascade do |t| + t.string "sku", default: "", null: false + t.decimal "weight", precision: 8, scale: 2, default: "0.0" + t.decimal "height", precision: 8, scale: 2 + t.decimal "width", precision: 8, scale: 2 + t.decimal "depth", precision: 8, scale: 2 + t.datetime "deleted_at", precision: nil + t.boolean "is_master", default: false + t.bigint "product_id" + t.decimal "cost_price", precision: 10, scale: 2 + t.integer "position" + t.string "cost_currency" + t.boolean "track_inventory", default: true + t.bigint "tax_category_id" + t.datetime "updated_at", precision: nil, null: false + t.datetime "discontinue_on", precision: nil + t.datetime "created_at", precision: nil, null: false + t.jsonb "public_metadata" + t.jsonb "private_metadata" + t.string "barcode" + t.string "weight_unit" + t.string "dimensions_unit" + t.index ["barcode"], name: "index_spree_variants_on_barcode" + t.index ["deleted_at"], name: "index_spree_variants_on_deleted_at" + t.index ["discontinue_on"], name: "index_spree_variants_on_discontinue_on" + t.index ["is_master"], name: "index_spree_variants_on_is_master" + t.index ["position"], name: "index_spree_variants_on_position" + t.index ["product_id"], name: "index_spree_variants_on_product_id" + t.index ["sku"], name: "index_spree_variants_on_sku" + t.index ["tax_category_id"], name: "index_spree_variants_on_tax_category_id" + t.index ["track_inventory"], name: "index_spree_variants_on_track_inventory" + end + + create_table "spree_webhooks_events", force: :cascade do |t| + t.integer "execution_time" + t.string "name", null: false + t.string "request_errors" + t.string "response_code" + t.bigint "subscriber_id", null: false + t.boolean "success" + t.string "url", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["response_code"], name: "index_spree_webhooks_events_on_response_code" + t.index ["subscriber_id"], name: "index_spree_webhooks_events_on_subscriber_id" + t.index ["success"], name: "index_spree_webhooks_events_on_success" + end + + create_table "spree_webhooks_subscribers", force: :cascade do |t| + t.string "url", null: false + t.boolean "active", default: false + t.jsonb "subscriptions" + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.string "secret_key", null: false + t.index ["active"], name: "index_spree_webhooks_subscribers_on_active" + end + + create_table "spree_wished_items", force: :cascade do |t| + t.bigint "variant_id" + t.bigint "wishlist_id" + t.integer "quantity", default: 1, null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["variant_id", "wishlist_id"], name: "index_spree_wished_items_on_variant_id_and_wishlist_id", unique: true + t.index ["variant_id"], name: "index_spree_wished_items_on_variant_id" + t.index ["wishlist_id"], name: "index_spree_wished_items_on_wishlist_id" + end + + create_table "spree_wishlists", force: :cascade do |t| + t.bigint "user_id" + t.bigint "store_id" + t.string "name" + t.string "token", null: false + t.boolean "is_private", default: true, null: false + t.boolean "is_default", default: false, null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.index ["store_id"], name: "index_spree_wishlists_on_store_id" + t.index ["token"], name: "index_spree_wishlists_on_token", unique: true + t.index ["user_id", "is_default"], name: "index_spree_wishlists_on_user_id_and_is_default" + t.index ["user_id"], name: "index_spree_wishlists_on_user_id" + end + + create_table "spree_zone_members", force: :cascade do |t| + t.string "zoneable_type" + t.bigint "zoneable_id" + t.bigint "zone_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["zone_id"], name: "index_spree_zone_members_on_zone_id" + t.index ["zoneable_id", "zoneable_type"], name: "index_spree_zone_members_on_zoneable_id_and_zoneable_type" + end + + create_table "spree_zones", force: :cascade do |t| + t.string "name" + t.string "description" + t.boolean "default_tax", default: false + t.integer "zone_members_count", default: 0 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "kind", default: "state" + t.index ["default_tax"], name: "index_spree_zones_on_default_tax" + t.index ["kind"], name: "index_spree_zones_on_kind" + end + + add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" + add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" + add_foreign_key "spree_oauth_access_grants", "spree_oauth_applications", column: "application_id" + add_foreign_key "spree_oauth_access_tokens", "spree_oauth_applications", column: "application_id" + add_foreign_key "spree_option_type_translations", "spree_option_types" + add_foreign_key "spree_option_value_translations", "spree_option_values" + add_foreign_key "spree_payment_sources", "spree_payment_methods", column: "payment_method_id" + add_foreign_key "spree_payment_sources", "spree_users", column: "user_id" + add_foreign_key "spree_product_property_translations", "spree_product_properties" + add_foreign_key "spree_product_translations", "spree_products" + add_foreign_key "spree_property_translations", "spree_properties" + add_foreign_key "spree_store_translations", "spree_stores" + add_foreign_key "spree_taxon_translations", "spree_taxons" + add_foreign_key "spree_taxonomy_translations", "spree_taxonomies" +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000..a741615 --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,11 @@ +# This file should ensure the existence of records required to run the application in every environment (production, +# development, test). The code here should be idempotent so that it can be executed at any point in every environment. +# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). +# +# Example: +# +# ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| +# MovieGenre.find_or_create_by!(name: genre_name) +# end + +Spree::Core::Engine.load_seed if defined?(Spree::Core) diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..0e635b0 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,20 @@ +services: + postgres: + image: postgres:16-alpine + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: password + volumes: + - 'postgres:/var/lib/postgresql/data' + ports: + - "5432:5432" + redis: + image: redis:7-alpine + ports: + - "6379:6379" + volumes: + - 'redis:/data' + +volumes: + postgres: + redis: \ No newline at end of file diff --git a/h -u origin main --force b/h -u origin main --force new file mode 100644 index 0000000..892a25e --- /dev/null +++ b/h -u origin main --force @@ -0,0 +1,11242 @@ +commit efcbe3495a86b1995a81f2a3c97d05907adbd5b4 (HEAD -> main) +Author: Damian Legawiec +Date: Wed Oct 22 16:46:45 2025 +0200 + + Ignore `ActiveStorage::FileNotFoundError` in Sentry + +commit 10d151f87563337cd18d3f8ba7e5adca8408f53e +Author: Damian Legawiec +Date: Wed Oct 22 13:45:24 2025 +0200 + + Fix: 1st time render deployment + +commit ee691c7f349ff8727d9e7f9dc8aaa7f6d9e7fa7a +Author: Mike Faber +Date: Fri Oct 17 16:47:56 2025 +0200 + + Update README.md + + link updates + +commit 2fd20b42fcd2f053319f8150ea0d48abed36b414 +Author: Damian Legawiec +Date: Mon Sep 29 15:16:18 2025 +0200 + + Bump Spree to 5.1.7 (#1278) + +commit 94df37b393466e3d350c13a97bff118fa0f57b0d +Author: Damian Legawiec +Date: Thu Sep 18 17:39:53 2025 +0200 + + Bump Spree to 5.1.6 (#1277) + +commit 54b6623439eec6fae9af6de3d79f0317c424798e +Author: Damian Legawiec +Date: Thu Aug 7 21:31:44 2025 +0200 + + Update 20250623212019_add_missing_fields_to_users.spree.rb + +commit c0fb65b5681811c7b39f4bfeda4dfe485879dc18 +Author: Damian Legawiec +Date: Thu Aug 7 20:28:23 2025 +0200 + + Fixed `AddMissingFieldsToUsers` migration + +commit 3a93028e8cb8219963ae649cec2f72a8b400f9f2 +Author: Damian Legawiec +Date: Wed Aug 6 16:49:36 2025 +0200 + + Remove selenium webdriver leftovers + +commit 67f6b6858459602ef45da16f4e48089f9d289bba +Author: Damian Legawiec +Date: Wed Aug 6 16:49:09 2025 +0200 + + Bump spree to 5.1.5 + +commit 79ef4165f59c1355a82073590cf9a601e4c95b9c +Author: Damian Legawiec +Date: Mon Aug 4 18:39:26 2025 +0200 + + Fix: drop selenium-webdriver dependency (#1267) + + This is handled by spree_dev_tools + +commit 15240085fd40bc3ed4c1d9000594fa01ceb6d100 +Author: Damian Legawiec +Date: Mon Aug 4 09:51:28 2025 +0200 + + Bump spree_paypal_checkout + +commit 75ba9cb1ab6a1429e865fc208bb9c0684263bf0f +Author: Damian Legawiec +Date: Fri Aug 1 12:19:43 2025 +0200 + + Use `spree_dev_tools` for standarized testing environment 🚀 + +commit da9542deb56333b4b20d82bb50ab690ba311938c +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jul 28 19:11:29 2025 +0200 + + Bump foreman from 0.88.1 to 0.90.0 (#1265) + + Bumps [foreman](https://github.com/ddollar/foreman) from 0.88.1 to 0.90.0. + - [Changelog](https://github.com/ddollar/foreman/blob/main/Changelog.md) + - [Commits](https://github.com/ddollar/foreman/compare/v0.88.1...v0.90.0) + + --- + updated-dependencies: + - dependency-name: foreman + dependency-version: 0.90.0 + dependency-type: direct:development + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 69109928b172020c540a94c5d1bcb08f505a0bc3 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jul 28 19:11:15 2025 +0200 + + Bump pg from 1.5.9 to 1.6.0 (#1263) + + Bumps [pg](https://github.com/ged/ruby-pg) from 1.5.9 to 1.6.0. + - [Changelog](https://github.com/ged/ruby-pg/blob/master/CHANGELOG.md) + - [Commits](https://github.com/ged/ruby-pg/compare/v1.5.9...v1.6.0) + + --- + updated-dependencies: + - dependency-name: pg + dependency-version: 1.6.0 + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 882542310726fb9e5405af53fa900890885fce7d +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jul 28 19:11:06 2025 +0200 + + Bump spree_klaviyo from 1.0.1 to 1.0.2 (#1264) + + Bumps [spree_klaviyo](https://github.com/spree/spree_klaviyo) from 1.0.1 to 1.0.2. + - [Release notes](https://github.com/spree/spree_klaviyo/releases) + - [Commits](https://github.com/spree/spree_klaviyo/compare/v1.0.1...v1.0.2) + + --- + updated-dependencies: + - dependency-name: spree_klaviyo + dependency-version: 1.0.2 + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 5040ee42465b16c5631eb9c0f3d4d8d5847d37d8 +Author: Damian Legawiec +Date: Fri Jul 25 19:23:38 2025 +0200 + + Bump spree stripe + +commit 147cedb3211f20e5d876853d6f7edde5c208328f +Author: Damian Legawiec +Date: Thu Jul 24 21:31:02 2025 +0200 + + Bump spree stripe + +commit 6964a69ea7ca81f5a2df5666c448fb8866d36625 +Author: Damian Legawiec +Date: Thu Jul 24 14:12:46 2025 +0200 + + Bump Spree to 5.1.4 + +commit 7f0a5979837f50dab75fc8ac44493c6e6f017029 +Author: Damian Legawiec +Date: Sun Jul 20 19:27:38 2025 +0200 + + Bump Spree to 5.1.3 + +commit 79f1b0d3b6b8326148f783ba2d7f285b6b55c049 +Author: Damian Legawiec +Date: Thu Jul 17 17:04:42 2025 +0200 + + Setup AdminUser class as a dedicated model for admin authentication (#1261) + + * Setup AdminUser class as a dedicated model for admin authentication + + * Update admin_user.rb + + * Update routes.rb + +commit f72ab26520e035b4befa34ebe408a0314678a607 +Author: Damian Legawiec +Date: Wed Jul 16 10:16:25 2025 +0200 + + Bump Spree Stripe to 1.2.6 + +commit fda0c0786499e18f01e99329a4d6aa58eacf38ea +Author: Damian Legawiec +Date: Mon Jul 14 15:09:49 2025 +0200 + + Bump Spree to 5.1.2 (#1260) + +commit 73e1a7b647750d64543e03bc9f2f31d082ff94ae +Author: Damian Legawiec +Date: Tue Jul 8 14:40:03 2025 +0200 + + Bump Spree to 5.1.1 (#1259) + +commit d2ce03275330c216e6936d80b4fdf18a2e310cdb +Author: Damian Legawiec +Date: Mon Jul 7 16:19:59 2025 +0200 + + Bump spree stripe + +commit 20e3a3219b9018a0b747ab9c3240105da0c0cb2c +Author: Damian Legawiec +Date: Thu Jul 3 16:50:01 2025 +0200 + + Bump Spree to 5.1.0 (#1258) + + * Bump Spree to 5.1.0 + + * Update Gemfile.lock + +commit df1ecabfa313ee36c7b8aadc5894474159ab5879 +Author: Damian Legawiec +Date: Wed Jul 2 18:15:41 2025 +0200 + + Update Spree to 5.1.0.rc1 (#1257) + +commit 19e9a2edae13cffde3938c2f7fb9bc49f6f79709 +Author: Damian Legawiec +Date: Mon Jun 23 23:21:05 2025 +0200 + + added missing migrations from spree + +commit 26ec11e4a2f6e16d1743cb91ac747b7b537ba8c5 +Author: Damian Legawiec +Date: Mon Jun 9 17:05:02 2025 +0200 + + Update config.yml + +commit 26135b6a33e4f35c51e436f14a96238f9d2bd372 +Author: Damian Legawiec +Date: Mon Jun 9 15:33:34 2025 +0200 + + Nicer rspec output in CI + +commit c21b74879db4a717a93e234629929c1e2261bd6b +Author: Damian Legawiec +Date: Thu Jun 5 12:28:51 2025 +0200 + + Bump spree and add paypal payment (#1248) + + * Bump spree and add paypal payment + + * Update Gemfile + + * fix + + * Update Gemfile.lock + +commit 2e2ba34561166b0512b08ee5a262df82f82fa147 +Author: Damian Legawiec +Date: Wed Jun 4 10:54:25 2025 +0200 + + Fallback to memory store cache if redis cache is not set (#1246) + + better than no caching at all! + +commit ce040b83077e6d42eedfb6c837a615a31c257aaa +Author: brozek <39567956+brozek95@users.noreply.github.com> +Date: Tue Jun 3 15:13:26 2025 +0200 + + Fix for storage config (#1245) + + * FIX storage.yml + + * DEL comments as its not confirmed its required + +commit 0dcd28f4901391c50ac9b922b816c12c607b740f +Author: Damian Legawiec +Date: Tue Jun 3 12:42:16 2025 +0200 + + Fixed https://github.com/spree/spree_starter/issues/1241 + + Revert to old style of `bin/dev` and use foreman + +commit 7af781d3a4b911da9306971f8bcfd6e64d69cf42 +Author: Damian Legawiec +Date: Fri May 30 15:59:52 2025 +0200 + + Added Klaviyo integration (#1242) + +commit 1daa4b6616d16342c6dd8b68064bac77b3d1d1ba +Author: Damian Legawiec +Date: Thu May 29 12:22:13 2025 +0200 + + Fix: run missing migrations from Spree + +commit 6460b30ce6016b5c1addcce5b32fe1fd03e42540 +Author: Damian Legawiec +Date: Thu May 29 12:21:01 2025 +0200 + + Update Spree to 5.1.0.beta3 (#1239) + +commit 85ffc3952afa6452159dee9d6f4ffd62ff846f76 +Author: Damian Legawiec +Date: Thu May 22 16:14:53 2025 +0200 + + Bump Rails to 8.0 🚀 (#1237) + + * Bump Rails to 8.0 🚀 + + * Use Spree 5.1.0.beta2 from RubyGems + +commit 5e72d6236cc107700a4c6e5977d446704263bc96 +Author: Damian Legawiec +Date: Tue May 20 15:56:22 2025 +0200 + + Add `spree_google_analytics` (#1236) + +commit 55c98e24e05fba7f401058b33f2da6a5ec6182c8 +Author: Damian Legawiec +Date: Tue May 20 14:38:08 2025 +0200 + + Bump Spree to 5.1.0 beta (#1235) + +commit 95ecbf31dcfd8242506b3c2cd47ed2ae93a09ba7 +Author: Damian Legawiec +Date: Tue May 20 12:44:11 2025 +0200 + + Update config.yml + +commit fcaadad7e32e9636e2089859b50fd74f2c27be36 +Author: Damian Legawiec +Date: Tue May 20 12:43:24 2025 +0200 + + Update config.yml + +commit 8704c143cf310bf97bb9f873c30d920a7a2bd7f2 +Author: Damian Legawiec +Date: Tue May 13 12:12:54 2025 +0200 + + Bump rails to `7.2.2.1` (#1229) + +commit e5c6703940c979904632ef711cb2258ce78cac3e +Author: Damian Legawiec +Date: Tue May 13 12:04:20 2025 +0200 + + Update dependencies + +commit 6539c00baa4a5737a896fcc7bbef8dc8c1c83670 +Author: Damian Legawiec +Date: Thu May 8 16:14:29 2025 +0200 + + Update 20250210131678_backfill_friendly_id_slug_locale.spree.rb + +commit 99c98cf5017ec6eb0b1e98cb89db968a71e1b6c4 +Author: Damian Legawiec +Date: Wed May 7 16:26:08 2025 +0200 + + Support Cloudflare R2 for Active Storage, `GOOGLE_PLACES_API_KEY` and `SCREENSHOT_API_TOKEN` ENVs (#1224) + +commit fbfacb8808070d8bf2c460b1118369a34612c292 +Author: Damian Legawiec +Date: Wed May 7 15:51:25 2025 +0200 + + Add standalone devise authentication controllers for storefront (#1223) + + * Add standalone devise authentication controllers for storefront + + To work in tandem with https://github.com/spree/spree/pull/12700 + + * Update config.yml + + * Update devise.rb + +commit cda69050850de1ad80a6693c499acff9d02fffc6 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Wed May 7 14:42:07 2025 +0200 + + Bump selenium-webdriver from 4.7.1 to 4.10.0 (#1203) + + Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.7.1 to 4.10.0. + - [Release notes](https://github.com/SeleniumHQ/selenium/releases) + - [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES) + - [Commits](https://github.com/SeleniumHQ/selenium/commits/selenium-4.10.0) + + --- + updated-dependencies: + - dependency-name: selenium-webdriver + dependency-version: 4.10.0 + dependency-type: direct:development + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 3834539e09c7802ae71af61c0f63c20be989a1e5 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Wed May 7 14:41:58 2025 +0200 + + Bump rspec-rails from 6.1.5 to 8.0.0 (#1218) + + Bumps [rspec-rails](https://github.com/rspec/rspec-rails) from 6.1.5 to 8.0.0. + - [Changelog](https://github.com/rspec/rspec-rails/blob/main/Changelog.md) + - [Commits](https://github.com/rspec/rspec-rails/compare/v6.1.5...v8.0.0) + + --- + updated-dependencies: + - dependency-name: rspec-rails + dependency-version: 8.0.0 + dependency-type: direct:development + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 2c29504f87d2a30bc05df916f7f1d4f6c98c302a +Author: Damian Legawiec +Date: Wed May 7 14:41:09 2025 +0200 + + Add brakeman to CI (#1222) + + * Add brakeman to CI + + * Update config.yml + +commit 2e8db9a8196b2ec6ce4d7281d529e8f880ba320a +Author: Damian Legawiec +Date: Wed May 7 14:33:57 2025 +0200 + + Setup Rubocop and Solargraph + +commit b7097022fff6286d6809bb13a1fca8290fe6ee8f +Author: Damian Legawiec +Date: Wed May 7 14:22:58 2025 +0200 + + Added `SENDGRID_DOMAIN` env support + +commit f6c007c2bd4678d732810d73e9c2b6b8d6ecdccc +Author: Damian Kaczmarczyk +Date: Tue May 6 17:50:35 2025 +0200 + + Add option to use SendGrid as a mailer on the production env (#1221) + + * Add option to use Sendgrid as a mailer on the production env + + * Update config/environments/production.rb + + Co-authored-by: Damian Legawiec + + * Update config/environments/production.rb + + Co-authored-by: Damian Legawiec + + * Add missing comma + + --------- + + Co-authored-by: Damian Legawiec + +commit efea1c74f71f07103a73dde70f1ca5f4dbaed85e +Author: Damian Legawiec +Date: Tue May 6 12:40:20 2025 +0200 + + Update Spree to 5.0.3 (#1220) + +commit 338ac1b4ef4028102b5442f9c1527542a8e5679d +Author: Damian Legawiec +Date: Mon May 5 20:42:51 2025 +0200 + + Add config for sentry error/performance monitoring (#1216) + + * Add config for sentry error/performance monitoring + + * Update config/initializers/sentry.rb + + * Update sentry.rb + + * Update README.md + +commit 77d1c8a95eeea767ef2c6eedc503157d4b41a3f4 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Apr 28 16:18:19 2025 +0200 + + Bump ruby-lsp-rails from 0.4.0 to 0.4.1 (#1214) + + Bumps [ruby-lsp-rails](https://github.com/Shopify/ruby-lsp-rails) from 0.4.0 to 0.4.1. + - [Release notes](https://github.com/Shopify/ruby-lsp-rails/releases) + - [Commits](https://github.com/Shopify/ruby-lsp-rails/compare/v0.4.0...v0.4.1) + + --- + updated-dependencies: + - dependency-name: ruby-lsp-rails + dependency-version: 0.4.1 + dependency-type: direct:development + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 54c34b4fff90829897f2f8ef9da2621bd1f8b7bf +Author: Damian Legawiec +Date: Tue Apr 22 15:28:12 2025 +0200 + + Bump Spree to 5.0.2 (#1210) + +commit 845af345d36077b8675be74e292b0d3c37600d9d +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Tue Apr 22 09:10:25 2025 +0200 + + Bump brakeman from 7.0.0 to 7.0.2 (#1201) + + Bumps [brakeman](https://github.com/presidentbeef/brakeman) from 7.0.0 to 7.0.2. + - [Release notes](https://github.com/presidentbeef/brakeman/releases) + - [Changelog](https://github.com/presidentbeef/brakeman/blob/main/CHANGES.md) + - [Commits](https://github.com/presidentbeef/brakeman/compare/v7.0.0...v7.0.2) + + --- + updated-dependencies: + - dependency-name: brakeman + dependency-version: 7.0.2 + dependency-type: direct:development + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit ef248d74196a92a6c91115e68391d2112099b963 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Tue Apr 22 09:10:06 2025 +0200 + + Bump dotenv-rails from 2.8.1 to 3.1.8 (#1208) + + Bumps [dotenv-rails](https://github.com/bkeepers/dotenv) from 2.8.1 to 3.1.8. + - [Release notes](https://github.com/bkeepers/dotenv/releases) + - [Changelog](https://github.com/bkeepers/dotenv/blob/main/Changelog.md) + - [Commits](https://github.com/bkeepers/dotenv/compare/v2.8.1...v3.1.8) + + --- + updated-dependencies: + - dependency-name: dotenv-rails + dependency-version: 3.1.8 + dependency-type: direct:development + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit bc685b4ec7f5378c58a90c67bb11e0eccb4f3cfd +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Tue Apr 22 09:09:34 2025 +0200 + + Bump nokogiri from 1.18.7 to 1.18.8 in the bundler group (#1209) + + Bumps the bundler group with 1 update: [nokogiri](https://github.com/sparklemotion/nokogiri). + + + Updates `nokogiri` from 1.18.7 to 1.18.8 + - [Release notes](https://github.com/sparklemotion/nokogiri/releases) + - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) + - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.18.7...v1.18.8) + + --- + updated-dependencies: + - dependency-name: nokogiri + dependency-version: 1.18.8 + dependency-type: indirect + dependency-group: bundler + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit ed0b969e7790d2862678b41dc5d74eb5ffd0f0f0 +Author: Damian Legawiec +Date: Sun Apr 13 19:03:05 2025 +0200 + + Fixed Dockerfile to use production env, install redis tools (#1207) + +commit e5a5ef05e59a04841655c401e1ba7ba2b9bdb1ec +Author: Damian Legawiec +Date: Sun Apr 13 18:10:28 2025 +0200 + + Do not require `REDIS_CACHE_URL` env variable (#1206) + +commit 3d40a3d1a1e78928c2bb17d73a189d8aea809dc2 +Author: Damian Kaczmarczyk +Date: Thu Apr 10 13:27:48 2025 +0200 + + Update Spree and Spree Stripe (#1205) + +commit 693ba658e76a997ab6ae48bb0924ae04d81ee6d5 +Author: Damian Kaczmarczyk +Date: Fri Apr 4 13:23:43 2025 +0200 + + Bump `spree_stripe` version (#1198) + +commit 01f633e966627dd2320c7d4fe977e93d3f39dd3f +Author: Mike Faber +Date: Thu Apr 3 22:56:36 2025 +0200 + + Update README.md + +commit c8ed86d71e75350c5dae76b138f5db4ac6320548 +Author: Damian Legawiec +Date: Thu Apr 3 16:57:58 2025 +0200 + + Spree 5 stable release is here! (#1197) + +commit 3ece43d6bdf23b897be6c3014e05349758552b9b +Author: Damian Legawiec +Date: Wed Apr 2 15:49:29 2025 +0200 + + Update README.md + +commit 9fc015564636fc909d6de0a0b784ebdef64c91a2 +Author: Damian Legawiec +Date: Wed Apr 2 15:37:30 2025 +0200 + + Fix for first-time render deployment to make storefront urls work + +commit 4a68d945d6759e83fb74e26c0b0621f49227401e +Author: Damian Legawiec +Date: Wed Apr 2 15:13:40 2025 +0200 + + Fixed cache config for prod + +commit 8c22b79cfd4d1c638f5b0764f144954adcaf3d35 +Author: Damian Legawiec +Date: Wed Apr 2 15:04:25 2025 +0200 + + Remove `solid_queue` leftovers + +commit 2948b4b092a9c379be8b38a4ef425409c03c93d7 +Author: Damian Legawiec +Date: Wed Apr 2 15:03:26 2025 +0200 + + Update database.yml + +commit f33f0a02f82cb920e41c55089d783ef3a217425f +Author: Damian Legawiec +Date: Wed Apr 2 14:41:03 2025 +0200 + + Switch back to redis/valkey for caching (#1196) + +commit b5da588a6fd0f3202ae6fd01e7a6b5f846874cbf +Author: Damian Legawiec +Date: Wed Apr 2 13:47:52 2025 +0200 + + Fix/replace credentials with envs (#1195) + + * Replace rails credentials with ENVs + + * Update render.yaml + +commit b5599050660e2f7be8a22de489f36e8921088490 +Author: Damian Legawiec +Date: Wed Apr 2 13:26:34 2025 +0200 + + Drop redis in CI, use test active job adapter, fix CircleCI config (#1194) + +commit 794773f20df9b2e3d1382c99079df3fae8260560 +Author: Damian Legawiec +Date: Wed Apr 2 13:18:15 2025 +0200 + + Update config.yml + +commit fa9e6176f7e337faa6cf627c913ae83679ff0ab0 +Author: Damian Legawiec +Date: Wed Apr 2 13:14:43 2025 +0200 + + Update config.yml + +commit e5c52b9a6a4657b17b1cfccd5958a6c73f0ef609 +Author: Damian Legawiec +Date: Wed Apr 2 13:13:59 2025 +0200 + + Setup test environment with `rspec` and CircleCI (#1193) + +commit e8555a8093520ee57df5520b943fee87a57006ec +Author: Damian Legawiec +Date: Wed Apr 2 12:26:33 2025 +0200 + + Replace `solid_queue` with `sidekiq` (#1192) + +commit 79b00a2ae710c20dfa24338de0c100127c916ede +Author: Mike Faber +Date: Wed Apr 2 12:09:44 2025 +0200 + + Update README.md + +commit c58613d0caf7be54f79bed2989ca03aec366c22b +Author: Damian Legawiec +Date: Tue Apr 1 23:02:38 2025 +0200 + + Update Procfile.dev + +commit 396cee143ed19176ff114c19a32efcd3cf904e19 +Author: Damian Legawiec +Date: Tue Apr 1 22:23:43 2025 +0200 + + Use Spree Stripe from RubyGems + +commit cd4c4cc0987a5bc09ab947be723ced401b090433 +Author: Damian Legawiec +Date: Tue Apr 1 22:17:05 2025 +0200 + + Use Spree from RubyGems + +commit 49890746006da3ff72c5fb36b1e952c4c109b4a8 +Merge: 29ab68e dc13dd9 +Author: Damian Legawiec +Date: Mon Mar 31 11:36:50 2025 +0200 + + Update Spree + +commit 29ab68e9272aa631f7b74cdcb174668677525b72 +Author: Damian Legawiec +Date: Mon Mar 31 11:36:02 2025 +0200 + + Update Spree & Spree Stripe + +commit dc13dd97e95e51b4f2d99bd6e0a0b2849266adb1 +Author: Damian Kaczmarczyk +Date: Fri Mar 28 20:17:31 2025 +0100 + + Update Spree and Spree Stripe dependency (#1191) + +commit b26e299c3480e695e1ec66ac1b25e5a86c1007db +Author: Łukasz Adamczyk +Date: Wed Mar 26 18:32:37 2025 +0100 + + Update spree + +commit 4a00ab82c3cdd14a4072a946c72a481734148671 +Author: Mike Faber +Date: Wed Mar 26 11:42:01 2025 +0100 + + Update README.md + +commit 11e9005499a063d06a13ada59bf66ccd019c7c0a +Author: Łukasz Adamczyk +Date: Tue Mar 25 16:25:49 2025 +0100 + + Update spree + +commit 3b8ba3b07dce567eef188fc1c025153d1e2e488b +Author: Łukasz Adamczyk +Date: Mon Mar 24 18:07:58 2025 +0100 + + Update spree + +commit 016520df82cb4e6bef9f6b1ef3e6ca02a57a7dd1 +Author: Łukasz Adamczyk +Date: Mon Mar 24 11:09:45 2025 +0100 + + Update spree (#1190) + +commit 743f089d5b90c6a4e4e2348700d670418bcc5cb6 +Author: Damian Legawiec +Date: Fri Mar 21 21:48:08 2025 +0100 + + Update Spree + +commit 30e9a8928e82cc1becde2f17c1c35a40b031421d +Author: Damian Legawiec +Date: Fri Mar 21 17:08:43 2025 +0100 + + Update Spree + +commit 9a04dbd83f55d1d5bbbe2bab3b8c94fa0bc05fae +Author: Damian Legawiec +Date: Fri Mar 21 15:27:01 2025 +0100 + + Update Spree + +commit 4c59c0eb356a24ce54a4b59608992e1dbeac88b0 +Author: Damian Legawiec +Date: Wed Mar 19 16:19:58 2025 +0100 + + Remove outdated acts as taggable on migrations, fixed schema + +commit 45e2c6246430a59d61d6e7852a48ccf7fd6b0f5a +Author: Damian Legawiec +Date: Wed Mar 19 16:12:56 2025 +0100 + + Fixed MySQL migrations + +commit 87f844bdd64f7a0ec37550c9a2e29343415056b3 +Author: Mike Faber +Date: Wed Mar 19 15:43:49 2025 +0100 + + Update README.md + +commit 5b8cb37fd00dc2950e0ee743303b5d5ddf84fe2f +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Mar 17 13:23:29 2025 +0100 + + Bump solid_queue from 1.1.3 to 1.1.4 (#1188) + + Bumps [solid_queue](https://github.com/rails/solid_queue) from 1.1.3 to 1.1.4. + - [Release notes](https://github.com/rails/solid_queue/releases) + - [Commits](https://github.com/rails/solid_queue/compare/v1.1.3...v1.1.4) + + --- + updated-dependencies: + - dependency-name: solid_queue + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit ee77f03e2087a7a0cef6338730436ae3bc1a490d +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Mar 17 13:23:13 2025 +0100 + + Bump spree_stripe from `7a03e31` to `1fb01c2` (#1189) + + Bumps [spree_stripe](https://github.com/spree/spree_stripe) from `7a03e31` to `1fb01c2`. + - [Commits](https://github.com/spree/spree_stripe/compare/7a03e3131b890693f154962f1f280569a890ba96...1fb01c29f74f35c7cdb5fba64470d3e122fabab2) + + --- + updated-dependencies: + - dependency-name: spree_stripe + dependency-type: direct:production + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 2b14fc20c647ceb41494d127f05d62984c832a20 +Author: Damian Legawiec +Date: Fri Mar 14 12:49:52 2025 +0100 + + Update Spree + +commit 207726da1745efcbf98dfae49858a191efb8a1a1 +Author: Damian Legawiec +Date: Thu Mar 13 10:14:45 2025 +0100 + + Update README.md + +commit 1314adf29320afa51d20cd49273c6924f2fbcb20 +Author: Łukasz Adamczyk +Date: Thu Mar 13 10:12:16 2025 +0100 + + Add `spree_stripe` gem (#1187) + +commit 66f27f4752e1f14da33d97701392648fe4d308b2 +Author: Damian Legawiec +Date: Wed Mar 12 23:49:24 2025 +0100 + + Update Spree + +commit 96769883bfb62c095539847f4fac00af20de9b1f +Author: Damian Legawiec +Date: Tue Mar 11 14:50:35 2025 +0100 + + Updated Spree + +commit d9ac4d15df1a8780359d1353ab64bcebf4b83981 +Author: Damian Legawiec +Date: Fri Mar 7 12:52:08 2025 +0100 + + Update Spree + +commit 2017981b9bbb995a0b1836e27ddcb1d47cd10ec0 +Author: Damian Legawiec +Date: Thu Mar 6 15:10:26 2025 +0100 + + Update Spree + +commit c37d9ced57a55dd6c970ed58232028542b27cb73 +Author: Damian Legawiec +Date: Thu Mar 6 10:07:21 2025 +0100 + + Update Gemfile.lock + +commit fd039e13125f9b8cb92b90e1ed5916640aa2c9db +Author: Łukasz Adamczyk +Date: Wed Mar 5 15:10:11 2025 +0100 + + Update spree/spree to f321e8a revision (#1185) + +commit e38879c0897f3ae68fa764df661a7b2af0a44cff +Author: Damian Legawiec +Date: Tue Mar 4 09:30:49 2025 +0100 + + Update README.md + +commit b20d9a98ed855b8823ec0c9eceae15eac3155be1 +Author: Damian Legawiec +Date: Mon Mar 3 20:31:38 2025 +0100 + + Setup Solid Queue 1.x + +commit ee8cb973d5232702967529cd79980fe62783915d +Author: Damian Legawiec +Date: Mon Mar 3 18:59:16 2025 +0100 + + Update Spree + +commit 954d12464129420100ef378813973e0c9b68f11a +Author: Damian Legawiec +Date: Sat Mar 1 21:51:39 2025 +0100 + + Update spree, remove old spree v4 asset files + +commit 9994662b34c9d6074bfcb26583e8fd299553d0cd +Author: Damian Legawiec +Date: Sat Mar 1 11:20:33 2025 +0100 + + Update render.yaml + +commit bddea4683ecc4440f31bd1a26948eb8c19df8e27 +Author: Damian Legawiec +Date: Fri Feb 28 17:48:53 2025 +0100 + + Fixed asset precompilation in environments without node + +commit c00b644783347cffbd3eb6b60726c8d8805af943 +Author: Damian Legawiec +Date: Fri Feb 28 14:53:46 2025 +0100 + + Setup new credentials when running `bin/setup` + +commit bce9432eb1cb4feaa488190ed8aa2e1182c51737 +Author: Damian Legawiec +Date: Fri Feb 28 11:51:53 2025 +0100 + + Update README.md + +commit 2d10fb838ad19aaaa17a9f186342fa7977b65978 +Author: Damian Legawiec +Date: Thu Feb 27 18:56:42 2025 +0100 + + Update Gemfile.lock + +commit f62ba5aa5f10b0eade95557f1e9bb91f439708f0 +Author: Damian Legawiec +Date: Thu Feb 27 14:32:56 2025 +0100 + + Setup Spree 5 starter (#1180) + + * Setup Spree 5 starter + + * install dartsass + + * Use PostgreSQL for default database + + * Update render-build.sh + + * fix admin css + + * Rails 7.2 upgrade + + * Setup new Spree storefront + + * Switch to `rbenv` as it's more mature + + * fix storefront css + + * Update Starter to use the latest devise authentication generator + +commit 02a9eae3cb8569c0608c24d5fb4da395870532ba +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Oct 14 07:25:47 2024 -0700 + + Bump importmap-rails from 2.0.2 to 2.0.3 (#1160) + + Bumps [importmap-rails](https://github.com/rails/importmap-rails) from 2.0.2 to 2.0.3. + - [Release notes](https://github.com/rails/importmap-rails/releases) + - [Commits](https://github.com/rails/importmap-rails/compare/v2.0.2...v2.0.3) + + --- + updated-dependencies: + - dependency-name: importmap-rails + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 4d366c3d1cf4e2238023f1a910d2d58bd33ddf9a +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Oct 7 14:58:17 2024 +0200 + + Bump importmap-rails from 2.0.1 to 2.0.2 (#1159) + + Bumps [importmap-rails](https://github.com/rails/importmap-rails) from 2.0.1 to 2.0.2. + - [Release notes](https://github.com/rails/importmap-rails/releases) + - [Commits](https://github.com/rails/importmap-rails/compare/v2.0.1...v2.0.2) + + --- + updated-dependencies: + - dependency-name: importmap-rails + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 8c5f8f7589231f110185bb9b02878f20e74100be +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Sep 30 14:55:05 2024 +0200 + + Bump solid_queue from 0.8.2 to 1.0.0 (#1158) + + Bumps [solid_queue](https://github.com/rails/solid_queue) from 0.8.2 to 1.0.0. + - [Release notes](https://github.com/rails/solid_queue/releases) + - [Commits](https://github.com/rails/solid_queue/compare/v0.8.2...v1.0.0) + + --- + updated-dependencies: + - dependency-name: solid_queue + dependency-type: direct:production + update-type: version-update:semver-major + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 0fde2573d86f8729074489727daf23b99aa2b1d5 +Author: Damian Legawiec +Date: Thu Sep 12 17:00:10 2024 +0200 + + switch to sqlite3, added docker image + +commit cd4c148a0e45a8a2b1b6982811b18db42ab93fb3 +Author: Damian Legawiec +Date: Fri Sep 6 14:36:37 2024 +0200 + + Bump Spree to v4.10 + +commit 5fcd8cccb34f4b4922226d0516f9c5b2a3900e8d +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Sep 2 14:59:09 2024 +0200 + + Bump selenium-webdriver from 4.23.0 to 4.24.0 (#1149) + + Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.23.0 to 4.24.0. + - [Release notes](https://github.com/SeleniumHQ/selenium/releases) + - [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES) + - [Commits](https://github.com/SeleniumHQ/selenium/compare/selenium-4.23.0...selenium-4.24.0) + + --- + updated-dependencies: + - dependency-name: selenium-webdriver + dependency-type: direct:development + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 72d4a08e0e4c6ed22e4a51c7e1cea332d9a13b7a +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Sep 2 14:52:49 2024 +0200 + + Bump solid_queue from 0.6.0 to 0.6.1 (#1148) + + Bumps [solid_queue](https://github.com/rails/solid_queue) from 0.6.0 to 0.6.1. + - [Release notes](https://github.com/rails/solid_queue/releases) + - [Commits](https://github.com/rails/solid_queue/compare/v0.6.0...v0.6.1) + + --- + updated-dependencies: + - dependency-name: solid_queue + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit dfb5ebbf135138b61ec90888be79c382da92ac8c +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 26 15:55:44 2024 +0200 + + Bump redis from 5.2.0 to 5.3.0 (#1143) + + Bumps [redis](https://github.com/redis/redis-rb) from 5.2.0 to 5.3.0. + - [Changelog](https://github.com/redis/redis-rb/blob/master/CHANGELOG.md) + - [Commits](https://github.com/redis/redis-rb/compare/v5.2.0...v5.3.0) + + --- + updated-dependencies: + - dependency-name: redis + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 5ece3c25c3fd9e85a1fddbc8d2833c44ad27414d +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 26 15:55:38 2024 +0200 + + Bump rails from 7.1.3.4 to 7.1.4 (#1144) + + Bumps [rails](https://github.com/rails/rails) from 7.1.3.4 to 7.1.4. + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v7.1.3.4...v7.1.4) + + --- + updated-dependencies: + - dependency-name: rails + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 4b23e17ddcd1166e00cfe8f4c6b6abecc220bf79 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 26 15:55:27 2024 +0200 + + Bump solid_queue from 0.5.0 to 0.6.0 (#1145) + + Bumps [solid_queue](https://github.com/rails/solid_queue) from 0.5.0 to 0.6.0. + - [Release notes](https://github.com/rails/solid_queue/releases) + - [Commits](https://github.com/rails/solid_queue/compare/v0.5.0...v0.6.0) + + --- + updated-dependencies: + - dependency-name: solid_queue + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 423253a882e6ff2665fc8bf912b9dff59e977b34 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Wed Aug 21 15:56:00 2024 +0200 + + Bump mini_racer from 0.13.0 to 0.14.1 (#1140) + + Bumps [mini_racer](https://github.com/discourse/mini_racer) from 0.13.0 to 0.14.1. + - [Changelog](https://github.com/rubyjs/mini_racer/blob/main/CHANGELOG) + - [Commits](https://github.com/discourse/mini_racer/compare/v0.13.0...v0.14.1) + + --- + updated-dependencies: + - dependency-name: mini_racer + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit a0a093a1806b4a542d0f8691f01a853d93b6c3c1 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Wed Aug 21 14:02:55 2024 +0200 + + Bump stimulus-rails from 1.3.3 to 1.3.4 (#1138) + + Bumps [stimulus-rails](https://github.com/hotwired/stimulus-rails) from 1.3.3 to 1.3.4. + - [Release notes](https://github.com/hotwired/stimulus-rails/releases) + - [Commits](https://github.com/hotwired/stimulus-rails/compare/v1.3.3...v1.3.4) + + --- + updated-dependencies: + - dependency-name: stimulus-rails + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 01acbfdb55c5b8cbf20b4cc3b424b1adea908a5d +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Wed Aug 21 14:02:45 2024 +0200 + + Bump solid_queue from 0.4.1 to 0.5.0 (#1139) + + Bumps [solid_queue](https://github.com/rails/solid_queue) from 0.4.1 to 0.5.0. + - [Release notes](https://github.com/rails/solid_queue/releases) + - [Commits](https://github.com/rails/solid_queue/compare/v0.4.1...v0.5.0) + + --- + updated-dependencies: + - dependency-name: solid_queue + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit c15a520787c3121ce909c435a7dada6ad5fb5180 +Author: Damian Legawiec +Date: Wed Aug 14 14:19:31 2024 +0200 + + Bump Spree to 4.9 :rocket: + +commit 5f230ddadbbbe9d5d106fd112e850cdd53d23753 +Author: Damian Legawiec +Date: Mon Aug 12 19:50:37 2024 +0200 + + Fixed docker build + + Fixes https://github.com/spree/spree/issues/12109 + +commit 84f334f32bf7c63a617c269c9fd34807165fe778 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 12 19:46:58 2024 +0200 + + Bump bootsnap from 1.18.3 to 1.18.4 (#1129) + + Bumps [bootsnap](https://github.com/Shopify/bootsnap) from 1.18.3 to 1.18.4. + - [Changelog](https://github.com/Shopify/bootsnap/blob/main/CHANGELOG.md) + - [Commits](https://github.com/Shopify/bootsnap/compare/v1.18.3...v1.18.4) + + --- + updated-dependencies: + - dependency-name: bootsnap + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 46ae824331d9d9c4cc3b7ddd50a53ff3304b3c13 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 12 19:46:50 2024 +0200 + + Bump spree_backend from 4.8.3 to 4.8.4 (#1130) + + Bumps [spree_backend](https://github.com/spree/spree_backend) from 4.8.3 to 4.8.4. + - [Release notes](https://github.com/spree/spree_backend/releases) + - [Commits](https://github.com/spree/spree_backend/commits) + + --- + updated-dependencies: + - dependency-name: spree_backend + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit f0623291367ff719e570a9491f2abeb6daf46446 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 12 19:46:36 2024 +0200 + + Bump sprockets-rails from 3.5.1 to 3.5.2 (#1131) + + Bumps [sprockets-rails](https://github.com/rails/sprockets-rails) from 3.5.1 to 3.5.2. + - [Release notes](https://github.com/rails/sprockets-rails/releases) + - [Commits](https://github.com/rails/sprockets-rails/compare/v3.5.1...v3.5.2) + + --- + updated-dependencies: + - dependency-name: sprockets-rails + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit dea2a3db7480298707d4050d878edcb5c7339697 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 12 19:46:28 2024 +0200 + + Bump solid_cache from 0.6.0 to 0.7.0 (#1132) + + Bumps [solid_cache](https://github.com/rails/solid_cache) from 0.6.0 to 0.7.0. + - [Release notes](https://github.com/rails/solid_cache/releases) + - [Commits](https://github.com/rails/solid_cache/compare/v0.6.0...v0.7.0) + + --- + updated-dependencies: + - dependency-name: solid_cache + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 96404119f015f3397ce2449489122efeab5cb1f5 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Aug 12 14:43:08 2024 +0200 + + Bump solid_queue from 0.3.4 to 0.4.1 (#1134) + + Bumps [solid_queue](https://github.com/rails/solid_queue) from 0.3.4 to 0.4.1. + - [Release notes](https://github.com/rails/solid_queue/releases) + - [Commits](https://github.com/rails/solid_queue/compare/v0.3.4...v0.4.1) + + --- + updated-dependencies: + - dependency-name: solid_queue + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit ebbe9a569b1acb243c3d7f030c9ff1b0c801a65b +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Fri Aug 2 10:16:21 2024 +0200 + + Bump rexml from 3.3.2 to 3.3.3 in the bundler group (#1128) + + Bumps the bundler group with 1 update: [rexml](https://github.com/ruby/rexml). + + + Updates `rexml` from 3.3.2 to 3.3.3 + - [Release notes](https://github.com/ruby/rexml/releases) + - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) + - [Commits](https://github.com/ruby/rexml/compare/v3.3.2...v3.3.3) + + --- + updated-dependencies: + - dependency-name: rexml + dependency-type: indirect + dependency-group: bundler + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit ca1d40fa36b497a4830390c91c70502042a05b25 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jul 29 14:38:00 2024 +0200 + + Bump selenium-webdriver from 4.22.0 to 4.23.0 (#1124) + + Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.22.0 to 4.23.0. + - [Release notes](https://github.com/SeleniumHQ/selenium/releases) + - [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES) + - [Commits](https://github.com/SeleniumHQ/selenium/compare/selenium-4.22.0...selenium-4.23.0) + + --- + updated-dependencies: + - dependency-name: selenium-webdriver + dependency-type: direct:development + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 9e48f9c6a207c08484e53649bbf792a7f02ce7df +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jul 29 14:37:53 2024 +0200 + + Bump turbo-rails from 2.0.5 to 2.0.6 (#1123) + + Bumps [turbo-rails](https://github.com/hotwired/turbo-rails) from 2.0.5 to 2.0.6. + - [Release notes](https://github.com/hotwired/turbo-rails/releases) + - [Commits](https://github.com/hotwired/turbo-rails/compare/v2.0.5...v2.0.6) + + --- + updated-dependencies: + - dependency-name: turbo-rails + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 238fbf865a73366f9f98ac716c497b3d23cd9e41 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jul 29 14:37:46 2024 +0200 + + Bump solid_queue from 0.3.3 to 0.3.4 (#1125) + + Bumps [solid_queue](https://github.com/rails/solid_queue) from 0.3.3 to 0.3.4. + - [Release notes](https://github.com/rails/solid_queue/releases) + - [Commits](https://github.com/rails/solid_queue/compare/v0.3.3...v0.3.4) + + --- + updated-dependencies: + - dependency-name: solid_queue + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit a8e99ff51e8523b02097dbb57ed8b60d52b95be3 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jul 29 14:37:33 2024 +0200 + + Bump pg from 1.5.6 to 1.5.7 (#1127) + + Bumps [pg](https://github.com/ged/ruby-pg) from 1.5.6 to 1.5.7. + - [Changelog](https://github.com/ged/ruby-pg/blob/master/History.md) + - [Commits](https://github.com/ged/ruby-pg/compare/v1.5.6...v1.5.7) + + --- + updated-dependencies: + - dependency-name: pg + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 6fc77e961bf8f950f2783031887a646f0b57a9bc +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jul 29 14:37:22 2024 +0200 + + Bump image_processing from 1.12.2 to 1.13.0 (#1126) + + Bumps [image_processing](https://github.com/janko/image_processing) from 1.12.2 to 1.13.0. + - [Changelog](https://github.com/janko/image_processing/blob/master/CHANGELOG.md) + - [Commits](https://github.com/janko/image_processing/compare/v1.12.2...v1.13.0) + + --- + updated-dependencies: + - dependency-name: image_processing + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 69c33ed63b14ff5080b713dd6c5e5e4a95784f66 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jul 15 14:10:59 2024 +0200 + + Bump spree_backend from 4.8.2 to 4.8.3 (#1121) + + Bumps [spree_backend](https://github.com/spree/spree_backend) from 4.8.2 to 4.8.3. + - [Release notes](https://github.com/spree/spree_backend/releases) + - [Commits](https://github.com/spree/spree_backend/compare/v4.8.2...v4.8.3) + + --- + updated-dependencies: + - dependency-name: spree_backend + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 3fb2ffe595dbad6c34c7c89d67777fee3b321de6 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jun 24 15:09:15 2024 +0200 + + Bump selenium-webdriver from 4.21.1 to 4.22.0 (#1119) + + Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.21.1 to 4.22.0. + - [Release notes](https://github.com/SeleniumHQ/selenium/releases) + - [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES) + - [Commits](https://github.com/SeleniumHQ/selenium/commits/selenium-4.22.0) + + --- + updated-dependencies: + - dependency-name: selenium-webdriver + dependency-type: direct:development + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 5ec5573e6748b78de0e28b55684c269b0d7f58a5 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Sat Jun 22 09:40:08 2024 +0200 + + Bump spree_emails from 4.8.2 to 4.8.3 (#1118) + + Bumps [spree_emails](https://github.com/spree/spree) from 4.8.2 to 4.8.3. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/main/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v4.8.2...v4.8.3) + + --- + updated-dependencies: + - dependency-name: spree_emails + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 2ceb6976043a291da30183ec74849daa22360ef2 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jun 17 15:50:29 2024 +0200 + + Bump spree_sample from 4.8.2 to 4.8.3 (#1117) + + Bumps [spree_sample](https://github.com/spree/spree) from 4.8.2 to 4.8.3. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/main/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v4.8.2...v4.8.3) + + --- + updated-dependencies: + - dependency-name: spree_sample + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit cc7edc0714c06aaefdd0464df57c797c3221aed7 +Author: Damian Legawiec +Date: Thu Jun 13 22:13:52 2024 +0200 + + Upgrade spree_backend to v4.8.2 + +commit aed03d3aeb16ae2bce27fccad92ad9ad2ab1bc0a +Author: Damian Legawiec +Date: Thu Jun 13 13:01:53 2024 +0200 + + Upgrade spree to 4.8.3 + +commit ec68da8b0eb834587a8864a9377c596651be8264 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Jun 10 15:48:30 2024 +0200 + + Bump solid_queue from 0.3.1 to 0.3.2 (#1112) + + Bumps [solid_queue](https://github.com/rails/solid_queue) from 0.3.1 to 0.3.2. + - [Release notes](https://github.com/rails/solid_queue/releases) + - [Commits](https://github.com/rails/solid_queue/compare/v0.3.1...v0.3.2) + + --- + updated-dependencies: + - dependency-name: solid_queue + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 74c65a40b55f2d6dd6886a6e5a5d1b8e348b0b2a +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Thu Jun 6 11:57:01 2024 +0200 + + Bump the bundler group with 2 updates (#1114) + + Bumps the bundler group with 2 updates: [actionpack](https://github.com/rails/rails) and [actiontext](https://github.com/rails/rails). + + + Updates `actionpack` from 7.1.3.3 to 7.1.3.4 + - [Release notes](https://github.com/rails/rails/releases) + - [Changelog](https://github.com/rails/rails/blob/v7.1.3.4/actionpack/CHANGELOG.md) + - [Commits](https://github.com/rails/rails/compare/v7.1.3.3...v7.1.3.4) + + Updates `actiontext` from 7.1.3.3 to 7.1.3.4 + - [Release notes](https://github.com/rails/rails/releases) + - [Changelog](https://github.com/rails/rails/blob/v7.1.3.4/actiontext/CHANGELOG.md) + - [Commits](https://github.com/rails/rails/compare/v7.1.3.3...v7.1.3.4) + + --- + updated-dependencies: + - dependency-name: actionpack + dependency-type: indirect + dependency-group: bundler + - dependency-name: actiontext + dependency-type: indirect + dependency-group: bundler + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit b2d4b25121871459500942a787d8a16741e2f972 +Author: Damian Legawiec +Date: Thu Jun 6 11:56:34 2024 +0200 + + fix: Gemfile to reduce vulnerabilities (#1115) + + The following vulnerabilities are fixed with an upgrade: + - https://snyk.io/vuln/SNYK-RUBY-ACTIONTEXT-7210236 + - https://snyk.io/vuln/SNYK-RUBY-ACTIONPACK-7210237 + + Co-authored-by: snyk-bot + +commit 26d3bae8b3f5954c1a1e0bd40d4dcd625a2ac65a +Merge: 182a5b9 15bb123 +Author: Damian Legawiec +Date: Wed May 29 18:00:48 2024 +0200 + + Merge branch 'main' of github.com:spree/spree_starter + +commit 182a5b9ecc04a952ee974a16bf498f3e18e62485 +Author: Damian Legawiec +Date: Wed May 29 18:00:40 2024 +0200 + + Bump gems + +commit 15bb1230727ce388151606af3ce66d1da4908484 +Author: Damian Legawiec +Date: Tue May 28 18:13:23 2024 +0200 + + Delete config/initializers/mission_control_jobs.rb + + This isn't needed anymore as the fix was merged into this gem + +commit 18460d7105205af680a05cee8f17399568aa30b0 +Author: Damian Legawiec +Date: Mon May 27 15:39:25 2024 +0200 + + update spree frontend gem + +commit 9bfc44d3a912e8155b18362c1528703e926c4fb1 +Author: Damian Legawiec +Date: Thu May 23 17:43:32 2024 +0200 + + Bump Spree to v4.8 :rocket: + +commit 768bc087bab5363e77ebd61ca1eca4f142378101 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon May 20 15:43:13 2024 +0200 + + Bump rails from 7.1.3.2 to 7.1.3.3 (#1110) + +commit bc17ff80c712821c2d828555e05724869cfeaa78 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon May 20 15:43:02 2024 +0200 + + Bump selenium-webdriver from 4.20.1 to 4.21.1 (#1109) + +commit 0bbe1244717a8db7183459d5b32e47b9e77faccd +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Thu May 16 23:52:32 2024 +0200 + + Bump the bundler group with 2 updates (#1108) + + Bumps the bundler group with 2 updates: [nokogiri](https://github.com/sparklemotion/nokogiri) and [rexml](https://github.com/ruby/rexml). + + + Updates `nokogiri` from 1.16.4 to 1.16.5 + - [Release notes](https://github.com/sparklemotion/nokogiri/releases) + - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) + - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.16.4...v1.16.5) + + Updates `rexml` from 3.2.6 to 3.2.8 + - [Release notes](https://github.com/ruby/rexml/releases) + - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) + - [Commits](https://github.com/ruby/rexml/compare/v3.2.6...v3.2.8) + + --- + updated-dependencies: + - dependency-name: nokogiri + dependency-type: indirect + dependency-group: bundler + - dependency-name: rexml + dependency-type: indirect + dependency-group: bundler + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit eafa386997250f10058a3cd55afdd65e06d89687 +Author: Damian Legawiec +Date: Sat May 11 11:06:47 2024 +0200 + + Bump gems + +commit 62f38eb9b214410df10868f05b3f0c0045ed531a +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Fri May 10 09:22:43 2024 +0200 + + Bump spree_backend from `a3ff98e` to `2cf8a1d` (#1106) + + Bumps [spree_backend](https://github.com/spree/spree_backend) from `a3ff98e` to `2cf8a1d`. + - [Release notes](https://github.com/spree/spree_backend/releases) + - [Commits](https://github.com/spree/spree_backend/compare/a3ff98ea57e24ee0cfe293d2e7a98d1ceda618eb...2cf8a1ded5355e309660018244e57f322232d737) + + --- + updated-dependencies: + - dependency-name: spree_backend + dependency-type: direct:production + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit d5ecd914d72bfd9fddea2832a6edaa18d6568da9 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Fri May 10 09:22:33 2024 +0200 + + Bump spree_frontend from `96857bb` to `63300a7` (#1105) + + Bumps [spree_frontend](https://github.com/spree/spree_rails_frontend) from `96857bb` to `63300a7`. + - [Release notes](https://github.com/spree/spree_rails_frontend/releases) + - [Commits](https://github.com/spree/spree_rails_frontend/compare/96857bb4b605b143f3e59fa3ac37430c1104f1f2...63300a7f04af1e345090a7037fd0a36526bba815) + + --- + updated-dependencies: + - dependency-name: spree_frontend + dependency-type: direct:production + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit edd620d84bb9b3393a89b2aef2669c3623feb1df +Author: Damian Legawiec +Date: Tue Apr 30 22:54:28 2024 +0200 + + Use stable version of Spree Auth Devise, bump gems + +commit 435ad82e012dc7b38f131524fddef348afebc435 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Apr 29 23:24:29 2024 +0200 + + Bump mission_control-jobs from 0.2.0 to 0.2.1 (#1104) + + Bumps [mission_control-jobs](https://github.com/basecamp/mission_control-jobs) from 0.2.0 to 0.2.1. + - [Release notes](https://github.com/basecamp/mission_control-jobs/releases) + - [Commits](https://github.com/basecamp/mission_control-jobs/compare/v0.2.0...v0.2.1) + + --- + updated-dependencies: + - dependency-name: mission_control-jobs + dependency-type: direct:production + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 8003e67293ba325c85b3fac8aaa4b0cf892206f2 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Apr 29 23:24:16 2024 +0200 + + Bump selenium-webdriver from 4.18.1 to 4.20.1 (#1103) + + Bumps [selenium-webdriver](https://github.com/SeleniumHQ/selenium) from 4.18.1 to 4.20.1. + - [Release notes](https://github.com/SeleniumHQ/selenium/releases) + - [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES) + - [Commits](https://github.com/SeleniumHQ/selenium/commits) + + --- + updated-dependencies: + - dependency-name: selenium-webdriver + dependency-type: direct:development + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 621474eb1989abb6d8a6263b64f87759c836cda1 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Apr 29 23:24:10 2024 +0200 + + Bump redis from 5.1.0 to 5.2.0 (#1102) + + Bumps [redis](https://github.com/redis/redis-rb) from 5.1.0 to 5.2.0. + - [Changelog](https://github.com/redis/redis-rb/blob/master/CHANGELOG.md) + - [Commits](https://github.com/redis/redis-rb/compare/v5.1.0...v5.2.0) + + --- + updated-dependencies: + - dependency-name: redis + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 438742e6297730d123810e3ad5a59560dd7ee522 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Apr 29 23:22:32 2024 +0200 + + Bump jbuilder from 2.11.5 to 2.12.0 (#1101) + + Bumps [jbuilder](https://github.com/rails/jbuilder) from 2.11.5 to 2.12.0. + - [Release notes](https://github.com/rails/jbuilder/releases) + - [Commits](https://github.com/rails/jbuilder/compare/v2.11.5...v2.12.0) + + --- + updated-dependencies: + - dependency-name: jbuilder + dependency-type: direct:production + update-type: version-update:semver-minor + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 8b99f4dcc7c198d67471373aef31fa48249c2e39 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Apr 29 23:22:19 2024 +0200 + + Bump debug from 1.9.1 to 1.9.2 (#1100) + + Bumps [debug](https://github.com/ruby/debug) from 1.9.1 to 1.9.2. + - [Release notes](https://github.com/ruby/debug/releases) + - [Commits](https://github.com/ruby/debug/compare/v1.9.1...v1.9.2) + + --- + updated-dependencies: + - dependency-name: debug + dependency-type: direct:development + update-type: version-update:semver-patch + ... + + Signed-off-by: dependabot[bot] + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 4b91ae10428df3243afe9eddda765eaef836db0d +Author: Damian Legawiec +Date: Mon Apr 29 23:20:14 2024 +0200 + + Create dependabot.yml + +commit a8780efa21199836ad74d89443d2cf8ba3822d25 +Author: Damian Legawiec +Date: Thu Mar 21 12:04:11 2024 +0100 + + Bump gems + +commit 677cd236e04fe2a77c782a5dd43b9fa08e1ef83d +Author: Damian Legawiec +Date: Sun Mar 10 21:26:00 2024 +0100 + + Setup a new fresh minimal Rails 7 app with Spree installed (#1099) + + * Setup a new fresh minimal Rails 7 app with Spree installed + + * added solid queue and mission control + + mission control is only accesible to admin users + + * Added Solid Cache + + * gems update + + * Update render.yaml + + * Update Gemfile.lock + + * Create mission_control_jobs.rb + + * fix cdn url + + * Update Gemfile.lock + + * fix request utility import + + * bump spree backend + + * fix importmap + + * Delete sortablejs.js + + * Update database.yml + + * heroku deploy + + * Switch to Postgres fixed + +commit 406d8062f16740bba5929b0d9265ee079e4b719a +Merge: 9b7ad21 cd25581 +Author: Rafał Cymerys +Date: Fri Nov 17 15:26:03 2023 +0100 + + Merge pull request #1092 from spree/sp-116/npm-explicit-installation + +commit cd255813b880872cd44ed69c90dc4961e80e1894 +Author: Rafal Cymerys +Date: Fri Nov 17 15:08:08 2023 +0100 + + Use apt-get for installing npm + +commit 5e9667d089c75cb21c5fd48aadceba5eb75d4cdb +Author: Mateusz Porębski +Date: Fri Nov 17 10:25:58 2023 +0100 + + Update Dockerfiles + +commit 9b7ad21ec2c7d962c3bc940dd3696b9725cc7516 +Merge: 031279a f8504fd +Author: Rafał Cymerys +Date: Thu Nov 16 15:03:03 2023 +0100 + + Merge pull request #1091 from spree/sp-111/ruby-version-partial-match-gemfile + + Updated Gemfile + +commit f8504fd1e03447087c7737cdb5e1d5cd7b134472 +Author: Mateusz Porębski +Date: Thu Nov 16 14:46:38 2023 +0100 + + Updated Gemfile + +commit 031279acdf05f25a0ede7b052deaadea283765b7 +Merge: 33d1f0d 115e68a +Author: Rafał Cymerys +Date: Thu Nov 16 14:25:15 2023 +0100 + + Merge pull request #1089 from spree/sp-110/dockerfile-ruby-322 + + Updated Dockerfiles + +commit 33d1f0d9d81d5dc8527df063eea0bb140166ad47 +Merge: 28fc3d7 2e40dfa +Author: Rafał Cymerys +Date: Thu Nov 16 14:20:38 2023 +0100 + + Merge pull request #1088 from fdocr/fix-dockerfiles-package-json-step + + Add DST to COPY command + +commit 28fc3d742d0ff692eb42a78eb62039bbf223a08d +Merge: 1256c12 b58a2e4 +Author: Rafał Cymerys +Date: Thu Nov 16 14:19:04 2023 +0100 + + Merge pull request #1090 from spree/sp-112/dockerfile-netcat-traditional + + Updated Dockerfiles + +commit b58a2e4bb2bb5fd818d5fc6e277615d63b974f94 +Author: Mateusz Porębski +Date: Thu Nov 16 14:07:27 2023 +0100 + + Updated Dockerfiles + +commit 115e68a17b5d7b5d6498b7e38325bc6d17f823e7 +Author: Mateusz Porębski +Date: Thu Nov 16 12:58:53 2023 +0100 + + Updated Dockerfiles + +commit 2e40dfa03743d217dd48ac0ae5fdc4c03a956c80 +Author: Fernando Valverde +Date: Wed Nov 15 21:49:14 2023 -0600 + + Add DST to COPY command + +commit 1256c125a31131ab74aed1b11a465008b32f855e +Author: Rafal Cymerys +Date: Fri Nov 10 15:24:26 2023 +0100 + + Use Ruby 3.2.2 + +commit 3430a7972edc21d5a8712347abc48b573d8ed07d (tag: v4.7.0) +Author: Rafal Cymerys +Date: Mon Oct 30 20:27:00 2023 +0100 + + Upgrade to Rails 7.1 + +commit 16c884c6084f52b82deead2d102e27691f1357ba (tag: v4.6.2) +Author: Rafal Cymerys +Date: Thu Sep 21 13:07:34 2023 +0200 + + Upgrade Rails and Spree Auth Devise + +commit c678848a11dbb11618ae5a97440c5108a4c59068 +Author: Rafal Cymerys +Date: Mon Sep 4 21:10:52 2023 +0200 + + Bump Spree to 4.6.2 + +commit 92fcd87f9543ba8bb3da751755dac17d7f3ac96a (tag: v4.6.1) +Author: Rafal Cymerys +Date: Tue Jul 25 10:18:40 2023 +0200 + + Update dependencies for Spree 4.6.1 + +commit 3f1614ff8d98ad305f0e585a66e3279842712846 (tag: v4.6.0) +Author: Rafal Cymerys +Date: Wed May 31 17:48:31 2023 +0200 + + Update lockfile for Spree 4.6 + +commit 1f872a99c4bd12c7df09bd48a65fbe17525c783a +Author: Rafal Cymerys +Date: Wed May 31 17:45:12 2023 +0200 + + Upgrade to Spree 4.6 + +commit d0861f75574a3007a3be130c865dd8a1b71eeaec +Author: Rafal Cymerys +Date: Fri Apr 21 12:08:19 2023 +0200 + + Update dependencies + +commit 0c3d717c70abe0d7cb89d9511a2594cc55b46a94 +Merge: 440bb52 324eaad +Author: Rafał Cymerys +Date: Wed Jan 25 16:04:29 2023 +0100 + + Merge pull request #1055 from spree/feat/update_docker_compose_commands_to_new_syntax + + feat/update_docker_compose_commands_to_new_syntax + +commit 324eaadf3ab94002180a8b204a29de9d098d7c94 +Author: Rafal Cymerys +Date: Wed Jan 25 15:44:00 2023 +0100 + + Update docker compose commands to new syntax + +commit 440bb52d664c0b9dc1f2b48a40bedca0f3344733 +Merge: 1d52e69 e982a29 +Author: Rafał Cymerys +Date: Mon Jan 23 18:52:52 2023 +0100 + + Merge pull request #1052 from spree/chore/cleanup-docker-setup-scripts + + Cleanup docker setup scripts + +commit e982a293ca281eed2f0fbb3c68af5ed88e27721e +Author: Rafal Cymerys +Date: Fri Jan 20 14:48:30 2023 +0100 + + Cleanup docker setup scripts + +commit 1d52e69aecc1ab4151d86603f02274830e9e2848 +Merge: 68abd6e bafeeab +Author: Rafał Cymerys +Date: Wed Jan 18 14:42:27 2023 +0100 + + Merge pull request #1051 from spree/feature/use-ruby-3-2 + + Use Ruby 3.2 + +commit bafeeabbe8556b5a496f9aefe3f0f36d981f81c4 +Author: Rafal Cymerys +Date: Wed Jan 18 14:31:58 2023 +0100 + + Use Ruby 3.2.0 + +commit 7feb1629511023811a413492fa6721ccda37fef4 +Author: Rafal Cymerys +Date: Wed Jan 18 14:24:09 2023 +0100 + + Update Gemfile to Spree 4.5.1 + +commit 68abd6ef77483f997c664119cb6c4e5e65c7915c +Merge: eec23f6 2400b91 +Author: Rafał Cymerys +Date: Wed Jan 18 14:22:14 2023 +0100 + + Merge pull request #1049 from spree/chore/update-start-scripts + + Update scripts for hybrid setup + +commit 2400b916392339f0626557fa1c2dd2ac8d355919 +Author: Rafal Cymerys +Date: Wed Jan 18 14:19:22 2023 +0100 + + Add yarn build to start hybrid script + +commit 6e1134b72f41d8f3988618f7695f19f0b9f2b897 +Author: Rafal Cymerys +Date: Tue Jan 17 10:07:53 2023 +0100 + + Update readme + +commit de25b6c0422b2b914622380018a18d083335a3ca +Author: Rafal Cymerys +Date: Tue Jan 17 10:06:25 2023 +0100 + + Update naming of setup scripts + +commit eec23f65634eb637e3ef24b209c3e6886f935068 +Author: Rafal Cymerys +Date: Mon Jan 16 17:12:16 2023 +0100 + + Don't load seeds during render deployment + +commit bd74cc0f6692bd2a036f49132021b6cc742ac74b +Merge: c2e5bcd 3c743c3 +Author: Rafał Cymerys +Date: Mon Jan 16 17:05:06 2023 +0100 + + Merge pull request #1050 from spree/fix/remove_incorrect_migration + + Remove migration from Spree 4.6 beta + +commit 3c743c3613aa8deb520ba653ada6ab6e3c85ba32 +Author: Rafal Cymerys +Date: Mon Jan 16 17:04:00 2023 +0100 + + Remove migration from Spree 4.6 beta + +commit 31c56e49a691a6ff7355942c50fef9451322f37e +Author: Rafal Cymerys +Date: Mon Jan 16 16:54:55 2023 +0100 + + Update scripts for hybrid setup + +commit c2e5bcdc33ac3071970e86c1f6bc199517ab0f7a +Merge: e225e51 6dfa0ac +Author: Rafał Cymerys +Date: Wed Jan 11 12:33:43 2023 +0100 + + Merge pull request #1035 from spree/dependabot/bundler/nokogiri-1.13.10 + + Bump nokogiri from 1.13.9 to 1.13.10 + +commit e225e513a85c0504fe2ce40e8713f8327186d38c +Merge: 4f93e9b 396e3b3 +Author: Rafał Cymerys +Date: Wed Jan 11 12:33:04 2023 +0100 + + Merge pull request #1037 from spree/dependabot/bundler/rails-html-sanitizer-1.4.4 + + Bump rails-html-sanitizer from 1.4.3 to 1.4.4 + +commit 4f93e9bf809264329be434f04d0856bd8c374d89 +Merge: 7a38832 81ec1e8 +Author: Rafał Cymerys +Date: Wed Dec 21 18:37:05 2022 +0100 + + Merge pull request #1039 from wjwitek/locale_in_user + + Locale in user + +commit 81ec1e87f3807dd637c2f5c29601f2446fcaa9c9 +Author: wjwitek +Date: Wed Dec 21 11:09:39 2022 +0100 + + change migration to be compatible with rails 6.1 + +commit 9629cd40ae0ad91ae1379160630f5f6be78c948c +Author: wjwitek +Date: Tue Dec 20 13:25:41 2022 +0100 + + change migration file to work for other user types + +commit f5062ad5f4fc68836c806e7d86b723e5bd0e152c +Author: wjwitek +Date: Thu Dec 15 17:17:56 2022 +0100 + + change saved_locale to selected_locale + +commit 8fddf6f5611c4468c2c7f95b812bc89d05a438da +Merge: 9cb25d0 7a38832 +Author: Weronika Witek <74113640+wjwitek@users.noreply.github.com> +Date: Thu Dec 15 11:55:18 2022 +0100 + + Merge pull request #1 from spree/main + + Fix default assets port + +commit 9cb25d0103ee5ca1828cc09ececf82800ca65786 +Author: wjwitek +Date: Thu Dec 15 11:54:04 2022 +0100 + + add column with locale to user + +commit 396e3b397067b81b545ad0be413b6b1852be2fd7 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Wed Dec 14 15:29:36 2022 +0000 + + Bump rails-html-sanitizer from 1.4.3 to 1.4.4 + + Bumps [rails-html-sanitizer](https://github.com/rails/rails-html-sanitizer) from 1.4.3 to 1.4.4. + - [Release notes](https://github.com/rails/rails-html-sanitizer/releases) + - [Changelog](https://github.com/rails/rails-html-sanitizer/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rails/rails-html-sanitizer/compare/v1.4.3...v1.4.4) + + --- + updated-dependencies: + - dependency-name: rails-html-sanitizer + dependency-type: indirect + ... + + Signed-off-by: dependabot[bot] + +commit 7a388325df71e4492ac21d6cbf19054506db351d +Author: Rafal Cymerys +Date: Wed Dec 14 12:55:19 2022 +0100 + + Fix default assets port + +commit 6dfa0acdc32fe1265e400ec61a2e1b28a6d3cae1 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Thu Dec 8 04:48:25 2022 +0000 + + Bump nokogiri from 1.13.9 to 1.13.10 + + Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.13.9 to 1.13.10. + - [Release notes](https://github.com/sparklemotion/nokogiri/releases) + - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) + - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.13.9...v1.13.10) + + --- + updated-dependencies: + - dependency-name: nokogiri + dependency-type: indirect + ... + + Signed-off-by: dependabot[bot] + +commit 7191bb645820261cb6d753f1fc79c16786f4412f +Merge: eaffda5 8005204 +Author: Rafał Cymerys +Date: Wed Dec 7 10:21:16 2022 +0100 + + Merge pull request #1034 from spree/rails-7-troubleshooting-notes + + Rails 7 troubleshooting notes + +commit eaffda55aad2f2daea019a8718276fbe75209763 +Merge: 7c5a8b1 21ea38d +Author: Rafał Cymerys +Date: Wed Dec 7 10:20:52 2022 +0100 + + Merge pull request #1031 from spree/spree-config-rails-7-compatibility + + Update spree config initialization to be compatible w rails 7 + +commit 80052042c10b85aa0de7eab49496e237c73ad56b +Author: nciemniak +Date: Wed Dec 7 09:59:43 2022 +0100 + + rollback changes to spree config file + +commit 0037feed294a54fbdd9efeb4cd3f9133b5553a39 +Author: nciemniak +Date: Wed Dec 7 09:57:20 2022 +0100 + + Update spree config initialization to be compatible w rails 7 pt2 + +commit 888ee247a02c6172a10b99afa25dd904cbe50e3d +Author: nciemniak +Date: Wed Dec 7 09:54:25 2022 +0100 + + Update spree config initialization to be compatible w rails 7 + +commit 21ea38d0afca3eaa151dcc4e536f6b081712079c +Author: nciemniak +Date: Mon Dec 5 11:43:22 2022 +0100 + + Update spree config initialization to be compatible w rails 7 + +commit 7c5a8b1486561bf7cee8aa20056f910b8605b344 (tag: v4.5.0) +Merge: fcf8236 c36f47b +Author: Rafał Cymerys +Date: Thu Dec 1 17:56:16 2022 +0100 + + Merge pull request #1028 from spree/spree-4-5-development + + Spree 4.5 + +commit c36f47be03ca991b5bf5d33ed9664984fe061142 +Author: Rafal Cymerys +Date: Thu Dec 1 17:49:18 2022 +0100 + + Use published 4.5.0 gem + +commit 77012e88da711c1e2877b8992073dddfb54616cf +Author: nciemniak +Date: Thu Dec 1 10:49:09 2022 +0100 + + Add redis to render config (#1027) + +commit 30f7c2340c365e3bae2aa2dda934fdd20b298e92 +Merge: 1392e01 10b30f1 +Author: Rafał Cymerys +Date: Fri Nov 25 10:20:08 2022 +0100 + + Merge pull request #1024 from nciemniak/feat/add-render-legacy-frontend-option + + Add deploy instructions for using legacy frontend + +commit 10b30f1ba01f6ae595c6ccc17ddeaaffbe4bfd59 +Author: nciemniak +Date: Fri Nov 25 10:00:50 2022 +0100 + + add option to deploy to render w legacy frontend + +commit 1392e015bb082363ca7472b6490f8f694af09521 +Author: nciemniak +Date: Fri Nov 25 09:36:49 2022 +0100 + + Revert "add option to deploy to render w legacy frontend" + +commit bcf2a62cd8333a90a0ab3e698c7deb1c64e3c299 +Author: nciemniak +Date: Fri Nov 25 09:33:28 2022 +0100 + + add option to deploy to render w legacy frontend + +commit 09194745aa98c01208041f8d0637a2bd6ccc621c +Author: nciemniak +Date: Mon Nov 21 10:50:03 2022 +0100 + + update spree-specific gems to latest commit SHAs + +commit b0e44ef52f16cae2504bdc664e509c19f5daa05b +Author: nciemniak +Date: Mon Nov 21 09:46:18 2022 +0100 + + run bundle update spree + +commit e2024ff65f9c135ed535745e2cd068ef0cc8fa67 +Merge: a02970f 8547f43 +Author: Rafał Cymerys +Date: Thu Nov 17 17:05:37 2022 +0100 + + Merge pull request #1022 from nciemniak/update/legacy-frontend-troubleshooting-notes + + legacy frontend troubleshooting note + +commit 8547f4359d02ac2c75f434e653400c685253b53b +Author: nciemniak +Date: Thu Nov 17 15:39:25 2022 +0100 + + link to spree_legacy_frontend troubleshooting + +commit c90ceaf6bfb8907e3b335accab548d8b34851014 +Author: nciemniak +Date: Thu Nov 17 15:36:54 2022 +0100 + + update to point to spree legacy frontend (DRY!) + +commit 674420288527f93b6e5c9a4727a0eafebc256628 +Author: nciemniak +Date: Thu Nov 17 15:28:12 2022 +0100 + + legacy frontend troubleshooting note + +commit fcf8236dccb1cb6fb19108588e77f7f52c52b22c +Merge: 0a0a2f7 7ce13fd +Author: Rafał Cymerys +Date: Mon Nov 14 13:14:37 2022 +0100 + + Merge pull request #1020 from nciemniak/update-readme-vips-info + + add vips to install instructions + +commit 7ce13fde2e1f90a0fb020cb3448ea52897f1b79c +Author: nciemniak +Date: Mon Nov 14 12:08:06 2022 +0100 + + add vips to install instructions + +commit a02970f1d586408dd84419c5b2f2bd71745d501c +Merge: 72c4801 c0231b2 +Author: Rafał Cymerys +Date: Wed Nov 9 18:58:45 2022 +0100 + + Merge pull request #1019 from nciemniak/feature/set-vips-as-default + + set vips as default image processing gem + +commit c0231b28af093bef4f9968f31fa68f53f484fa47 +Author: nciemniak +Date: Tue Nov 8 09:50:48 2022 +0100 + + set vips as default image processing gem + +commit 72c48016f55f6264c3b743a30e41a8f3f3b988ed +Author: Rafal Cymerys +Date: Mon Oct 17 14:18:09 2022 +0200 + + Update lockfile + +commit 9620e3b47d10bb5b95115311ade3da5b4987342c +Author: Rafal Cymerys +Date: Fri Sep 30 12:46:31 2022 +0200 + + Update application and environment configuration + +commit 8a83fa44b015a7efa5934a9df9b0c3d6a1e39591 +Author: Rafal Cymerys +Date: Fri Sep 30 11:37:05 2022 +0200 + + Add migrations from Spree 4.5 + +commit 001a9fbf98b8b895ffe72d9f51de6234058d6957 +Author: Rafal Cymerys +Date: Fri Sep 30 11:19:09 2022 +0200 + + Update spree_i18n dependency + +commit 51ae2cc3869cc14633fc30bf5047ccc1ed2aceeb +Author: Rafal Cymerys +Date: Fri Sep 30 11:10:00 2022 +0200 + + Fix devise initializer + +commit 14dc861c1a5fda95018da2ff7633e2438fd9c45b +Author: Rafal Cymerys +Date: Fri Sep 30 10:34:25 2022 +0200 + + Add libvips to Dockerfile + +commit 49823123e3c72a5255276a93966e9ebf26eb0886 +Author: Rafal Cymerys +Date: Fri Sep 30 10:17:30 2022 +0200 + + Use upstream spree_auth_devise and spree_gateway + +commit 40ac16d5385c24413922b249fc6f76306a9e4dec +Author: Rafal Cymerys +Date: Fri Sep 30 10:10:33 2022 +0200 + + Update ruby image for tests + +commit a4a2fe51014efbaca8bc1b8c3d2f7853f1dcd9e7 +Author: Rafal Cymerys +Date: Fri Sep 30 10:06:07 2022 +0200 + + Add libvips to the build process + +commit c9a7513b517a77fbd580bb510329ce81703a376d +Author: Rafal Cymerys +Date: Fri Sep 30 09:35:51 2022 +0200 + + Update dependencies to use upstream Spree 4.5 + +commit 0a0a2f7498a2e4eeb48926bb07d2f6bc76f312cb +Merge: 1b7d213 834530d +Author: Rafał Cymerys +Date: Tue Sep 20 11:09:16 2022 +0200 + + Merge pull request #1016 from spree/fix/lock-heroku-stack + + Lock Heroku stack to `heroku-20` in `app.json` + +commit 834530dfd5785cb593f69891b992073c3458627c +Author: Karol Szuster +Date: Tue Sep 20 11:04:24 2022 +0200 + + Lock Heroku stack to `heroku-20` in `app.json` + +commit 1b7d213ed25201c865402499db312b4a5a3ef8ed +Merge: a0a91c9 eff13b3 +Author: Rafał Cymerys +Date: Thu Sep 15 15:37:13 2022 +0200 + + Merge pull request #1015 from spree/fix/circleci_tests + + Fix CircleCi test pipeline + +commit eff13b35d6829483042a4b64ea4372dc8bf822a8 +Author: Rafal Kosla +Date: Thu Sep 15 14:25:22 2022 +0200 + + fix: fix circleci test + +commit a0a91c9e454bb592b173b38d20d4ac49476d295b +Merge: d2bfae3 fa9ccc8 +Author: Rafał Cymerys +Date: Thu Sep 15 13:01:04 2022 +0200 + + Merge pull request #1014 from spree/feat/add_hybrid_start + + Add hybrid setup + +commit fa9ccc8c4d81dc777a8af279b917d388394cafae +Author: Rafal Kosla +Date: Wed Sep 14 12:39:21 2022 +0200 + + Update README + +commit 15be33463bd59117635e137465dad863613359bc +Author: Rafal Kosla +Date: Wed Sep 14 11:09:25 2022 +0200 + + Add hybrid setup + +commit d2bfae3ec18f984f9ef36f24d117de0cd873820d +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Thu Mar 10 12:00:55 2022 +0100 + + Bump nokogiri from 1.13.1 to 1.13.3 (#996) + + Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.13.1 to 1.13.3. + - [Release notes](https://github.com/sparklemotion/nokogiri/releases) + - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) + - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.13.1...v1.13.3) + + --- + updated-dependencies: + - dependency-name: nokogiri + dependency-type: indirect + ... + + Signed-off-by: dependabot[bot] + + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit e175a72d26f720259cd86ff8f4ff558ccb4b1698 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Thu Mar 10 12:00:45 2022 +0100 + + Bump image_processing from 1.12.1 to 1.12.2 (#998) + + Bumps [image_processing](https://github.com/janko/image_processing) from 1.12.1 to 1.12.2. + - [Release notes](https://github.com/janko/image_processing/releases) + - [Changelog](https://github.com/janko/image_processing/blob/master/CHANGELOG.md) + - [Commits](https://github.com/janko/image_processing/compare/v1.12.1...v1.12.2) + + --- + updated-dependencies: + - dependency-name: image_processing + dependency-type: indirect + ... + + Signed-off-by: dependabot[bot] + + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit 56347282e5942a2a9424844f0508c475c8364231 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Wed Feb 23 14:21:03 2022 +0100 + + Bump puma from 5.6.0 to 5.6.2 (#994) + + Bumps [puma](https://github.com/puma/puma) from 5.6.0 to 5.6.2. + - [Release notes](https://github.com/puma/puma/releases) + - [Changelog](https://github.com/puma/puma/blob/master/History.md) + - [Commits](https://github.com/puma/puma/compare/v5.6.0...v5.6.2) + + --- + updated-dependencies: + - dependency-name: puma + dependency-type: direct:production + ... + + Signed-off-by: dependabot[bot] + + Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> + +commit ad8e675f9a27212ebf7e3ada875f7ab707f4b586 +Author: Damian Legawiec +Date: Wed Jan 26 14:35:23 2022 +0100 + + Use Spree 4.4 final release :rocket: + +commit 6f9d6302268fca646c7784cc44e2cb5b1e33af8f +Author: Damian Legawiec +Date: Mon Jan 10 13:52:52 2022 +0100 + + Upgrade Spree to 4.4 RC2 :rocket: + +commit 3186f4ca5d1f70f94a260fc5a99ec5fb91ca90c7 +Author: John Beynon +Date: Fri Dec 10 13:00:04 2021 +0000 + + Update render.yaml (#985) + + Specify the admin user/password as environment variables as the deploy to render fails at the `Create Admin user` prompt because it's not an interactive terminal. + +commit 996317ecf7f021ca8380672ea73c6b852d26b85d +Author: Damian Legawiec +Date: Thu Dec 9 21:55:22 2021 +0100 + + Fixed docker start command for web service + +commit 7f03f736b9e6580a782f886abcb157c7d4caa076 +Author: Damian Legawiec +Date: Thu Dec 9 12:31:42 2021 +0100 + + Update Dockerfile.production + +commit f99742cfd338d5a73b0a3fa5b3d46164a6fda2f9 +Author: Damian Legawiec +Date: Thu Dec 9 12:31:25 2021 +0100 + + Update Dockerfile.development + +commit cd68510ab6b3e67cf5d9f5d04f6e5ef3a8550eaf +Author: Damian Legawiec +Date: Sat Dec 4 19:08:22 2021 +0100 + + Update README.md + +commit 66f0fc75b22b3726bce2f87c7501798f60c499c6 +Author: Damian Legawiec +Date: Sat Dec 4 19:06:36 2021 +0100 + + Upgrade to Spree 4.4 RC1 (#986) + + * Upgrade to Spree 4.4 RC1 + + * Replace uglifier with terser + Replace mini_magick with node + + * update sidekiq + + * Bump to 4.4 RC1 from rubygems + + * Bump @spree/dashboard + + * Updated README setup instructions + + * Updated Dockerfiles to include node + + * fix node version + + * add nvm version file + +commit e7a8dbed135874eb7f0620385f1565826177084a +Author: Damian Legawiec +Date: Sun Nov 21 21:49:38 2021 +0100 + + Added missing queue for creating stock items + +commit 61982624178bffc54f65f87d4e5e248146c91ae6 +Author: Damian Legawiec +Date: Wed Nov 17 15:15:35 2021 +0100 + + Bump spree_auth_devise to 4.4.1 + +commit 615a32b0939c137ca952f40d567f82cbd8fc4600 +Author: Damian Legawiec +Date: Wed Nov 3 21:57:34 2021 +0100 + + Ensure to redirect user to admin dashboard post deploy + +commit d3d7318dbf01ea6fa4717fdce17775d76af8fd17 +Author: Damian Legawiec +Date: Wed Oct 13 23:01:49 2021 +0200 + + Replace Rails storefront with Nextjs/Vue Storefront (#982) + + * Replace rails storefront with Nextjs/Vue Storefront + + * remove outdated specs + +commit 10267bff603dab0e78af321c04c40d0f615c6721 +Author: Damian Legawiec +Date: Tue Sep 14 15:28:26 2021 +0200 + + Spree 4.3 final release 🔥 (#977) + + * Bump Spree Auth Devise to 4.4 + + * Bump spree gateway to 3.9.4 + + * Bump spree gems to 4.3 + +commit d0da06ca6a15d61ede0fdcee49561847055e8974 +Author: Damian Legawiec +Date: Mon Sep 13 13:25:24 2021 +0200 + + By default allow all hosts to connect (#975) + +commit 27db902eded805688e5067a100642e6a029efdc3 +Author: Tomek Niezgoda <1410097+tniezg@users.noreply.github.com> +Date: Mon Sep 13 13:25:15 2021 +0200 + + Change default port from 3000 to 4000 (#976) + +commit 611d3c487415d43d022bf72ff144d708a098e3ce +Author: Damian Legawiec +Date: Mon Sep 13 12:25:33 2021 +0200 + + Allow all hosts for dev environment (#974) + +commit 33658dda98e127183f0a70dcb0a45ace12353771 +Author: Damian Legawiec +Date: Thu Sep 9 18:29:30 2021 +0200 + + Update README.md + +commit 25f66a3d653107c5899790ea5871e1d74d88122d +Author: Damian Legawiec +Date: Thu Sep 9 18:27:50 2021 +0200 + + Render.com deployment PoC (#973) + + * Render.com deployment PoC + + * Setup seed data and add button + +commit 086f11edbbe76d10f3488204b2191b02b29f1298 +Author: Damian Legawiec +Date: Sun Sep 5 19:26:11 2021 +0300 + + Delete jsroutes.rb (#972) + +commit cd4aff49003f44d8c13a5d2f2323a649a1dc8353 +Author: Damian Legawiec +Date: Sun Sep 5 17:45:23 2021 +0300 + + Add ability to use Starter without Docker (#971) + +commit 5bb4f1f2660ba926f58cbc51bbebcd25aeff8cbd +Author: Damian Legawiec +Date: Tue Aug 31 00:13:25 2021 +0300 + + Bump spree to 4.3 RC3 (#969) + +commit fd51c9684a01fcc3e64d4ba244438d0e0d052b30 +Author: Tomek Niezgoda <1410097+tniezg@users.noreply.github.com> +Date: Tue Aug 24 15:01:08 2021 +0200 + + Take the 'web' service's host port from DOCKER_HOST_WEB_PORT env and default to 3000 (#967) + + Co-authored-by: tniezg + +commit f8066b57c4788ea3b16f92cbe483f07a12627ef7 +Author: Piotr Milewski +Date: Tue Aug 24 10:53:02 2021 +0200 + + [NX-9] Include CORS handling in Spree Starter (#963) + + * [NX-9] Include CORS handling in Spree Starter + + * Update config/initializers/cors.rb + + Co-authored-by: Damian Legawiec + +commit 7270e2a5282c6dd6d4e081408bf084bc487c2b18 +Author: Damian Legawiec +Date: Mon Aug 23 20:48:00 2021 +0200 + + Use Spree 4.3 RC2 and Ruby 3.0.2 :rocket: (#966) + + * Use Spree 4.3 RC2 and Ruby 3.0.2 :rocket: + + * fix + +commit d85e2b8fd2cfa4911bf86f55cf9fcb8ccd396390 +Author: Damian Legawiec +Date: Mon Aug 23 18:14:00 2021 +0200 + + Skip installing chromedriver, rely on webdrivers instead (#965) + +commit 6eccbb10a793a7650b93d4ea007b0f39b2644baa +Author: Damian Legawiec +Date: Mon Aug 23 17:33:27 2021 +0200 + + Switch to Ruby 3 (#964) + +commit a4db9d75cecb0abfe9935cd6e3c3035f5837e810 +Author: Damian Legawiec +Date: Fri Aug 20 14:05:51 2021 +0200 + + Drop webpack(er) (#960) + + * Drop webpack(er) + + It can be easily added in via https://github.com/rails/webpacker#installation + + However, we encourage everyone to use Storefront API and SDK to build a custom Storefront UI + + https://dev-docs.spreecommerce.org/getting-started/headless-commerce + +commit e9eb0df259039e756d6942431de3871a3bd4599f +Author: Damian Legawiec +Date: Fri Aug 20 12:44:23 2021 +0200 + + Use node 16 and ruby 2.7.4 (#959) + + * Use node 16 and ruby 2.7.4 + + * Bump Postgres to v13 + +commit 420b8b174edd0d8b3eba7cae77cf41b99a06bb82 +Author: Damian Legawiec +Date: Tue Aug 17 23:47:13 2021 +0200 + + Update session_store.rb (#958) + +commit 84a5b8a113d80c392a9bebd63650c7cb1e1cb834 +Author: Damian Legawiec +Date: Tue Aug 17 16:20:46 2021 +0200 + + Delete spree_storefront.rb + +commit 9a13444d49096e588cce800ca1425be200f80f39 +Author: Damian Legawiec +Date: Tue Aug 17 16:20:32 2021 +0200 + + Delete spree_storefront.yml + +commit 133a6a343bab38f7efca41706f649504460de889 +Author: Damian Legawiec +Date: Wed Aug 11 19:04:49 2021 +0200 + + Use Spree 4.3 RC1 :rocket: (#954) + +commit 378942b1459e38f084d4d6ece753e1b7ae24bbb0 +Author: Damian Legawiec +Date: Tue Aug 10 10:03:58 2021 +0200 + + Delete 20170201152991_make_existing_credit_cards_default.spree.rb + + Connected to https://github.com/spree/spree/commit/5165564429d336d027fd021ee7a7b96d3606b2ca + +commit a6b7cb9bdd8e8dd71c31975a574be03426b74b2b +Author: Damian Legawiec +Date: Tue Aug 3 12:09:11 2021 +0200 + + Remove forced available locales + +commit 426677455a570dbdbd800923d012e5c98060ece2 +Merge: bc196d6 d58766e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Aug 2 06:18:32 2021 +0000 + + Merge pull request #944 from spree/dependabot/bundler/aws-sdk-s3-1.98.0 + +commit d58766e9af8cd4a9e97ac040faac1770acdca81f +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Aug 2 06:14:44 2021 +0000 + + Bump aws-sdk-s3 from 1.97.0 to 1.98.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.97.0 to 1.98.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit bc196d6b23b60e3b83098ec478594bc6122826d6 +Merge: 29e6a57 f004e04 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jul 30 06:21:52 2021 +0000 + + Merge pull request #943 from spree/dependabot/bundler/puma-5.4.0 + +commit f004e04cd7baf80bf12a74531a4d06515d202927 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jul 30 06:17:56 2021 +0000 + + Bump puma from 5.3.2 to 5.4.0 + + Bumps [puma](https://github.com/puma/puma) from 5.3.2 to 5.4.0. + - [Release notes](https://github.com/puma/puma/releases) + - [Changelog](https://github.com/puma/puma/blob/master/History.md) + - [Commits](https://github.com/puma/puma/compare/v5.3.2...v5.4.0) + + Signed-off-by: dependabot-preview[bot] + +commit 29e6a5776381176fc1b14f9273424d52e31a490f +Merge: a6800ad e50973b +Author: Damian Legawiec +Date: Thu Jul 29 08:35:19 2021 +0200 + + Merge pull request #941 from spree/feature/add-oj + + Add oj gem to improve JSON API performance + +commit a6800ad5f6e569a00ccab8e6929c943704ebf25f +Merge: 9e429c7 8b7317b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Jul 29 06:22:11 2021 +0000 + + Merge pull request #942 from spree/dependabot/bundler/aws-sdk-s3-1.97.0 + +commit 8b7317b02c91e603e855465ffcc05bbbaf9c40d1 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Jul 29 06:18:46 2021 +0000 + + Bump aws-sdk-s3 from 1.96.2 to 1.97.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.96.2 to 1.97.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit e50973be8e8833f5d6eeaa0226f322746a860cd2 +Author: Damian Legawiec +Date: Wed Jul 28 23:25:58 2021 +0200 + + Add oj gem to improve JSON API performance + +commit 9e429c7b9b9c15f2ce35b33998b505c6b9afeb78 +Merge: b5b1c1e ae646ed +Author: Damian Legawiec +Date: Tue Jul 27 09:03:02 2021 +0200 + + Merge pull request #937 from spree/fix/session-multi-store + + Use session across main domain and subdomains for multi store support + +commit b5b1c1efd399a4130ead69df5acfd690b8edf6c0 +Merge: 0fa7e10 1b6070a +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Jul 21 06:23:28 2021 +0000 + + Merge pull request #938 from spree/dependabot/bundler/aws-sdk-s3-1.96.2 + +commit 1b6070a032941d6086169da56497695103c84d59 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Jul 21 06:20:14 2021 +0000 + + Bump aws-sdk-s3 from 1.96.1 to 1.96.2 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.96.1 to 1.96.2. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit ae646ed3f056bcf6ab07160bba071bad0be81299 +Author: Damian Legawiec +Date: Thu Jul 15 15:48:55 2021 +0200 + + Use session across main domain and subdomains for multi store support + +commit 0fa7e109f6b42835722b55f8484b1cd748f76acb +Merge: ed3b8a3 5835e97 +Author: Damian Legawiec +Date: Tue Jul 13 11:57:35 2021 +0200 + + Merge pull request #936 from spree/dependabot/bundler/addressable-2.8.0 + + [Security] Bump addressable from 2.7.0 to 2.8.0 + +commit 5835e975350e6983ed266f225e870f03cc66dc65 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Jul 12 17:37:18 2021 +0000 + + [Security] Bump addressable from 2.7.0 to 2.8.0 + + Bumps [addressable](https://github.com/sporkmonger/addressable) from 2.7.0 to 2.8.0. **This update includes a security fix.** + - [Release notes](https://github.com/sporkmonger/addressable/releases) + - [Changelog](https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md) + - [Commits](https://github.com/sporkmonger/addressable/compare/addressable-2.7.0...addressable-2.8.0) + + Signed-off-by: dependabot-preview[bot] + +commit ed3b8a32b8b0d274077745d3f36fb1a18a980f25 +Merge: aa910bb ff7247c +Author: Damian Legawiec +Date: Sun Jun 27 13:05:58 2021 +0200 + + Merge pull request #933 from spree/fix/spree-4-3-preps + + Preparations for Spree 4.3 + +commit ff7247cb46e67396830021183b8ab6da8e53de6a +Author: Damian Legawiec +Date: Sun Jun 27 12:52:16 2021 +0200 + + Preparations for Spree 4.3 + +commit aa910bbe3c5ba6898210024ebed7de59894c172d +Merge: 43a14a6 53e6e43 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jun 25 06:25:27 2021 +0000 + + Merge pull request #932 from spree/dependabot/bundler/rails-6.1.4 + +commit 53e6e437d9fcf9d26271b6cdb5552d15cbdacfd5 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jun 25 06:22:20 2021 +0000 + + Bump rails from 6.1.3.2 to 6.1.4 + + Bumps [rails](https://github.com/rails/rails) from 6.1.3.2 to 6.1.4. + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v6.1.3.2...v6.1.4) + + Signed-off-by: dependabot-preview[bot] + +commit 43a14a648fafd1a98ef50ddf00387e6aa2a2d141 +Merge: b803b23 58813e7 +Author: Damian Legawiec +Date: Tue Jun 15 17:13:52 2021 +0200 + + Merge pull request #926 from spree/dependabot/npm_and_yarn/ws-6.2.2 + + Bump ws from 6.2.1 to 6.2.2 + +commit b803b231fc0d40bee172749585f8057f67a693aa +Merge: c3fd038 047800d +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jun 11 06:17:32 2021 +0000 + + Merge pull request #930 from spree/dependabot/bundler/aws-sdk-s3-1.96.1 + +commit 047800daaa5d9d4b8e095864202823a878d65527 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jun 11 06:14:51 2021 +0000 + + Bump aws-sdk-s3 from 1.96.0 to 1.96.1 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.96.0 to 1.96.1. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit c3fd0383857c507399b19205443bb2c548556d8e +Merge: ec08231 2c61d16 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Jun 9 06:25:21 2021 +0000 + + Merge pull request #929 from spree/dependabot/bundler/scout_apm-4.1.1 + +commit 2c61d1699e51db1b0a6d984cef87825fc08b942b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Jun 9 06:21:41 2021 +0000 + + Bump scout_apm from 4.1.0 to 4.1.1 + + Bumps [scout_apm](https://github.com/scoutapp/scout_apm_ruby) from 4.1.0 to 4.1.1. + - [Release notes](https://github.com/scoutapp/scout_apm_ruby/releases) + - [Changelog](https://github.com/scoutapp/scout_apm_ruby/blob/master/CHANGELOG.markdown) + - [Commits](https://github.com/scoutapp/scout_apm_ruby/compare/v4.1.0...v4.1.1) + + Signed-off-by: dependabot-preview[bot] + +commit ec0823123daf668c08595bacf1c2e04e93bb08ef +Merge: d673159 06c7e48 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jun 4 06:24:24 2021 +0000 + + Merge pull request #928 from spree/dependabot/bundler/aws-sdk-s3-1.96.0 + +commit 06c7e48f517d8c130038f2c1c8f5bfbf62813286 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jun 4 06:20:50 2021 +0000 + + Bump aws-sdk-s3 from 1.95.1 to 1.96.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.95.1 to 1.96.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 58813e7bbaddc4f43a6552d3c671ee33b7fc4aa1 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Thu Jun 3 07:43:22 2021 +0000 + + Bump ws from 6.2.1 to 6.2.2 + + Bumps [ws](https://github.com/websockets/ws) from 6.2.1 to 6.2.2. + - [Release notes](https://github.com/websockets/ws/releases) + - [Commits](https://github.com/websockets/ws/commits) + + --- + updated-dependencies: + - dependency-name: ws + dependency-type: indirect + ... + + Signed-off-by: dependabot[bot] + +commit d673159b8c9563f8886d3dc801e504904705c20d +Merge: c8e0f83 711004e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Jun 3 06:27:35 2021 +0000 + + Merge pull request #925 from spree/dependabot/bundler/scout_apm-4.1.0 + +commit 711004e03574e4547ad5f6ca909f94837706bfa8 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Jun 3 06:23:27 2021 +0000 + + Bump scout_apm from 4.0.4 to 4.1.0 + + Bumps [scout_apm](https://github.com/scoutapp/scout_apm_ruby) from 4.0.4 to 4.1.0. + - [Release notes](https://github.com/scoutapp/scout_apm_ruby/releases) + - [Changelog](https://github.com/scoutapp/scout_apm_ruby/blob/master/CHANGELOG.markdown) + - [Commits](https://github.com/scoutapp/scout_apm_ruby/compare/v4.0.4...v4.1.0) + + Signed-off-by: dependabot-preview[bot] + +commit c8e0f834371abcb741944a7fd6452fd95fb65c87 +Merge: e96f4df 9dbaa69 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Jun 1 06:20:19 2021 +0000 + + Merge pull request #924 from spree/dependabot/bundler/spree-4.2.5 + +commit 9dbaa6967173880f122976e64661fd07649d419b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Jun 1 06:16:45 2021 +0000 + + Bump spree from 4.2.4 to 4.2.5 + + Bumps [spree](https://github.com/spree/spree) from 4.2.4 to 4.2.5. + - [Release notes](https://github.com/spree/spree/releases) + - [Commits](https://github.com/spree/spree/commits/v4.2.5) + + Signed-off-by: dependabot-preview[bot] + +commit e96f4df850f990536e760ad8f541ab25890233e9 +Merge: b9a2286 b0c92d2 +Author: Damian Legawiec +Date: Fri May 28 16:44:37 2021 +0200 + + Merge pull request #923 from spree/dependabot/npm_and_yarn/dns-packet-1.3.4 + + Bump dns-packet from 1.3.1 to 1.3.4 + +commit b0c92d227e28c2a21d588a20f0d5dfef64e5fb00 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Thu May 27 08:54:31 2021 +0000 + + Bump dns-packet from 1.3.1 to 1.3.4 + + Bumps [dns-packet](https://github.com/mafintosh/dns-packet) from 1.3.1 to 1.3.4. + - [Release notes](https://github.com/mafintosh/dns-packet/releases) + - [Changelog](https://github.com/mafintosh/dns-packet/blob/master/CHANGELOG.md) + - [Commits](https://github.com/mafintosh/dns-packet/compare/v1.3.1...v1.3.4) + + Signed-off-by: dependabot[bot] + +commit b9a2286f1bcd673964c684b8e161ad33b72046d6 +Merge: a177902 b364c71 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon May 24 19:13:45 2021 +0000 + + Merge pull request #922 from spree/dependabot/bundler/aws-sdk-s3-1.95.1 + +commit b364c71ed7de7cc7018e104f17aa997b29d88cc6 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon May 24 19:10:30 2021 +0000 + + Bump aws-sdk-s3 from 1.95.0 to 1.95.1 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.95.0 to 1.95.1. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit a17790260eac9a25b9fc2d354326ba5256513a7f +Merge: da576b8 22df01d +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri May 21 19:11:14 2021 +0000 + + Merge pull request #921 from spree/dependabot/bundler/aws-sdk-s3-1.95.0 + +commit 22df01d52d7d3ac0d6915b204bd2af2c0289c53b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri May 21 19:08:17 2021 +0000 + + Bump aws-sdk-s3 from 1.94.1 to 1.95.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.94.1 to 1.95.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit da576b861d2dd699aab56a788af00334879482f6 +Merge: 7081c76 8c6ce22 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri May 21 17:36:06 2021 +0000 + + Merge pull request #920 from spree/dependabot/bundler/puma-5.3.2 + +commit 8c6ce229fad8be7473631f32d4775e877a862e5c +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri May 21 17:32:46 2021 +0000 + + Bump puma from 5.3.1 to 5.3.2 + + Bumps [puma](https://github.com/puma/puma) from 5.3.1 to 5.3.2. + - [Release notes](https://github.com/puma/puma/releases) + - [Changelog](https://github.com/puma/puma/blob/master/History.md) + - [Commits](https://github.com/puma/puma/compare/v5.3.1...v5.3.2) + + Signed-off-by: dependabot-preview[bot] + +commit 7081c76c1bdcad26c166bba063777f4a4fd238a6 +Merge: 229997d 33b235e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu May 20 21:25:43 2021 +0000 + + Merge pull request #919 from spree/dependabot/bundler/webpacker-5.4.0 + +commit 33b235efc3468431a3764c237f047b650a8aa62e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue May 18 10:56:38 2021 +0000 + + Bump webpacker from 5.3.0 to 5.4.0 + + Bumps [webpacker](https://github.com/rails/webpacker) from 5.3.0 to 5.4.0. + - [Release notes](https://github.com/rails/webpacker/releases) + - [Changelog](https://github.com/rails/webpacker/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rails/webpacker/compare/v5.3.0...v5.4.0) + + Signed-off-by: dependabot-preview[bot] + +commit 229997de510ab36b57e78e704cacd4c2f92c2500 +Merge: 16c87f5 2404476 +Author: Damian Legawiec +Date: Mon May 17 21:37:14 2021 +0200 + + Merge pull request #918 from spree/fix/clean-up-gemfile + + Tidy up Gemfile + +commit 2404476fd4fd86de57ebb09947ca68edac378ee3 +Author: Damian Legawiec +Date: Mon May 17 20:19:36 2021 +0200 + + Don't need to require this in the app, it's declared in Spree + +commit c84373dc5cb10372d74e1412c499e5800c3bc48c +Author: Damian Legawiec +Date: Mon May 17 20:18:51 2021 +0200 + + Remove unused and outdated gems to make the build smaller + +commit 16c87f5b4ff497ce2fc180ee144ae9b4eaac3d71 +Merge: 756ac3c 9e690c1 +Author: Damian Legawiec +Date: Mon May 17 15:09:40 2021 +0200 + + Merge pull request #917 from spree/dependabot/bundler/spree-4.2.4 + + Bump spree from 4.2.3.1 to 4.2.4 + +commit 9e690c15651cce7be547db06d017c3aa6384a7fc +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon May 17 12:35:09 2021 +0000 + + Bump spree from 4.2.3.1 to 4.2.4 + + Bumps [spree](https://github.com/spree/spree) from 4.2.3.1 to 4.2.4. + - [Release notes](https://github.com/spree/spree/releases) + - [Commits](https://github.com/spree/spree/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 756ac3c57ffc9f8b25a1e31daf39d7caadbb4be5 +Merge: 3f3e8ac 5e381e8 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue May 11 15:01:44 2021 +0000 + + Merge pull request #914 from spree/dependabot/bundler/puma-5.3.1 + +commit 5e381e8b90203fb0745a4b57bfbe433db7cdf97b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue May 11 14:57:33 2021 +0000 + + Bump puma from 5.3.0 to 5.3.1 + + Bumps [puma](https://github.com/puma/puma) from 5.3.0 to 5.3.1. + - [Release notes](https://github.com/puma/puma/releases) + - [Changelog](https://github.com/puma/puma/blob/master/History.md) + - [Commits](https://github.com/puma/puma/compare/v5.3.0...v5.3.1) + + Signed-off-by: dependabot-preview[bot] + +commit 3f3e8ac31564cf1817a0bb80a2f19096512c9898 +Merge: 1cd2a6c c5904c9 +Author: Damian Legawiec +Date: Sun May 9 19:22:22 2021 +0200 + + Merge pull request #909 from spree/fix/SD-1322 + + Webpack clean install + +commit 1cd2a6c60843660f68265a270529f7b66a3bd047 +Merge: 4f07f70 6e255f8 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri May 7 14:55:57 2021 +0000 + + Merge pull request #911 from spree/dependabot/bundler/puma-5.3.0 + +commit 6e255f81ff762260dded5ce522ce71b26044ce0a +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri May 7 14:51:28 2021 +0000 + + Bump puma from 5.2.2 to 5.3.0 + + Bumps [puma](https://github.com/puma/puma) from 5.2.2 to 5.3.0. + - [Release notes](https://github.com/puma/puma/releases) + - [Changelog](https://github.com/puma/puma/blob/master/History.md) + - [Commits](https://github.com/puma/puma/compare/v5.2.2...v5.3.0) + + Signed-off-by: dependabot-preview[bot] + +commit c5904c956e13572a6f98731eecec033d99307cb5 +Author: Damian Kaczmarczyk +Date: Thu May 6 09:23:28 2021 +0200 + + Webpack clean install + +commit 4f07f702360e7df64ebf2101eb7fdc99b36d9d32 +Merge: 1d9eb36 98f1a20 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed May 5 18:56:28 2021 +0000 + + Merge pull request #907 from spree/dependabot/bundler/spree-4.2.3.1 + +commit 98f1a20100e42bfc32b90cf6dddca2a4143ec0fe +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed May 5 18:52:38 2021 +0000 + + Bump spree from 4.2.3 to 4.2.3.1 + + Bumps [spree](https://github.com/spree/spree) from 4.2.3 to 4.2.3.1. + - [Release notes](https://github.com/spree/spree/releases) + - [Commits](https://github.com/spree/spree/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 1d9eb36e224e88c1e720a7517dcdf64459334cae +Merge: 99897c2 75a67c4 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed May 5 15:55:48 2021 +0000 + + Merge pull request #906 from spree/dependabot/bundler/rails-6.1.3.2 + +commit 75a67c49f76655624d29d1c6a64ead9b72a7967b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed May 5 15:50:49 2021 +0000 + + Bump rails from 6.1.3.1 to 6.1.3.2 + + Bumps [rails](https://github.com/rails/rails) from 6.1.3.1 to 6.1.3.2. + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v6.1.3.1...v6.1.3.2) + + Signed-off-by: dependabot-preview[bot] + +commit 99897c283e3fff92232dbaae8548079ea3f199f6 +Merge: 03fe4c6 7bc9a1e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed May 5 11:17:04 2021 +0000 + + Merge pull request #887 from spree/dependabot/bundler/mini_racer-0.4.0 + +commit 7bc9a1e24aff4cbb765d35f613194eba4d1b8aa9 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed May 5 11:13:40 2021 +0000 + + Bump mini_racer from 0.3.1 to 0.4.0 + + Bumps [mini_racer](https://github.com/discourse/mini_racer) from 0.3.1 to 0.4.0. + - [Release notes](https://github.com/discourse/mini_racer/releases) + - [Changelog](https://github.com/rubyjs/mini_racer/blob/master/CHANGELOG) + - [Commits](https://github.com/discourse/mini_racer/compare/v0.3.1...v0.4.0) + + Signed-off-by: dependabot-preview[bot] + +commit 03fe4c67725666da1cd63d34f9181c4f83dc2808 +Merge: 6e49ef5 35123b4 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed May 5 11:11:42 2021 +0000 + + Merge pull request #905 from spree/dependabot/bundler/spree-4.2.3 + +commit 35123b432672ecd7b9f5cbed276490e0e0fa0534 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed May 5 11:07:50 2021 +0000 + + Bump spree from 4.2.2 to 4.2.3 + + Bumps [spree](https://github.com/spree/spree) from 4.2.2 to 4.2.3. + - [Release notes](https://github.com/spree/spree/releases) + - [Commits](https://github.com/spree/spree/compare/v4.2.2...v4.2.3) + + Signed-off-by: dependabot-preview[bot] + +commit 6e49ef55c9495cd110b7e56226ea22d2f3b94c28 +Merge: b378fc5 29bdbc4 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed May 5 03:46:55 2021 +0000 + + Merge pull request #904 from spree/dependabot/bundler/aws-sdk-s3-1.94.1 + +commit 29bdbc4299a0de38bfb113aee138e2bf7185ff4c +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed May 5 03:42:23 2021 +0000 + + Bump aws-sdk-s3 from 1.94.0 to 1.94.1 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.94.0 to 1.94.1. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit b378fc583823552564333ac84e388a28941dcd40 +Merge: 4d9b362 7b2a975 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Apr 29 22:14:36 2021 +0000 + + Merge pull request #900 from spree/dependabot/bundler/rack-mini-profiler-2.3.2 + +commit 7b2a97567b71a6aa3bb7efbf9174033ec7801afc +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Apr 29 22:11:51 2021 +0000 + + Bump rack-mini-profiler from 2.3.1 to 2.3.2 + + Bumps [rack-mini-profiler](https://github.com/MiniProfiler/rack-mini-profiler) from 2.3.1 to 2.3.2. + - [Release notes](https://github.com/MiniProfiler/rack-mini-profiler/releases) + - [Changelog](https://github.com/MiniProfiler/rack-mini-profiler/blob/master/CHANGELOG.md) + - [Commits](https://github.com/MiniProfiler/rack-mini-profiler/compare/v2.3.1...v2.3.2) + + Signed-off-by: dependabot-preview[bot] + +commit 4d9b3621a8692d3eb90d84d4f4d31cd21e7429bb +Merge: 4ef31e8 a2ac6ac +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 28 16:38:09 2021 +0000 + + Merge pull request #898 from spree/dependabot/bundler/webpacker-5.3.0 + +commit 4ef31e815134103db2aea3e4b74c2fd001b29de6 +Merge: 15e66af 3818f5c +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 28 16:37:32 2021 +0000 + + Merge pull request #895 from spree/dependabot/bundler/spree-4.2.2 + +commit 15e66afbbada061d0a023b80a01f0d69599f0600 +Merge: e724e5a 9837634 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 28 10:05:10 2021 +0000 + + Merge pull request #899 from spree/dependabot/bundler/aws-sdk-s3-1.94.0 + +commit 98376348d268469014e8fab699e3441f56f81840 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 28 10:01:47 2021 +0000 + + Bump aws-sdk-s3 from 1.93.0 to 1.94.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.93.0 to 1.94.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit a2ac6ac57520d3c713ba5190fd96d399576b92cc +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 28 08:48:37 2021 +0000 + + Bump webpacker from 5.2.1 to 5.3.0 + + Bumps [webpacker](https://github.com/rails/webpacker) from 5.2.1 to 5.3.0. + - [Release notes](https://github.com/rails/webpacker/releases) + - [Changelog](https://github.com/rails/webpacker/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rails/webpacker/compare/v5.2.1...v5.3.0) + + Signed-off-by: dependabot-preview[bot] + +commit 3818f5c977af399e8925ac07f01fa2cc58aea7ef +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Apr 27 19:37:55 2021 +0000 + + Bump spree from 4.2.1 to 4.2.2 + + Bumps [spree](https://github.com/spree/spree) from 4.2.1 to 4.2.2. + - [Release notes](https://github.com/spree/spree/releases) + - [Commits](https://github.com/spree/spree/compare/v4.2.1...v4.2.2) + + Signed-off-by: dependabot-preview[bot] + +commit e724e5a886e5995fba835c25405e7264b264ca65 +Merge: 2c88f5d 9fbd466 +Author: Damian Legawiec +Date: Tue Apr 27 14:13:59 2021 +0200 + + Merge pull request #892 from spree/dependabot/npm_and_yarn/ssri-6.0.2 + + Bump ssri from 6.0.1 to 6.0.2 + +commit 2c88f5d3b6b2dd953dc9e899f22400a4cbb81a63 +Merge: cc4a84f 1eb39e1 +Author: Damian Legawiec +Date: Tue Apr 27 13:48:13 2021 +0200 + + Merge pull request #893 from spree/dependabot/bundler/bootsnap-1.7.4 + + Bump bootsnap from 1.7.2 to 1.7.4 + +commit 1eb39e1065b299c655ca2ef5a6c94e9620e61409 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Apr 22 07:00:24 2021 +0000 + + Bump bootsnap from 1.7.2 to 1.7.4 + + Bumps [bootsnap](https://github.com/Shopify/bootsnap) from 1.7.2 to 1.7.4. + - [Release notes](https://github.com/Shopify/bootsnap/releases) + - [Changelog](https://github.com/Shopify/bootsnap/blob/master/CHANGELOG.md) + - [Commits](https://github.com/Shopify/bootsnap/compare/v1.7.2...v1.7.4) + + Signed-off-by: dependabot-preview[bot] + +commit 9fbd466d5386bd232e2a2fe0b6e6015eb77b9a39 +Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> +Date: Mon Apr 19 15:40:41 2021 +0000 + + Bump ssri from 6.0.1 to 6.0.2 + + Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2. + - [Release notes](https://github.com/npm/ssri/releases) + - [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md) + - [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2) + + Signed-off-by: dependabot[bot] + +commit cc4a84f4527c8abd82cad18a1ff7b01b5c06329c +Merge: 66e11a7 10fdd5e +Author: Damian Legawiec +Date: Tue Apr 13 22:19:39 2021 +0200 + + Merge pull request #891 from spree/fix/docker-builds + + Fix production docker builds + +commit 10fdd5ea6f1b1b67f49586466ca911a0d26ddb21 +Author: Damian Legawiec +Date: Tue Apr 13 22:19:13 2021 +0200 + + Fix production docker builds + +commit 66e11a72ff31e2d345e3a1d948d7ecfb6445cedc +Author: Damian Legawiec +Date: Tue Apr 13 20:42:39 2021 +0200 + + Update config.yml + +commit 802be29e107b429809d9fd8482daa883435d1667 +Merge: a546fb5 53c073d +Author: Damian Legawiec +Date: Tue Apr 13 19:20:30 2021 +0200 + + Merge pull request #890 from spree/fix/883-docker-ports + + Fix https://github.com/spree/spree_starter/issues/883 do not expose P… + +commit 53c073d9fb5362003efcc63970d552df907d5392 +Author: Damian Legawiec +Date: Tue Apr 13 19:18:21 2021 +0200 + + Fix https://github.com/spree/spree_starter/issues/883 do not expose Postgres/Redis ports + +commit a546fb5cf45ea248c6efc0df20fade42f78d3284 +Merge: f01a9c7 5562fea +Author: Damian Legawiec +Date: Tue Apr 13 19:05:18 2021 +0200 + + Merge pull request #889 from spree/fix/ruby-2-7-3-rails-6-1-3 + + Bump Ruby to 2.7.3 + +commit 5562fea1ab788b5173073dc1b1d8730cb6d589d5 +Author: Damian Legawiec +Date: Tue Apr 13 19:02:25 2021 +0200 + + Bump Ruby to 2.7.3 + +commit f01a9c7fff8c14db62b0c1ac989e369f677d0044 +Merge: e2693b2 927b400 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Mar 29 16:18:25 2021 +0000 + + Merge pull request #884 from spree/dependabot/bundler/sentry-raven-3.1.2 + +commit 927b4005d18a03d7a659b74c4b1b8b34f8bf133c +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Mar 29 16:15:34 2021 +0000 + + Bump sentry-raven from 3.1.1 to 3.1.2 + + Bumps [sentry-raven](https://github.com/getsentry/raven-ruby) from 3.1.1 to 3.1.2. + - [Release notes](https://github.com/getsentry/raven-ruby/releases) + - [Commits](https://github.com/getsentry/raven-ruby/compare/3.1.1...sentry-raven-v3.1.2) + + Signed-off-by: dependabot-preview[bot] + +commit e2693b2bf232b6fd3b9c2a523ff39cf6b0bcce57 +Merge: 9253c82 f0d1838 +Author: Damian Legawiec +Date: Mon Mar 29 13:40:40 2021 +0200 + + Merge pull request #879 from Vegann/feature/sprockets-update-manifest + + Add manifest.js for the Sprockets update + +commit 9253c821fe8618be5d6d530643bec489d9d047d8 +Merge: 65543c8 6a8336e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Mar 26 18:19:43 2021 +0000 + + Merge pull request #881 from spree/dependabot/bundler/rails-6.1.3.1 + +commit 6a8336ef7d3cdc6e478ba7b7becef0643c44375c +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Mar 26 18:16:37 2021 +0000 + + Bump rails from 6.1.3 to 6.1.3.1 + + Bumps [rails](https://github.com/rails/rails) from 6.1.3 to 6.1.3.1. + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v6.1.3...v6.1.3.1) + + Signed-off-by: dependabot-preview[bot] + +commit f0d18385ddbed5dd8e86f75bd75592e31e3d9286 +Author: Damian Kaczmarczyk +Date: Fri Mar 26 08:48:29 2021 +0100 + + Add manifest.js for the Sprockets update + +commit 65543c82e2cd56d6a4c11c99de1ef12c0c60538a +Merge: 6a7e54e 455034a +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Mar 24 19:29:49 2021 +0000 + + Merge pull request #878 from spree/dependabot/bundler/aws-sdk-s3-1.93.0 + +commit 455034aeadebe4d60cc55c66b995658c52935fcf +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Mar 24 19:26:27 2021 +0000 + + Bump aws-sdk-s3 from 1.90.0 to 1.93.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.90.0 to 1.93.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 6a7e54e4b44b64f0cc5dbd7b024bef4297b29c84 +Merge: 37f14e9 3ffb5cd +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Mar 15 19:30:46 2021 +0000 + + Merge pull request #873 from spree/dependabot/bundler/sidekiq-6.2.0 + +commit 3ffb5cd68f5abbd19cabb8414f9fcc274966f8ec +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Mar 15 19:27:43 2021 +0000 + + Bump sidekiq from 6.1.3 to 6.2.0 + + Bumps [sidekiq](https://github.com/mperham/sidekiq) from 6.1.3 to 6.2.0. + - [Release notes](https://github.com/mperham/sidekiq/releases) + - [Changelog](https://github.com/mperham/sidekiq/blob/master/Changes.md) + - [Commits](https://github.com/mperham/sidekiq/compare/v6.1.3...v6.2.0) + + Signed-off-by: dependabot-preview[bot] + +commit 37f14e94e56cd4685202940a893079661098da2e +Merge: b47e575 c1a7149 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Mar 11 14:07:32 2021 +0000 + + Merge pull request #872 from spree/dependabot/bundler/spree_dev_tools-0.1.8 + +commit c1a7149fc6bc80acc8f315fe88c1adbb3470b4fd +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Mar 11 09:31:48 2021 +0000 + + Bump spree_dev_tools from 0.1.7 to 0.1.8 + + Bumps [spree_dev_tools](https://github.com/spree/spree_dev_tools) from 0.1.7 to 0.1.8. + - [Release notes](https://github.com/spree/spree_dev_tools/releases) + - [Commits](https://github.com/spree/spree_dev_tools/compare/v0.1.7...v0.1.8) + + Signed-off-by: dependabot-preview[bot] + +commit b47e575c368f9f814b2353d89468a0cbe0d1c14f +Merge: 4f66e63 617e68d +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Mar 8 20:14:23 2021 +0000 + + Merge pull request #869 from spree/dependabot/bundler/aws-sdk-s3-1.90.0 + +commit 617e68db69104ada12412edd624d8bbdd4483ad1 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Mar 8 20:11:59 2021 +0000 + + Bump aws-sdk-s3 from 1.89.0 to 1.90.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.89.0 to 1.90.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 4f66e6324decf2e93232f5cac6b22010125f6d16 +Merge: 6853312 1c4f196 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Mar 8 07:24:24 2021 +0000 + + Merge pull request #868 from spree/dependabot/bundler/spree-4.2.1 + +commit 1c4f19614ceca72fd7aff07c53515e853d3125d3 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Mar 8 07:21:45 2021 +0000 + + Bump spree from 4.2.0 to 4.2.1 + + Bumps [spree](https://github.com/spree/spree) from 4.2.0 to 4.2.1. + - [Release notes](https://github.com/spree/spree/releases) + - [Commits](https://github.com/spree/spree/compare/v4.2.0...v4.2.1) + + Signed-off-by: dependabot-preview[bot] + +commit 68533123a008d90d7a02166612b437aa537d3807 +Merge: ebb2936 bffb4de +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sun Mar 7 18:16:57 2021 +0000 + + Merge pull request #867 from spree/dependabot/bundler/awesome_print-1.9.2 + +commit bffb4de135692c658d72a570a429a5ceb4d7e52e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sun Mar 7 18:13:49 2021 +0000 + + Bump awesome_print from 1.8.0 to 1.9.2 + + Bumps [awesome_print](https://github.com/awesome-print/awesome_print) from 1.8.0 to 1.9.2. + - [Release notes](https://github.com/awesome-print/awesome_print/releases) + - [Changelog](https://github.com/awesome-print/awesome_print/blob/master/CHANGELOG.md) + - [Commits](https://github.com/awesome-print/awesome_print/compare/v1.8.0...v1.9.2) + + Signed-off-by: dependabot-preview[bot] + +commit ebb293685b8e3ddf9a3924709d6d57eb54e95cba +Merge: 67af0db 610855a +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Mar 2 16:17:51 2021 +0000 + + Merge pull request #864 from spree/dependabot/bundler/puma-5.2.2 + +commit 610855a6dcc7f5a076b7dffea856a363958d43fd +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Mar 2 16:13:53 2021 +0000 + + Bump puma from 5.2.1 to 5.2.2 + + Bumps [puma](https://github.com/puma/puma) from 5.2.1 to 5.2.2. + - [Release notes](https://github.com/puma/puma/releases) + - [Changelog](https://github.com/puma/puma/blob/master/History.md) + - [Commits](https://github.com/puma/puma/compare/v5.2.1...v5.2.2) + + Signed-off-by: dependabot-preview[bot] + +commit 67af0db8a0bd15b9aa7d252bd818c899ac24d103 +Merge: ca2ffc4 2a46b1d +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Feb 26 20:10:18 2021 +0000 + + Merge pull request #862 from spree/dependabot/bundler/aws-sdk-s3-1.89.0 + +commit 2a46b1d928fabbc38b050f8e576610a0fa999fe4 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Feb 26 20:07:50 2021 +0000 + + Bump aws-sdk-s3 from 1.88.1 to 1.89.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.88.1 to 1.89.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit ca2ffc4ea6a5415b5e66b7d7a568f3b99d86e86d +Author: Damian Legawiec +Date: Thu Feb 25 09:59:17 2021 +0100 + + Use Spree 4.2 final :rocket: + +commit ca6ad55e37a239686de051b6071876f666e79814 +Merge: e2e9f68 6ac4bcd +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Feb 24 15:28:00 2021 +0000 + + Merge pull request #855 from spree/dependabot/bundler/spree_auth_devise-4.3.4 + +commit 6ac4bcd7cf1f931a4fe29f516fc8e4cd6e05ec5f +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Feb 24 15:24:56 2021 +0000 + + Bump spree_auth_devise from 4.3.3 to 4.3.4 + + Bumps [spree_auth_devise](https://github.com/spree/spree_auth_devise) from 4.3.3 to 4.3.4. + - [Release notes](https://github.com/spree/spree_auth_devise/releases) + - [Changelog](https://github.com/spree/spree_auth_devise/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree_auth_devise/compare/v4.3.3...v4.3.4) + + Signed-off-by: dependabot-preview[bot] + +commit e2e9f68beb5b878aa9d1596e04d0228d626b7aca +Author: Damian Legawiec +Date: Mon Feb 22 19:45:19 2021 +0100 + + Include Spree Storefront SCSS files for easy customization + +commit 87df31475c2a900a67da0d87c0cec2500ade6e08 +Merge: 1563181 d65c5db +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Feb 17 19:00:27 2021 +0000 + + Merge pull request #854 from spree/dependabot/bundler/rails-6.1.3 + +commit d65c5dbac91d1363f2c6ee25b5576fa93d0998b6 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Feb 17 18:58:08 2021 +0000 + + Bump rails from 6.1.2.1 to 6.1.3 + + Bumps [rails](https://github.com/rails/rails) from 6.1.2.1 to 6.1.3. + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v6.1.2.1...v6.1.3) + + Signed-off-by: dependabot-preview[bot] + +commit 1563181db003efe9acea6bd6a5a6747431ec5c18 +Merge: 01b38a6 6f2682d +Author: Damian Legawiec +Date: Wed Feb 17 14:59:09 2021 +0100 + + Merge pull request #853 from spree/fix/headless-slimming-down + + Fix/headless slimming down + +commit 6f2682dca5cb12852a8bd18f3d60c9b7bed9f87d +Author: Damian Legawiec +Date: Wed Feb 17 13:47:06 2021 +0100 + + Production ready Dockerfile + +commit 5bdf6efc3c288de090ae604017e648fd8c5e2920 +Author: Damian Legawiec +Date: Wed Feb 17 13:30:12 2021 +0100 + + Remove preferences that are the same as defaults + +commit ecfdc89eb81ee7ea46cf145462bfd4373a2d7cfb +Author: Damian Legawiec +Date: Wed Feb 17 13:29:54 2021 +0100 + + Load some initializers when required gems are installed + +commit 01b38a6d8927e1c90162118842a14a17451873a3 +Merge: 9eb0924 bf441b0 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Feb 16 16:12:18 2021 +0000 + + Merge pull request #852 from spree/dependabot/bundler/sendgrid-actionmailer-3.2.0 + +commit bf441b015f3e45ac96efa03bf0fec6c13a93204b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Feb 16 16:09:34 2021 +0000 + + Bump sendgrid-actionmailer from 3.1.1 to 3.2.0 + + Bumps [sendgrid-actionmailer](https://github.com/eddiezane/sendgrid-actionmailer) from 3.1.1 to 3.2.0. + - [Release notes](https://github.com/eddiezane/sendgrid-actionmailer/releases) + - [Changelog](https://github.com/eddiezane/sendgrid-actionmailer/blob/master/CHANGELOG.md) + - [Commits](https://github.com/eddiezane/sendgrid-actionmailer/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 9eb09249bbd76a92b4ba56286ffe32a1fb5c0177 +Merge: aaa2a7a 6a48b52 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Feb 12 20:21:04 2021 +0000 + + Merge pull request #850 from spree/dependabot/bundler/aws-sdk-s3-1.88.1 + +commit 6a48b5277f09f3b4643535815af7324b61e9633d +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Feb 12 20:18:10 2021 +0000 + + Bump aws-sdk-s3 from 1.88.0 to 1.88.1 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.88.0 to 1.88.1. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit aaa2a7a5c7f701bf8ac7eb1e445b32556dc3ffe0 +Merge: dd3347c d292c10 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Feb 10 21:02:36 2021 +0000 + + Merge pull request #849 from spree/dependabot/bundler/rails-6.1.2.1 + +commit d292c10197e7e400b839652439390c56d747335b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Feb 10 20:59:44 2021 +0000 + + Bump rails from 6.1.2 to 6.1.2.1 + + Bumps [rails](https://github.com/rails/rails) from 6.1.2 to 6.1.2.1. + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v6.1.2...v6.1.2.1) + + Signed-off-by: dependabot-preview[bot] + +commit dd3347c56d17e3a21220578c0e41ccceb02449e7 +Merge: 72ccf03 e64c6cf +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Feb 10 20:38:09 2021 +0000 + + Merge pull request #848 from spree/dependabot/bundler/scout_apm-4.0.4 + +commit e64c6cfabf743488ef587e6bcb323d6d347636df +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Feb 10 20:35:19 2021 +0000 + + Bump scout_apm from 4.0.3 to 4.0.4 + + Bumps [scout_apm](https://github.com/scoutapp/scout_apm_ruby) from 4.0.3 to 4.0.4. + - [Release notes](https://github.com/scoutapp/scout_apm_ruby/releases) + - [Changelog](https://github.com/scoutapp/scout_apm_ruby/blob/master/CHANGELOG.markdown) + - [Commits](https://github.com/scoutapp/scout_apm_ruby/compare/v4.0.3...v4.0.4) + + Signed-off-by: dependabot-preview[bot] + +commit 72ccf0344c85d1bf5d56b6550ecca38ed901a0e9 +Merge: 9ecd74f aa3c97a +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Feb 9 21:36:22 2021 +0000 + + Merge pull request #847 from spree/dependabot/bundler/rails-6.1.2 + +commit aa3c97a04be2f0038e6264bce3af8a490f26cd76 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Feb 9 21:34:00 2021 +0000 + + Bump rails from 6.1.1 to 6.1.2 + + Bumps [rails](https://github.com/rails/rails) from 6.1.1 to 6.1.2. + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v6.1.1...v6.1.2) + + Signed-off-by: dependabot-preview[bot] + +commit 9ecd74f98ff6296034cb70daea0e2b66be9b8751 +Merge: 0afc9df b529695 +Author: Damian Legawiec +Date: Mon Feb 8 17:13:32 2021 +0100 + + Merge pull request #846 from spree/feature/spree-dev-tools + + Feature/spree dev tools + +commit b5296953d2289e6c2aa3d5dd0cda991faa197fcd +Author: Damian Legawiec +Date: Mon Feb 8 17:10:10 2021 +0100 + + Remove rubocop, bring back junit formatter + +commit c09cc93843c0f164a4aee380a94b9a4979faa487 +Author: Damian Legawiec +Date: Mon Feb 8 15:05:48 2021 +0100 + + Use Spree Dev Tools + +commit 596c4cd510bf81bfff681e1a039c409806ecc995 +Author: Damian Legawiec +Date: Mon Feb 8 15:05:21 2021 +0100 + + Requuire webdrivers here + +commit 0721c348798e47bb93b251f8042a4a9e80bcce37 +Author: Damian Legawiec +Date: Mon Feb 8 15:04:53 2021 +0100 + + Added missing migration from Spree 4.2.0.rc5 upgrade + +commit d4cac4bd42f103f3439a47a6cb91afebcb87aac0 +Author: Damian Legawiec +Date: Mon Feb 8 15:04:20 2021 +0100 + + Use Bullet only when defined + +commit 0afc9dfd0b752838a72683b72843bb789d3e48c5 +Merge: 8cc4eea 68c87f3 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Feb 5 22:32:46 2021 +0000 + + Merge pull request #844 from spree/dependabot/bundler/puma-5.2.1 + +commit 68c87f303a269bdaf251c4478951d7e1a568bb84 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Feb 5 22:29:54 2021 +0000 + + Bump puma from 5.2.0 to 5.2.1 + + Bumps [puma](https://github.com/puma/puma) from 5.2.0 to 5.2.1. + - [Release notes](https://github.com/puma/puma/releases) + - [Changelog](https://github.com/puma/puma/blob/master/History.md) + - [Commits](https://github.com/puma/puma/compare/v5.2.0...v5.2.1) + + Signed-off-by: dependabot-preview[bot] + +commit 8cc4eeaef94c14f0ecb0eb321ba0a560f8bf3bed +Merge: 2b7c5d4 104366a +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 4 23:47:50 2021 +0000 + + Merge pull request #842 from spree/dependabot/bundler/aws-sdk-s3-1.88.0 + +commit 2b7c5d4f8a6bc4cb89057295e45abf311fb3e959 +Merge: e9bfc3c fb65c83 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 4 23:46:59 2021 +0000 + + Merge pull request #841 from spree/dependabot/bundler/spree_auth_devise-4.3.3 + +commit 104366a7a19dbf2a27ee5a1b6ead573534a88531 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 4 23:45:27 2021 +0000 + + Bump aws-sdk-s3 from 1.87.0 to 1.88.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.87.0 to 1.88.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit fb65c83e33bc11becf289830b2e31406f8505c31 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 4 23:44:27 2021 +0000 + + Bump spree_auth_devise from 4.3.2 to 4.3.3 + + Bumps [spree_auth_devise](https://github.com/spree/spree_auth_devise) from 4.3.2 to 4.3.3. + - [Release notes](https://github.com/spree/spree_auth_devise/releases) + - [Changelog](https://github.com/spree/spree_auth_devise/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree_auth_devise/commits/v4.3.3) + + Signed-off-by: dependabot-preview[bot] + +commit e9bfc3c0c428d29d75764b584ca492d09d2c7b6a +Author: Damian Legawiec +Date: Thu Feb 4 18:13:24 2021 +0100 + + Rename config to config.yml + +commit c31f74ca8e28676a1be80e8ade8a11396c981552 +Merge: 4132bcd b224c29 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 4 17:11:10 2021 +0000 + + Merge pull request #832 from spree/dependabot/bundler/rack-mini-profiler-2.3.1 + +commit 4132bcd4cfa2b9e9ac72ba7e8f4799b7b3f48149 +Merge: 0e300bb 8bf52a1 +Author: Damian Legawiec +Date: Thu Feb 4 18:10:55 2021 +0100 + + Merge pull request #835 from spree/dependabot/bundler/capybara-3.35.3 + + Bump capybara from 3.34.0 to 3.35.3 + +commit 0e300bb80920262706d657783806091bd7f1ed22 +Merge: faa76df fc52fc7 +Author: Damian Legawiec +Date: Thu Feb 4 17:30:07 2021 +0100 + + Merge branch 'main' of github.com:spree/spree_starter into main + +commit faa76dfe774866626e402888825fb1e86385e1f4 +Author: Damian Legawiec +Date: Thu Feb 4 17:29:49 2021 +0100 + + Setup automatic updates with dependabot + +commit fc52fc78840258541c97954b920ca967b83668d6 +Merge: c10d424 69d02a1 +Author: Damian Legawiec +Date: Thu Feb 4 17:21:32 2021 +0100 + + Merge pull request #838 from spree/dependabot/bundler/rubocop-1.9.1 + + Bump rubocop from 1.8.1 to 1.9.1 + +commit c10d4240892979735cc8ddda83b1452ac8240cba +Merge: a1341f3 082dc3f +Author: Damian Legawiec +Date: Thu Feb 4 17:20:37 2021 +0100 + + Merge pull request #833 from spree/dependabot/bundler/bootsnap-1.7.1 + + Bump bootsnap from 1.5.1 to 1.7.1 + +commit a1341f3a09ed680252d4d0de204037b1a6114463 +Merge: 005dde6 f84cd8c +Author: Damian Legawiec +Date: Thu Feb 4 17:20:25 2021 +0100 + + Merge pull request #836 from spree/dependabot/bundler/puma-5.2.0 + + Bump puma from 5.1.1 to 5.2.0 + +commit 69d02a1cbe7bffdc2fe0031f31675a54eaf7f0a7 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 4 16:17:37 2021 +0000 + + Bump rubocop from 1.8.1 to 1.9.1 + + Bumps [rubocop](https://github.com/rubocop-hq/rubocop) from 1.8.1 to 1.9.1. + - [Release notes](https://github.com/rubocop-hq/rubocop/releases) + - [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rubocop-hq/rubocop/compare/v1.8.1...v1.9.1) + + Signed-off-by: dependabot-preview[bot] + +commit f84cd8c8aa174802431bc289efc96381e1abe198 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 4 16:16:54 2021 +0000 + + Bump puma from 5.1.1 to 5.2.0 + + Bumps [puma](https://github.com/puma/puma) from 5.1.1 to 5.2.0. + - [Release notes](https://github.com/puma/puma/releases) + - [Changelog](https://github.com/puma/puma/blob/master/History.md) + - [Commits](https://github.com/puma/puma/compare/v5.1.1...v5.2.0) + + Signed-off-by: dependabot-preview[bot] + +commit 8bf52a1ad6c6ad797faf8f7f2b4a287aaf7da42e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 4 16:16:20 2021 +0000 + + Bump capybara from 3.34.0 to 3.35.3 + + Bumps [capybara](https://github.com/teamcapybara/capybara) from 3.34.0 to 3.35.3. + - [Release notes](https://github.com/teamcapybara/capybara/releases) + - [Changelog](https://github.com/teamcapybara/capybara/blob/master/History.md) + - [Commits](https://github.com/teamcapybara/capybara/compare/3.34.0...3.35.3) + + Signed-off-by: dependabot-preview[bot] + +commit 082dc3f12c426435b06cd5536cace6c1adb34420 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 4 16:15:56 2021 +0000 + + Bump bootsnap from 1.5.1 to 1.7.1 + + Bumps [bootsnap](https://github.com/Shopify/bootsnap) from 1.5.1 to 1.7.1. + - [Release notes](https://github.com/Shopify/bootsnap/releases) + - [Changelog](https://github.com/Shopify/bootsnap/blob/master/CHANGELOG.md) + - [Commits](https://github.com/Shopify/bootsnap/compare/v1.5.1...v1.7.1) + + Signed-off-by: dependabot-preview[bot] + +commit b224c29a681abd61953e495cf82a3a41fe0ef22c +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 4 16:15:24 2021 +0000 + + Bump rack-mini-profiler from 2.3.0 to 2.3.1 + + Bumps [rack-mini-profiler](https://github.com/MiniProfiler/rack-mini-profiler) from 2.3.0 to 2.3.1. + - [Release notes](https://github.com/MiniProfiler/rack-mini-profiler/releases) + - [Changelog](https://github.com/MiniProfiler/rack-mini-profiler/blob/master/CHANGELOG.md) + - [Commits](https://github.com/MiniProfiler/rack-mini-profiler/compare/v2.3.0...v2.3.1) + + Signed-off-by: dependabot-preview[bot] + +commit 005dde61c0630b91768d7baf51ab65c482a02040 +Author: Damian Legawiec +Date: Thu Feb 4 15:25:56 2021 +0100 + + Use Spree 4.2.0.rc5 + +commit 77639a734e65fb8e7242f28116ca20e44a9a8700 +Author: Damian Legawiec +Date: Tue Jan 26 16:11:00 2021 +0100 + + Use Spree I18n from RubyGems + +commit e3e10b866e26bbbb8b25ab906b97b215e8ceb0e1 +Author: Damian Legawiec +Date: Mon Jan 25 12:38:21 2021 +0100 + + Use Spree Auth Devise 4.3.2 + +commit f915eac49ae28992dd77799d5be7ff5c0d5cb9d9 +Author: Damian Legawiec +Date: Wed Jan 20 16:25:33 2021 +0100 + + Update Spree to 4.1.0.rc4 + +commit 94d1adbe25066999766f65f4bc25892b649b80d1 +Author: Damian Legawiec +Date: Tue Jan 19 22:53:57 2021 +0100 + + Make bin/setup less error-prone + + Sometimes some editors / apps create .env directory making impossible to run the setup script. This way we're making sure nothing bad will happen + +commit 17752bc153a735762e385a422955f61760ed03de +Author: Damian Legawiec +Date: Tue Jan 19 19:30:15 2021 +0100 + + Allow to use lvh.me subdomains for multiple stores in development (#831) + + * Allow to use lvh.me subdomains for multple stores in development + + Connected to https://github.com/spree/spree/pull/10695 + + * fix + +commit f6c020e76f5a3d271ec5b176ee04cfd859697db1 +Author: Damian Legawiec +Date: Mon Jan 18 16:33:53 2021 +0100 + + Use always the newest postgres 12.x version + +commit 959d784061b775deb6c5f70d110fd8263a96f80a +Author: Damian Legawiec +Date: Mon Jan 18 16:33:38 2021 +0100 + + Fixed rubocop ruby version + +commit a635e1ccafa89cae427a4f1aae7f0fb0700bf823 +Author: Damian Legawiec +Date: Mon Jan 18 16:33:22 2021 +0100 + + Rebranding to Spree Starter + +commit ede17881e2d262d90d67a71b5aab6d9444a6c1c1 +Author: Damian Legawiec +Date: Mon Jan 18 16:20:49 2021 +0100 + + Remove spree analytics trackers leftovers + +commit 2b07ebebdeb4f8624ca7d2bd83ce2eb9fc543dc8 +Merge: 19b3c95 02f9d7a +Author: Damian Legawiec +Date: Mon Jan 18 15:47:57 2021 +0100 + + Merge pull request #826 from spark-solutions/feature/heroku-button + + Heroku button support + +commit 02f9d7a981171e0a9b22d16da92c490f2e8a38a6 +Author: Damian Legawiec +Date: Mon Jan 18 15:00:24 2021 +0100 + + Use Spree 4.2.0.rc3 and remove Analytics Trackers + +commit 562d266efb5e4d502a9fc129d9d2efd39129971a +Author: Damian Legawiec +Date: Mon Jan 18 12:57:04 2021 +0100 + + We only need Ruby buildpack + +commit 19b3c959536a317b72ce93448c7aa550aa7d033a +Merge: d55a709 6da7d4f +Author: Damian Legawiec +Date: Mon Jan 18 11:59:49 2021 +0100 + + Merge pull request #828 from spark-solutions/dependabot/npm_and_yarn/eslint-config-standard-16.0.2 + + Bump eslint-config-standard from 14.1.1 to 16.0.2 + +commit 2dcc12e68454150a8ac5189786efc8f5c1d22d31 +Author: Damian Legawiec +Date: Mon Jan 18 11:58:28 2021 +0100 + + Update Spree + +commit 6da7d4f685eca3436c7ff1f93263178ea312db12 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Jan 18 04:31:14 2021 +0000 + + Bump eslint-config-standard from 14.1.1 to 16.0.2 + + Bumps [eslint-config-standard](https://github.com/standard/eslint-config-standard) from 14.1.1 to 16.0.2. + - [Release notes](https://github.com/standard/eslint-config-standard/releases) + - [Changelog](https://github.com/standard/eslint-config-standard/blob/master/CHANGELOG.md) + - [Commits](https://github.com/standard/eslint-config-standard/compare/v14.1.1...v16.0.2) + + Signed-off-by: dependabot-preview[bot] + +commit ef25d8af6344354ea6d7f942a1340513fe4d2385 +Author: Damian Legawiec +Date: Sun Jan 17 21:21:29 2021 +0100 + + Use proxy not redirects for active storage + +commit fef397ffed3595dd96e9f7bba8288617748ff868 +Author: Damian Legawiec +Date: Sun Jan 17 20:55:19 2021 +0100 + + Update Active Storage + +commit 7efb282d7b6e39691fb9e8c9daa8ac1bf1215cef +Author: Damian Legawiec +Date: Sat Jan 16 17:39:47 2021 +0100 + + Heroku button support + +commit d55a709cc1b23b4b1325d72792f41473b8484404 +Author: Damian Legawiec +Date: Sat Jan 16 21:20:36 2021 +0100 + + Added DEBUG_ASSETS env to enable/disable asset debugging in development + +commit b9fb8b5d65bc671b285097f5d02dc8234bbcb370 +Author: Damian Legawiec +Date: Sat Jan 16 21:20:19 2021 +0100 + + Fix - remove react leftovers + +commit 0dd2200c4613c049951ef99c4e73038972f3fee2 +Author: Damian Legawiec +Date: Sat Jan 16 21:13:18 2021 +0100 + + Update schame.rb + +commit 40a92daa36d52c751d5ff42d2fbe07978b7bf17d +Author: Damian Legawiec +Date: Sat Jan 16 21:12:49 2021 +0100 + + Spree 4.1 upgrade - fix RMA class name + +commit e5b8b01a319f6eecb2ea233ef453d5244f4efc4b +Author: Damian Legawiec +Date: Sat Jan 16 21:12:35 2021 +0100 + + Rails 6.1 fix - replace removed update_attributes! with update + +commit 9880c044b4975358d2fa9d46303cbd0609bf4de6 +Author: Damian Legawiec +Date: Sat Jan 16 19:57:22 2021 +0100 + + Update Spree Auth Devise + +commit e610038ed5a33d4c2b71674416b35b27511b5a3e +Author: Damian Legawiec +Date: Sat Jan 16 15:13:37 2021 +0100 + + fix spec + +commit 164ea9c70293f37bdc1f89a20eb4ffd58aad3e99 +Author: Damian Legawiec +Date: Fri Jan 15 17:44:15 2021 +0100 + + Remove react-rails + +commit 161926073e28159f09f64a4f55fe146ab65ce8c6 +Author: Damian Legawiec +Date: Fri Jan 15 17:43:20 2021 +0100 + + Bump Rails to 6.1 + +commit eb63bce0a116c4ee03dcc217e72adf3ee2a9150e +Author: Damian Legawiec +Date: Fri Jan 15 17:19:33 2021 +0100 + + Remove outdated ENVs from app.json + +commit 362ecde4f4e2ffdb21efc3483664a291f266a4a4 +Author: Damian Legawiec +Date: Fri Jan 15 17:19:19 2021 +0100 + + Use AWS S3 only if credentials are supplied + +commit 9af3b6f6c5badecaf9cba74fe8b3ead039c95482 +Author: Damian Legawiec +Date: Fri Jan 15 17:19:01 2021 +0100 + + Update Procfile + +commit 76792ef03c45f198a25c25e1a0883a49d5492e7b +Author: Damian Legawiec +Date: Fri Jan 15 17:18:57 2021 +0100 + + Update LICENSE.md + +commit 5874c20b0dc81366203397397d42ea94203554f2 +Author: Damian Legawiec +Date: Fri Jan 15 17:18:52 2021 +0100 + + Remove React + +commit f22c2708dbdaa2bc9ed1c702107f494d96ad42dd +Author: Damian Legawiec +Date: Sat Jan 16 16:34:56 2021 +0100 + + Use Redis 6.0 + +commit 5109d14f542000443f492996558d376942d496b2 +Merge: 3968198 d09c15f +Author: Damian Legawiec +Date: Sat Jan 16 16:14:42 2021 +0100 + + Merge pull request #741 from spark-solutions/dependabot/npm_and_yarn/babel/plugin-syntax-jsx-7.12.1 + + Bump @babel/plugin-syntax-jsx from 7.8.3 to 7.12.1 + +commit 396819802415309d880fb51268e3af813ea2c2cc +Merge: ed0f7a9 66fedd9 +Author: Damian Legawiec +Date: Sat Jan 16 16:14:33 2021 +0100 + + Merge pull request #765 from spark-solutions/dependabot/npm_and_yarn/eslint-plugin-standard-5.0.0 + + Bump eslint-plugin-standard from 4.0.2 to 5.0.0 + +commit ed0f7a989bb9c3f4ea726e18c792603be4bbc27e +Merge: b170133 1a30a35 +Author: Damian Legawiec +Date: Sat Jan 16 16:14:19 2021 +0100 + + Merge pull request #823 from spark-solutions/dependabot/npm_and_yarn/eslint-7.18.0 + + Bump eslint from 6.8.0 to 7.18.0 + +commit b170133b16c24bc7f8e3c7b121be5af5c50d1c0b +Merge: 0a22709 6098813 +Author: Damian Legawiec +Date: Sat Jan 16 16:13:51 2021 +0100 + + Merge pull request #790 from spark-solutions/dependabot/npm_and_yarn/ini-1.3.8 + + [Security] Bump ini from 1.3.5 to 1.3.8 + +commit 0a22709c0b82a760006c72cb88e9796d56b065cb +Merge: 4bc6593 0fffb6c +Author: Damian Legawiec +Date: Sat Jan 16 16:13:34 2021 +0100 + + Merge pull request #825 from spark-solutions/feature/add-papertrail + + Add papertrail support + +commit 4bc6593bb327bfdafac430893bd28b2e78fc4418 +Author: Damian Legawiec +Date: Sat Jan 16 16:13:17 2021 +0100 + + Update deface + +commit 0fffb6c1616e1e5b50e9964d39db691ec1cd6aec +Author: Damian Legawiec +Date: Sat Jan 16 15:28:42 2021 +0100 + + Add papertrail support + +commit 66fedd9375b54037bd183b8c3dda4076487f14ba +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sat Jan 16 14:21:20 2021 +0000 + + Bump eslint-plugin-standard from 4.0.2 to 5.0.0 + + Bumps [eslint-plugin-standard](https://github.com/standard/eslint-plugin-standard) from 4.0.2 to 5.0.0. + - [Release notes](https://github.com/standard/eslint-plugin-standard/releases) + - [Commits](https://github.com/standard/eslint-plugin-standard/compare/v4.0.2...v5.0.0) + + Signed-off-by: dependabot-preview[bot] + +commit 1a30a35360f0ecf264b24cf22271392f8c9276ee +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sat Jan 16 14:21:16 2021 +0000 + + Bump eslint from 6.8.0 to 7.18.0 + + Bumps [eslint](https://github.com/eslint/eslint) from 6.8.0 to 7.18.0. + - [Release notes](https://github.com/eslint/eslint/releases) + - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) + - [Commits](https://github.com/eslint/eslint/compare/v6.8.0...v7.18.0) + + Signed-off-by: dependabot-preview[bot] + +commit 231ed1f600724c8fafac35a4a65dced647842f00 +Author: Damian Legawiec +Date: Sat Jan 16 15:19:10 2021 +0100 + + Bump Spree JS SDK + +commit f22c54b1d19e1cf9e308d6b023f5e7d071a5a377 +Merge: 3442664 24b8431 +Author: Damian Legawiec +Date: Fri Jan 15 15:47:48 2021 +0100 + + Merge pull request #821 from spark-solutions/feature/spree-4-2 + + Bump Spree to 4.2.0.rc3 + +commit 24b8431b2938d0f34d72b0d41d1883229ccfdd33 +Author: Damian Legawiec +Date: Fri Jan 15 15:41:27 2021 +0100 + + Bump Spree to 4.2.0.rc3 + +commit 34426645299111d6afddd904b579f93ad77178f1 +Merge: 280a114 7278089 +Author: Damian Legawiec +Date: Thu Jan 14 22:03:47 2021 +0100 + + Merge pull request #817 from spark-solutions/sendgrid-api + + Updates SendGrid authentication method + +commit 72780893faf745cbe8e8abc12fd6b13588d4b45b +Author: Robert Nowakowski +Date: Thu Jan 14 13:49:29 2021 +0100 + + Updates SendGrid authentication method + +commit 609881366a8f90a8b6965170873d9f7fda028e20 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Dec 14 04:16:18 2020 +0000 + + [Security] Bump ini from 1.3.5 to 1.3.8 + + Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8. **This update includes a security fix.** + - [Release notes](https://github.com/isaacs/ini/releases) + - [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8) + + Signed-off-by: dependabot-preview[bot] + +commit 280a1140bdb4ece0984f6ded36fe096d0dc3c91c +Merge: 8ff3346 6d15a95 +Author: Damian Legawiec +Date: Fri Nov 13 09:08:34 2020 +0100 + + Merge pull request #754 from spark-solutions/dependabot/bundler/rubocop-1.3.0 + + Bump rubocop from 1.2.0 to 1.3.0 + +commit 8ff3346c9d41fac287c26512ce93a375b35881e3 +Merge: eec9760 0a66fd5 +Author: Damian Legawiec +Date: Fri Nov 13 09:08:19 2020 +0100 + + Merge pull request #750 from spark-solutions/dependabot/bundler/spree-4.1.12 + + Bump spree from 4.1.11 to 4.1.12 + +commit 6d15a95f6b1273e738da66dd13bbb04e63554b40 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Nov 13 04:17:41 2020 +0000 + + Bump rubocop from 1.2.0 to 1.3.0 + + Bumps [rubocop](https://github.com/rubocop-hq/rubocop) from 1.2.0 to 1.3.0. + - [Release notes](https://github.com/rubocop-hq/rubocop/releases) + - [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rubocop-hq/rubocop/compare/v1.2.0...v1.3.0) + + Signed-off-by: dependabot-preview[bot] + +commit 0a66fd57d510d573660ff8b233d3c8c30af6a70c +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Nov 11 04:19:44 2020 +0000 + + Bump spree from 4.1.11 to 4.1.12 + + Bumps [spree](https://github.com/spree/spree) from 4.1.11 to 4.1.12. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v4.1.11...v4.1.12) + + Signed-off-by: dependabot-preview[bot] + +commit d09c15fd742f53c70a3e9232d98cd75ecd2a5158 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Nov 11 04:16:21 2020 +0000 + + Bump @babel/plugin-syntax-jsx from 7.8.3 to 7.12.1 + + Bumps [@babel/plugin-syntax-jsx](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-syntax-jsx) from 7.8.3 to 7.12.1. + - [Release notes](https://github.com/babel/babel/releases) + - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) + - [Commits](https://github.com/babel/babel/commits/v7.12.1/packages/babel-plugin-syntax-jsx) + + Signed-off-by: dependabot-preview[bot] + +commit eec97601cb1d25f7f7eef41767b0836b3ab88a6f +Merge: 4a4c0c9 5882db7 +Author: Damian Legawiec +Date: Tue Nov 10 16:20:05 2020 +0100 + + Merge pull request #697 from spark-solutions/dependabot/npm_and_yarn/http-proxy-1.18.1 + + [Security] Bump http-proxy from 1.18.0 to 1.18.1 + +commit 4a4c0c9e6d7c06b2da73640cd1bb6c892c92a697 +Merge: f7e8365 8d42ab8 +Author: Damian Legawiec +Date: Tue Nov 10 16:19:43 2020 +0100 + + Merge pull request #738 from spark-solutions/dependabot/bundler/aws-sdk-s3-1.84.0 + + Bump aws-sdk-s3 from 1.64.0 to 1.84.0 + +commit 8d42ab85a8cd2e2a8ae57a78c8a73f85e49ce286 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Nov 10 15:11:01 2020 +0000 + + Bump aws-sdk-s3 from 1.64.0 to 1.84.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.64.0 to 1.84.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit f7e836503f30f7ccfedf042ba8f202660203bbba +Merge: 721f3ce 2ee4c39 +Author: Damian Legawiec +Date: Tue Nov 10 16:09:10 2020 +0100 + + Merge pull request #737 from spark-solutions/update-11-2020 + + Update dependencies + +commit 2ee4c39a893c05dc1f3b128aa1b2d76bdd3851aa +Author: Damian Legawiec +Date: Mon Nov 9 14:28:16 2020 +0100 + + Docker fixes + +commit b8ae33394b072ab21054bb505915fbbe5c423394 +Author: Damian Legawiec +Date: Mon Nov 9 14:28:06 2020 +0100 + + Added missing Spree extensions mgirations + +commit 59b94f4ec7be2b14627b14125f846f31dbe9d641 +Author: Damian Legawiec +Date: Mon Nov 9 09:46:40 2020 +0100 + + Move to ruby 2.7.2 + +commit cd8be82d5fd09fea7629eb1bca0a5ea16bab376a +Author: Damian Legawiec +Date: Mon Nov 9 09:40:22 2020 +0100 + + Update dependencies + +commit 5882db7bd19af21bcf741450d5044f542696680b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sat Sep 5 01:35:58 2020 +0000 + + [Security] Bump http-proxy from 1.18.0 to 1.18.1 + + Bumps [http-proxy](https://github.com/http-party/node-http-proxy) from 1.18.0 to 1.18.1. **This update includes a security fix.** + - [Release notes](https://github.com/http-party/node-http-proxy/releases) + - [Changelog](https://github.com/http-party/node-http-proxy/blob/master/CHANGELOG.md) + - [Commits](https://github.com/http-party/node-http-proxy/compare/1.18.0...1.18.1) + + Signed-off-by: dependabot-preview[bot] + +commit 721f3ce63a84c41baf5a76d3d16501afd951f6eb +Merge: ec3a32d 4e0526b +Author: Damian Legawiec +Date: Tue Aug 4 07:07:11 2020 +0200 + + Merge pull request #678 from spark-solutions/add-active_storage_analysis-queue-to-sidekiq-config + + Add active_storage_analysis queue to sidekiq.yml + +commit 4e0526b4bed8e5bc9ca86c07d9a9ffc9b6092854 +Author: Konrad Gorazd +Date: Mon Aug 3 19:10:51 2020 +0200 + + Add active_storage_analysis queue to sidekiq.yml + +commit ec3a32dbfe370e8a33893328330c6b3e3e8a3d54 +Merge: 29c9438 c9fb142 +Author: Damian Legawiec +Date: Tue Jun 9 22:29:58 2020 +0200 + + Merge pull request #634 from spark-solutions/dependabot/npm_and_yarn/websocket-extensions-0.1.4 + + [Security] Bump websocket-extensions from 0.1.3 to 0.1.4 + +commit 29c9438e1b47c1d4cb9b56ea0a9d537a93edd4b9 +Merge: e7ca6d2 d8f3193 +Author: Damian Legawiec +Date: Tue Jun 9 22:29:44 2020 +0200 + + Merge pull request #633 from spark-solutions/dependabot/bundler/websocket-extensions-0.1.5 + + [Security] Bump websocket-extensions from 0.1.4 to 0.1.5 + +commit c9fb142b3da154b12b826c1f165a9ee593dc24ce +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jun 5 16:19:57 2020 +0000 + + [Security] Bump websocket-extensions from 0.1.3 to 0.1.4 + + Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4. **This update includes a security fix.** + - [Release notes](https://github.com/faye/websocket-extensions-node/releases) + - [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md) + - [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4) + + Signed-off-by: dependabot-preview[bot] + +commit d8f31933791df3969fa66c32a22641e620f98022 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jun 5 14:26:33 2020 +0000 + + [Security] Bump websocket-extensions from 0.1.4 to 0.1.5 + + Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-ruby) from 0.1.4 to 0.1.5. **This update includes a security fix.** + - [Release notes](https://github.com/faye/websocket-extensions-ruby/releases) + - [Changelog](https://github.com/faye/websocket-extensions-ruby/blob/master/CHANGELOG.md) + - [Commits](https://github.com/faye/websocket-extensions-ruby/compare/0.1.4...0.1.5) + + Signed-off-by: dependabot-preview[bot] + +commit e7ca6d27ffb9967451db3af310079be8cbb6209d +Merge: 25c87fd 9d98752 +Author: Damian Legawiec +Date: Mon May 11 18:26:06 2020 +0200 + + Merge pull request #601 from spark-solutions/ruby-2-7 + + Use Ruby 2.7 and Bundler 2 + +commit 9d98752f374bb359b161cc661e23cc85fe43b367 +Author: Damian Legawiec +Date: Mon May 11 17:13:29 2020 +0200 + + Use Ruby 2.7 and Bundler 2 + +commit 25c87fd9d9624176ee89d421a12a55cdb54a3344 +Merge: 29e6b5f 6954c92 +Author: Damian Legawiec +Date: Thu May 7 10:25:40 2020 +0200 + + Merge pull request #598 from spark-solutions/dependabot/bundler/rails-6.0.3 + + Bump rails from 6.0.2.2 to 6.0.3 + +commit 29e6b5f2f50dd05a3b9e3570eb1679ffd4ecae16 +Merge: 5c69cc1 f465d3a +Author: Damian Legawiec +Date: Thu May 7 10:25:30 2020 +0200 + + Merge pull request #597 from spark-solutions/dependabot/bundler/spree-4.1.6 + + Bump spree from 4.1.5 to 4.1.6 + +commit 5c69cc1bf1b6c96af4ca7f881749eb9443d8f5af +Merge: f17fc33 90080d8 +Author: Damian Legawiec +Date: Thu May 7 10:25:17 2020 +0200 + + Merge pull request #595 from spark-solutions/dependabot/bundler/doorkeeper-5.3.2 + + [Security] Bump doorkeeper from 5.3.1 to 5.3.2 + +commit 6954c92f39686188fe895236f8e87934685b3f15 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu May 7 04:17:19 2020 +0000 + + Bump rails from 6.0.2.2 to 6.0.3 + + Bumps [rails](https://github.com/rails/rails) from 6.0.2.2 to 6.0.3. + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v6.0.2.2...v6.0.3) + + Signed-off-by: dependabot-preview[bot] + +commit f465d3a93405ceeb82282a2d24154fbf13e542db +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu May 7 04:16:45 2020 +0000 + + Bump spree from 4.1.5 to 4.1.6 + + Bumps [spree](https://github.com/spree/spree) from 4.1.5 to 4.1.6. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v4.1.5...v4.1.6) + + Signed-off-by: dependabot-preview[bot] + +commit 90080d8a7c02b37b8bc948acc7f214c4361df403 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue May 5 08:33:31 2020 +0000 + + [Security] Bump doorkeeper from 5.3.1 to 5.3.2 + + Bumps [doorkeeper](https://github.com/doorkeeper-gem/doorkeeper) from 5.3.1 to 5.3.2. **This update includes a security fix.** + - [Release notes](https://github.com/doorkeeper-gem/doorkeeper/releases) + - [Changelog](https://github.com/doorkeeper-gem/doorkeeper/blob/master/CHANGELOG.md) + - [Commits](https://github.com/doorkeeper-gem/doorkeeper/compare/v.5.3.1...v5.3.2) + + Signed-off-by: dependabot-preview[bot] + +commit f17fc33fdf09bf252d75e4ae4bcda7a74c5e8568 +Merge: 832ce46 b56eb2a +Author: Damian Legawiec +Date: Mon Apr 27 14:50:29 2020 +0200 + + Merge pull request #587 from spark-solutions/feature/updates-04-2020 + + Feature/updates 04 2020 + +commit b56eb2a95652c44d96795f8074adc9939d47a74a +Author: Damian Legawiec +Date: Mon Apr 27 14:44:21 2020 +0200 + + NPM update 04/2020 + +commit a9e447210d14c3b035589422173233caea23e82a +Author: Damian Legawiec +Date: Mon Apr 27 14:42:33 2020 +0200 + + Gems update 04/2020 + +commit 832ce46fd7bc3b40f5fbfc721dfa007d564e1575 +Merge: ee8d36a fa7c392 +Author: Damian Legawiec +Date: Mon Apr 27 14:38:14 2020 +0200 + + Merge pull request #586 from spark-solutions/fix/async-and-hmr + + Fixed HMR in docker environment + +commit fa7c392c1cfdd58b5cd61f19d56f0c7f284fb93e +Author: Damian Legawiec +Date: Mon Apr 27 14:35:38 2020 +0200 + + Fixed HMR in docker environment + +commit ee8d36a3e1fd109cc0b26fc2c52158c3bf400cce +Merge: 04772e5 8532e24 +Author: Damian Legawiec +Date: Sun Apr 26 09:50:19 2020 +0200 + + Merge pull request #584 from spark-solutions/dependabot/npm_and_yarn/node-sass-4.14.0 + + Bump node-sass from 4.13.1 to 4.14.0 + +commit 8532e244b11b4ad1d10e9b672824845412fbf4dc +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Apr 24 04:18:08 2020 +0000 + + Bump node-sass from 4.13.1 to 4.14.0 + + Bumps [node-sass](https://github.com/sass/node-sass) from 4.13.1 to 4.14.0. + - [Release notes](https://github.com/sass/node-sass/releases) + - [Changelog](https://github.com/sass/node-sass/blob/master/CHANGELOG.md) + - [Commits](https://github.com/sass/node-sass/compare/v4.13.1...v4.14.0) + + Signed-off-by: dependabot-preview[bot] + +commit 04772e5be815f6b09fd4bf0593d59aeef07fff72 +Merge: 41ae03b 87d1bb5 +Author: Damian Legawiec +Date: Wed Apr 22 12:02:46 2020 +0200 + + Merge pull request #577 from spark-solutions/dependabot/npm_and_yarn/rails/webpacker-5.1.1 + + Bump @rails/webpacker from 5.0.1 to 5.1.1 + +commit 87d1bb5420a790d86273e8661f5496fc9f70a6e1 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 22 09:56:49 2020 +0000 + + Bump @rails/webpacker from 5.0.1 to 5.1.1 + + Bumps [@rails/webpacker](https://github.com/rails/webpacker) from 5.0.1 to 5.1.1. + - [Release notes](https://github.com/rails/webpacker/releases) + - [Changelog](https://github.com/rails/webpacker/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rails/webpacker/compare/v5.0.1...v5.1.1) + + Signed-off-by: dependabot-preview[bot] + +commit 41ae03b7160bcbd31686422988fce420e1659b99 +Merge: 55bfaae 7f2e59f +Author: Damian Legawiec +Date: Wed Apr 22 11:55:09 2020 +0200 + + Merge pull request #578 from spark-solutions/dependabot/bundler/webpacker-5.1.1 + + Bump webpacker from 5.0.1 to 5.1.1 + +commit 55bfaae2c3c55ddd94d3fb7c0ee74e44826c09bf +Merge: 703b85e 317c6a5 +Author: Damian Legawiec +Date: Wed Apr 22 11:54:55 2020 +0200 + + Merge pull request #574 from spark-solutions/dependabot/npm_and_yarn/spree/storefront-api-v2-sdk-4.1.0 + + Bump @spree/storefront-api-v2-sdk from 4.0.6 to 4.1.0 + +commit 703b85e327fd0dd4616f6d27029f428f4241527a +Merge: 5fff1c4 331a72b +Author: Damian Legawiec +Date: Wed Apr 22 11:54:40 2020 +0200 + + Merge pull request #580 from spark-solutions/dependabot/bundler/mini_racer-0.2.10 + + Bump mini_racer from 0.2.9 to 0.2.10 + +commit 331a72bc6f1b2a1d45df2757dc41bf08c574915b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 22 04:18:05 2020 +0000 + + Bump mini_racer from 0.2.9 to 0.2.10 + + Bumps [mini_racer](https://github.com/discourse/mini_racer) from 0.2.9 to 0.2.10. + - [Release notes](https://github.com/discourse/mini_racer/releases) + - [Changelog](https://github.com/rubyjs/mini_racer/blob/master/CHANGELOG) + - [Commits](https://github.com/discourse/mini_racer/compare/v0.2.9...v0.2.10) + + Signed-off-by: dependabot-preview[bot] + +commit 7f2e59f075ef6b6d3c128058b49c53184d972a97 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Apr 21 04:17:39 2020 +0000 + + Bump webpacker from 5.0.1 to 5.1.1 + + Bumps [webpacker](https://github.com/rails/webpacker) from 5.0.1 to 5.1.1. + - [Release notes](https://github.com/rails/webpacker/releases) + - [Changelog](https://github.com/rails/webpacker/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rails/webpacker/compare/v5.0.1...v5.1.1) + + Signed-off-by: dependabot-preview[bot] + +commit 317c6a5fa2e8f5b9183c629344d10c38de92762b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Apr 20 04:16:30 2020 +0000 + + Bump @spree/storefront-api-v2-sdk from 4.0.6 to 4.1.0 + + Bumps [@spree/storefront-api-v2-sdk](https://github.com/spark-solutions/spree-storefront-api-v2-js-sdk) from 4.0.6 to 4.1.0. + - [Release notes](https://github.com/spark-solutions/spree-storefront-api-v2-js-sdk/releases) + - [Commits](https://github.com/spark-solutions/spree-storefront-api-v2-js-sdk/compare/v4.0.6...v4.1.0) + + Signed-off-by: dependabot-preview[bot] + +commit 5fff1c4772a5d0b3561a0c107bf1421be0740b09 +Merge: bb3b18c 15d4575 +Author: Damian Legawiec +Date: Wed Apr 15 11:22:53 2020 +0200 + + Merge pull request #569 from spark-solutions/dependabot/bundler/spree-4.1.5 + + Bump spree from 4.1.4 to 4.1.5 + +commit bb3b18c567f97953664208fbeafbdb474ddd75ff +Merge: 7113cc1 79172cf +Author: Damian Legawiec +Date: Wed Apr 15 11:22:35 2020 +0200 + + Merge pull request #570 from spark-solutions/dependabot/bundler/webdrivers-4.3.0 + + Bump webdrivers from 4.2.0 to 4.3.0 + +commit 79172cf21a1a42dc5146e899e69946ddc962c126 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 15 04:19:06 2020 +0000 + + Bump webdrivers from 4.2.0 to 4.3.0 + + Bumps [webdrivers](https://github.com/titusfortner/webdrivers) from 4.2.0 to 4.3.0. + - [Release notes](https://github.com/titusfortner/webdrivers/releases) + - [Changelog](https://github.com/titusfortner/webdrivers/blob/master/CHANGELOG.md) + - [Commits](https://github.com/titusfortner/webdrivers/compare/v4.2.0...v4.3.0) + + Signed-off-by: dependabot-preview[bot] + +commit 15d4575d634e9647b35847cbe83996a6e55613e1 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 15 04:18:09 2020 +0000 + + Bump spree from 4.1.4 to 4.1.5 + + Bumps [spree](https://github.com/spree/spree) from 4.1.4 to 4.1.5. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v4.1.4...v4.1.5) + + Signed-off-by: dependabot-preview[bot] + +commit 7113cc138fa39137bd6c0377d3f858f34136720c +Merge: 162b97e 25ce214 +Author: Damian Legawiec +Date: Tue Apr 14 11:56:05 2020 +0200 + + Merge pull request #568 from spark-solutions/fix/async-and-hmr + + Enable async/await methods for JS + +commit 25ce21483d5a7e9809bd4835a0d9a3d7e424710b +Author: Damian Legawiec +Date: Tue Apr 14 10:22:36 2020 +0200 + + Enable async/await methods for JS + +commit 162b97eae46c7d69651cbf455da0c91bc045683d +Merge: d70a603 4afb898 +Author: Damian Legawiec +Date: Mon Apr 13 21:55:50 2020 +0200 + + Merge pull request #564 from spark-solutions/dependabot/npm_and_yarn/react-dom-16.13.1 + + Bump react-dom from 16.13.0 to 16.13.1 + +commit d70a6033ba38ee5bc0b426b79cbf8b67f56d37ec +Merge: 52737fa 42f955d +Author: Damian Legawiec +Date: Mon Apr 13 21:55:33 2020 +0200 + + Merge pull request #566 from spark-solutions/dependabot/npm_and_yarn/spree/storefront-api-v2-sdk-4.0.6 + + Bump @spree/storefront-api-v2-sdk from 4.0.5 to 4.0.6 + +commit 52737fa646ad8871abcd7b0675fa3a43522fcbe9 +Merge: b6c7cfa da9499c +Author: Damian Legawiec +Date: Mon Apr 13 21:55:10 2020 +0200 + + Merge pull request #565 from spark-solutions/dependabot/bundler/spree_gateway-3.7.5 + + Bump spree_gateway from 3.7.4 to 3.7.5 + +commit b6c7cfa6d8c54a254d58d18069842a31a172f569 +Merge: c257e3e aded1df +Author: Damian Legawiec +Date: Mon Apr 13 21:54:38 2020 +0200 + + Merge pull request #567 from spark-solutions/dependabot/npm_and_yarn/eslint-plugin-prettier-3.1.3 + + Bump eslint-plugin-prettier from 3.1.2 to 3.1.3 + +commit aded1dfe8bc75936c56412103b8aeb41b6f9d77a +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Apr 13 04:15:33 2020 +0000 + + Bump eslint-plugin-prettier from 3.1.2 to 3.1.3 + + Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 3.1.2 to 3.1.3. + - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) + - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) + - [Commits](https://github.com/prettier/eslint-plugin-prettier/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 42f955d9fc64c466df132e970a876a9bd70e0dac +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Apr 13 04:14:58 2020 +0000 + + Bump @spree/storefront-api-v2-sdk from 4.0.5 to 4.0.6 + + Bumps [@spree/storefront-api-v2-sdk](https://github.com/spark-solutions/spree-storefront-api-v2-js-sdk) from 4.0.5 to 4.0.6. + - [Release notes](https://github.com/spark-solutions/spree-storefront-api-v2-js-sdk/releases) + - [Commits](https://github.com/spark-solutions/spree-storefront-api-v2-js-sdk/compare/v4.0.5...v4.0.6) + + Signed-off-by: dependabot-preview[bot] + +commit da9499c4ac25179ebe3c227bab82f09d786154b9 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Apr 10 04:18:05 2020 +0000 + + Bump spree_gateway from 3.7.4 to 3.7.5 + + Bumps [spree_gateway](https://spreecommerce.org) from 3.7.4 to 3.7.5. + + Signed-off-by: dependabot-preview[bot] + +commit 4afb898eafcce4bf49f106160afa676f43707b92 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Apr 9 04:15:41 2020 +0000 + + Bump react-dom from 16.13.0 to 16.13.1 + + Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 16.13.0 to 16.13.1. + - [Release notes](https://github.com/facebook/react/releases) + - [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md) + - [Commits](https://github.com/facebook/react/commits/v16.13.1/packages/react-dom) + + Signed-off-by: dependabot-preview[bot] + +commit c257e3ecd47650617f230114b93755dbc8d68a86 +Author: Damian Legawiec +Date: Wed Apr 8 22:28:03 2020 +0200 + + Update README.md + +commit a7ade9b268d120096632feac1a05ce60669f303e +Author: Damian Legawiec +Date: Wed Apr 8 22:27:07 2020 +0200 + + Update README.md + +commit f38ea1e32f8237c719bf1c089bbdf5277e10cf05 +Merge: bcab272 1127930 +Author: Damian Legawiec +Date: Wed Apr 8 22:26:09 2020 +0200 + + Merge pull request #558 from spark-solutions/dependabot/npm_and_yarn/prettier-2.0.4 + + Bump prettier from 1.19.1 to 2.0.4 + +commit bcab27267c8e8f785406d5019ee5164009fb3233 +Merge: 9147ae1 0f35b17 +Author: Damian Legawiec +Date: Wed Apr 8 22:25:57 2020 +0200 + + Merge pull request #552 from spark-solutions/dependabot/npm_and_yarn/rails/webpacker-5.0.1 + + Bump @rails/webpacker from 4.2.2 to 5.0.1 + +commit 9147ae1d0ba746b0d72b64f38e843d729c170784 +Merge: 39fcac2 51a0898 +Author: Damian Legawiec +Date: Wed Apr 8 22:25:34 2020 +0200 + + Merge pull request #542 from spark-solutions/dependabot/npm_and_yarn/react-16.13.1 + + Bump react from 16.13.0 to 16.13.1 + +commit 39fcac26be4107ea8fffa806b580c84d1a7d6798 +Merge: 863fc33 5831b7a +Author: Damian Legawiec +Date: Wed Apr 8 22:25:23 2020 +0200 + + Merge pull request #535 from spark-solutions/fix/js-minification + + Minimize JS code for production + +commit 863fc3375b8f82ea3b14282bdc43ab625944ee5a +Merge: 7579ff7 be2d94f +Author: Damian Legawiec +Date: Wed Apr 8 22:25:09 2020 +0200 + + Merge pull request #563 from spark-solutions/feature/docker + + Feature/docker + +commit be2d94ff926e12538aa30fa069d017fc78f729e3 +Author: Damian Legawiec +Date: Wed Apr 8 22:19:06 2020 +0200 + + Fix Circcle CI config + +commit ef7c0e78ceec5f8a57cf273a2fb2696f49436e33 +Author: Damian Legawiec +Date: Wed Apr 8 22:14:59 2020 +0200 + + Include js routes in frontend + +commit a140bdba49139cba7908fa9c57fa530fc4d3a30e +Author: Damian Legawiec +Date: Wed Apr 8 22:14:51 2020 +0200 + + Added add to cart capybara support method + +commit 3bb844d5a755995bb63a61cf005089672e4cfb7d +Author: Damian Legawiec +Date: Wed Apr 8 22:14:40 2020 +0200 + + Update raven config + +commit 8f1a7418919deab975a43037333a2098660db300 +Author: Damian Legawiec +Date: Wed Apr 8 22:05:44 2020 +0200 + + Dockerize application + +commit 0f35b1741a84d547a201d5f3821e943a9cb29ca2 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 8 19:29:47 2020 +0000 + + Bump @rails/webpacker from 4.2.2 to 5.0.1 + + Bumps [@rails/webpacker](https://github.com/rails/webpacker) from 4.2.2 to 5.0.1. + - [Release notes](https://github.com/rails/webpacker/releases) + - [Changelog](https://github.com/rails/webpacker/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rails/webpacker/compare/v4.2.2...v5.0.1) + + Signed-off-by: dependabot-preview[bot] + +commit 7579ff73a858aa183770e5e2cc76f4be5f01aca7 +Merge: 2dfef05 3ec31d3 +Author: Damian Legawiec +Date: Wed Apr 8 21:27:40 2020 +0200 + + Merge pull request #562 from spark-solutions/feature/update + + Feature/update + +commit 3ec31d3da801833a7430335b581bfc9d26fcf4be +Author: Damian Legawiec +Date: Wed Apr 8 21:22:28 2020 +0200 + + Upgrade yarn + +commit 89c852759c4aaba84ce40650191e402f3584ba2c +Author: Damian Legawiec +Date: Wed Apr 8 21:21:15 2020 +0200 + + Gems upgrade + +commit 2dfef05ae8659016f3bf0e24661865380bab7ae0 +Merge: 1c5228c 34104dd +Author: Damian Legawiec +Date: Wed Apr 8 21:18:18 2020 +0200 + + Merge pull request #540 from spark-solutions/dependabot/bundler/pg-1.2.3 + + Bump pg from 1.2.2 to 1.2.3 + +commit 1c5228c5c8439719dc9e6efafcb581275f001ee2 +Merge: d05154b 7ece446 +Author: Damian Legawiec +Date: Wed Apr 8 21:18:05 2020 +0200 + + Merge pull request #541 from spark-solutions/dependabot/bundler/rails-6.0.2.2 + + Bump rails from 6.0.2.1 to 6.0.2.2 + +commit d05154b33b8ada1313db0dff9719608aa33e2b00 +Merge: 2e4a629 a7fe3ff +Author: Damian Legawiec +Date: Wed Apr 8 21:17:51 2020 +0200 + + Merge pull request #557 from spark-solutions/dependabot/bundler/aws-sdk-s3-1.61.2 + + Bump aws-sdk-s3 from 1.60.2 to 1.61.2 + +commit 2e4a62983b87b062aa651ca9115fe20286203d1c +Merge: 8629db9 9f75fbc +Author: Damian Legawiec +Date: Wed Apr 8 21:17:25 2020 +0200 + + Merge pull request #553 from spark-solutions/dependabot/bundler/rspec-rails-4.0.0 + + Bump rspec-rails from 4.0.0.beta4 to 4.0.0 + +commit 8629db9fd740e0f92e3cd157d23866f04ca14c20 +Merge: c630e54 9e509d9 +Author: Damian Legawiec +Date: Wed Apr 8 21:17:09 2020 +0200 + + Merge pull request #559 from spark-solutions/dependabot/bundler/spree-4.1.4 + + Bump spree from 4.1.0 to 4.1.4 + +commit 9e509d9c938691330a9a8e8799a77b1c6dbd65fc +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Apr 8 04:17:16 2020 +0000 + + Bump spree from 4.1.0 to 4.1.4 + + Bumps [spree](https://github.com/spree/spree) from 4.1.0 to 4.1.4. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 1127930dd4d6d89da716e92c415ea24e497458ac +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Apr 7 04:17:20 2020 +0000 + + Bump prettier from 1.19.1 to 2.0.4 + + Bumps [prettier](https://github.com/prettier/prettier) from 1.19.1 to 2.0.4. + - [Release notes](https://github.com/prettier/prettier/releases) + - [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md) + - [Commits](https://github.com/prettier/prettier/compare/1.19.1...2.0.4) + + Signed-off-by: dependabot-preview[bot] + +commit a7fe3ff6b78bf50c235cd196a72f3350ed776694 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Apr 6 04:17:28 2020 +0000 + + Bump aws-sdk-s3 from 1.60.2 to 1.61.2 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.60.2 to 1.61.2. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 9f75fbc5abf058eae63870d7932cf3b66633a718 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Mar 25 04:18:16 2020 +0000 + + Bump rspec-rails from 4.0.0.beta4 to 4.0.0 + + Bumps [rspec-rails](https://github.com/rspec/rspec-rails) from 4.0.0.beta4 to 4.0.0. + - [Release notes](https://github.com/rspec/rspec-rails/releases) + - [Changelog](https://github.com/rspec/rspec-rails/blob/master/Changelog.md) + - [Commits](https://github.com/rspec/rspec-rails/compare/v4.0.0.beta4...v4.0.0) + + Signed-off-by: dependabot-preview[bot] + +commit 51a0898933382bbe9b08c13dc502da2f48b14461 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Mar 20 04:17:45 2020 +0000 + + Bump react from 16.13.0 to 16.13.1 + + Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 16.13.0 to 16.13.1. + - [Release notes](https://github.com/facebook/react/releases) + - [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md) + - [Commits](https://github.com/facebook/react/commits/v16.13.1/packages/react) + + Signed-off-by: dependabot-preview[bot] + +commit 7ece4469dc65214848a14ba57b3b97599224ee97 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Mar 20 04:16:30 2020 +0000 + + Bump rails from 6.0.2.1 to 6.0.2.2 + + Bumps [rails](https://github.com/rails/rails) from 6.0.2.1 to 6.0.2.2. + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v6.0.2.1...v6.0.2.2) + + Signed-off-by: dependabot-preview[bot] + +commit 34104ddc1ef7be5b84fb6b2dcf0e24bff411f8f2 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Mar 19 04:17:14 2020 +0000 + + Bump pg from 1.2.2 to 1.2.3 + + Bumps [pg](https://github.com/ged/ruby-pg) from 1.2.2 to 1.2.3. + - [Release notes](https://github.com/ged/ruby-pg/releases) + - [Changelog](https://github.com/ged/ruby-pg/blob/master/History.rdoc) + - [Commits](https://github.com/ged/ruby-pg/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 5831b7a42b538fd8eccdc5614d9a6362ac9fbf15 +Author: Damian Legawiec +Date: Mon Mar 16 11:48:44 2020 +0100 + + Minimize JS code for production + +commit c630e5453efce0702b7debfb7ebc27bd7aabedcf +Merge: 0162035 9777142 +Author: Damian Legawiec +Date: Fri Mar 13 23:11:41 2020 +0100 + + Merge pull request #532 from spark-solutions/dependabot/npm_and_yarn/acorn-6.4.1 + + [Security] Bump acorn from 6.4.0 to 6.4.1 + +commit 9777142193f4d9d968577630b21ebeea841c0caa +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Mar 13 21:14:01 2020 +0000 + + [Security] Bump acorn from 6.4.0 to 6.4.1 + + Bumps [acorn](https://github.com/acornjs/acorn) from 6.4.0 to 6.4.1. **This update includes a security fix.** + - [Release notes](https://github.com/acornjs/acorn/releases) + - [Commits](https://github.com/acornjs/acorn/compare/6.4.0...6.4.1) + + Signed-off-by: dependabot-preview[bot] + +commit 0162035559918d419d23e13d40f74f3b98deb509 +Merge: 6c2614a 9005181 +Author: Damian Legawiec +Date: Tue Mar 10 09:41:18 2020 +0100 + + Merge pull request #528 from spark-solutions/dependabot/bundler/spree_gateway-3.7.4 + + Bump spree_gateway from 3.7.3 to 3.7.4 + +commit 9005181be2f98d3ea926523852763c0b82654083 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Mar 10 04:16:44 2020 +0000 + + Bump spree_gateway from 3.7.3 to 3.7.4 + + Bumps [spree_gateway](https://spreecommerce.org) from 3.7.3 to 3.7.4. + + Signed-off-by: dependabot-preview[bot] + +commit 6c2614ac6e68d816720b824e13de3d516c9fc339 +Merge: ba6f589 97b98da +Author: Damian Legawiec +Date: Mon Mar 9 10:18:12 2020 +0100 + + Merge pull request #524 from spark-solutions/dependabot/bundler/spree_gateway-3.7.3 + + Bump spree_gateway from 3.7.2 to 3.7.3 + +commit 97b98da6979cd0be8c9da3f20a828cbdcd1fdac9 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Mar 9 04:17:09 2020 +0000 + + Bump spree_gateway from 3.7.2 to 3.7.3 + + Bumps [spree_gateway](https://spreecommerce.org) from 3.7.2 to 3.7.3. + + Signed-off-by: dependabot-preview[bot] + +commit ba6f5891d30c92fb60913c306c8844b590bfcea7 +Merge: 71c6edf b60d31b +Author: Damian Legawiec +Date: Fri Mar 6 12:41:04 2020 +0100 + + Merge pull request #486 from spark-solutions/dependabot/npm_and_yarn/eslint-config-standard-jsx-8.1.0 + + Bump eslint-config-standard-jsx from 6.0.2 to 8.1.0 + +commit 71c6edf4bdff845837926e714db101f3ebe1a66b +Merge: 1e8a2cc e9282e8 +Author: Damian Legawiec +Date: Fri Mar 6 12:40:53 2020 +0100 + + Merge pull request #513 from spark-solutions/dependabot/npm_and_yarn/react-16.13.0 + + Bump react from 16.12.0 to 16.13.0 + +commit b60d31b9a9d742806817b7c830490be0ceccdaba +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Mar 6 11:35:17 2020 +0000 + + Bump eslint-config-standard-jsx from 6.0.2 to 8.1.0 + + Bumps [eslint-config-standard-jsx](https://github.com/standard/eslint-config-standard-jsx) from 6.0.2 to 8.1.0. + - [Release notes](https://github.com/standard/eslint-config-standard-jsx/releases) + - [Commits](https://github.com/standard/eslint-config-standard-jsx/compare/v6.0.2...v8.1.0) + + Signed-off-by: dependabot-preview[bot] + +commit e9282e843e663a0abdb7680ff12550993fa43aa8 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Mar 6 11:35:05 2020 +0000 + + Bump react from 16.12.0 to 16.13.0 + + Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 16.12.0 to 16.13.0. + - [Release notes](https://github.com/facebook/react/releases) + - [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md) + - [Commits](https://github.com/facebook/react/commits/v16.13.0/packages/react) + + Signed-off-by: dependabot-preview[bot] + +commit 1e8a2cca564df8b70c3a793164900bb53a225d78 +Merge: 72ba837 dab74f1 +Author: Damian Legawiec +Date: Fri Mar 6 12:33:32 2020 +0100 + + Merge pull request #484 from spark-solutions/dependabot/npm_and_yarn/eslint-config-standard-14.1.0 + + Bump eslint-config-standard from 12.0.0 to 14.1.0 + +commit 72ba8372763271555ca93770c3a9e6d22e192fde +Merge: 3d34018 ba4dd9c +Author: Damian Legawiec +Date: Fri Mar 6 12:33:03 2020 +0100 + + Merge pull request #512 from spark-solutions/dependabot/npm_and_yarn/react-dom-16.13.0 + + Bump react-dom from 16.12.0 to 16.13.0 + +commit ba4dd9cb78a13f554c57e1e0d3a5dd3122ba33cf +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Mar 6 11:26:10 2020 +0000 + + Bump react-dom from 16.12.0 to 16.13.0 + + Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 16.12.0 to 16.13.0. + - [Release notes](https://github.com/facebook/react/releases) + - [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md) + - [Commits](https://github.com/facebook/react/commits/v16.13.0/packages/react-dom) + + Signed-off-by: dependabot-preview[bot] + +commit 3d340184557c5d59a89c66939ad228beeedfe4ad +Merge: 3d0d9a8 5e8d7bd +Author: Damian Legawiec +Date: Fri Mar 6 12:24:16 2020 +0100 + + Merge pull request #522 from spark-solutions/feature/spree-4-1-0 + + Spree 4.1 upgrade + +commit 5e8d7bd153bdb5894842bbe62176775ca73b0dc5 +Author: Damian Legawiec +Date: Fri Mar 6 12:16:29 2020 +0100 + + Upgrade to Spree 4.1 + +commit 9b4b13d6401e950c897ba2604b594dfcf80c2f2b +Author: Damian Legawiec +Date: Fri Mar 6 12:05:55 2020 +0100 + + Remove deprecated behaviour + +commit 3d0d9a86ec3dcc8656759bcf2f898474dfe1981c +Merge: 38092e9 6b7a3a3 +Author: Damian Legawiec +Date: Tue Feb 25 06:26:30 2020 +0100 + + Merge pull request #509 from spark-solutions/dependabot/bundler/spree_gateway-3.7.2 + + Bump spree_gateway from 3.7.1 to 3.7.2 + +commit 6b7a3a3f9d7da9594d7d2e9b5713f92dc0ffdd45 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Feb 25 04:17:26 2020 +0000 + + Bump spree_gateway from 3.7.1 to 3.7.2 + + Bumps [spree_gateway](https://spreecommerce.org) from 3.7.1 to 3.7.2. + + Signed-off-by: dependabot-preview[bot] + +commit 38092e997e0a609596e967d42004f87a30705d85 +Merge: e6a7ae5 53c477e +Author: Damian Legawiec +Date: Fri Feb 21 05:29:42 2020 +0100 + + Merge pull request #506 from spark-solutions/dependabot/bundler/spree_gateway-3.7.1 + + Bump spree_gateway from 3.7.0 to 3.7.1 + +commit e6a7ae5f22dc1a3086aa0cbfdfc872351d3122af +Merge: 8709b46 84ca3cc +Author: Damian Legawiec +Date: Fri Feb 21 05:29:30 2020 +0100 + + Merge pull request #508 from spark-solutions/dependabot/bundler/spree_auth_devise-4.1.0 + + Bump spree_auth_devise from 4.1.0.rc1 to 4.1.0 + +commit 84ca3cce205e42cdd7793f43b75c33925c5788d8 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Feb 21 04:17:29 2020 +0000 + + Bump spree_auth_devise from 4.1.0.rc1 to 4.1.0 + + Bumps [spree_auth_devise](https://github.com/spree/spree_auth_devise) from 4.1.0.rc1 to 4.1.0. + - [Release notes](https://github.com/spree/spree_auth_devise/releases) + - [Changelog](https://github.com/spree/spree_auth_devise/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree_auth_devise/compare/v4.1.0.rc1...v4.1.0) + + Signed-off-by: dependabot-preview[bot] + +commit 53c477e7ef136d1b70df64c9428abc22a853d576 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Feb 21 04:16:45 2020 +0000 + + Bump spree_gateway from 3.7.0 to 3.7.1 + + Bumps [spree_gateway](https://spreecommerce.org) from 3.7.0 to 3.7.1. + + Signed-off-by: dependabot-preview[bot] + +commit 8709b4698268d127a2cc877c12c2d56104bbe9a4 +Merge: 81a04b2 b35b6b3 +Author: Damian Legawiec +Date: Tue Feb 18 07:15:00 2020 +0100 + + Merge pull request #503 from spark-solutions/dependabot/npm_and_yarn/react-redux-7.2.0 + + Bump react-redux from 7.1.3 to 7.2.0 + +commit b35b6b31613309c0d3c37c8a4bfdf01912797dcd +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Feb 18 04:17:14 2020 +0000 + + Bump react-redux from 7.1.3 to 7.2.0 + + Bumps [react-redux](https://github.com/reduxjs/react-redux) from 7.1.3 to 7.2.0. + - [Release notes](https://github.com/reduxjs/react-redux/releases) + - [Changelog](https://github.com/reduxjs/react-redux/blob/master/CHANGELOG.md) + - [Commits](https://github.com/reduxjs/react-redux/compare/v7.1.3...v7.2.0) + + Signed-off-by: dependabot-preview[bot] + +commit 81a04b2fbb7e3bbe5a359990f45d8c8c29e3dc05 +Merge: 0ca3787 24c660f +Author: Damian Legawiec +Date: Mon Feb 17 09:40:27 2020 +0100 + + Merge pull request #502 from spark-solutions/dependabot/npm_and_yarn/spree/storefront-api-v2-sdk-4.0.5 + + Bump @spree/storefront-api-v2-sdk from 4.0.3 to 4.0.5 + +commit 0ca37877a7c1b9d5f147f5e00727f71ad59ba1ea +Merge: b98427d 27cfbe4 +Author: Damian Legawiec +Date: Mon Feb 17 09:40:15 2020 +0100 + + Merge pull request #501 from spark-solutions/dependabot/bundler/spree-4.1.0.rc3 + + Bump spree from 4.1.0.rc2 to 4.1.0.rc3 + +commit 24c660fe99c166c1222f3ee033b283373cee7eb0 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Feb 17 04:17:46 2020 +0000 + + Bump @spree/storefront-api-v2-sdk from 4.0.3 to 4.0.5 + + Bumps [@spree/storefront-api-v2-sdk](https://github.com/spark-solutions/spree-storefront-api-v2-js-sdk) from 4.0.3 to 4.0.5. + - [Release notes](https://github.com/spark-solutions/spree-storefront-api-v2-js-sdk/releases) + - [Commits](https://github.com/spark-solutions/spree-storefront-api-v2-js-sdk/compare/v4.0.3...v4.0.5) + + Signed-off-by: dependabot-preview[bot] + +commit 27cfbe4eddf63a97bb273a320ac315c321f86a6b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Feb 17 04:17:18 2020 +0000 + + Bump spree from 4.1.0.rc2 to 4.1.0.rc3 + + Bumps [spree](https://github.com/spree/spree) from 4.1.0.rc2 to 4.1.0.rc3. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v4.1.0.rc2...v4.1.0.rc3) + + Signed-off-by: dependabot-preview[bot] + +commit b98427d26d91195cc48c004a273c5435348edc29 +Merge: a9c8991 d143e14 +Author: Damian Legawiec +Date: Sat Feb 15 09:36:09 2020 +0100 + + Merge pull request #492 from spark-solutions/dependabot/npm_and_yarn/yarn-1.22.0 + + [Security] Bump yarn from 1.21.1 to 1.22.0 + +commit d143e1453383c2d91aa802b3845ee49ea024a8db +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Feb 6 04:18:55 2020 +0000 + + Bump yarn from 1.21.1 to 1.22.0 + + Bumps [yarn](https://github.com/yarnpkg/yarn) from 1.21.1 to 1.22.0. + - [Release notes](https://github.com/yarnpkg/yarn/releases) + - [Changelog](https://github.com/yarnpkg/yarn/blob/master/CHANGELOG.md) + - [Commits](https://github.com/yarnpkg/yarn/compare/v1.21.1...v1.22.0) + + Signed-off-by: dependabot-preview[bot] + +commit a9c8991669c76a7907070c9f6c6e91411a038388 +Merge: 658dd6e 38fcd68 +Author: Damian Legawiec +Date: Wed Feb 5 11:58:01 2020 +0100 + + Merge pull request #489 from spark-solutions/dependabot/bundler/spree-4.1.0.rc2 + + Bump spree from 4.1.0.rc1 to 4.1.0.rc2 + +commit 38fcd68827702ec3ddce045d622120d092b56ec8 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Feb 5 04:16:38 2020 +0000 + + Bump spree from 4.1.0.rc1 to 4.1.0.rc2 + + Bumps [spree](https://github.com/spree/spree) from 4.1.0.rc1 to 4.1.0.rc2. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v4.1.0.rc1...v4.1.0.rc2) + + Signed-off-by: dependabot-preview[bot] + +commit 658dd6ee66f040a0e203749519f85cf2f029912a +Author: Damian Legawiec +Date: Mon Feb 3 11:08:45 2020 +0100 + + Update gems and npm packages + +commit dab74f100cb7027f0ee6bc927024df6d9f23b243 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Feb 3 04:17:30 2020 +0000 + + Bump eslint-config-standard from 12.0.0 to 14.1.0 + + Bumps [eslint-config-standard](https://github.com/standard/eslint-config-standard) from 12.0.0 to 14.1.0. + - [Release notes](https://github.com/standard/eslint-config-standard/releases) + - [Changelog](https://github.com/standard/eslint-config-standard/blob/master/CHANGELOG.md) + - [Commits](https://github.com/standard/eslint-config-standard/compare/v12.0.0...v14.1.0) + + Signed-off-by: dependabot-preview[bot] + +commit b1628e410c4fdbace121fa5685b5bcb19ccfe252 +Merge: e1ceda1 da00c23 +Author: Damian Legawiec +Date: Sun Feb 2 10:06:02 2020 +0100 + + Merge pull request #457 from spark-solutions/dependabot/npm_and_yarn/eslint-plugin-prettier-3.1.2 + + Bump eslint-plugin-prettier from 2.7.0 to 3.1.2 + +commit da00c23fbdf3db952b5a7ccdc1d77017be56a0e6 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sat Feb 1 19:51:09 2020 +0000 + + Bump eslint-plugin-prettier from 2.7.0 to 3.1.2 + + Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 2.7.0 to 3.1.2. + - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) + - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md) + - [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v2.7.0...v3.1.2) + + Signed-off-by: dependabot-preview[bot] + +commit e1ceda139da6914201d56c607e6e9efe7f9d3e79 +Merge: b3ff042 49337c2 +Author: Damian Legawiec +Date: Sat Feb 1 20:49:17 2020 +0100 + + Merge pull request #460 from spark-solutions/dependabot/npm_and_yarn/eslint-plugin-node-11.0.0 + + Bump eslint-plugin-node from 8.0.1 to 11.0.0 + +commit b3ff0424594c406a5907373f68838315bcd92490 +Merge: 384340c 13fe330 +Author: Damian Legawiec +Date: Sat Feb 1 20:49:05 2020 +0100 + + Merge pull request #472 from spark-solutions/dependabot/npm_and_yarn/babel/plugin-syntax-jsx-7.8.3 + + Bump @babel/plugin-syntax-jsx from 7.2.0 to 7.8.3 + +commit 384340c73aba0ba9d393fd588bd6d3f976898945 +Merge: ff8f05a ac41f03 +Author: Damian Legawiec +Date: Sat Feb 1 20:48:54 2020 +0100 + + Merge pull request #477 from spark-solutions/dependabot/npm_and_yarn/eslint-config-prettier-6.10.0 + + Bump eslint-config-prettier from 3.6.0 to 6.10.0 + +commit ac41f03fb1d6331c1c2ea5da9c013d800890e1bd +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sat Feb 1 18:14:33 2020 +0000 + + Bump eslint-config-prettier from 3.6.0 to 6.10.0 + + Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 3.6.0 to 6.10.0. + - [Release notes](https://github.com/prettier/eslint-config-prettier/releases) + - [Changelog](https://github.com/prettier/eslint-config-prettier/blob/master/CHANGELOG.md) + - [Commits](https://github.com/prettier/eslint-config-prettier/compare/v3.6.0...v6.10.0) + + Signed-off-by: dependabot-preview[bot] + +commit 13fe33099804d4c66a0394fc39fb6862d5275468 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sat Feb 1 18:14:26 2020 +0000 + + Bump @babel/plugin-syntax-jsx from 7.2.0 to 7.8.3 + + Bumps [@babel/plugin-syntax-jsx](https://github.com/babel/babel) from 7.2.0 to 7.8.3. + - [Release notes](https://github.com/babel/babel/releases) + - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) + - [Commits](https://github.com/babel/babel/compare/v7.2.0...v7.8.3) + + Signed-off-by: dependabot-preview[bot] + +commit 49337c2c8e7140f021cea99bd771ffb70522dc5b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sat Feb 1 18:14:24 2020 +0000 + + Bump eslint-plugin-node from 8.0.1 to 11.0.0 + + Bumps [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) from 8.0.1 to 11.0.0. + - [Release notes](https://github.com/mysticatea/eslint-plugin-node/releases) + - [Commits](https://github.com/mysticatea/eslint-plugin-node/compare/v8.0.1...v11.0.0) + + Signed-off-by: dependabot-preview[bot] + +commit ff8f05a3d6d6c00d120e15f239de4130ab730276 +Merge: 512b342 95af8dc +Author: Damian Legawiec +Date: Sat Feb 1 19:12:33 2020 +0100 + + Merge pull request #482 from spark-solutions/feature/spree-4-1 + + Spree 4.1 upgrade + +commit 95af8dc27288abe9fcabc8ef5ec6eb5a31a71cb4 +Author: Damian Legawiec +Date: Sat Feb 1 19:05:19 2020 +0100 + + Bump node-sass to support newer node versions + +commit f98790b699d38972c396f777a5cc11c57d12a54c +Author: Damian Legawiec +Date: Sat Feb 1 17:32:14 2020 +0100 + + Added rack-cache support for development + +commit c7d98c6cafc5f5ba18db9d1cfbba61ba6087bfb7 +Author: Damian Legawiec +Date: Sat Feb 1 15:47:31 2020 +0100 + + Replace chromedriver-helper with webdrivers + +commit 25610f98caf470915da3d5235f95f8c81a10458a +Author: Damian Legawiec +Date: Sat Feb 1 15:33:42 2020 +0100 + + Reorganize rails helper + +commit ff35f47dde93e1314d61c8c0980327e74064a479 +Author: Damian Legawiec +Date: Sat Feb 1 13:59:09 2020 +0100 + + Fixed feature tests for Spree 4.1 + +commit 7035f194456c7fc88e29ec8b17e015266124d0f1 +Author: Damian Legawiec +Date: Sat Feb 1 13:47:30 2020 +0100 + + fix ruby version for circle ci + +commit 2a76193f47a4e6d1ba447850c8d0fa21cb42aeaa +Author: Damian Legawiec +Date: Sat Feb 1 13:43:23 2020 +0100 + + Spree 4.1 upgrade + +commit 3c0b6dd447baf303a8941400306ca17d33f77483 +Author: Damian Legawiec +Date: Sat Feb 1 11:26:11 2020 +0100 + + WIP + +commit 8a8900908e9e02d2a5b5ba12e19944fb371a2b26 +Author: Damian Legawiec +Date: Sat Feb 1 10:51:31 2020 +0100 + + Move to Node 12 and update packages + +commit 80d16092fac25e11fcbb16b642d5ff5996c1bc46 +Author: Damian Legawiec +Date: Sat Feb 1 10:28:08 2020 +0100 + + Move to ruby 2.6.5 and update gems + +commit 512b342fd434b63278f81287b46a016bcdb618ac +Author: Damian Legawiec +Date: Mon Jan 13 10:35:24 2020 +0100 + + Enable multiple puma workers + +commit 32b096fff7ffb36aee8b95a3e7e3d0a037e6b928 +Author: Damian Legawiec +Date: Fri Jan 3 14:01:55 2020 +0100 + + removed deprecated standard-react + +commit 1bb39c6e8a5b43136ed784564178a91c476852de +Merge: 0fc8b5f 116b812 +Author: Damian Legawiec +Date: Fri Jan 3 13:40:55 2020 +0100 + + Merge pull request #437 from spark-solutions/dependabot/npm_and_yarn/react-16.12.0 + + Bump react from 16.8.0 to 16.12.0 + +commit 116b8125c7de76225bceea87e5335927e31d03fa +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jan 3 12:20:16 2020 +0000 + + Bump react from 16.8.0 to 16.12.0 + + Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 16.8.0 to 16.12.0. + - [Release notes](https://github.com/facebook/react/releases) + - [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md) + - [Commits](https://github.com/facebook/react/commits/v16.12.0/packages/react) + + Signed-off-by: dependabot-preview[bot] + +commit 0fc8b5f6d724f143fe92bf4c8b4a8247d75e9c5c +Merge: f08bfa1 fe81f98 +Author: Damian Legawiec +Date: Fri Jan 3 13:18:23 2020 +0100 + + Merge pull request #374 from spark-solutions/dependabot/npm_and_yarn/eslint-config-standard-react-9.0.0 + + Bump eslint-config-standard-react from 7.0.2 to 9.0.0 + +commit f08bfa1144c88230eadf858530387c0adf39b6f3 +Merge: e370021 3e36b39 +Author: Damian Legawiec +Date: Fri Jan 3 13:14:08 2020 +0100 + + Merge pull request #337 from spark-solutions/dependabot/npm_and_yarn/react-hotkeys-2.0.0 + + Bump react-hotkeys from 2.0.0-pre3 to 2.0.0 + +commit fe81f984cee0fd7df11d7043ed39c5f686e67572 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jan 3 12:13:16 2020 +0000 + + Bump eslint-config-standard-react from 7.0.2 to 9.0.0 + + Bumps [eslint-config-standard-react](https://github.com/feross/eslint-config-standard-react) from 7.0.2 to 9.0.0. + - [Release notes](https://github.com/feross/eslint-config-standard-react/releases) + - [Commits](https://github.com/feross/eslint-config-standard-react/compare/v7.0.2...v9.0.0) + + Signed-off-by: dependabot-preview[bot] + +commit e37002102b03fa72291c65e46b60e80841153231 +Merge: 46addbf aba78e8 +Author: Damian Legawiec +Date: Fri Jan 3 13:11:13 2020 +0100 + + Merge pull request #456 from spark-solutions/npm-packages-update-3-1-2020 + + Npm packages update 3 1 2020 + +commit aba78e8612689bdce755315dc60d73eeeac20411 +Author: Damian Legawiec +Date: Fri Jan 3 13:04:07 2020 +0100 + + Upgrade npm packages + +commit fa5b14457c1a12a39b1e7a89ebd099f898afb49d +Author: Damian Legawiec +Date: Fri Jan 3 13:03:58 2020 +0100 + + Move to node 8.16 + +commit 46addbf217acaa07418d6cd3fd82737c1184a4f7 +Merge: 8c26193 7e48615 +Author: Damian Legawiec +Date: Fri Jan 3 12:58:52 2020 +0100 + + Merge pull request #455 from spark-solutions/gems-update-3-1-2020 + + Gems updates + +commit 8c261938e67f4a9375c4efc7866d985c8f17c999 +Merge: a2cf788 d936604 +Author: Damian Legawiec +Date: Fri Jan 3 12:58:20 2020 +0100 + + Merge pull request #441 from spark-solutions/dependabot/npm_and_yarn/eslint-plugin-react-7.17.0 + + Bump eslint-plugin-react from 7.11.1 to 7.17.0 + +commit a2cf788a9c1703619de011a3a9164919b3cc6fa7 +Merge: a148777 67a4b44 +Author: Damian Legawiec +Date: Fri Jan 3 12:58:06 2020 +0100 + + Merge pull request #452 from spark-solutions/dependabot/npm_and_yarn/webpack-dev-server-3.10.1 + + Bump webpack-dev-server from 3.1.14 to 3.10.1 + +commit a148777bb458413d1c385d6d9206bd8a6d11559d +Merge: 2f0fff6 d7cc279 +Author: Damian Legawiec +Date: Fri Jan 3 12:57:13 2020 +0100 + + Merge pull request #453 from spark-solutions/dependabot/npm_and_yarn/typescript-3.7.4 + + Bump typescript from 3.3.4000 to 3.7.4 + +commit 7e486151ac4cf946db9b5c4cc960489d20120a33 +Author: Damian Legawiec +Date: Fri Jan 3 12:52:34 2020 +0100 + + Gems updates + +commit d7cc27960677d04b8b018d12de14c7377d66362e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Dec 23 04:19:35 2019 +0000 + + Bump typescript from 3.3.4000 to 3.7.4 + + Bumps [typescript](https://github.com/Microsoft/TypeScript) from 3.3.4000 to 3.7.4. + - [Release notes](https://github.com/Microsoft/TypeScript/releases) + - [Commits](https://github.com/Microsoft/TypeScript/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 67a4b44675ec91aa6fcd7ac2bd3672d172927646 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Dec 20 04:28:58 2019 +0000 + + Bump webpack-dev-server from 3.1.14 to 3.10.1 + + Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 3.1.14 to 3.10.1. + - [Release notes](https://github.com/webpack/webpack-dev-server/releases) + - [Changelog](https://github.com/webpack/webpack-dev-server/blob/v3.10.1/CHANGELOG.md) + - [Commits](https://github.com/webpack/webpack-dev-server/compare/v3.1.14...v3.10.1) + + Signed-off-by: dependabot-preview[bot] + +commit d9366042214e1a248e2e13522e6231dc10cc4e88 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Dec 2 04:23:42 2019 +0000 + + Bump eslint-plugin-react from 7.11.1 to 7.17.0 + + Bumps [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) from 7.11.1 to 7.17.0. + - [Release notes](https://github.com/yannickcr/eslint-plugin-react/releases) + - [Changelog](https://github.com/yannickcr/eslint-plugin-react/blob/master/CHANGELOG.md) + - [Commits](https://github.com/yannickcr/eslint-plugin-react/compare/v7.11.1...v7.17.0) + + Signed-off-by: dependabot-preview[bot] + +commit 2f0fff65a8ff797e4c6ad12fa5ef5a0f26ff3e77 +Merge: 8e8e2b2 03f1644 +Author: Damian Legawiec +Date: Mon Nov 18 17:25:26 2019 +0100 + + Merge pull request #405 from spark-solutions/dependabot/bundler/rubyzip-1.3.0 + + [Security] Bump rubyzip from 1.2.4 to 1.3.0 + +commit 8e8e2b2990077f1371b2f060fda9912e15e67a95 +Merge: 645bd93 21403c7 +Author: Damian Legawiec +Date: Mon Nov 18 17:25:00 2019 +0100 + + Merge pull request #430 from spark-solutions/dependabot/bundler/loofah-2.3.1 + + [Security] Bump loofah from 2.3.0 to 2.3.1 + +commit 645bd9374a28a4e653780103f998717d7b6474d9 +Merge: 0f93a15 e1dd551 +Author: Damian Legawiec +Date: Mon Nov 18 17:24:39 2019 +0100 + + Merge pull request #438 from spark-solutions/dependabot/bundler/nokogiri-1.10.5 + + [Security] Bump nokogiri from 1.10.4 to 1.10.5 + +commit e1dd5514e32bb5043ac9752a5785685cdf1d638f +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sun Nov 17 20:43:20 2019 +0000 + + [Security] Bump nokogiri from 1.10.4 to 1.10.5 + + Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.10.4 to 1.10.5. **This update includes a security fix.** + - [Release notes](https://github.com/sparklemotion/nokogiri/releases) + - [Changelog](https://github.com/sparklemotion/nokogiri/blob/master/CHANGELOG.md) + - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.10.4...v1.10.5) + + Signed-off-by: dependabot-preview[bot] + +commit 21403c7eba5f6e06b82c71e2c14ef12f644e3aef +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Oct 24 03:01:05 2019 +0000 + + [Security] Bump loofah from 2.3.0 to 2.3.1 + + Bumps [loofah](https://github.com/flavorjones/loofah) from 2.3.0 to 2.3.1. **This update includes a security fix.** + - [Release notes](https://github.com/flavorjones/loofah/releases) + - [Changelog](https://github.com/flavorjones/loofah/blob/master/CHANGELOG.md) + - [Commits](https://github.com/flavorjones/loofah/compare/v2.3.0...v2.3.1) + + Signed-off-by: dependabot-preview[bot] + +commit 0f93a156407c7e8769fba7cf2a15ef6ab05b58eb +Merge: ff84222 22684aa +Author: Damian Legawiec +Date: Wed Oct 9 14:45:30 2019 +0200 + + Merge pull request #424 from spark-solutions/feautre/storage_cache_control + + Storage cache control + CDN + +commit 22684aaf4c9deec493b2925e49368dc4cbca2ce8 +Author: Alexey Suslyakov +Date: Wed Oct 9 14:34:47 2019 +0200 + + Set cache-control header when using S3 storage on production + + To set cache-control header on S3 we can use ActiveStorage interface + https://github.com/rails/rails/blob/6-0-stable/activestorage/lib/active_storage/service/s3_service.rb#L12 + It accepts upload options (from AWS SDK) that we can pass in storage.yml + +commit f47ce4175fe9585fc7bfaa3637ad694ce7d372ca +Author: Alexey Suslyakov +Date: Wed Oct 9 14:33:59 2019 +0200 + + Prioritize CDN over app url when CDN is provided + +commit ff84222082e33ac4db2741f350a86ac86929c005 +Author: Damian Legawiec +Date: Mon Oct 7 16:34:02 2019 +0200 + + Added cache control for static files + +commit 03f16440fe0cd812358cffb71d465ed9d7c08b14 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Sep 30 12:17:31 2019 +0000 + + [Security] Bump rubyzip from 1.2.4 to 1.3.0 + + Bumps [rubyzip](https://github.com/rubyzip/rubyzip) from 1.2.4 to 1.3.0. **This update includes a security fix.** + - [Release notes](https://github.com/rubyzip/rubyzip/releases) + - [Changelog](https://github.com/rubyzip/rubyzip/blob/master/Changelog.md) + - [Commits](https://github.com/rubyzip/rubyzip/compare/v1.2.4...v1.3.0) + + Signed-off-by: dependabot-preview[bot] + +commit 861e8e8cbeb88b5ad46289c411392a9f155a0e9f +Merge: df9bf1f a2bbb3d +Author: Damian Legawiec +Date: Mon Sep 30 11:24:07 2019 +0200 + + Merge pull request #378 from spark-solutions/dependabot/npm_and_yarn/rails/webpacker-4.0.7 + + Bump @rails/webpacker from 4.0.0-rc.7 to 4.0.7 + +commit a2bbb3dc07d64a78cc23cb33b8e77459fb9e0479 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Sep 30 09:18:10 2019 +0000 + + Bump @rails/webpacker from 4.0.0-rc.7 to 4.0.7 + + Bumps [@rails/webpacker](https://github.com/rails/webpacker) from 4.0.0-rc.7 to 4.0.7. + - [Release notes](https://github.com/rails/webpacker/releases) + - [Changelog](https://github.com/rails/webpacker/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rails/webpacker/commits/v4.0.7) + + Signed-off-by: dependabot-preview[bot] + +commit df9bf1fcb78cb6097d29aa37b5fc34a602d04e1c +Merge: 767190d 6067620 +Author: Damian Legawiec +Date: Mon Sep 30 11:16:13 2019 +0200 + + Merge pull request #403 from spark-solutions/dependabot/bundler/spree_gateway-3.6.4 + + Bump spree_gateway from 3.6.1 to 3.6.4 + +commit 767190dda52621b05d7b8e35ce5acad63a956349 +Merge: bad5df7 e4e881a +Author: Damian Legawiec +Date: Mon Sep 30 11:16:00 2019 +0200 + + Merge pull request #404 from spark-solutions/dependabot/npm_and_yarn/babel/plugin-proposal-class-properties-7.5.5 + + Bump @babel/plugin-proposal-class-properties from 7.3.0 to 7.5.5 + +commit 606762010341510be9e74e8d041fbb2b794639be +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Sep 30 08:56:47 2019 +0000 + + Bump spree_gateway from 3.6.1 to 3.6.4 + + Bumps [spree_gateway](https://spreecommerce.org) from 3.6.1 to 3.6.4. + + Signed-off-by: dependabot-preview[bot] + +commit bad5df770107f37fdcdc77f7844d01317fc4a072 +Merge: 9e63bdd f6f7468 +Author: Damian Legawiec +Date: Mon Sep 30 10:55:20 2019 +0200 + + Merge pull request #401 from spark-solutions/dependabot/bundler/spree-4.0.0.rc3 + + Bump spree from 4.0.0.rc2 to 4.0.0.rc3 + +commit e4e881a65b32b14cab102429b76f1b8f39bf60a6 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Sep 30 04:26:26 2019 +0000 + + Bump @babel/plugin-proposal-class-properties from 7.3.0 to 7.5.5 + + Bumps [@babel/plugin-proposal-class-properties](https://github.com/babel/babel) from 7.3.0 to 7.5.5. + - [Release notes](https://github.com/babel/babel/releases) + - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) + - [Commits](https://github.com/babel/babel/compare/v7.3.0...v7.5.5) + + Signed-off-by: dependabot-preview[bot] + +commit f6f7468f2aeb71ca389c210562cdf6b81ed66072 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Sep 30 04:25:37 2019 +0000 + + Bump spree from 4.0.0.rc2 to 4.0.0.rc3 + + Bumps [spree](https://github.com/spree/spree) from 4.0.0.rc2 to 4.0.0.rc3. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v4.0.0.rc2...v4.0.0.rc3) + + Signed-off-by: dependabot-preview[bot] + +commit 9e63bdd721d0fb9a916b1516bb04eb8a779fe419 +Merge: e38bdc0 d71610a +Author: Damian Legawiec +Date: Sun Sep 29 17:11:57 2019 +0200 + + Merge pull request #394 from spark-solutions/dependabot/npm_and_yarn/babel/preset-env-7.6.2 + + Bump @babel/preset-env from 7.3.1 to 7.6.2 + +commit d71610adde439ed4a6212d78cde42dbc965109a0 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sun Sep 29 14:15:45 2019 +0000 + + Bump @babel/preset-env from 7.3.1 to 7.6.2 + + Bumps [@babel/preset-env](https://github.com/babel/babel) from 7.3.1 to 7.6.2. + - [Release notes](https://github.com/babel/babel/releases) + - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) + - [Commits](https://github.com/babel/babel/compare/v7.3.1...v7.6.2) + + Signed-off-by: dependabot-preview[bot] + +commit e38bdc02ea0d782b49c20347e6b1954badb67f39 +Merge: 4c085ac c3b17e5 +Author: Damian Legawiec +Date: Sun Sep 29 16:13:52 2019 +0200 + + Merge pull request #393 from spark-solutions/dependabot/npm_and_yarn/babel/core-7.6.2 + + Bump @babel/core from 7.2.2 to 7.6.2 + +commit 4c085ac8a3a9223ed2d25052e8d656d8b577f306 +Merge: 260b2bb f6d1faf +Author: Damian Legawiec +Date: Sun Sep 29 16:13:20 2019 +0200 + + Merge pull request #391 from spark-solutions/dependabot/bundler/puma-4.2.0 + + Bump puma from 4.1.1 to 4.2.0 + +commit 260b2bb29064abcff554011b384d308bda22a379 +Merge: c1099cc 7cddee4 +Author: Damian Legawiec +Date: Sun Sep 29 16:13:03 2019 +0200 + + Merge pull request #392 from spark-solutions/dependabot/bundler/scout_apm-2.6.1 + + Bump scout_apm from 2.6.0 to 2.6.1 + +commit c1099ccbfd6e525cdcc49348b64d14ccf6acbc70 +Merge: 3362742 953f60f +Author: Damian Legawiec +Date: Sun Sep 29 16:12:50 2019 +0200 + + Merge pull request #399 from spark-solutions/dependabot/bundler/sentry-raven-2.11.3 + + Bump sentry-raven from 2.11.2 to 2.11.3 + +commit 336274200c8247bfff2407aa180bde7afcc54bbf +Merge: 943bc6d 75108a0 +Author: Damian Legawiec +Date: Sun Sep 29 16:12:37 2019 +0200 + + Merge pull request #398 from spark-solutions/dependabot/bundler/uglifier-4.2.0 + + Bump uglifier from 4.1.20 to 4.2.0 + +commit 943bc6d7cd767059d6bb8bdf67b0bd1ea112db11 +Merge: be94c61 3b7f5c6 +Author: Damian Legawiec +Date: Sun Sep 29 16:12:22 2019 +0200 + + Merge pull request #397 from spark-solutions/dependabot/bundler/factory_bot-5.1.0 + + Bump factory_bot from 5.0.2 to 5.1.0 + +commit 953f60f72694ed5f59f42a4f5e35fafba2a46e28 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Sep 27 04:20:26 2019 +0000 + + Bump sentry-raven from 2.11.2 to 2.11.3 + + Bumps [sentry-raven](https://github.com/getsentry/raven-ruby) from 2.11.2 to 2.11.3. + - [Release notes](https://github.com/getsentry/raven-ruby/releases) + - [Changelog](https://github.com/getsentry/raven-ruby/blob/master/changelog.md) + - [Commits](https://github.com/getsentry/raven-ruby/compare/v2.11.2...v2.11.3) + + Signed-off-by: dependabot-preview[bot] + +commit 75108a037fed3747dd66f8442f98c3b4652a22ea +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Sep 26 04:20:35 2019 +0000 + + Bump uglifier from 4.1.20 to 4.2.0 + + Bumps [uglifier](https://github.com/lautis/uglifier) from 4.1.20 to 4.2.0. + - [Release notes](https://github.com/lautis/uglifier/releases) + - [Changelog](https://github.com/lautis/uglifier/blob/master/CHANGELOG.md) + - [Commits](https://github.com/lautis/uglifier/commits) + + Signed-off-by: dependabot-preview[bot] + +commit 3b7f5c66569461450950d9f40f6f15928d407705 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Sep 25 04:21:16 2019 +0000 + + Bump factory_bot from 5.0.2 to 5.1.0 + + Bumps [factory_bot](https://github.com/thoughtbot/factory_bot) from 5.0.2 to 5.1.0. + - [Release notes](https://github.com/thoughtbot/factory_bot/releases) + - [Changelog](https://github.com/thoughtbot/factory_bot/blob/master/NEWS.md) + - [Commits](https://github.com/thoughtbot/factory_bot/compare/v5.0.2...v5.1.0) + + Signed-off-by: dependabot-preview[bot] + +commit c3b17e590dc52c7d1c74bfbc20190b6465bd3630 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Sep 24 04:33:13 2019 +0000 + + Bump @babel/core from 7.2.2 to 7.6.2 + + Bumps [@babel/core](https://github.com/babel/babel) from 7.2.2 to 7.6.2. + - [Release notes](https://github.com/babel/babel/releases) + - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) + - [Commits](https://github.com/babel/babel/compare/v7.2.2...v7.6.2) + + Signed-off-by: dependabot-preview[bot] + +commit 7cddee41453a181658cfb54adff186f633683374 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Sep 24 04:31:52 2019 +0000 + + Bump scout_apm from 2.6.0 to 2.6.1 + + Bumps [scout_apm](https://github.com/scoutapp/scout_apm_ruby) from 2.6.0 to 2.6.1. + - [Release notes](https://github.com/scoutapp/scout_apm_ruby/releases) + - [Changelog](https://github.com/scoutapp/scout_apm_ruby/blob/master/CHANGELOG.markdown) + - [Commits](https://github.com/scoutapp/scout_apm_ruby/compare/v2.6.0...v2.6.1) + + Signed-off-by: dependabot-preview[bot] + +commit f6d1faf10552c56f8559aae4a7527b397e0aa358 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Sep 24 04:30:59 2019 +0000 + + Bump puma from 4.1.1 to 4.2.0 + + Bumps [puma](https://github.com/puma/puma) from 4.1.1 to 4.2.0. + - [Release notes](https://github.com/puma/puma/releases) + - [Changelog](https://github.com/puma/puma/blob/master/History.md) + - [Commits](https://github.com/puma/puma/compare/v4.1.1...v4.2.0) + + Signed-off-by: dependabot-preview[bot] + +commit be94c611dde7bfd8de6c87c323a72c7fa0945583 +Merge: 4b3e056 4fac6bb +Author: Damian Legawiec +Date: Thu Sep 19 17:03:13 2019 +0200 + + Merge pull request #387 from spark-solutions/dependabot/bundler/webmock-3.7.5 + + Bump webmock from 3.7.2 to 3.7.5 + +commit 4b3e05649987cd682a1dd511ab8c421059d87a85 +Merge: 1481f52 4aad787 +Author: Damian Legawiec +Date: Thu Sep 19 17:03:02 2019 +0200 + + Merge pull request #388 from spark-solutions/dependabot/bundler/sentry-raven-2.11.2 + + Bump sentry-raven from 2.11.1 to 2.11.2 + +commit 1481f529b4921a14f7dad5449dcc4679c88c6654 +Merge: 5f57106 cd77355 +Author: Damian Legawiec +Date: Thu Sep 19 17:02:50 2019 +0200 + + Merge pull request #389 from spark-solutions/dependabot/bundler/spree-4.0.0.rc2 + + Bump spree from 4.0.0.rc1 to 4.0.0.rc2 + +commit cd77355d5fd39787237ac8990bdc3b16581ce2c6 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Sep 18 04:20:58 2019 +0000 + + Bump spree from 4.0.0.rc1 to 4.0.0.rc2 + + Bumps [spree](https://github.com/spree/spree) from 4.0.0.rc1 to 4.0.0.rc2. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v4.0.0.rc1...v4.0.0.rc2) + + Signed-off-by: dependabot-preview[bot] + +commit 4aad78775f34ec59b9462da6f98b3471c9b7dbd0 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Sep 18 04:20:23 2019 +0000 + + Bump sentry-raven from 2.11.1 to 2.11.2 + + Bumps [sentry-raven](https://github.com/getsentry/raven-ruby) from 2.11.1 to 2.11.2. + - [Release notes](https://github.com/getsentry/raven-ruby/releases) + - [Changelog](https://github.com/getsentry/raven-ruby/blob/master/changelog.md) + - [Commits](https://github.com/getsentry/raven-ruby/compare/v2.11.1...v2.11.2) + + Signed-off-by: dependabot-preview[bot] + +commit 4fac6bbad2a4c875acc8405c4bacd661a4c0cf1d +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Sep 18 04:19:47 2019 +0000 + + Bump webmock from 3.7.2 to 3.7.5 + + Bumps [webmock](https://github.com/bblimke/webmock) from 3.7.2 to 3.7.5. + - [Release notes](https://github.com/bblimke/webmock/releases) + - [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md) + - [Commits](https://github.com/bblimke/webmock/compare/v3.7.2...v3.7.5) + + Signed-off-by: dependabot-preview[bot] + +commit 5f57106cd4b15af59806029eccf1d83ca8e2a3aa +Merge: e972d34 efc51a6 +Author: Damian Legawiec +Date: Fri Sep 13 10:45:08 2019 +0200 + + Merge pull request #377 from spark-solutions/dependabot/bundler/web-console-4.0.1 + + Bump web-console from 3.7.0 to 4.0.1 + +commit e972d343728df5423500492ff99502be9629b38d +Merge: bc054be 2edf5af +Author: Damian Legawiec +Date: Fri Sep 13 10:44:40 2019 +0200 + + Merge pull request #372 from spark-solutions/dependabot/npm_and_yarn/eslint-5.16.0 + + Bump eslint from 5.6.0 to 5.16.0 + +commit bc054befa2eb0fdccf5d2a4e767a8a04f6b4fe1c +Merge: 3c28fb3 03b0ef9 +Author: Damian Legawiec +Date: Fri Sep 13 10:44:24 2019 +0200 + + Merge pull request #375 from spark-solutions/dependabot/bundler/spree-4.0.0.rc1 + + Bump spree from 4.0.0.beta to 4.0.0.rc1 + +commit 03b0ef989be12a52fca4e2bc17b4ec7e29f6c91d +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Sep 13 08:43:58 2019 +0000 + + Bump spree from 4.0.0.beta to 4.0.0.rc1 + + Bumps [spree](https://github.com/spree/spree) from 4.0.0.beta to 4.0.0.rc1. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v4.0.0.beta...v4.0.0.rc1) + + Signed-off-by: dependabot-preview[bot] + +commit 3c28fb35d3966f0b945a01577f063943a538dff4 +Merge: 2f90f02 707d38d +Author: Damian Legawiec +Date: Fri Sep 13 10:42:24 2019 +0200 + + Merge pull request #381 from spark-solutions/dependabot/bundler/spree_gateway-3.6.1 + + Bump spree_gateway from 3.6.0 to 3.6.1 + +commit 707d38ddabe776962a39f1576ab1fadc8dd989eb +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Sep 13 04:20:35 2019 +0000 + + Bump spree_gateway from 3.6.0 to 3.6.1 + + Bumps [spree_gateway](https://spreecommerce.org) from 3.6.0 to 3.6.1. + + Signed-off-by: dependabot-preview[bot] + +commit 2f90f0202ce8d75a3c1699dee0a4ac55400a897c +Merge: 0358a7d ef11223 +Author: Damian Legawiec +Date: Thu Sep 12 15:04:48 2019 +0200 + + Merge pull request #380 from spark-solutions/hotfix/post-update + + Hotfix/post update + +commit ef11223c51f33921f64555159c58b1117bab4aa8 +Author: Punkbooster +Date: Thu Sep 12 14:35:25 2019 +0200 + + Remove unneeded migration file + +commit e9422dbeda24fe5ae6b3224690d15c70e46a9e5c +Author: Punkbooster +Date: Thu Sep 12 14:35:06 2019 +0200 + + Remove unused frontend helper decorator + +commit efc51a6d466d94ababfdfd2e8ebb01ba137fc8e9 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Sep 11 04:22:45 2019 +0000 + + Bump web-console from 3.7.0 to 4.0.1 + + Bumps [web-console](https://github.com/rails/web-console) from 3.7.0 to 4.0.1. + - [Release notes](https://github.com/rails/web-console/releases) + - [Changelog](https://github.com/rails/web-console/blob/master/CHANGELOG.markdown) + - [Commits](https://github.com/rails/web-console/compare/v3.7.0...v4.0.1) + + Signed-off-by: dependabot-preview[bot] + +commit 2edf5af816f3e129693d5fd22a0fd560c7fb3c24 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Sep 11 04:21:15 2019 +0000 + + Bump eslint from 5.6.0 to 5.16.0 + + Bumps [eslint](https://github.com/eslint/eslint) from 5.6.0 to 5.16.0. + - [Release notes](https://github.com/eslint/eslint/releases) + - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) + - [Commits](https://github.com/eslint/eslint/compare/v5.6.0...v5.16.0) + + Signed-off-by: dependabot-preview[bot] + +commit 0358a7d3e926bb9959e72b165842ddb1e3fb3087 +Merge: a2375b1 967367f +Author: Damian Legawiec +Date: Tue Sep 10 16:51:22 2019 +0200 + + Merge pull request #341 from spark-solutions/dependabot/npm_and_yarn/babel/plugin-proposal-object-rest-spread-7.5.5 + + Bump @babel/plugin-proposal-object-rest-spread from 7.3.2 to 7.5.5 + +commit 3e36b39506fc24b5644af0f7f0a08cffafffc1d4 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Sep 10 14:51:07 2019 +0000 + + Bump react-hotkeys from 2.0.0-pre3 to 2.0.0 + + Bumps [react-hotkeys](https://github.com/greena13/react-hotkeys) from 2.0.0-pre3 to 2.0.0. + - [Release notes](https://github.com/greena13/react-hotkeys/releases) + - [Commits](https://github.com/greena13/react-hotkeys/compare/v2.0.0-pre3...v2.0.0) + + Signed-off-by: dependabot-preview[bot] + +commit a2375b129e036fbd978225c05d542b7b137e5385 +Merge: 01a4fda c8da3fa +Author: Damian Legawiec +Date: Tue Sep 10 16:49:49 2019 +0200 + + Merge pull request #343 from spark-solutions/dependabot/npm_and_yarn/eslint-plugin-import-2.18.2 + + Bump eslint-plugin-import from 2.14.0 to 2.18.2 + +commit 01a4fdad21e0d71ea8b7c24c43365e0443a383c5 +Merge: ac8bb91 d0cfe25 +Author: Damian Legawiec +Date: Tue Sep 10 16:49:33 2019 +0200 + + Merge pull request #310 from spark-solutions/dependabot/npm_and_yarn/styled-components-4.3.2 + + Bump styled-components from 4.1.3 to 4.3.2 + +commit ac8bb91e5bf120ffc9d5cd61e87c604d65efc910 +Merge: ea8f39a 169e8ce +Author: Damian Legawiec +Date: Tue Sep 10 16:49:24 2019 +0200 + + Merge pull request #336 from spark-solutions/dependabot/npm_and_yarn/formik-1.5.8 + + Bump formik from 1.4.3 to 1.5.8 + +commit ea8f39a1a869ea7cc73236a43b6d1f342e70e063 +Merge: 23ef7b8 595f222 +Author: Damian Legawiec +Date: Tue Sep 10 16:49:01 2019 +0200 + + Merge pull request #355 from spark-solutions/dependabot/npm_and_yarn/react-dom-16.9.0 + + Bump react-dom from 16.8.0 to 16.9.0 + +commit 23ef7b8184799b2915e589f2ff9a8909449812cb +Merge: bdf3980 f9713f5 +Author: Damian Legawiec +Date: Tue Sep 10 16:48:46 2019 +0200 + + Merge pull request #354 from spark-solutions/dependabot/bundler/react-rails-2.6.0 + + Bump react-rails from 2.5.0 to 2.6.0 + +commit bdf39805ae50687531fb4a0fbef9e9c3739f94f3 +Merge: c971851 e6a2de3 +Author: Damian Legawiec +Date: Tue Sep 10 16:45:35 2019 +0200 + + Merge pull request #359 from spark-solutions/dependabot/npm_and_yarn/react_ujs-2.6.0 + + Bump react_ujs from 2.4.4 to 2.6.0 + +commit f9713f5bc4c945b725b684d1156a3d0a6f4e1def +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Sep 10 14:45:09 2019 +0000 + + Bump react-rails from 2.5.0 to 2.6.0 + + Bumps [react-rails](https://github.com/reactjs/react-rails) from 2.5.0 to 2.6.0. + - [Release notes](https://github.com/reactjs/react-rails/releases) + - [Changelog](https://github.com/reactjs/react-rails/blob/master/CHANGELOG.md) + - [Commits](https://github.com/reactjs/react-rails/compare/v2.5.0...v2.6.0) + + Signed-off-by: dependabot-preview[bot] + +commit c971851eb23cc18503335bbcbc268cb6d2ee0662 +Merge: b91671a 985e5d8 +Author: Damian Legawiec +Date: Tue Sep 10 16:43:31 2019 +0200 + + Merge pull request #371 from spark-solutions/feature/spree-4-rails-6 + + Spree 4 and Rails 6 + +commit 985e5d8e74495d1061e4c6b5b07846bbcd86feae +Author: Damian Legawiec +Date: Tue Sep 10 15:56:55 2019 +0200 + + Fix zeitwerk error + +commit b62b74523af0166cd912ce53ae7e450e68b4b170 +Author: Damian Legawiec +Date: Tue Sep 10 15:49:13 2019 +0200 + + Updated to Spree 4 and Rails 6 + +commit 0d95c2462d4a3b17ed6b3e0340fdf3b023de46f9 +Author: Damian Legawiec +Date: Tue Sep 10 12:25:43 2019 +0200 + + Update gems + +commit b91671a7516620e953b0a5a069193ef280d77140 +Merge: 45970ac 2f94c49 +Author: Damian Legawiec +Date: Mon Sep 2 10:17:15 2019 +0200 + + Merge pull request #356 from spark-solutions/dependabot/bundler/nokogiri-1.10.4 + + [Security] Bump nokogiri from 1.10.3 to 1.10.4 + +commit 45970ac84aaa998cbe7083967ca3e6019e0cbcf1 +Merge: 184287f 20f9113 +Author: Damian Legawiec +Date: Mon Sep 2 10:17:02 2019 +0200 + + Merge pull request #361 from spark-solutions/dependabot/npm_and_yarn/eslint-utils-1.4.2 + + [Security] Bump eslint-utils from 1.3.1 to 1.4.2 + +commit 184287f7a16f83393be08812617b862ca2973b32 +Merge: b80e197 3e188fd +Author: Damian Legawiec +Date: Fri Aug 30 12:22:15 2019 +0200 + + Merge pull request #362 from spark-solutions/dependabot/npm_and_yarn/mixin-deep-1.3.2 + + [Security] Bump mixin-deep from 1.3.1 to 1.3.2 + +commit 3e188fd063c933d95f6e9761b92c4ac25b5da657 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Aug 27 20:02:20 2019 +0000 + + [Security] Bump mixin-deep from 1.3.1 to 1.3.2 + + Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2. **This update includes a security fix.** + - [Release notes](https://github.com/jonschlinkert/mixin-deep/releases) + - [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2) + + Signed-off-by: dependabot-preview[bot] + +commit 20f9113bb03d94728139707452e1503bfce69df1 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Aug 26 18:45:24 2019 +0000 + + [Security] Bump eslint-utils from 1.3.1 to 1.4.2 + + Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.3.1 to 1.4.2. **This update includes a security fix.** + - [Release notes](https://github.com/mysticatea/eslint-utils/releases) + - [Commits](https://github.com/mysticatea/eslint-utils/compare/v1.3.1...v1.4.2) + + Signed-off-by: dependabot-preview[bot] + +commit e6a2de3c37a68a033188140050580f2511147026 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Aug 12 04:45:25 2019 +0000 + + Bump react_ujs from 2.4.4 to 2.6.0 + + Bumps [react_ujs](https://github.com/reactjs/react-rails) from 2.4.4 to 2.6.0. + - [Release notes](https://github.com/reactjs/react-rails/releases) + - [Changelog](https://github.com/reactjs/react-rails/blob/master/CHANGELOG.md) + - [Commits](https://github.com/reactjs/react-rails/compare/v2.4.4...v2.6.0) + + Signed-off-by: dependabot-preview[bot] + +commit 2f94c49edd0548e4cef601dff4d92ff5a72dda03 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Sun Aug 11 21:40:36 2019 +0000 + + [Security] Bump nokogiri from 1.10.3 to 1.10.4 + + Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.10.3 to 1.10.4. **This update includes a security fix.** + - [Release notes](https://github.com/sparklemotion/nokogiri/releases) + - [Changelog](https://github.com/sparklemotion/nokogiri/blob/master/CHANGELOG.md) + - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.10.3...v1.10.4) + + Signed-off-by: dependabot-preview[bot] + +commit 595f2228cf5b727f6d5fc3f34bf4271322700779 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Aug 9 04:40:00 2019 +0000 + + Bump react-dom from 16.8.0 to 16.9.0 + + Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 16.8.0 to 16.9.0. + - [Release notes](https://github.com/facebook/react/releases) + - [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md) + - [Commits](https://github.com/facebook/react/commits/v16.9.0/packages/react-dom) + + Signed-off-by: dependabot-preview[bot] + +commit c8da3fa9b9d034d91f08747a067d61ce9585c574 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Aug 6 11:16:00 2019 +0000 + + Bump eslint-plugin-import from 2.14.0 to 2.18.2 + + Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.14.0 to 2.18.2. + - [Release notes](https://github.com/benmosher/eslint-plugin-import/releases) + - [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md) + - [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.14.0...v2.18.2) + + Signed-off-by: dependabot-preview[bot] + +commit 169e8ce97880cbc33ecd7786719a05c9de8c066d +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Aug 6 11:15:37 2019 +0000 + + Bump formik from 1.4.3 to 1.5.8 + + Bumps [formik](https://github.com/jaredpalmer/formik) from 1.4.3 to 1.5.8. + - [Release notes](https://github.com/jaredpalmer/formik/releases) + - [Commits](https://github.com/jaredpalmer/formik/compare/v1.4.3...v1.5.8) + + Signed-off-by: dependabot-preview[bot] + +commit b80e19776c2d4b409ee1a81fad5aacd68dbf9f98 +Merge: fae9324 b06998c +Author: Damian Legawiec +Date: Tue Aug 6 13:14:51 2019 +0200 + + Merge pull request #351 from spark-solutions/dependabot/bundler/capybara-3.28.0 + + Bump capybara from 3.19.0 to 3.28.0 + +commit fae932469e71a6d3fad73365e2e84c5a5ca593cc +Merge: 005b413 e345e28 +Author: Damian Legawiec +Date: Tue Aug 6 13:14:31 2019 +0200 + + Merge pull request #350 from spark-solutions/dependabot/bundler/dotenv-rails-2.7.5 + + Bump dotenv-rails from 2.7.2 to 2.7.5 + +commit 005b4135ade417438959a65ca88a926bb8e68535 +Merge: 8dba559 896dc3e +Author: Damian Legawiec +Date: Tue Aug 6 13:13:59 2019 +0200 + + Merge pull request #211 from spark-solutions/dependabot/npm_and_yarn/eslint-plugin-node-8.0.1 + + Bump eslint-plugin-node from 7.0.1 to 8.0.1 + +commit 8dba559894f0972a6a277686c6c187e47e057d71 +Merge: 7d32829 d7e9fc8 +Author: Damian Legawiec +Date: Tue Aug 6 13:13:14 2019 +0200 + + Merge pull request #342 from spark-solutions/dependabot/npm_and_yarn/lodash-es-4.17.15 + + [Security] Bump lodash-es from 4.17.11 to 4.17.15 + +commit d7e9fc834a951090b0c77811039dd8369deb127e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Tue Aug 6 11:06:54 2019 +0000 + + [Security] Bump lodash-es from 4.17.11 to 4.17.15 + + Bumps [lodash-es](https://github.com/lodash/lodash) from 4.17.11 to 4.17.15. **This update includes security fixes.** + - [Release notes](https://github.com/lodash/lodash/releases) + - [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.15) + + Signed-off-by: dependabot-preview[bot] + +commit 7d328299aecdb89fe4f0a733827be64fd1b2b67f +Merge: 5a3dac4 af3704b +Author: Damian Legawiec +Date: Tue Aug 6 13:05:41 2019 +0200 + + Merge pull request #333 from spark-solutions/dependabot/npm_and_yarn/lodash-4.17.13 + + [Security] Bump lodash from 4.17.11 to 4.17.13 + +commit 5a3dac418172b59a068181c855f1e9108f70373e +Merge: 61717ff a2b636d +Author: Damian Legawiec +Date: Tue Aug 6 13:05:24 2019 +0200 + + Merge pull request #332 from spark-solutions/dependabot/npm_and_yarn/lodash.template-4.5.0 + + [Security] Bump lodash.template from 4.4.0 to 4.5.0 + +commit 61717ff56a575e4b0ff33be0577665d5904d7e26 +Merge: e20901c 591b836 +Author: Damian Legawiec +Date: Tue Aug 6 13:05:11 2019 +0200 + + Merge pull request #331 from spark-solutions/dependabot/npm_and_yarn/lodash.merge-4.6.2 + + [Security] Bump lodash.merge from 4.6.1 to 4.6.2 + +commit b06998c35e3030d17b474ea58b826140703fb4f8 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Mon Aug 5 04:31:55 2019 +0000 + + Bump capybara from 3.19.0 to 3.28.0 + + Bumps [capybara](https://github.com/teamcapybara/capybara) from 3.19.0 to 3.28.0. + - [Release notes](https://github.com/teamcapybara/capybara/releases) + - [Changelog](https://github.com/teamcapybara/capybara/blob/master/History.md) + - [Commits](https://github.com/teamcapybara/capybara/compare/3.19.0...3.28.0) + + Signed-off-by: dependabot-preview[bot] + +commit e345e2898dc80d3f16a3aaedfc1537408953e11b +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Aug 1 04:25:59 2019 +0000 + + Bump dotenv-rails from 2.7.2 to 2.7.5 + + Bumps [dotenv-rails](https://github.com/bkeepers/dotenv) from 2.7.2 to 2.7.5. + - [Release notes](https://github.com/bkeepers/dotenv/releases) + - [Changelog](https://github.com/bkeepers/dotenv/blob/master/Changelog.md) + - [Commits](https://github.com/bkeepers/dotenv/compare/v2.7.2...v2.7.5) + + Signed-off-by: dependabot-preview[bot] + +commit 967367f8a3cea5d22ee839a0e730ed7d738ca37e +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Jul 18 16:10:31 2019 +0000 + + Bump @babel/plugin-proposal-object-rest-spread from 7.3.2 to 7.5.5 + + Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.3.2 to 7.5.5. + - [Release notes](https://github.com/babel/babel/releases) + - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) + - [Commits](https://github.com/babel/babel/compare/v7.3.2...v7.5.5) + + Signed-off-by: dependabot-preview[bot] + +commit af3704be3ac9d13f049caef92fa02a88b9e3ddeb +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Thu Jul 11 02:25:16 2019 +0000 + + [Security] Bump lodash from 4.17.11 to 4.17.13 + + Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.13. **This update includes security fixes.** + - [Release notes](https://github.com/lodash/lodash/releases) + - [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.13) + + Signed-off-by: dependabot-preview[bot] + +commit a2b636d30129e70beb2516f3303956bc9f9768d4 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Jul 10 23:52:03 2019 +0000 + + [Security] Bump lodash.template from 4.4.0 to 4.5.0 + + Bumps [lodash.template](https://github.com/lodash/lodash) from 4.4.0 to 4.5.0. **This update includes security fixes.** + - [Release notes](https://github.com/lodash/lodash/releases) + - [Commits](https://github.com/lodash/lodash/compare/4.4.0...4.5.0) + + Signed-off-by: dependabot-preview[bot] + +commit 591b836c31a9b05837cae3eba6c2bcd9c490fda1 +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Wed Jul 10 22:25:46 2019 +0000 + + [Security] Bump lodash.merge from 4.6.1 to 4.6.2 + + Bumps [lodash.merge](https://github.com/lodash/lodash) from 4.6.1 to 4.6.2. **This update includes security fixes.** + - [Release notes](https://github.com/lodash/lodash/releases) + - [Commits](https://github.com/lodash/lodash/commits) + + Signed-off-by: dependabot-preview[bot] + +commit e20901c62128942a9552417a6f76f49684f00009 +Merge: 95db2d4 de9ff57 +Author: Damian Legawiec +Date: Sun Jun 23 23:11:46 2019 +0200 + + Merge pull request #285 from spark-solutions/dependabot/bundler/rubocop-0.71.0 + + Bump rubocop from 0.69.0 to 0.71.0 + +commit 95db2d42aedf2d6da5478c9d152490b3ef3d8d13 +Merge: 9e5a924 d83f537 +Author: Damian Legawiec +Date: Sun Jun 23 23:11:27 2019 +0200 + + Merge pull request #293 from spark-solutions/dependabot/bundler/webpacker-4.0.7 + + Bump webpacker from 4.0.2 to 4.0.7 + +commit 9e5a924dd8f4e4f3f169aa838d961619f1ed1bf6 +Merge: 443dad0 eaeac18 +Author: Damian Legawiec +Date: Sun Jun 23 23:11:07 2019 +0200 + + Merge pull request #261 from spark-solutions/dependabot/bundler/mini_racer-0.2.6 + + Bump mini_racer from 0.2.5 to 0.2.6 + +commit d0cfe25858a72de4727ff5cb4a77cc3af447433a +Author: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> +Date: Fri Jun 21 04:28:37 2019 +0000 + + Bump styled-components from 4.1.3 to 4.3.2 + + Bumps [styled-components](https://github.com/styled-components/styled-components) from 4.1.3 to 4.3.2. + - [Release notes](https://github.com/styled-components/styled-components/releases) + - [Changelog](https://github.com/styled-components/styled-components/blob/master/CHANGELOG.md) + - [Commits](https://github.com/styled-components/styled-components/compare/v4.1.3...v4.3.2) + + Signed-off-by: dependabot-preview[bot] + +commit 443dad0590b629d8cb19b839e2b7cf38415ab66b +Merge: 687c314 d18ed3a +Author: Damian Legawiec +Date: Wed Jun 12 14:41:46 2019 +0200 + + Merge pull request #277 from spark-solutions/dependabot/npm_and_yarn/tar-2.2.2 + + [Security] Bump tar from 2.2.1 to 2.2.2 + +commit 687c314ef7e97e357e9a8301aa9bf59c065794e8 +Merge: 55e59ed ac94e7b +Author: Damian Legawiec +Date: Wed Jun 12 14:41:29 2019 +0200 + + Merge pull request #289 from spark-solutions/dependabot/npm_and_yarn/axios-0.18.1 + + [Security] Bump axios from 0.18.0 to 0.18.1 + +commit d83f537dde19ed3b537f527d9eab2fbc1b406003 +Author: dependabot-preview[bot] +Date: Tue Jun 4 04:57:49 2019 +0000 + + Bump webpacker from 4.0.2 to 4.0.7 + + Bumps [webpacker](https://github.com/rails/webpacker) from 4.0.2 to 4.0.7. + - [Release notes](https://github.com/rails/webpacker/releases) + - [Changelog](https://github.com/rails/webpacker/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rails/webpacker/compare/v4.0.2...v4.0.7) + +commit ac94e7bcaa31b4931facf493cdb28ba81902bc15 +Author: dependabot-preview[bot] +Date: Mon Jun 3 05:01:30 2019 +0000 + + [Security] Bump axios from 0.18.0 to 0.18.1 + + Bumps [axios](https://github.com/axios/axios) from 0.18.0 to 0.18.1. **This update includes security fixes.** + - [Release notes](https://github.com/axios/axios/releases) + - [Changelog](https://github.com/axios/axios/blob/v0.18.1/CHANGELOG.md) + - [Commits](https://github.com/axios/axios/compare/v0.18.0...v0.18.1) + +commit de9ff577d25bc91cfa92ce0560a65aed341ab1da +Author: dependabot-preview[bot] +Date: Fri May 31 05:00:41 2019 +0000 + + Bump rubocop from 0.69.0 to 0.71.0 + + Bumps [rubocop](https://github.com/rubocop-hq/rubocop) from 0.69.0 to 0.71.0. + - [Release notes](https://github.com/rubocop-hq/rubocop/releases) + - [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.69.0...v0.71.0) + +commit d18ed3af6b16c109b8c80d1ee53db6a86b3dc02b +Author: dependabot-preview[bot] +Date: Fri May 24 17:47:39 2019 +0000 + + [Security] Bump tar from 2.2.1 to 2.2.2 + + Bumps [tar](https://github.com/npm/node-tar) from 2.2.1 to 2.2.2. **This update includes security fixes.** + - [Release notes](https://github.com/npm/node-tar/releases) + - [Commits](https://github.com/npm/node-tar/compare/v2.2.1...v2.2.2) + +commit 55e59edd1ba881d60a4cd6cea9c0cb077f07a7af +Author: Damian Legawiec +Date: Wed May 15 16:13:55 2019 +0200 + + Bump Spree to 3.7.3 + +commit eaeac18a00e83b93f67f8c03f735393ef7e33474 +Author: dependabot[bot] +Date: Wed May 15 04:49:58 2019 +0000 + + Bump mini_racer from 0.2.5 to 0.2.6 + + Bumps [mini_racer](https://github.com/discourse/mini_racer) from 0.2.5 to 0.2.6. + - [Release notes](https://github.com/discourse/mini_racer/releases) + - [Changelog](https://github.com/discourse/mini_racer/blob/master/CHANGELOG) + - [Commits](https://github.com/discourse/mini_racer/commits) + + Signed-off-by: dependabot[bot] + +commit 0e16e4f4bbf4a6e0820065a74a7bc7e774dc81ec +Merge: 2e6c1de e6e9e87 +Author: Damian Legawiec +Date: Tue May 14 17:10:43 2019 +0200 + + Merge pull request #216 from spark-solutions/dependabot/bundler/react-rails-2.5.0 + + Bump react-rails from 2.4.7 to 2.5.0 + +commit 2e6c1de48522418e24f0772092ee8a4f8a7c0cbe +Merge: eed4de5 4fc77a9 +Author: Damian Legawiec +Date: Tue May 14 17:10:04 2019 +0200 + + Merge pull request #260 from spark-solutions/dependabot/bundler/rubocop-0.69.0 + + Bump rubocop from 0.68.1 to 0.69.0 + +commit 4fc77a99ecae986e7a6a274104ce641f46e81851 +Author: dependabot[bot] +Date: Tue May 14 04:55:34 2019 +0000 + + Bump rubocop from 0.68.1 to 0.69.0 + + Bumps [rubocop](https://github.com/rubocop-hq/rubocop) from 0.68.1 to 0.69.0. + - [Release notes](https://github.com/rubocop-hq/rubocop/releases) + - [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.68.1...v0.69.0) + + Signed-off-by: dependabot[bot] + +commit eed4de5b24d2261eaf6c82c328f925e9155e1184 +Merge: fcf2252 1fc61a1 +Author: Damian Legawiec +Date: Fri May 10 17:40:03 2019 +0200 + + Merge pull request #250 from spark-solutions/dependabot/npm_and_yarn/node-sass-4.12.0 + + Bump node-sass from 4.9.3 to 4.12.0 + +commit fcf2252c020ab3ec297748538076d17b94e819e5 +Merge: e287626 273ef67 +Author: Damian Legawiec +Date: Fri May 10 17:37:56 2019 +0200 + + Merge pull request #257 from spark-solutions/feature/add-flipper + + Add flipper + +commit 273ef678cd9cc7040f1299b815a71992765a2fb1 +Author: Damian Legawiec +Date: Fri May 10 17:32:45 2019 +0200 + + Fixed default redis url + +commit 2ff7bbef3c99113f395025faea980c5eba820dd8 +Author: Damian Legawiec +Date: Fri May 10 17:32:35 2019 +0200 + + Added flipper + +commit e287626ac271c56079981fa7720d3f76f95eaa7c +Merge: a76c20c 18af4d4 +Author: Damian Legawiec +Date: Fri May 10 17:16:50 2019 +0200 + + Merge pull request #256 from spark-solutions/update/bundle-update + + Update/bundle update + +commit 18af4d4acd86999f243dbd7208a2443a16914c8a +Author: Damian Legawiec +Date: Thu May 9 18:27:21 2019 +0200 + + Bump ruby to 2.6.3 + +commit a30a27af7e94543b1bb07d4661a94204e43f9625 +Author: Damian Legawiec +Date: Thu May 9 18:10:48 2019 +0200 + + Use latest chromedriver on Circle CI + +commit bf6c1b48e321871dfd7a6bd3df931db6dd2d261a +Author: Damian Legawiec +Date: Thu May 9 17:47:30 2019 +0200 + + Bundle update + +commit 1fc61a1142216c5b9ff16fcff26e1ba78d5862f2 +Author: dependabot[bot] +Date: Mon Apr 29 04:52:01 2019 +0000 + + Bump node-sass from 4.9.3 to 4.12.0 + + Bumps [node-sass](https://github.com/sass/node-sass) from 4.9.3 to 4.12.0. + - [Release notes](https://github.com/sass/node-sass/releases) + - [Changelog](https://github.com/sass/node-sass/blob/master/CHANGELOG.md) + - [Commits](https://github.com/sass/node-sass/compare/v4.9.3...v4.12.0) + + Signed-off-by: dependabot[bot] + +commit a76c20c0075af688bcfb9dae4e47df7defb6830d +Merge: bc23cd3 da4ddfd +Author: Damian Legawiec +Date: Tue Apr 23 08:02:34 2019 +0200 + + Merge pull request #244 from spark-solutions/dependabot/bundler/nokogiri-1.10.3 + + [Security] Bump nokogiri from 1.10.2 to 1.10.3 + +commit da4ddfdebf1e7f2ea2f6030268e878436cef1e60 +Author: dependabot[bot] +Date: Mon Apr 22 18:28:30 2019 +0000 + + [Security] Bump nokogiri from 1.10.2 to 1.10.3 + + Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.10.2 to 1.10.3. **This update includes security fixes.** + - [Release notes](https://github.com/sparklemotion/nokogiri/releases) + - [Changelog](https://github.com/sparklemotion/nokogiri/blob/master/CHANGELOG.md) + - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.10.2...v1.10.3) + + Signed-off-by: dependabot[bot] + +commit bc23cd3821078e5c76607d056821a2d5c3350c43 +Merge: 6e96ccd 2ea4f4f +Author: Damian Legawiec +Date: Fri Apr 19 08:03:30 2019 +0200 + + Merge pull request #240 from spark-solutions/dependabot/bundler/capybara-3.17.0 + + Bump capybara from 3.15.0 to 3.17.0 + +commit 2ea4f4f683adbb26e4f2f5c5f20e7db78018ff36 +Author: dependabot[bot] +Date: Fri Apr 19 04:48:14 2019 +0000 + + Bump capybara from 3.15.0 to 3.17.0 + + Bumps [capybara](https://github.com/teamcapybara/capybara) from 3.15.0 to 3.17.0. + - [Release notes](https://github.com/teamcapybara/capybara/releases) + - [Changelog](https://github.com/teamcapybara/capybara/blob/master/History.md) + - [Commits](https://github.com/teamcapybara/capybara/compare/3.15.0...3.17.0) + + Signed-off-by: dependabot[bot] + +commit 6e96ccd8b48b67b6eb481c7f432903e6c12a2fb4 +Merge: a66d39c 12b594b +Author: Damian Legawiec +Date: Wed Apr 10 22:03:28 2019 +0200 + + Merge pull request #231 from spark-solutions/dependabot/bundler/spree-3.7.2 + + Bump spree from 3.7.1 to 3.7.2 + +commit 12b594b27705e7cf634b48cded07c1f2f618a66a +Author: dependabot[bot] +Date: Wed Apr 10 04:50:15 2019 +0000 + + Bump spree from 3.7.1 to 3.7.2 + + Bumps [spree](https://github.com/spree/spree) from 3.7.1 to 3.7.2. + - [Release notes](https://github.com/spree/spree/releases) + - [Changelog](https://github.com/spree/spree/blob/master/CHANGELOG.md) + - [Commits](https://github.com/spree/spree/compare/v3.7.1...v3.7.2) + + Signed-off-by: dependabot[bot] + +commit a66d39c3f0d2d48883b3153fa4b7338496d1cd6e +Author: Damian Legawiec +Date: Wed Apr 3 12:25:14 2019 +0200 + + Fix for Redis config on Heroku + +commit eefd0c487de9a1cc7786a4d7453e00e386ead4a5 +Merge: fb6306f cb15076 +Author: Damian Legawiec +Date: Wed Apr 3 12:14:58 2019 +0200 + + Merge pull request #224 from spark-solutions/dependabot/bundler/ffaker-2.11.0 + + Bump ffaker from 2.10.0 to 2.11.0 + +commit fb6306f3ae4d92cc0447a15d2dca2959c1801a10 +Author: Damian Legawiec +Date: Wed Apr 3 12:14:00 2019 +0200 + + Updated Spree Auth Devise + +commit cb150762df5672f6e1de63fd8d2bd81bfe4af68e +Author: dependabot[bot] +Date: Wed Apr 3 05:24:30 2019 +0000 + + Bump ffaker from 2.10.0 to 2.11.0 + + Bumps [ffaker](https://github.com/ffaker/ffaker) from 2.10.0 to 2.11.0. + - [Release notes](https://github.com/ffaker/ffaker/releases) + - [Changelog](https://github.com/ffaker/ffaker/blob/master/Changelog.md) + - [Commits](https://github.com/ffaker/ffaker/commits) + + Signed-off-by: dependabot[bot] + +commit cf5b00119c406ddb3470dd7175bb03293598285a +Author: Damian Legawiec +Date: Tue Apr 2 16:59:27 2019 +0200 + + Use Spree Analytics Trackers from RubyGems + +commit e6e9e876af512293753708b5e81a38a7bd6a089a +Author: dependabot[bot] +Date: Tue Apr 2 14:01:49 2019 +0000 + + Bump react-rails from 2.4.7 to 2.5.0 + + Bumps [react-rails](https://github.com/reactjs/react-rails) from 2.4.7 to 2.5.0. + - [Release notes](https://github.com/reactjs/react-rails/releases) + - [Changelog](https://github.com/reactjs/react-rails/blob/master/CHANGELOG.md) + - [Commits](https://github.com/reactjs/react-rails/compare/v2.4.7...v2.5.0) + + Signed-off-by: dependabot[bot] + +commit e38528b5f186bdfd1f03fbf93680ae28fdb337f2 +Merge: 03f2f63 669e39d +Author: Damian Legawiec +Date: Tue Apr 2 15:59:25 2019 +0200 + + Merge pull request #219 from spark-solutions/dependabot/bundler/rails-5.2.3 + + Bump rails from 5.2.2.1 to 5.2.3 + +commit 03f2f637daf350e283ed7f6dadaa9a820245e3f8 +Author: Damian Legawiec +Date: Mon Apr 1 16:15:34 2019 +0200 + + Unify Circle CI config files + +commit 669e39d5526079465583bc5ce6ecd9b96e5601ba +Author: dependabot[bot] +Date: Tue Apr 2 04:14:57 2019 +0000 + + Bump rails from 5.2.2.1 to 5.2.3 + + Bumps [rails](https://github.com/rails/rails) from 5.2.2.1 to 5.2.3. + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v5.2.2.1...v5.2.3) + + Signed-off-by: dependabot[bot] + +commit 4f3a8f0e31802757c11d6e2b8f286340acd32589 +Author: Damian Legawiec +Date: Mon Apr 1 16:15:34 2019 +0200 + + Unify Circle CI config files + +commit 20c6b78879f9a3702ba320b8875f2c98e671dea2 +Merge: e9ae15f 4397fa4 +Author: Damian Legawiec +Date: Thu Mar 28 08:14:08 2019 +0100 + + Merge pull request #214 from spark-solutions/dependabot/bundler/bootsnap-1.4.2 + + Bump bootsnap from 1.4.1 to 1.4.2 + +commit 4397fa45a349de5bb90a512e91de6bcce837de80 +Author: dependabot[bot] +Date: Thu Mar 28 04:22:18 2019 +0000 + + Bump bootsnap from 1.4.1 to 1.4.2 + + Bumps [bootsnap](https://github.com/Shopify/bootsnap) from 1.4.1 to 1.4.2. + - [Release notes](https://github.com/Shopify/bootsnap/releases) + - [Changelog](https://github.com/Shopify/bootsnap/blob/master/CHANGELOG.md) + - [Commits](https://github.com/Shopify/bootsnap/compare/v1.4.1...v1.4.2) + + Signed-off-by: dependabot[bot] + +commit e9ae15fbbf9b33c3caea5466c4f4633f141048f9 +Merge: 2f1be70 94e923d +Author: Damian Legawiec +Date: Wed Mar 27 10:52:57 2019 +0100 + + Merge pull request #213 from spark-solutions/apiv2-sdk-dependency + + Add @spree/storefront-api-v2-sdk npm dependency + +commit 94e923dbe1d1b3b41eed85be1815503c393806d6 +Author: tniezg +Date: Wed Mar 27 10:46:44 2019 +0100 + + Add @spree/storefront-api-v2-sdk npm dependency + +commit 2f1be701215bf08757c5b466740ecf80bc893367 +Merge: 3f01928 c0a4a49 +Author: Damian Legawiec +Date: Wed Mar 27 10:41:09 2019 +0100 + + Merge pull request #208 from spark-solutions/dependabot/bundler/capybara-3.15.0 + + Bump capybara from 3.14.0 to 3.15.0 + +commit 3f019284293dae8d37ff543b6d1a26b32ad34316 +Merge: 0482c44 11cee12 +Author: Damian Legawiec +Date: Wed Mar 27 10:40:45 2019 +0100 + + Merge pull request #209 from spark-solutions/dependabot/bundler/dotenv-rails-2.7.2 + + Bump dotenv-rails from 2.7.1 to 2.7.2 + +commit 896dc3ec2b5e50d6212fb9194ca6273ed89ff53f +Author: dependabot[bot] +Date: Tue Mar 26 04:39:34 2019 +0000 + + Bump eslint-plugin-node from 7.0.1 to 8.0.1 + + Bumps [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) from 7.0.1 to 8.0.1. + - [Release notes](https://github.com/mysticatea/eslint-plugin-node/releases) + - [Commits](https://github.com/mysticatea/eslint-plugin-node/compare/v7.0.1...v8.0.1) + + Signed-off-by: dependabot[bot] + +commit 11cee1263fc7dcc992028d3e8ab7501cfa81d218 +Author: dependabot[bot] +Date: Tue Mar 26 04:21:05 2019 +0000 + + Bump dotenv-rails from 2.7.1 to 2.7.2 + + Bumps [dotenv-rails](https://github.com/bkeepers/dotenv) from 2.7.1 to 2.7.2. + - [Release notes](https://github.com/bkeepers/dotenv/releases) + - [Changelog](https://github.com/bkeepers/dotenv/blob/master/Changelog.md) + - [Commits](https://github.com/bkeepers/dotenv/compare/v2.7.1...v2.7.2) + + Signed-off-by: dependabot[bot] + +commit c0a4a493c4a453985131d4b7c299daa7aebea22e +Author: dependabot[bot] +Date: Tue Mar 26 04:20:47 2019 +0000 + + Bump capybara from 3.14.0 to 3.15.0 + + Bumps [capybara](https://github.com/teamcapybara/capybara) from 3.14.0 to 3.15.0. + - [Release notes](https://github.com/teamcapybara/capybara/releases) + - [Changelog](https://github.com/teamcapybara/capybara/blob/master/History.md) + - [Commits](https://github.com/teamcapybara/capybara/compare/3.14.0...3.15.0) + + Signed-off-by: dependabot[bot] + +commit 0482c44691b7ef49b8147d7dddd0e3fc55fb8fb8 +Merge: 1a169c7 71c0df2 +Author: Damian Legawiec +Date: Tue Mar 26 00:15:25 2019 +0100 + + Merge pull request #203 from spark-solutions/dependabot/bundler/rubocop-0.66.0 + + Bump rubocop from 0.65.0 to 0.66.0 + +commit 1a169c7c6439d5be54ded405e33346ce6cb63525 +Merge: 7a64cc5 3c3a65a +Author: Damian Legawiec +Date: Tue Mar 26 00:15:14 2019 +0100 + + Merge pull request #207 from spark-solutions/dependabot/bundler/dalli-2.7.10 + + Bump dalli from 2.7.9 to 2.7.10 + +commit 7a64cc5550d2326a02a53f9b936dcfaa5787ef85 +Merge: aa1297e edbf337 +Author: Damian Legawiec +Date: Mon Mar 25 17:41:52 2019 +0100 + + Merge pull request #196 from spark-solutions/dependabot/bundler/aws-sdk-s3-1.35.0 + + Bump aws-sdk-s3 from 1.30.1 to 1.35.0 + +commit 3c3a65ae112aee2fcc3bddb82cba9ea48eec43b0 +Author: dependabot[bot] +Date: Mon Mar 25 16:41:45 2019 +0000 + + Bump dalli from 2.7.9 to 2.7.10 + + Bumps [dalli](https://github.com/petergoldstein/dalli) from 2.7.9 to 2.7.10. + - [Release notes](https://github.com/petergoldstein/dalli/releases) + - [Changelog](https://github.com/petergoldstein/dalli/blob/master/History.md) + - [Commits](https://github.com/petergoldstein/dalli/compare/v2.7.9...v2.7.10) + + Signed-off-by: dependabot[bot] + +commit aa1297eb281071b95a01058dd084eb1a53ac0967 +Merge: 4c92cad 8ea3ae8 +Author: Damian Legawiec +Date: Mon Mar 25 17:41:44 2019 +0100 + + Merge pull request #193 from spark-solutions/dependabot/npm_and_yarn/resolve-url-loader-3.0.1 + + Bump resolve-url-loader from 3.0.0 to 3.0.1 + +commit 4c92cad4c1b17ad028d861d5207dc7fc75a7d59b +Merge: fa3a39a f8e84bf +Author: Damian Legawiec +Date: Mon Mar 25 17:41:29 2019 +0100 + + Merge pull request #195 from spark-solutions/dependabot/npm_and_yarn/typescript-3.3.4000 + + Bump typescript from 3.3.1 to 3.3.4000 + +commit fa3a39aa6da5a19ca1f91c3cf0add3d48d4f45e0 +Author: Damian Legawiec +Date: Mon Mar 25 17:41:11 2019 +0100 + + Update README.md + +commit 71c0df2fc94f9430a908569f084e842794716d0f +Author: dependabot[bot] +Date: Mon Mar 25 16:40:54 2019 +0000 + + Bump rubocop from 0.65.0 to 0.66.0 + + Bumps [rubocop](https://github.com/rubocop-hq/rubocop) from 0.65.0 to 0.66.0. + - [Release notes](https://github.com/rubocop-hq/rubocop/releases) + - [Changelog](https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md) + - [Commits](https://github.com/rubocop-hq/rubocop/compare/v0.65.0...v0.66.0) + + Signed-off-by: dependabot[bot] + +commit 2af3741e6a9cc65d3b833233701b14bb2a3e655b +Merge: 6053f7b 77715a4 +Author: Damian Legawiec +Date: Mon Mar 25 17:39:41 2019 +0100 + + Merge pull request #199 from spark-solutions/dependabot/bundler/chromedriver-helper-2.1.1 + + Bump chromedriver-helper from 2.1.0 to 2.1.1 + +commit 6053f7b147541a8bd06078df30f8634ec8e9a0c2 +Merge: 157a4ab 05a7cd9 +Author: Damian Legawiec +Date: Mon Mar 25 17:38:50 2019 +0100 + + Merge pull request #192 from spark-solutions/dependabot/bundler/rails-5.2.2.1 + + [Security] Bump rails from 5.2.2 to 5.2.2.1 + +commit 157a4abcc3bc01d4c12c0cf98f7b92b23d9449f9 +Merge: 65d5939 f769a12 +Author: Damian Legawiec +Date: Mon Mar 25 17:38:34 2019 +0100 + + Merge pull request #191 from spark-solutions/dependabot/bundler/scout_apm-2.4.24 + + Bump scout_apm from 2.4.21 to 2.4.24 + +commit 65d59399c0f23044703526fd2a8cec580d09d193 +Merge: de51dce 5fb2629 +Author: Damian Legawiec +Date: Mon Mar 25 17:38:11 2019 +0100 + + Merge pull request #190 from spark-solutions/dependabot/bundler/puma-3.12.1 + + Bump puma from 3.12.0 to 3.12.1 + +commit 77715a437ab8fade931c3c25b4bd92065a2d5a12 +Author: dependabot[bot] +Date: Mon Mar 25 16:35:12 2019 +0000 + + Bump chromedriver-helper from 2.1.0 to 2.1.1 + + Bumps [chromedriver-helper](https://github.com/flavorjones/chromedriver-helper) from 2.1.0 to 2.1.1. + - [Release notes](https://github.com/flavorjones/chromedriver-helper/releases) + - [Changelog](https://github.com/flavorjones/chromedriver-helper/blob/master/CHANGELOG.md) + - [Commits](https://github.com/flavorjones/chromedriver-helper/compare/v2.1.0...v2.1.1) + + Signed-off-by: dependabot[bot] + +commit edbf33744f3a9ca13d7845f40273cea1452224b4 +Author: dependabot[bot] +Date: Mon Mar 25 16:34:59 2019 +0000 + + Bump aws-sdk-s3 from 1.30.1 to 1.35.0 + + Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.30.1 to 1.35.0. + - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) + - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-s3/CHANGELOG.md) + - [Commits](https://github.com/aws/aws-sdk-ruby/compare/1.30.1...v1.35.0) + + Signed-off-by: dependabot[bot] + +commit f8e84bf71d87a727f51f386b686301d19643b918 +Author: dependabot[bot] +Date: Mon Mar 25 16:34:50 2019 +0000 + + Bump typescript from 3.3.1 to 3.3.4000 + + Bumps [typescript](https://github.com/Microsoft/TypeScript) from 3.3.1 to 3.3.4000. + - [Release notes](https://github.com/Microsoft/TypeScript/releases) + - [Commits](https://github.com/Microsoft/TypeScript/compare/v3.3.1...v3.3.4000) + + Signed-off-by: dependabot[bot] + +commit 8ea3ae83fd1405cd287d5d1c4480d6f1067ec2e3 +Author: dependabot[bot] +Date: Mon Mar 25 16:34:20 2019 +0000 + + Bump resolve-url-loader from 3.0.0 to 3.0.1 + + Bumps [resolve-url-loader](https://github.com/bholloway/resolve-url-loader) from 3.0.0 to 3.0.1. + - [Release notes](https://github.com/bholloway/resolve-url-loader/releases) + - [Commits](https://github.com/bholloway/resolve-url-loader/compare/v3.0.0...3.0.1) + + Signed-off-by: dependabot[bot] + +commit 05a7cd90a3941bc647f508cf0fbbf2e3e2846071 +Author: dependabot[bot] +Date: Mon Mar 25 16:34:19 2019 +0000 + + [Security] Bump rails from 5.2.2 to 5.2.2.1 + + Bumps [rails](https://github.com/rails/rails) from 5.2.2 to 5.2.2.1. **This update includes security fixes.** + - [Release notes](https://github.com/rails/rails/releases) + - [Commits](https://github.com/rails/rails/compare/v5.2.2...v5.2.2.1) + + Signed-off-by: dependabot[bot] + +commit f769a12e01be5fa7e708a176fd57c9b19dce7f1d +Author: dependabot[bot] +Date: Mon Mar 25 16:33:43 2019 +0000 + + Bump scout_apm from 2.4.21 to 2.4.24 + + Bumps [scout_apm](https://github.com/scoutapp/scout_apm_ruby) from 2.4.21 to 2.4.24. + - [Release notes](https://github.com/scoutapp/scout_apm_ruby/releases) + - [Changelog](https://github.com/scoutapp/scout_apm_ruby/blob/master/CHANGELOG.markdown) + - [Commits](https://github.com/scoutapp/scout_apm_ruby/compare/v2.4.21...v2.4.24) + + Signed-off-by: dependabot[bot] + +commit 5fb262969a14390bc18dadf017b7f0588798844b +Author: dependabot[bot] +Date: Mon Mar 25 16:33:25 2019 +0000 + + Bump puma from 3.12.0 to 3.12.1 + + Bumps [puma](https://github.com/puma/puma) from 3.12.0 to 3.12.1. + - [Release notes](https://github.com/puma/puma/releases) + - [Changelog](https://github.com/puma/puma/blob/master/History.md) + - [Commits](https://github.com/puma/puma/compare/v3.12.0...v3.12.1) + + Signed-off-by: dependabot[bot] + +commit de51dce08819db3f57ec015ffb613efd1bcab52d +Author: Damian Legawiec +Date: Thu Mar 7 11:39:19 2019 +0100 + + Bump Spree to 3.7.1 + +commit 2b740fb58565c30ccc9476b81fecb39c8de3d04f +Author: Damian Legawiec +Date: Thu Feb 7 13:27:06 2019 +0100 + + Use documentation format with rspec on CI + +commit d1aa5aed2ff2d831c5a851187983e79c95629755 +Author: Damian Legawiec +Date: Thu Feb 7 13:24:51 2019 +0100 + + Add .rspec file + +commit fb76c8a067e6694d3c525eb32336172e926db4a7 +Author: Damian Legawiec +Date: Thu Feb 7 13:22:24 2019 +0100 + + Added note about HMR + +commit 38796fc22b66bea612b6e8eb7ca4e52934ac9832 +Merge: 780436f 696e264 +Author: Damian Legawiec +Date: Thu Feb 7 08:50:38 2019 +0100 + + Merge pull request #189 from spark-solutions/upgrade-webpacker + + Upgrade to Webpack 4, Babel7 and React 16.8.0 + +commit 696e2640053343e0d02221646ebb8f0b231814e4 +Author: Damian Legawiec +Date: Thu Feb 7 08:39:57 2019 +0100 + + Added react sample integration tests + +commit 0ca82d604aecb3ddb16b292a3e5963c799d2a66b +Author: Damian Legawiec +Date: Thu Feb 7 08:39:42 2019 +0100 + + Fixed capybara screenshot config + +commit 3df11b99e40c3fbecce5f298b7c72736940d82b6 +Author: Damian Legawiec +Date: Thu Feb 7 07:37:41 2019 +0100 + + Upgrade to Webpack 4, Babel7 and React 16.8.0 + +commit 780436f46b7732f1ef9c84c2d83de24d1948dfa4 +Merge: 657d005 bb5d257 +Author: Damian Legawiec +Date: Wed Feb 6 17:55:15 2019 +0100 + + Merge pull request #187 from spark-solutions/feature/pr_template + + Create generalised Pull Request template + +commit 657d0057195e16174681fc6e77560931db08378b +Merge: ff9601e 66a112b +Author: Damian Legawiec +Date: Wed Feb 6 17:54:56 2019 +0100 + + Merge pull request #188 from spark-solutions/spree-3-7-ruby-2-6 + + Spree 3.7 & ruby 2.6 + +commit 66a112b547862133cf19ea7859c2d7da6ef509e7 +Author: Damian Legawiec +Date: Wed Feb 6 16:28:56 2019 +0100 + + Downgrade bundler to 1.17 due to heroku deployment difficulties + +commit d8cc605c6c953fcd5a36c19c206fe0e9bdf0e299 +Author: Damian Legawiec +Date: Wed Feb 6 16:01:31 2019 +0100 + + Fixed Webpacker assets directory + +commit 8c7fdaa1855757cc5f21c338f49d96cdf4748072 +Author: Damian Legawiec +Date: Wed Feb 6 15:50:32 2019 +0100 + + Added resolve-url-loader to yarn dependencies + +commit 9d1a2954f8074bb2f42ad776eaf229a1a43bf7f7 +Author: Damian Legawiec +Date: Wed Feb 6 15:44:06 2019 +0100 + + Fixed node engines for Heroku deploy + +commit 6871050d2419c9bbf57791601234f46ac806a03e +Author: Damian Legawiec +Date: Wed Feb 6 15:20:38 2019 +0100 + + Fixed typo + +commit cb215d7310b56dc33900ecab1b4fc33e5c986a06 +Author: Damian Legawiec +Date: Wed Feb 6 15:20:26 2019 +0100 + + Updated README + +commit 863e3a31f368c4b7bbaf3ee355e284086c4054ce +Author: Damian Legawiec +Date: Wed Feb 6 15:20:01 2019 +0100 + + Updated Circle CI config + +commit 3f6818d1247b20642c8b48709edcf6c00f3e28cf +Author: Damian Legawiec +Date: Wed Feb 6 15:19:36 2019 +0100 + + Updated test suite + +commit d81ce9a4a7873003797173ecefba1aa6f3e52256 +Author: Damian Legawiec +Date: Wed Feb 6 15:19:20 2019 +0100 + + Updated webpacker setup + +commit c69e2bb6798c2ec3d6460e2bd6793e75b092dda0 +Author: Damian Legawiec +Date: Wed Feb 6 15:19:02 2019 +0100 + + Updated setup script to use dotenv + +commit ddb59c9171506dfc9b17c82f40e61365ff99d1e8 +Author: Damian Legawiec +Date: Wed Feb 6 15:18:09 2019 +0100 + + Use Spree 3.7 and Ruby 2.6 + +commit 103c4f7ff383c13981b1b18c382d76f3a9a98bd1 +Author: Damian Legawiec +Date: Wed Feb 6 15:17:44 2019 +0100 + + Updated docker-compose setup to not use standard ports + +commit 1b90efd9dc31577ef9e31b0371901a165d2b2884 +Author: Damian Legawiec +Date: Wed Feb 6 15:15:32 2019 +0100 + + Remove ruby-version file - newer RVM versions use Gemfile ruby version + +commit bb5d2578f8470a1e9fa5dfd5dfbbe5e24ed1dec7 +Author: Alexey Suslyakov +Date: Fri Jan 18 16:50:58 2019 +0100 + + Create generalized Pull Request template + +commit ff9601ef1a4e9ba1d8341112339d17d8a0ba740e +Author: Damian Legawiec +Date: Fri Jan 11 16:14:06 2019 +0100 + + Bump spree to 3.7 + +commit 9e5f6ff48bf19dffa1c10639d28fef4c6e7db37a +Author: Damian Legawiec +Date: Mon Dec 17 12:08:59 2018 +0100 + + Install missing migration from Spree 3.7.beta + +commit e23b98e61e745131b451065af309ce322877eb04 +Author: Damian Legawiec +Date: Mon Dec 17 12:07:22 2018 +0100 + + Bump ruby to 2.5.3, rails to 5.2.2 and Spre to 3.7.beta + +commit 048298e1165c210ea8481764c83767146e69304a +Merge: 8dc5468 40ff04f +Author: Damian Legawiec +Date: Mon Nov 19 15:16:22 2018 +0100 + + Merge pull request #185 from spark-solutions/change-cache-keys + + change cache key in circleci config + +commit 40ff04fe718847a585d18e926d8c2d3a561ad754 +Author: Piotr Leniec +Date: Mon Nov 19 13:48:14 2018 +0100 + + change cache key in circleci config + +commit 8dc5468d4454a8adc718399bd63054d7f4e18e9f +Merge: 422284c fccc3ff +Author: Damian Legawiec +Date: Mon Nov 5 10:23:37 2018 +0100 + + Merge pull request #184 from spark-solutions/starter-update + + Starter update + +commit fccc3fff553bb84f2a635f93394e9bddd3a940de +Author: Punkbooster +Date: Sat Nov 3 19:00:52 2018 +0100 + + Make js work in integration tests + +commit 07a3af49667cbedc4c7761bc7fea59ba4f4eebce +Author: Punkbooster +Date: Sat Nov 3 18:56:31 2018 +0100 + + Include awesome print in the production + +commit 7454cba683b309f5899f196b29008556cacef420 +Author: Punkbooster +Date: Sat Nov 3 18:55:10 2018 +0100 + + Add dot env gem + +commit 422284cb511dba2e7a8c393ce513c83d68895d3f +Merge: 363c9d0 e2d3a4b +Author: Damian Legawiec +Date: Fri Oct 19 13:18:52 2018 +0200 + + Merge pull request #183 from spark-solutions/add-letter-opener + + Install letter_opener gem. + +commit e2d3a4bcc1fb0dd9b55947edaa74f8990147c9b5 +Author: Piotr Leniec +Date: Fri Oct 19 13:10:39 2018 +0200 + + install letter_opener + +commit 363c9d0664fbda17b77c274fafd910b7fec2e432 +Merge: f2ecf28 233e282 +Author: Damian Legawiec +Date: Thu Oct 4 19:36:49 2018 +0200 + + Merge pull request #182 from spark-solutions/fix/remove-unused-routes + + Remove unused routes + +commit 233e28212713f3966f0ed4ad201816ec71227b4e +Author: Damian Legawiec +Date: Thu Oct 4 18:25:25 2018 +0200 + + Remove unused routes + +commit f2ecf28e714b78aabe1aa110e5ad7e968a3d7a36 +Author: Damian Legawiec +Date: Wed Oct 3 15:44:24 2018 +0200 + + Added command required for Sentry to track git commits + +commit b9035ef04239c0eebc5f5920774557a527bdf615 +Merge: 72a0b43 f6f01c9 +Author: Damian Legawiec +Date: Wed Oct 3 15:39:44 2018 +0200 + + Merge pull request #181 from spark-solutions/fix/sentry-config + + Additional configuration for Sentry + +commit 72a0b439f60b6da822062dff7993aec0f58641ef +Merge: 4bb260e 0c67b58 +Author: Damian Legawiec +Date: Wed Oct 3 15:39:32 2018 +0200 + + Merge pull request #180 from spark-solutions/fix/add-nvm + + Added NVM support + +commit 0c67b588c074395eddd6671593fa18135a75d987 +Author: Damian Legawiec +Date: Wed Oct 3 15:18:32 2018 +0200 + + Updated installation instructions + +commit 226dda9715f22030477f6965720e27f657a9e4f2 +Author: Damian Legawiec +Date: Wed Oct 3 15:17:59 2018 +0200 + + Loosen the engines definitations for Yarn + +commit f6f01c96f438f8be8759f20c1da80fa826c59976 +Author: Damian Legawiec +Date: Wed Oct 3 15:30:45 2018 +0200 + + Additional configuration for Sentry + + * skip other envs besides production + * send error notification in async way via Active::Job + * sanitize errors to strip out sensitive information + * skop 404 errors + +commit b1f8ab92b653180903c6c500cbb5062022c01b1b +Author: Damian Legawiec +Date: Wed Oct 3 15:17:32 2018 +0200 + + Added NVM + +commit 4bb260ee30734d365220d04cac3baf2590d61c44 +Merge: 51e698f 0a9f527 +Author: Damian Legawiec +Date: Wed Oct 3 09:35:37 2018 +0200 + + Merge pull request #179 from spark-solutions/fix/hot-reload + + Move react-hot-loader into dependencies, it's required for asset prec… + +commit 0a9f5275fdd60e3c8d9556ab6ca5c5164f70dda6 +Author: Damian Legawiec +Date: Tue Oct 2 18:25:17 2018 +0200 + + Move react-hot-loader into dependencies, it's required for asset precompilation + +commit 51e698f71433fe5002eea44abff21c416cad65fa +Merge: 04ae8c6 dc28ca7 +Author: Damian Legawiec +Date: Tue Oct 2 17:57:17 2018 +0200 + + Merge pull request #178 from spark-solutions/fix/coffee-script + + Brough back coffee script (for now) to fix builds on heroku + +commit dc28ca7734e0c985e3f93ae6c1d58efe0a61ae71 +Author: Damian Legawiec +Date: Tue Oct 2 17:48:18 2018 +0200 + + Brough back coffee script (for now) to fix builds on heroku + +commit 04ae8c638854259500111eece8e4ccc304f64575 +Merge: 4a21919 9fe8b51 +Author: piotrleniec-spark <31412337+piotrleniec-spark@users.noreply.github.com> +Date: Tue Oct 2 17:08:56 2018 +0200 + + Merge pull request #177 from spark-solutions/replace-rollbar-and-newrelic + + Replace Rollbar with Sentry and NewRelic with Scout + +commit 9fe8b5116d8340ddafa985bc332d1d144b44b0e7 +Author: Piotr Leniec +Date: Tue Oct 2 17:02:08 2018 +0200 + + install scout_apm + +commit 301e1685ba09afa36dfcf819a1a027f55ccc851a +Author: Piotr Leniec +Date: Tue Oct 2 16:58:25 2018 +0200 + + install raven-ruby + +commit f586bf7937f4c01d1980e187a52402243e8b18e7 +Author: Piotr Leniec +Date: Tue Oct 2 16:54:11 2018 +0200 + + remove newrelic from the codebase + +commit b9fca8dc992639f46121b4a79c74638220183f93 +Author: Piotr Leniec +Date: Tue Oct 2 16:51:15 2018 +0200 + + remove rollbar from the codebase + +commit a4c4ff4e58d96f9db4fc0d9aa608204c80c97531 +Author: Piotr Leniec +Date: Tue Oct 2 15:19:41 2018 +0200 + + replace newrelic with scout + +commit f2467cc0eb08c25ba2958d735206ad64ec6891de +Author: Piotr Leniec +Date: Tue Oct 2 15:15:38 2018 +0200 + + replace rollbar with sentry + +commit 4a21919345076a3484d9a39e71212fd71d7ab9fd +Author: Damian Legawiec +Date: Tue Oct 2 14:49:28 2018 +0200 + + Update README.md + +commit ad683df457ee46f493f01c1409c2986a1eff29f9 +Merge: af80f57 ec85a7a +Author: Damian Legawiec +Date: Tue Oct 2 14:47:35 2018 +0200 + + Merge pull request #176 from spark-solutions/fix/circle-ci-ruby-cache + + Fix Circle CI bundler caching + +commit ec85a7a7e5a7fbb216972803bd17eceeaa13213c +Author: Damian Legawiec +Date: Tue Oct 2 14:39:23 2018 +0200 + + Fix Circle CI bundler caching + +commit af80f570b054468a4e9ff3a4a07ef426b178ffc9 +Merge: 0643b50 e8f9d2b +Author: Damian Legawiec +Date: Tue Oct 2 14:35:44 2018 +0200 + + Merge pull request #175 from spark-solutions/fix/reove-better-errors + + Remove better errors + +commit e8f9d2b4b74a0156c3e0babf7210b3b371931866 +Author: Damian Legawiec +Date: Tue Oct 2 14:29:28 2018 +0200 + + Remove better errors + +commit 0643b50347a6ce0236adceedff2006a08a3b1bde +Merge: 6511831 47785e5 +Author: Damian Legawiec +Date: Tue Oct 2 14:26:49 2018 +0200 + + Merge pull request #166 from spark-solutions/gems_and_tools + + Gems and tools + +commit 47785e577bedb5e0f4cdc4df58d7950a94506bee +Author: Punkbooster +Date: Mon Oct 1 16:24:40 2018 +0200 + + Remove reek & brakeman & add circle config instead + +commit 6511831d9062526a00e97e5208307b54cf842420 +Merge: 8eb7586 8a3a453 +Author: Damian Legawiec +Date: Mon Oct 1 15:32:13 2018 +0200 + + Merge pull request #174 from spark-solutions/deprecation_warnings + + Remove rollbar deprecation warning & some files + +commit 8a3a4535de0ba3ead3fde2529a4773b1392718b8 +Author: Punkbooster +Date: Mon Oct 1 15:22:37 2018 +0200 + + Remove unnecessary files & methods + +commit 2ecac70ca389de7fea35315586f6be44272f2a87 +Author: Punkbooster +Date: Mon Oct 1 15:22:17 2018 +0200 + + Fix rollbar was removed deprecation warning + +commit 50f49684d93359c1dddcaa83b4ecaef4fc4bb62d +Author: Punkbooster +Date: Wed Sep 26 15:35:07 2018 +0200 + + Add & configure monitoring tools + +commit 79a152a5c686f95f0b556b5d04f7b6d57abc23bc +Author: Punkbooster +Date: Tue Sep 25 15:00:09 2018 +0200 + + Update circleci config to use parallelism + +commit 936ffaee11c5396d8cdb9f2cadc010d21f344b1f +Author: Punkbooster +Date: Tue Sep 25 14:59:49 2018 +0200 + + Add reek & brakeman + +commit 8eb7586b7c194cb2c1efe0ba132fce359569f16f +Author: Damian Legawiec +Date: Fri Sep 28 20:06:32 2018 +0200 + + Update README.md + +commit bd58cd8ae09430da198ad126ed0228e7e2c1cafc +Merge: 78e7de7 7bca3be +Author: Damian Legawiec +Date: Fri Sep 28 11:50:10 2018 +0200 + + Merge pull request #167 from spark-solutions/feature/webpacker-react-hot-module-reload + + Add support for hot module reload + +commit 78e7de7c41a4c6ee84e1cff007b3a3d27bb9788c +Merge: 78ff913 619acd0 +Author: Damian Legawiec +Date: Thu Sep 27 19:22:14 2018 +0200 + + Merge pull request #173 from spark-solutions/feature/spree-3-7 + + Spree 3.7 + +commit 619acd0670d8a131860f73c73a43c37557b2c24d +Author: Damian Legawiec +Date: Thu Sep 27 16:33:05 2018 +0200 + + Upgrade to Spree 3.7 with API v2 + +commit 8b52eba30c37457b9ccf7525d3e5dc29f14f08f3 +Author: Damian Legawiec +Date: Thu Sep 27 17:17:56 2018 +0200 + + Fixed failing preferences migration in Spree 3.7 + + This is caused by https://github.com/spree/spree/commit/c42d3b034a88b83c8f27e52c05cc208bf15f0458#diff-fa901dae0e304366993ae2180c352c6f + +commit 78ff913248d73a167a59e76966b4a815beb69f67 +Merge: 1fb6e33 8f34d08 +Author: Damian Legawiec +Date: Thu Sep 27 19:05:35 2018 +0200 + + Merge pull request #172 from spark-solutions/fix/spree-initializer + + Fix Spree initializer for backward compability + +commit 8f34d08c2b896b7bcc53422c0c46dca8dae6398e +Author: Damian Legawiec +Date: Thu Sep 27 18:52:23 2018 +0200 + + Fix Spree initializer for backward compability + +commit 1fb6e331f4fe0570b9d265c6ede5f31422fd4323 +Merge: bbf61bb 72f06b4 +Author: Damian Legawiec +Date: Thu Sep 27 18:57:37 2018 +0200 + + Merge pull request #171 from spark-solutions/fix/add-bucketeer-to-review-apps + + Add bucketeer to review apps + +commit 72f06b4ab4a14825dcca9ac1ab4b448bb20c599a +Author: Damian Legawiec +Date: Thu Sep 27 17:53:38 2018 +0200 + + Add bucketeer to review apps + +commit bbf61bb0dfa705b7684477baa1d0c0a0feb2bfca +Merge: 41f9b2b 94cdc64 +Author: Damian Legawiec +Date: Thu Sep 27 17:08:46 2018 +0200 + + Merge pull request #170 from spark-solutions/fix/asset-precompile + + fixed asset precompile - redux logger isn't available in production env + +commit 94cdc641f97dd49a75869633a741eca7d90a5155 +Author: Damian Legawiec +Date: Thu Sep 27 16:46:08 2018 +0200 + + fixed asset precompile - redux logger isn't available in production env + +commit 41f9b2b77805911a7d3db9723058cf651993ec6e +Merge: 6e2e6c4 04727cb +Author: Damian Legawiec +Date: Thu Sep 27 16:43:42 2018 +0200 + + Merge pull request #169 from spark-solutions/fix/rack-timeout + + rack-timeout settings were moved to ENV variable RACK_TIMEOUT_SERVICE_TIMEOUT + +commit 04727cbeae70eabe25a7a49cdf79d89e39c31a08 +Author: Damian Legawiec +Date: Thu Sep 27 16:40:44 2018 +0200 + + rack-timeout settings were moved to ENV variable + RACK_TIMEOUT_SERVICE_TIMEOUT + +commit 7bca3bea9a4c87a88c8e81106ad9ef4fb096429e +Author: Damian Legawiec +Date: Thu Sep 27 00:54:16 2018 +0200 + + Add support for hot module reload + +commit 6e2e6c4784a1c89e5b210fec60f75431053a0c0e +Merge: ff7a420 f5284d3 +Author: Damian Legawiec +Date: Tue Sep 25 22:10:38 2018 +0200 + + Merge pull request #165 from spark-solutions/rebased_webpacker_migration + + Rebased webpacker migration + +commit f5284d3b9ae90091d4b44a0f6cf03ebb1a4e48dc +Author: Damian Legawiec +Date: Tue Sep 25 22:06:39 2018 +0200 + + Added webpack-dev-server + +commit f28a3990ea10671b0d7202bebc38c8622d63e059 +Author: Punkbooster +Date: Tue Sep 25 12:39:38 2018 +0200 + + Fix rubocop config & add react component render page + +commit 74058b2ba1943cbd725801491838ec6340f9968c +Author: Punkbooster +Date: Mon Sep 24 16:03:28 2018 +0200 + + Add standard eslint & prettier, fix all violations + +commit 3d5c9c2ff7e39880ad1eb2af7fe04bbb08dc8514 +Author: Punkbooster +Date: Mon Sep 24 12:37:23 2018 +0200 + + Add eslint basic config + +commit 5ab9ba052a9a2c78173d5a5994e49e7058e6c32e +Author: Punkbooster +Date: Fri Sep 21 15:04:47 2018 +0200 + + Add server side rendering default configuration + +commit e097bdbfd7f324c89e60eb8a89571e950d44dcc5 +Author: Punkbooster +Date: Fri Sep 21 12:30:32 2018 +0200 + + Setup css loader & remove unnecessary packages + +commit d49fe94811d9ada48d3f9239ee723d8cf8447c6b +Author: Punkbooster +Date: Thu Sep 20 14:53:18 2018 +0200 + + Use same store for all components on the page + +commit 016a8a07f7d1b73820eade31a288de30f66d07d8 +Author: Punkbooster +Date: Thu Sep 20 11:57:51 2018 +0200 + + Connect sample css module + +commit 61623516788d2fd4ea1a1a1dbe2357fd3beabf24 +Author: Punkbooster +Date: Thu Sep 20 10:30:53 2018 +0200 + + Move store setup to separate function + +commit 4548f109c59c9ea433624dccc898d16a2f473d6e +Author: Punkbooster +Date: Wed Sep 19 18:22:51 2018 +0200 + + Move redux setup to container for now + +commit 83cdaa73a2d0ec61f48a6746abc341374c6b834b +Author: Punkbooster +Date: Wed Sep 19 15:31:36 2018 +0200 + + Setup redux & a sample component + +commit 53e48be3c05fcfa827dd2cc2723c9913682bb133 +Author: Punkbooster +Date: Wed Sep 19 10:40:27 2018 +0200 + + Add webpacker initialz config & setup sample component + +commit ff7a42022aec496f6f5ba21634235c36cb23df09 +Merge: 16b4889 c4eb3dc +Author: Damian Legawiec +Date: Mon Sep 24 18:27:20 2018 +0200 + + Merge pull request #164 from spark-solutions/feature/circle-ci-2-0 + + Add circleci 2.0 config file & move to ruby 2.5 + +commit c4eb3dc94f1e3a8ea1049984182a5d17aea0844a +Author: Punkbooster +Date: Fri Sep 21 17:02:01 2018 +0200 + + Add circleci 2.0 config file & move to ruby 2.5 + +commit 16b4889734382530c496f7e3d66c676316e50989 +Merge: 3e0b0d2 72404ab +Author: Damian Legawiec +Date: Mon Sep 24 18:00:01 2018 +0200 + + Merge pull request #162 from spark-solutions/remove-active-model-serializers + + Remove Active Model Serializers + +commit 72404abb0eb6b5c866aaf2d9a4bc9635f9a491a8 +Author: Damian Legawiec +Date: Thu Dec 14 11:50:32 2017 +0100 + + Remove Active Model Serializers + +commit 3e0b0d2ad5d5a86756b0da450b536bb5ee425653 +Merge: 868c0db 6666944 +Author: Damian Legawiec +Date: Mon Sep 24 17:50:45 2018 +0200 + + Merge pull request #161 from spark-solutions/client_removal + + Remove client folder + +commit 6666944174a53992e0b1f642c14883078978fd3b +Author: Damian Legawiec +Date: Mon Sep 24 17:22:50 2018 +0200 + + Add Spree default assets setup + +commit 857da0c75db2523db0e3118346705b19c2ea0d6a +Author: Damian Legawiec +Date: Mon Sep 24 17:22:28 2018 +0200 + + Remove previous webpack setup leftovers + +commit f33e867a6427485a4365cfcc1478e10a5fd17e7e +Author: Damian Legawiec +Date: Mon Sep 24 16:12:01 2018 +0200 + + Remove Hound CI config, moving to CodeClimate + +commit 1a54c77221206fc0d0af6f73f7f4c23139f2b020 +Author: Punkbooster +Date: Tue Sep 18 13:35:04 2018 +0200 + + Remove client folder & unnecesssary views + +commit 868c0dbe0a2ffb4de97641216b87006f62afb98e +Merge: 5108d9f 49692ed +Author: Damian Legawiec +Date: Thu Sep 20 14:27:09 2018 +0200 + + Merge pull request #160 from spark-solutions/spree-3-6 + + Move to Spree 3.6 and Rails 5.2 + +commit 49692edb68cfafef4e92ce8c2ad493c0920aed2a +Author: Damian Legawiec +Date: Thu Sep 20 12:53:20 2018 +0200 + + Change Paperclip to ActiveStorage + +commit bea2e4eb2f55223bed4b5d8c5473b42a05d1d00d +Author: Damian Legawiec +Date: Thu Sep 20 10:45:43 2018 +0200 + + Drop versioning in README - doesn't matter that much + +commit e280633bca67fcf3b889238059b2d32914e8495b +Author: Damian Legawiec +Date: Thu Sep 20 10:44:46 2018 +0200 + + Added spree_analytics_trackers gem + +commit 989c33adad1dcd4a8a8a0ba0795a5fde09e257bc +Author: Damian Legawiec +Date: Thu Sep 20 10:02:25 2018 +0200 + + Move to Spree 3.6 and Rails 5.2 + +commit 5108d9ff2613203a50dc59754948846410f3138c +Merge: 70a99b0 68e554d +Author: Damian Legawiec +Date: Thu May 10 07:52:34 2018 +0200 + + Merge pull request #156 from spark-solutions/feature/add-application-job + + Add missing application job. + +commit 70a99b0a653560d0b0822babaa4a177d0a7bc2db +Author: Damian Legawiec +Date: Fri Feb 16 15:32:38 2018 +0100 + + Group rack-timeout errors by exception type, request HTTP method, and URL, so all timeouts for a particular endpoint are reported under the same entry + + https://github.com/heroku/rack-timeout#rollbar + +commit 68e554d56f36c3687383722989d6077e1020ff77 +Author: Argonus +Date: Fri Jan 26 14:15:02 2018 +0100 + + Add missing application job. + +commit 5f291be0dea1bc26a60608bae7c20930bdb7a8ba +Author: Damian Legawiec +Date: Mon Jan 22 17:48:37 2018 +0100 + + Gems update + + Lock pg at ~> 0.18, Rails doesn't support 1.0.0 yet + Use aws-sdk-s3 against all aws-sdk resources + +commit ec1823098d40a13de4f2fd677a7e0ea4bb9c8285 +Merge: f080b38 416f36a +Author: Damian Legawiec +Date: Fri Dec 15 15:49:05 2017 +0100 + + Merge pull request #155 from spark-solutions/fix/aws-sdk-version + + Fix aws version exception + +commit 416f36acb14d65e34e241b70e349a2a0c2564eb6 +Author: piotrekpasciak +Date: Fri Dec 15 11:35:13 2017 +0100 + + Fix aws version exception + +commit f080b38f2bc3a651b04a6691a0a0aa037c410e48 +Author: Damian Legawiec +Date: Fri Dec 15 08:42:58 2017 +0100 + + Upgrade to Spree 3.4.4 + +commit e31bca281c02f06645857d9340acf2bcefd025ae +Author: Damian Legawiec +Date: Thu Dec 14 11:53:21 2017 +0100 + + Fix startup script if another node process running at 3500 port + +commit 9e65b76ab400e55330ac619c40520cf7aa116ebd +Author: Damian Legawiec +Date: Thu Dec 14 11:35:51 2017 +0100 + + ESlint upgrade + +commit d5f2322d5ec3e7b8caa5232e390ab043c4cdbdf6 +Author: Damian Legawiec +Date: Wed Dec 13 17:56:52 2017 +0100 + + Remove shoulda matchers + +commit 3cadbe87d961bce4c62e5fff8901adedd171a84d +Author: Damian Legawiec +Date: Wed Dec 13 15:12:11 2017 +0100 + + Replace FactoryGirl with FactoryBot + +commit fb0f694129a4eca1f8f87fe28d0d5bec9a40607a +Author: Damian Legawiec +Date: Wed Dec 13 15:09:32 2017 +0100 + + Updated Spree gems + +commit 99d1334e368f8a7190a4c25651decd8aca4b31a9 +Author: Damian Legawiec +Date: Wed Dec 6 00:37:54 2017 +0100 + + Staging as a seperate rails env isn't recommended + +commit f6827da136657fb8ad983b3a23c75d38bc9625e1 +Author: Damian Legawiec +Date: Wed Dec 6 00:31:46 2017 +0100 + + Fixed DEPRECATION WARNING: ActiveSupport.halt_callback_chains_on_return_false= is deprecated and will be removed in Rails 5.2 + +commit 256986987b372efbb608849676bf46eb2288bb87 +Author: Damian Legawiec +Date: Wed Dec 6 00:29:50 2017 +0100 + + rubocop -a + +commit 79be7b9a2ca1390258e29c455976061529baf194 +Author: Damian Legawiec +Date: Wed Dec 6 00:28:08 2017 +0100 + + Updated rubocop config + +commit 0b645ce4bb818afb5149e6fbe7994d22c78566f6 +Author: Damian Legawiec +Date: Wed Dec 6 00:27:55 2017 +0100 + + Added rubocop to dev dependencies + +commit 8824d5cb35f9f5f0202e15ecf21f3a4b367177ed +Author: Damian Legawiec +Date: Wed Dec 6 00:19:24 2017 +0100 + + Updated Spree gems + +commit 69c434042658ac737ab663b9a8420d36b7843f96 +Author: Damian Legawiec +Date: Sun Oct 8 17:10:37 2017 +0200 + + Updated Spree website link + +commit 836425f709023adaa26f06301b7de22e5fa784a7 +Author: Damian Legawiec +Date: Thu Oct 5 11:14:43 2017 +0200 + + Fix for Firefox fetch api implementation + +commit 50516963e9a2780839c3159cfe8b572812bd2433 +Author: Damian Legawiec +Date: Thu Oct 5 10:55:27 2017 +0200 + + Delete spree.yml + + This file isn't used at all since Spree 3.1 + +commit 37e6138f1ad3e90df88792d99eab8649fe335f51 +Merge: 8c0f7fb a55448b +Author: Damian Legawiec +Date: Mon Sep 25 17:15:45 2017 +0200 + + Merge pull request #152 from arudnicka/fix/authenticity_token_fix + + Authenticity token cache fix (back-end/front-end no-store header) + +commit a55448b83796b164aa53972fc8d495ad50203fd3 +Author: Agnieszka Rudnicka +Date: Mon Sep 25 17:11:25 2017 +0200 + + Authenticity token cache fix (back-end/front-end no-store header) + +commit 8c0f7fb8e3b8c8657999a5d607d4caef7ed3698f +Merge: 32533a5 27cd107 +Author: Damian Legawiec +Date: Wed Sep 20 13:08:02 2017 +0200 + + Merge pull request #151 from spark-solutions/enable_rollbar_people_tracking + + Enable rollbar people tracking + +commit 27cd107a5d50f256e45835ca72f23a3975c8b037 +Author: Konrad Gorazd +Date: Wed Sep 20 12:28:08 2017 +0200 + + Enable rollbar people tracking + +commit 32533a54f00acafc24e284838644b6d9262a47b9 +Author: Damian Legawiec +Date: Thu Sep 14 13:08:46 2017 +0200 + + Update to Spree 3.3.1 & Rails 5.1.4 + +commit 651dc7360b96ba2218c95356cb35294a1b7d7378 +Author: Damian Legawiec +Date: Tue Aug 15 11:24:12 2017 +0200 + + Schema.db update + +commit e8864f967acf7ad86c6dd1a511b39478828e5144 +Author: Damian Legawiec +Date: Tue Aug 15 11:24:01 2017 +0200 + + Fixed docker setup + +commit 577b7ab7b889c02a1b21bf9b4c6d58fb9b791b94 +Author: Damian Legawiec +Date: Tue Aug 15 11:15:49 2017 +0200 + + Update README.md + +commit ed18f76f34be79d4695257584a69e9430c83cc49 +Merge: ad90a2a ceb1ab8 +Author: Damian Legawiec +Date: Mon Aug 7 15:34:04 2017 +0200 + + Merge pull request #149 from spark-solutions/spree-3-3-rails-5-1 + + Rails 5.1 & Spree 3.3 + +commit ceb1ab8372e61ccc43407f7d3947ce72a8ef415f +Author: Damian Legawiec +Date: Mon Aug 7 15:25:47 2017 +0200 + + rubocop update + +commit 37256c6ef16958b9fba3ac8f2e7cbd539d68e6d4 +Author: Damian Legawiec +Date: Fri Aug 4 17:47:45 2017 +0200 + + README.md version updated + +commit f0c7242d3df716ae310de12f06e36453b7ab1359 +Author: Damian Legawiec +Date: Fri Aug 4 17:47:20 2017 +0200 + + Use aws-sdk 2.x with paperclip 5.1.x + +commit 9fc419dd6c30e3a9f45581013fc6e843da57cddd +Author: Damian Legawiec +Date: Fri Aug 4 17:38:29 2017 +0200 + + Spree 3.3 migration + +commit 35e7b1d98dad01b5f4177028169a01c5cade05dc +Author: Damian Legawiec +Date: Fri Aug 4 16:59:27 2017 +0200 + + rails 5.1 upgrade + +commit 5a91c7c5b75e65dbc10b867b270d4b7e768daac5 +Author: Damian Legawiec +Date: Fri Aug 4 16:25:34 2017 +0200 + + year fix :) + +commit ad90a2a5024c5d4dbcec88bd11b8881562624642 +Merge: 2067bab 3842448 +Author: Damian Legawiec +Date: Fri Aug 4 16:18:11 2017 +0200 + + Merge pull request #148 from spark-solutions/feature/add-docker + + Docker support + +commit 38424481e3a2c779a27dd00ae36477adb47366ea +Author: Damian Legawiec +Date: Fri Aug 4 16:02:26 2017 +0200 + + Adding note about running tests + +commit 86ee3fbae79681e3ceff64d750ce402d928b654c +Author: Damian Legawiec +Date: Fri Aug 4 15:53:40 2017 +0200 + + Use docker for local development services like postgres, memcached, redis + +commit 2067bab59716968c351335711b82320f0f8f725d +Merge: 10f9470 83c7f04 +Author: Damian Legawiec +Date: Fri Aug 4 14:44:32 2017 +0200 + + Merge pull request #147 from spark-solutions/hotfix/node-update + + Update to NODE v8 and NPM 5.3 + +commit 83c7f0411bf1e292dec6b3bc3856e8c789ad9c63 +Author: Damian Legawiec +Date: Fri Aug 4 14:31:56 2017 +0200 + + Update to NODE v8 and NPM 5.3 + +commit 10f9470762aafb2e872c78494633db26167d9a68 +Merge: a6bf288 d04afe4 +Author: Damian Legawiec +Date: Fri Aug 4 13:57:11 2017 +0200 + + Merge pull request #146 from spark-solutions/hotfix/memcached-cleanup + + By default expires all cache keys in 1 week + +commit d04afe40aa215861a870ef6aac883223cbbf2e9d +Author: Damian Legawiec +Date: Fri Aug 4 13:52:21 2017 +0200 + + By default expires all cache keys in 1 week + + This will auto remove old unused keys after 1 week + +commit a6bf2883a931be66f0158fdc99fc20f9163697ed +Merge: b8b4f9b 20f003c +Author: Damian Legawiec +Date: Fri Aug 4 13:08:17 2017 +0200 + + Merge pull request #145 from spark-solutions/hotfix/review-apps-cdns + + CDN and CDN_UPLOADS variables shouldn't be set for Heroku Review Apps + +commit 20f003c3e1b6e8707e422a77ed3dfa605cfec4a5 +Author: Damian Legawiec +Date: Fri Aug 4 12:42:31 2017 +0200 + + CDN and CDN_UPLOADS variables shouldn't be set for Heroku Review Apps + + We want to use assets from this isolated instance, not from staging or production + +commit b8b4f9b1283bad84ebbb449813305dbfc81a2e65 +Merge: 4651438 98aac15 +Author: Damian Legawiec +Date: Fri Aug 4 12:41:37 2017 +0200 + + Merge pull request #144 from spark-solutions/hotfix/buildpacks + + Heroku buildpacks fixes + +commit 98aac15bb01490c685bad5d6bcf23ec0695d2c38 +Author: Damian Legawiec +Date: Fri Aug 4 11:13:34 2017 +0200 + + we're not using this as heroku release phase was available + +commit 1aa2058556ba2214cfe902c5735a8e7d82aafabc +Author: Damian Legawiec +Date: Fri Aug 4 11:13:19 2017 +0200 + + .buildpacks file isn't used anymore + +commit 4651438b9db6cd9019535aec1da092558bd2fff8 +Merge: 34b4dea 9bba83f +Author: Damian Legawiec +Date: Fri Aug 4 10:27:31 2017 +0200 + + Merge pull request #143 from spark-solutions/hotfix/gem-updates-08-04 + + Ruby & Gem updates + +commit 9bba83f168c32bca7db2cf3fb1aeecb22212a55e +Author: Damian Legawiec +Date: Fri Aug 4 09:46:11 2017 +0200 + + Set react-rails to ~> 1.10 + +commit c43ae0445ca9bfe8481e15bc378f1efb0d6e6c13 +Author: Damian Legawiec +Date: Fri Aug 4 09:45:59 2017 +0200 + + Bump ruby to 2.4.1 + +commit c8f26f03afc6a8916bd62cebb302ac028561c524 +Author: Damian Legawiec +Date: Fri Aug 4 09:13:39 2017 +0200 + + spree_gateway/auth_devise ~> 3.3 + +commit f0852a0e1e0e0384b1d9e27ee7fb19c57724e059 +Author: Damian Legawiec +Date: Fri Aug 4 09:12:51 2017 +0200 + + rails 5.0.5 + +commit 4a390a7bc68c88846a3e841fa2d31f60811761a9 +Author: Damian Legawiec +Date: Fri Aug 4 09:12:10 2017 +0200 + + bundle update + +commit 34b4dea11956b14b0bafba2448527fd104799dbf +Merge: 2bd8b65 63f4d14 +Author: Damian Legawiec +Date: Fri Aug 4 07:40:20 2017 +0200 + + Merge pull request #142 from bbonislawski/fix/remove-deprecated-babel + + Remove deprecated babel package in favor of babel-cli + +commit 63f4d14ca4b320d71ac08a7c247a0917550b8f76 +Author: Bartosz Bonisławski +Date: Thu Jul 27 22:33:56 2017 +0200 + + Remove deprecated babel package in favor of babel-cli + +commit 2bd8b65a007f05647a37bde1795b05e7b8ca5b28 +Merge: 0ecdc63 3ed8381 +Author: Damian Legawiec +Date: Sun Jul 2 23:11:59 2017 +0200 + + Merge pull request #140 from spark-solutions/fix/review-apps-cnd + + set asset_host to heroku url if heroku app name available + +commit 0ecdc63205cb2e7f322de691e9726893f34cd137 +Merge: b94f5a5 81b5852 +Author: Damian Legawiec +Date: Sun Jul 2 23:11:12 2017 +0200 + + Merge pull request #128 from muzykabart/feature/rollbar-js-support + + Add Rollbar.js support + +commit b94f5a5630cdfdc19c253b30a4432c979864bb5f +Merge: 3d524b4 53d02e1 +Author: Krzysztof Rybka +Date: Tue Jun 27 00:36:47 2017 +0300 + + Merge pull request #139 from spark-solutions/fix/cors-webpack-dev-sever + + set CORS for webpack-dev-server + +commit 3d524b46f3c1de11c5f55ebde19b4cd6f6c0b642 +Merge: ba3d3fe fd46685 +Author: Krzysztof Rybka +Date: Tue Jun 27 00:34:20 2017 +0300 + + Merge pull request #138 from spark-solutions/refactor/alerts + + Store alerts as array + +commit 3ed8381b09c143043f9967d768a9a064388ed759 +Author: Krzysztof Rybka +Date: Sat Jun 17 14:51:48 2017 +0200 + + set asset_host to heroku url if heroku app name available + +commit b417d998d7c601ee7f49c9860bcf820a63924b2d +Author: Krzysztof Rybka +Date: Sat Jun 17 14:51:32 2017 +0200 + + set default url options to heroku url if heroku app name available + +commit eef479866a4d3ca18b8ce0535d5f31a5f1d5b940 +Author: Krzysztof Rybka +Date: Sat Jun 17 14:30:12 2017 +0200 + + set HEROKU_APP_NAME for review apps + +commit 53d02e1d823971d2b4c7f5f938f20fc8d6d3b83f +Author: Krzysztof Rybka +Date: Sat Jun 17 13:47:11 2017 +0200 + + set CORS for webpack-dev-server + +commit fd46685de25723e890206ac8f5aadb975829c5de +Author: Krzysztof Rybka +Date: Sat Jun 17 13:38:08 2017 +0200 + + store alerts as array + +commit caf03322f4cf88aca04494d9c24e375548f05e00 +Author: Krzysztof Rybka +Date: Sat Jun 17 13:07:25 2017 +0200 + + use uuid instead of node-uuid + +commit ba3d3fe8ab984ecfb10cded4ef5eb08c88a72b7b +Merge: 2f6086a 1259d4b +Author: Damian Legawiec +Date: Thu Apr 13 14:56:15 2017 +0200 + + Merge pull request #129 from spark-solutions/view_erb + + Removed haml from gemfile & README + +commit 2f6086a0ba9137b26dfb5d5c0d42eb8c221e8010 +Merge: ee302ec 0f608f4 +Author: Damian Legawiec +Date: Thu Apr 13 14:55:48 2017 +0200 + + Merge pull request #136 from spark-solutions/remove_deprecation_warnings + + Removed serve_static_files & static_cache_control DEPRECATION WARNINGS + +commit 0f608f456bb66daf36983ffa2d83401b367d928c +Author: virginia +Date: Thu Apr 13 14:41:53 2017 +0200 + + Removed serve_static_files & static_cache_control DEPRECATION WARNINGS + +commit 1259d4baca639dc1674dba1e1f7a58ff87ed87d1 +Author: virginia +Date: Thu Apr 13 13:59:34 2017 +0200 + + Removed 'haml' from README file + +commit a26c20dc5c89488f780bf2509d57375eba9b664c +Author: virginia +Date: Thu Apr 13 13:59:14 2017 +0200 + + Removed haml from the gemfile + +commit ee302ec83dc7649ba273ef2b480c1a06cd8cbfce +Merge: 5770c53 75bb57a +Author: Damian Legawiec +Date: Wed Apr 12 17:15:27 2017 +0200 + + Merge pull request #135 from spark-solutions/revert-131-deprecation_warnings + + Revert "Deprecation warnings" + +commit 75bb57a4a8b46cec100bd9ccdfc6ce1710f95ebb +Author: Krzysztof Rybka +Date: Wed Apr 12 16:45:51 2017 +0200 + + Revert "Deprecation warnings" + +commit 5770c537ab7b3f5bb93e01bc6e548480abadda77 +Merge: 1479ee0 9c4ab25 +Author: Damian Legawiec +Date: Wed Apr 12 15:48:14 2017 +0200 + + Merge pull request #134 from spark-solutions/hotfix/memcached-fixes + + Memcached fixes + +commit 1479ee0d9a457ea517dc76864bb43a59de6a9da1 +Merge: 6153c00 2e12426 +Author: Damian Legawiec +Date: Wed Apr 12 15:23:57 2017 +0200 + + Merge pull request #131 from spark-solutions/deprecation_warnings + + Deprecation warnings + +commit 9c4ab25a9ef3fdce7692cc82e758b3bc3dc6ecf4 +Author: Damian Legawiec +Date: Wed Apr 12 15:23:05 2017 +0200 + + Disable compressing memcached keys - this can cause some issues + +commit 49ac493320df0b12065037b04e9afc14735f3163 +Author: Damian Legawiec +Date: Wed Apr 12 15:21:55 2017 +0200 + + Removed kgio gem + +commit 2e12426990b85c5f91bbce6fb701748c9bcc5b91 +Author: virginia +Date: Wed Apr 12 15:00:42 2017 +0200 + + aws-sdk gem updated + +commit 81b5852a6647cdf3bafda0daab62ba50d0ef9e88 +Author: Bart Muzyka +Date: Wed Apr 12 13:34:44 2017 +0200 + + Add Rollbar.js support + +commit 6153c004a24fa397a22b3cd89c08fb275f3de6bd +Merge: d8a22bb 53238a9 +Author: Damian Legawiec +Date: Wed Apr 12 13:58:47 2017 +0200 + + Merge pull request #127 from spark-solutions/view_erb + + Changed views extension to html.erb + +commit 53238a9df525012469761b078460cc75c63ca534 +Author: virginia +Date: Wed Apr 12 12:11:02 2017 +0200 + + Changed views extension to html.erb + +commit d8a22bb340e16a9598c789b4e5feb1afdf6f11bd +Merge: 8e5ab58 ecd2e89 +Author: Damian Legawiec +Date: Wed Apr 12 10:23:40 2017 +0200 + + Merge pull request #126 from spark-solutions/specs/additional-spree-preferences-example + + Example of setting spree preferences for rspec + +commit 8e5ab5896ba2f4e52946db21320fc876af0a49fa +Author: Janek +Date: Tue Apr 11 11:42:40 2017 +0200 + + Bump Spree to 3.2.1 + +commit e5807fd450a4eaf16d7e75d0b86afa267cd305fd +Author: Bart Muzyka +Date: Tue Apr 11 11:36:11 2017 +0200 + + Add Heroku generated app.json + +commit ecd2e8908ac36e29ce15014ef511b8c6f6dfa6e7 +Author: Damian Legawiec +Date: Wed Apr 12 10:13:47 2017 +0200 + + Example of setting spree preferences for rspec + +commit 6ed2362e0a40a5c0225918c164af8970a2acb076 +Author: Krzysztof Rybka +Date: Sat Apr 8 15:07:43 2017 +0200 + + update imports-loader (^0.7.1) + +commit 36dba74ea2b7efd130fbf1049644c147e20ea398 +Author: Krzysztof Rybka +Date: Sat Apr 8 15:07:23 2017 +0200 + + update file-loader (^0.11.1) + +commit f05a5debf36e1b9a7ce95ede1fda5fc6d704af36 +Merge: fa08a00 86054d5 +Author: Krzysztof Rybka +Date: Sat Apr 8 14:50:28 2017 +0200 + + Merge pull request #116 from spark-solutions/feature/update-mocha + + update mocha (^3.2.0) + +commit 86054d570949d0352db8e5ae8f9e2acd47d75cb1 +Author: Krzysztof Rybka +Date: Sat Apr 8 14:44:55 2017 +0200 + + update mocha (^3.2.0) + +commit fa08a0066723cab2c326e056c71508c81e151a33 +Merge: 7086b97 65ed37b +Author: Krzysztof Rybka +Date: Sat Apr 8 14:42:10 2017 +0200 + + Merge pull request #115 from spark-solutions/feature/update-jsdom + + update jsdom (^9.12.0) + +commit 7086b975e1541b90ff3ceb866b22547a478e4284 +Merge: 5424797 f42aafa +Author: Krzysztof Rybka +Date: Sat Apr 8 14:39:29 2017 +0200 + + Merge pull request #114 from spark-solutions/feature/update-should + + update should (^11.2.1) + +commit f42aafaf35fbe332c2db4d3dc2f8f85850515f82 +Author: Krzysztof Rybka +Date: Sat Apr 8 14:34:59 2017 +0200 + + update should (^11.2.1) + +commit 65ed37b5b47d644c2e2fd732d2646270bba622db +Author: Krzysztof Rybka +Date: Sat Apr 8 14:29:56 2017 +0200 + + update jsdom (^9.12.0) + +commit 5424797f7108887acc97a880d35a04f1a93dff6a +Merge: 0c2a476 f2684b1 +Author: Krzysztof Rybka +Date: Sat Apr 8 14:20:47 2017 +0200 + + Merge pull request #105 from spark-solutions/feature/update-redux-thunk + + update redux-thunk to 2.2.0 + +commit f2684b1037881b9897f411fd7c920b740114b4d8 +Author: Krzysztof Rybka +Date: Sun Mar 12 19:11:00 2017 +0100 + + update redux-thunk to 2.2.0 + +commit 0c2a476318e3cb385039f1e27f93924f027ea295 +Merge: 7ad29c3 5d28135 +Author: Krzysztof Rybka +Date: Sat Apr 8 13:43:35 2017 +0200 + + Merge pull request #108 from spark-solutions/feature/update-node-sass + + update node-sass to 4.5.0 + +commit 5d2813520f9627a506a3f4f5adc5e26f2e474925 +Author: Krzysztof Rybka +Date: Mon Mar 13 20:18:44 2017 +0100 + + update node-sass (^4.5.2) + +commit 7ad29c3043debd5c390f17aeff65dedab78a461f +Merge: b63d77f 13d0b51 +Author: Krzysztof Rybka +Date: Sat Apr 8 13:33:07 2017 +0200 + + Merge pull request #113 from spark-solutions/feature/update-redux-logger + + update redux-logger (^3.0.1) + +commit 13d0b5145e9ef6b66e99c3f9255d6045551d15a7 +Author: Krzysztof Rybka +Date: Sat Apr 8 13:27:59 2017 +0200 + + update redux-logger (^3.0.1) + +commit b63d77f5193f8eb75991616bf5937731c9c39c10 +Merge: 1f22e9c dda8309 +Author: Krzysztof Rybka +Date: Sat Apr 8 13:10:05 2017 +0200 + + Merge pull request #112 from spark-solutions/feature/remove-jscs-deps + + remove jscs from devdeps + +commit dda830954676f618bb690acdd8fba134aa39c3e4 +Author: Krzysztof Rybka +Date: Sat Apr 8 13:05:37 2017 +0200 + + remove jscs from devdeps + +commit 1f22e9cd9dce5bee330a01f3d6dca016dd553c43 +Merge: f8bc4f6 cf8a832 +Author: Krzysztof Rybka +Date: Sat Apr 8 12:36:35 2017 +0200 + + Merge pull request #103 from spark-solutions/feature/update-babel-packages + + update babel packages + +commit cf8a83230996caddeebf823ec880d483813d1fa3 +Author: Krzysztof Rybka +Date: Sun Mar 12 18:50:42 2017 +0100 + + update sass-resources-loader to 1.2.0 + +commit 9440f1591ff1d76356c4e68c7c4cca1cee35bb46 +Author: Krzysztof Rybka +Date: Sun Mar 12 18:47:42 2017 +0100 + + update postcss-loader to 1.3.3 + +commit d321ed55e861e4b77644c948d0a4d92c3be8655e +Author: Krzysztof Rybka +Date: Sun Mar 12 18:42:33 2017 +0100 + + update css-loader to 0.27.1 + +commit 993a40a678915c59153b76401053fafa40b5db55 +Author: Krzysztof Rybka +Date: Sun Mar 12 18:34:59 2017 +0100 + + update babel packages + +commit f8bc4f648f26204e37ed8abcbf07af516ed01053 +Merge: 3b8d52e fdb353f +Author: Damian Legawiec +Date: Mon Mar 13 08:57:25 2017 +0100 + + Merge pull request #104 from spark-solutions/feature/update-loaders + + Feature/update loaders + +commit 3b8d52eacdf978256ee11e4fe3c9562811ecccb9 +Merge: 9865228 b29a0aa +Author: Damian Legawiec +Date: Mon Mar 13 08:57:17 2017 +0100 + + Merge pull request #106 from spark-solutions/feature/update-es6-promise + + update es6-promise 4.1.0 + +commit 986522888fbb9c8d2d01e268b73dd8ab36960c76 +Merge: f2fb7a2 df8c999 +Author: Damian Legawiec +Date: Mon Mar 13 08:56:47 2017 +0100 + + Merge pull request #107 from spark-solutions/feature/update-rails-5-0-2 + + update rails to 5.0.2 + +commit df8c999824885bfe289a3314c7b07b7904d9b45c +Author: Krzysztof Rybka +Date: Sun Mar 12 22:26:44 2017 +0100 + + update rails to 5.0.2 + +commit f2fb7a282703fb2db1fe665b50956fc1af5553a3 +Merge: 10b9249 3bd744a +Author: Damian Legawiec +Date: Sun Mar 12 21:27:52 2017 +0100 + + Merge pull request #102 from spark-solutions/feature/use-mini-racer-instead-of-the-ruby-racer + + use mini racer instead of therubyracer + +commit 10b9249820e4ddb6ceb0390193a9317b7972fa5c +Merge: ed4e163 211f2f2 +Author: Damian Legawiec +Date: Sun Mar 12 21:27:37 2017 +0100 + + Merge pull request #101 from spark-solutions/fix/remove-12factor + + remove rails_12factor + +commit b29a0aacdeba8cb7f66937b388c6cc0dee40333f +Author: Krzysztof Rybka +Date: Sun Mar 12 19:29:45 2017 +0100 + + update es6-promise 4.1.0 + +commit fdb353f37a59075b205b059f310df4521a89a41f +Author: Krzysztof Rybka +Date: Sun Mar 12 19:01:53 2017 +0100 + + update resolve-url-loader 2.0.2 + +commit 23a4b40252b55a959740003fedd6ae2466165409 +Author: Krzysztof Rybka +Date: Sun Mar 12 19:01:32 2017 +0100 + + update loader-utils to 1.0.3 + +commit 3bd744a06bf30b66d6c952c98dfb1e0807dc96d8 +Author: Krzysztof Rybka +Date: Sat Mar 4 16:16:48 2017 +0100 + + use mini racer instead of therubyracer + +commit 211f2f28ec8a42ae424c20ad4ad5ed8c0771a58a +Author: Krzysztof Rybka +Date: Sat Mar 4 15:49:31 2017 +0100 + + remove rails_12factor + Rails 5 does not need it + +commit ed4e163c8196ca38910aa323b299d04434fcff78 +Merge: 591936a f1fb7a2 +Author: Damian Legawiec +Date: Thu Feb 2 14:27:40 2017 +0000 + + Merge pull request #97 from spark-solutions/fix/remove-polyfill-for-console-js + + remove polyfill for js console because it is fixed in react-rails 1.10.0 + +commit 591936a1ef238b6d77218e74634b094c36140932 +Merge: 0f9834a 04d28bd +Author: Damian Legawiec +Date: Thu Feb 2 14:27:25 2017 +0000 + + Merge pull request #96 from ridem/assets-webpack-fix + + Fix `webpack:assets` potential failures + +commit f1fb7a27c985ea5c9530351b472da4a4851b28c5 +Author: Krzysztof Rybka +Date: Thu Feb 2 13:00:36 2017 +0100 + + remove polyfill for js console because it is fixed in react-rails 1.10.0 + +commit 0f9834ab9b26c2a10936481db63045cd14463c8b +Author: Damian Legawiec +Date: Thu Feb 2 10:58:22 2017 +0000 + + CircleCI doesn't need those anymore + +commit 04d28bd004b7b0d29cd814c82b40047a8edf686c +Author: Mehdi Rejraji +Date: Thu Feb 2 10:15:00 2017 +0100 + + Status code + + Also fix the status code to make it 0 + +commit 29624f0d8c3a0e53a6903018ab084a97840c882e +Author: Mehdi Rejraji +Date: Thu Feb 2 08:55:05 2017 +0100 + + Fix `webpack:assets` potential failures + + This prevents the infamous `cp`command from failing (stdout and stderr) in case some file extensions are not in the `webpack` folder. + +commit 8a9e850ed937ddbecba385ffcd643646372bdcca +Author: Damian Legawiec +Date: Wed Feb 1 16:13:42 2017 +0000 + + Update README.md + +commit ff253497f17ad730ac29d3793037a26e4c10059a +Merge: 334172b 0c93c0b +Author: Krzysztof Rybka +Date: Wed Feb 1 17:12:51 2017 +0100 + + Merge pull request #95 from spark-solutions/feature/rails-5-spree-3-2 + + Rails 5 and Spree 3.2 migration + +commit 0c93c0b890fb57b7492dbbb22e8f476f2a6ea9cc +Author: Damian Legawiec +Date: Wed Feb 1 15:37:05 2017 +0000 + + CodeClimate fix + + https://github.com/codeclimate/ruby-test-reporter/blob/master/CHANGELOG. + md#v100-2016-11-03 + +commit fb78298a7ce0702e584584cc37b3695865a8419a +Author: Damian Legawiec +Date: Wed Feb 1 15:36:30 2017 +0000 + + test_after_commit isn't needed for Rails 5 + +commit 6abb99bc100a7ab2691f35ba89328b83267f3dec +Author: Damian Legawiec +Date: Wed Feb 1 15:36:15 2017 +0000 + + Updated migrations for Spree 3.2 and Rails 5 + +commit c9208a82979513b2901ae57e73e3a92c55361022 +Author: Damian Legawiec +Date: Wed Feb 1 13:46:25 2017 +0000 + + Spree 3.2 introduced SpreePaths javascript object, we need to include it + +commit 3339ec89badf2a3e0941a133f8d79279aa8d4965 +Author: Damian Legawiec +Date: Wed Feb 1 13:46:07 2017 +0000 + + Variant#stock_items_count was removed in Spree 3.2 + +commit 3e046c0fd554aa7a20098e3d7470c9dbf916ad45 +Author: Damian Legawiec +Date: Wed Feb 1 13:45:55 2017 +0000 + + Rails 5 boilerplate + +commit cd9a379f1c81bfda84ef031c9873cfeab2ac23db +Author: Damian Legawiec +Date: Wed Feb 1 13:45:21 2017 +0000 + + Missing migrations from Spree 3.2 + +commit 204d06396a69da1a24cc35549beaa351eee76761 +Author: Damian Legawiec +Date: Wed Feb 1 13:44:54 2017 +0000 + + Updated Gemfile for Rails 5 & Spree 3.2 + +commit 334172b12dc25a5c740df710ee4cb202bfbf032c +Merge: 6257000 0118d31 +Author: Damian Legawiec +Date: Wed Jan 25 12:09:11 2017 +0100 + + Merge pull request #94 from spark-solutions/fix/safari-response-body + + fix safari response body + +commit 0118d31cdf20c1c50c4d1539fc3cc4b48cc0cd2b +Author: Krzysztof Rybka +Date: Wed Jan 25 11:59:06 2017 +0100 + + fix safari response body + +commit 62570005cca3cad53d134f066b4e97fffab2200e +Merge: e9e0925 3ab0a8b +Author: Damian Legawiec +Date: Thu Dec 22 17:33:37 2016 +0100 + + Merge pull request #92 from spark-solutions/feature/clear-cache-on-deploy + + Clear cache after deploy + +commit 3ab0a8bc30aad999ff011977eb8e28f843106e16 +Author: symarys +Date: Tue Dec 20 12:55:47 2016 +0100 + + [#136417503] Clear cache after deploy + +commit e9e09257a96692f914da103c30f9e6d0851a96df +Merge: fe4e44f b7e102a +Author: Damian Legawiec +Date: Mon Nov 21 17:33:13 2016 +0100 + + Merge pull request #70 from spark-solutions/Updates + + Updates + +commit b7e102a00881bdc2ee51740cb40c6d2ac42d48bc +Author: Matt +Date: Sat Oct 22 13:40:45 2016 +0200 + + Chrome addon devtools are superior, so if present it should be used + +commit 40e7777238424cf6b8574ac0ac2c831ebb85bcae +Author: Matt +Date: Sat Oct 22 13:39:59 2016 +0200 + + Expose store to window so it will allow some manipulations from the console + +commit b96047b3df9d1146edeec40a92c9931c0c06b1e2 +Author: Matt +Date: Sat Oct 22 13:39:16 2016 +0200 + + Litte upgrades + +commit fe4e44f99f379024ddca7fda788b06501ef42c81 +Author: Damian Legawiec +Date: Thu Nov 3 11:04:36 2016 +0100 + + rack-cache in development + +commit 87873f6c978f42517e742c79bdc0bfba1d27a8f4 +Author: Damian Legawiec +Date: Mon Nov 14 16:56:16 2016 +0100 + + exclude admin routes from js-routes + +commit c96d1e722ea02f841b006edd9d5b59ebe6bab2a1 +Author: Damian Legawiec +Date: Fri Nov 18 12:27:16 2016 +0100 + + Proper routes.default_url_options setting for production + +commit 35e7355b14b841c41bcd9c7a6e063fa8cd120a48 +Merge: 3b2038d ef40722 +Author: Damian Legawiec +Date: Wed Nov 16 14:31:53 2016 +0100 + + Merge pull request #86 from spark-solutions/feature/spree-3-1-2 + + Update Spree to 3.1.2 + +commit ef40722e98b9a83095d94c43d7ae110813fda2ff +Author: Damian Legawiec +Date: Tue Nov 15 15:12:52 2016 +0100 + + Update Spree to 3.1.2 + +commit 3b2038de435b6e60681fcad7fa15578fd5c4e9b9 +Author: Damian Legawiec +Date: Tue Nov 8 11:18:37 2016 +0100 + + Revert "Removing rack-cache" + + This reverts commit 8481c8587c3100eb1e0dd3c7c83b4003ac82c40f. + +commit 1165fac4a56b5a0ce81f251a849ccda0beac3652 +Merge: 1430e05 aa77cb5 +Author: Damian Legawiec +Date: Mon Nov 7 11:46:21 2016 +0100 + + Merge pull request #83 from devilcoders/fix_css_sourcemaps + + Fix source maps + +commit aa77cb51a5bc4da6b946a49a8b94f58a6d61a5f1 +Author: Alexey Topolyanskiy +Date: Sun Nov 6 12:58:50 2016 +0100 + + Fix sourcemaps + +commit 1430e0581cf614d0a5c0e4820a06bf64a25091a8 +Merge: 9dfe10c 688014a +Author: Damian Legawiec +Date: Fri Nov 4 08:52:59 2016 +0100 + + Merge pull request #81 from andrewwu/generate-jpg-webpack + + Ensure that at least 1 jpg is generated in app/assets/webpack + +commit 688014aec464c2beb561f8545e184b58980cba81 +Author: Andrew Wu +Date: Thu Nov 3 21:22:02 2016 -0700 + + Ensure that at least 1 jpg is generated in app/assets/webpack + +commit 9dfe10cad58cd2ac84d2454afdad30833457f381 +Merge: 11f748b 9ab020e +Author: Damian Legawiec +Date: Sun Oct 30 20:58:49 2016 +0100 + + Merge pull request #77 from spark-solutions/feature/update-node-and-npm + + Update node and npm + +commit 11f748b74527f0731fc359c953d0c96941dca629 +Merge: 30ad47e 8972fc8 +Author: Damian Legawiec +Date: Sun Oct 30 20:58:40 2016 +0100 + + Merge pull request #74 from spark-solutions/feature/img-alias + + add alias in webpack to image's folder + +commit 30ad47e51dbf0937d382725d14af07366d89ef3d +Merge: 2ac9cd4 937abbc +Author: Damian Legawiec +Date: Sun Oct 30 20:58:27 2016 +0100 + + Merge pull request #79 from spark-solutions/feature/update-sidekiq-4-2-3 + + update sidekiq to 4.2.3 + +commit 937abbcca422651f4a53bfb880666f927edfa3a9 +Author: Krzysztof Rybka +Date: Sun Oct 30 09:08:57 2016 +0100 + + update sidekiq to 4.2.3 + +commit 2ac9cd4a42a5a669b0f4e81c12fd54df55f37a61 +Merge: 0bfe291 a72879b +Author: Krzysztof Rybka +Date: Sun Oct 30 08:46:17 2016 +0100 + + Merge pull request #76 from spark-solutions/feature/update-deps + + Update i18n-js, autoprefixer, js-routes and excon + +commit a72879b5bde6c90221d825ae0b27c10bc5af9e4d +Author: Krzysztof Rybka +Date: Sat Oct 22 23:37:05 2016 +0200 + + update excon to 0.54.0 + +commit e5dbf60dbd903652c696d1cc3d8c921907f2ac8c +Author: Krzysztof Rybka +Date: Sat Oct 22 23:29:55 2016 +0200 + + update js-routes to 1.3.0 + +commit 11b758963981d80fd56caddd4db6f7dd612f9ba7 +Author: Krzysztof Rybka +Date: Sat Oct 22 23:29:27 2016 +0200 + + update autoprefixer-rails to 6.5.1.1 + +commit 2255eb448f1a87a6aade8b71d88d3e94430732d4 +Author: Krzysztof Rybka +Date: Sat Oct 22 23:25:25 2016 +0200 + + update i18n-js to 3.0.0.rc14 + +commit 0bfe291259be1645ff1c8a9241ffbb3bc9842452 +Merge: b428fd5 53d60e7 +Author: Krzysztof Rybka +Date: Sun Oct 30 08:19:52 2016 +0100 + + Merge pull request #75 from spark-solutions/feature/update-babel-packages + + update babel packages + +commit 9ab020e19dfd155f5fd7f4c2a4a9ced6af1dc76e +Author: Krzysztof Rybka +Date: Wed Oct 26 19:49:18 2016 +0200 + + use npm 3.10.8 + +commit bae312cbe811b096037207be5c21c300e45a8fe4 +Author: Krzysztof Rybka +Date: Wed Oct 26 19:49:00 2016 +0200 + + use node 6.9.1 + +commit 53d60e7f9c16a33d9c576eec2110565c6ac71b83 +Author: Krzysztof Rybka +Date: Wed Oct 26 19:39:04 2016 +0200 + + update babel packages + +commit 8972fc8f490eaa73fc935c27008c29c25001954b +Author: Krzysztof Rybka +Date: Wed Oct 26 19:29:38 2016 +0200 + + add alias in webpack to image's folder + +commit b428fd54377a2d2e7587624c43b835315c6099da +Merge: ddda258 565b40e +Author: Krzysztof Rybka +Date: Wed Oct 26 19:16:41 2016 +0200 + + Merge pull request #73 from spark-solutions/feature/update-test-deps + + Update dev/test dependencies + +commit ddda258df8aab450d97f84a6a4bec0ba8c0ce6b5 +Merge: a130093 156516d +Author: Damian Legawiec +Date: Mon Oct 24 21:54:35 2016 +0200 + + Merge pull request #72 from spark-solutions/fix/less-lodash + + Fix/less lodash + +commit a130093fff6e5e2b815c4e65acdb23e5d82f3e2f +Merge: edbfa8f e7030df +Author: Damian Legawiec +Date: Mon Oct 24 21:54:09 2016 +0200 + + Merge pull request #63 from spark-solutions/hotfix/webpack-svg-loader + + Fixes double SVG parsing to url with Webpack url loader + +commit edbfa8f4e57f2b547393f57e116cf6b21d7dccea +Merge: 628027d c69f2fc +Author: Damian Legawiec +Date: Mon Oct 24 21:53:58 2016 +0200 + + Merge pull request #66 from spark-solutions/hotfix/jpg-precompile + + JPG image assets support + +commit 628027ddb3282dd7cf1c808091b2c0182e2ada9a +Merge: 4ed8451 3ee741c +Author: Krzysztof Rybka +Date: Sun Oct 23 14:54:56 2016 +0200 + + Merge pull request #69 from spark-solutions/fix/rspec-webpack-building + + build webpack for rspec only for type: :feature + +commit 565b40e538f91462a0bbe4310ba580f3bef256d9 +Author: Krzysztof Rybka +Date: Sat Oct 22 23:46:33 2016 +0200 + + update rspec-core to 3.5.4 + +commit 1576f3ffd8be944c85f46e38123cca4004ef0509 +Author: Krzysztof Rybka +Date: Sat Oct 22 23:46:15 2016 +0200 + + update rspec-rails to 3.5.2 + +commit 16230632e3cb16372a1098c887a57b2a3b1a146d +Author: Krzysztof Rybka +Date: Sat Oct 22 23:44:18 2016 +0200 + + update rollbar to 2.13.3 + +commit de0152799e8ff9d493a2e72287949b428a3cd770 +Author: Krzysztof Rybka +Date: Sat Oct 22 23:42:39 2016 +0200 + + update capybara-screenshot to 1.0.14 + +commit 07f26f402b3aabea47c19cc874994743bcebfca2 +Author: Krzysztof Rybka +Date: Sat Oct 22 23:40:42 2016 +0200 + + update capybara to 2.10.1 + +commit 7560b1f77f4017ff9bf8d50b30542dadfb120995 +Author: Krzysztof Rybka +Date: Sat Oct 22 23:39:01 2016 +0200 + + update bullet + +commit 3ee741cf888842cb8a5517621e6060b95f91288c +Author: Krzysztof Rybka +Date: Tue Oct 18 10:05:32 2016 +0200 + + build webpack for rspec only for type: :feature + +commit 156516dfa5ce6456ff74ac24cda9fa1ae53a4bab +Author: Krzysztof Rybka +Date: Sat Oct 22 17:27:48 2016 +0200 + + use lodash modularized packages + +commit 41d0badf64ecb7ec825bf38c63e2921ab5eabf65 +Author: Krzysztof Rybka +Date: Sat Oct 22 17:25:17 2016 +0200 + + map over keys instead of lodash map + +commit f2d09663beae6e9671e37619180d1c35b789dc54 +Author: Krzysztof Rybka +Date: Sat Oct 22 17:14:06 2016 +0200 + + use Array.isArray instead of lodash isArray + +commit 4ed84513b7ba60a81a428317aab963127166072e +Merge: 6942a7e df61a62 +Author: Damian Legawiec +Date: Sat Oct 22 23:10:11 2016 +0200 + + Merge pull request #71 from spark-solutions/fix/setTimeout-doesnt-exists + + Update react-rails to 1.9.0 and polyfill setTimeout for prerendering + +commit df61a62cd4c8090c1d4277ed3e5089f99b14f2c1 +Author: Krzysztof Rybka +Date: Sat Oct 22 15:02:26 2016 +0200 + + polyfill setTimeout for prerendering + +commit 615b88fd32b6a94b88cbdeeed78e353cd38ad064 +Author: Krzysztof Rybka +Date: Sat Oct 22 15:00:22 2016 +0200 + + update react-rails to 1.9.0 + +commit c69f2fcb1e66a5c2c439bc5b32da26f37e0eae78 +Author: Damian Legawiec +Date: Wed Oct 12 16:18:57 2016 +0200 + + JPG image assets support + +commit e7030dfc2f993498d8695dbb9637d45ecef354aa +Author: Damian Legawiec +Date: Mon Oct 3 12:54:18 2016 +0200 + + Fixes double SVG parsing to url with Webpack url loader + +commit 6942a7ed7daa39eeea16238448c351b76b9aa520 +Merge: 15d153c 314ed0a +Author: Damian Legawiec +Date: Tue Sep 6 12:42:44 2016 +0200 + + Merge pull request #60 from spark-solutions/fix/rubocop-configuration + + Update rubocop configuration + +commit 314ed0a104f6dd195f8ef22b91aba77a5e7bbf1d +Author: symarys +Date: Tue Sep 6 12:22:12 2016 +0200 + + Update rubocop configuration + +commit 15d153cb22baf430ab8ed8892aae7e48e4f7b8b4 +Merge: f47e695 d54f724 +Author: Damian Legawiec +Date: Mon Aug 29 10:27:15 2016 +0200 + + Merge pull request #58 from chrisdobler/master + + fixes multiple loginform default error (redux) + +commit d54f724be0ef11bdcdbd2ebaa2a1c756e92c6ed3 +Author: Christopher Dobler +Date: Sun Aug 28 16:46:42 2016 -0700 + + fixes multiple loginform default error + +commit f47e6958672c82f0e1280e9c4d97287088fa28a6 +Author: Damian Legawiec +Date: Tue Aug 16 12:18:18 2016 +0200 + + Bump Spree to 3.1.1 + +commit 8ff65a5ac546cde4120f3527ec9afa285a91a89a +Author: Damian Legawiec +Date: Tue Aug 16 11:09:46 2016 +0200 + + Capybara#save_and_open_page_path is deprecated, changed to s#save_path + +commit 40c8d51dee718cdfe2ae186a7302380024545b82 +Author: Damian Legawiec +Date: Tue Aug 16 10:18:29 2016 +0200 + + sass-rails updated to 5.0.6 silencing sprockets deprecation warnings (https://github.com/rails/sass-rails/pull/382) + +commit 3d5319f9be4e9f3567ef97fcd0dd2edf60927ea2 +Author: Damian Legawiec +Date: Mon Aug 15 19:16:58 2016 +0200 + + Always disable spring for any database / migrations / seed rake tasks in setup script + +commit 79a297c469daeff01125f85b8d0b8c70edf2e844 +Merge: 48776e6 94396b9 +Author: Damian Legawiec +Date: Sat Aug 13 10:28:22 2016 +0200 + + Merge pull request #54 from spark-solutions/update-ams + + Update active_model_serializers to ~> 0.10.2 + +commit 48776e6e794dc84f72593ebf16d6b21c56a8cb81 +Merge: 57c1f21 b52a684 +Author: Damian Legawiec +Date: Fri Aug 12 22:30:59 2016 +0200 + + Merge pull request #52 from spark-solutions/update-bable + + Update babel and sass loaders + +commit 57c1f210965f2b5dbd2f17f88594318221f81117 +Merge: 02c5d02 7114cc6 +Author: Damian Legawiec +Date: Fri Aug 12 22:30:45 2016 +0200 + + Merge pull request #53 from spark-solutions/hotfix/camelized-props + + change is_fetching => isFetching and is_fetched => isFetched + +commit 94396b992d35f9225b1da7cf18f0432f3c819edb +Author: Krzysztof Rybka +Date: Fri Aug 12 17:38:47 2016 +0200 + + :backorderable? => :backorderable in VariantSerializer + +commit 2f98bac38af4d06da27ba68a18d5520d7b2cf24f +Author: Krzysztof Rybka +Date: Fri Aug 12 17:38:04 2016 +0200 + + upgrade active_model_serializers to ~> 0.10.2 + +commit 7114cc6dad3ef006a583d7fc000ae755b62675e3 +Author: Krzysztof Rybka +Date: Fri Aug 12 17:21:14 2016 +0200 + + change is_fetching => isFetching and is_fetched => isFetched + +commit b52a68461935ecb5ddc9d0bd89e7b27035140902 +Author: Krzysztof Rybka +Date: Fri Aug 12 17:15:37 2016 +0200 + + update sass loader packages + +commit 0aeb73ea1c3820e6177019c16eae39f8ff7475f9 +Author: Krzysztof Rybka +Date: Fri Aug 12 17:07:57 2016 +0200 + + update babel packages + +commit 02c5d023da6413d3b0b6d1b338f3ac12a9b1d590 +Merge: 824cdc2 47480b2 +Author: Damian Legawiec +Date: Fri Aug 12 16:50:36 2016 +0200 + + Merge pull request #50 from spark-solutions/update-gems + + Update autoprefixer-rails, js-routes, puma, sprockets and twitter_cldr + +commit 47480b288fadb0570a538e10b15864b0a80ec7fa +Author: Krzysztof Rybka +Date: Fri Aug 12 16:38:47 2016 +0200 + + update twitter_cldr (3.5.0) + +commit 0235fe2f3b01a23e7f73a49396547501ba9bb729 +Author: Krzysztof Rybka +Date: Fri Aug 12 16:37:47 2016 +0200 + + update sprockets (3.7.0) + +commit c58a61f9b2d9da5311a46aa0a68d9527abb6673a +Author: Krzysztof Rybka +Date: Fri Aug 12 16:36:55 2016 +0200 + + update puma (3.6.0) + +commit 7e7ce51af793241573e3c1a00f288ba4c3090fdb +Author: Krzysztof Rybka +Date: Fri Aug 12 16:34:59 2016 +0200 + + update js-routes (1.2.9) + +commit 5ee2736ac322d03bb2560fb60982710d295e01d4 +Author: Krzysztof Rybka +Date: Fri Aug 12 16:34:04 2016 +0200 + + update autoprefixer-rails (6.4.0.1) + +commit 824cdc2e31c33d66e53decff630ec5e6f946201a +Merge: c9ef2a0 bb01867 +Author: Damian Legawiec +Date: Fri Aug 12 16:19:53 2016 +0200 + + Merge pull request #48 from spark-solutions/feature/redux-cart-actions + + Additional Cart management redux actions + +commit c9ef2a05eac7d553c758b8d1ee88f3b9f6427193 +Merge: 0c9ccc5 152e0a5 +Author: Damian Legawiec +Date: Fri Aug 12 16:19:06 2016 +0200 + + Merge pull request #49 from spark-solutions/update-rails + + update rails to 4.2.7.1 due to security patch + +commit 152e0a5cc4585eccb5903609579433e5a259f233 +Author: Krzysztof Rybka +Date: Fri Aug 12 15:12:18 2016 +0200 + + update rails to 4.2.7.1 due to security patch + +commit bb018671e9b6a1c1a11b9a1a7fd6df36e3027292 +Author: Damian Legawiec +Date: Fri Aug 12 13:06:53 2016 +0200 + + Additional Cart management redux actions + +commit 0c9ccc5835bebe10527ef37c5e6da7535a03e9e7 +Merge: 099478f 4d9553f +Author: Damian Legawiec +Date: Fri Aug 12 11:43:49 2016 +0200 + + Merge pull request #47 from spark-solutions/hotfix/alerts-styles + + Fix for alert format returned by spree_auth_devise + +commit 4d9553f5190899c3919dacf6069ccacc773a3aa6 +Author: Damian Legawiec +Date: Thu Aug 11 14:44:49 2016 +0200 + + Fix for alert format returned by spree_auth_devise + +commit 099478ff6247f16317f727193580480df980974f +Author: Damian Legawiec +Date: Thu Aug 11 14:34:57 2016 +0200 + + Fixes webpack assets precompile script + + We always need at least 1 image so the cp command won’t fail + +commit 7bc7210ff57e428d2c3b55e58031f6e7b406b8bf +Merge: c7e0d00 34f180f +Author: Damian Legawiec +Date: Thu Aug 11 13:52:10 2016 +0200 + + Merge pull request #46 from spark-solutions/feature/modern-layout + + More modern looking bootstrap layout + +commit 34f180fff90379507b1817b93d6b314ad65ab1c6 +Author: Damian Legawiec +Date: Thu Aug 11 13:46:25 2016 +0200 + + More modern looking bootstrap layout + +commit c7e0d0089fd52d76863b234c891c5ec5c2db7c8d +Merge: 0d0120d ce8d50f +Author: Damian Legawiec +Date: Thu Aug 11 13:12:32 2016 +0200 + + Merge pull request #45 from spark-solutions/feature/heroku-release-migrate + + Utilising Heroku Release Phase to run migrations + +commit 0d0120db9fce24cdbcbe7dec8052d839dc2d2de7 +Author: Damian Legawiec +Date: Thu Aug 11 12:59:44 2016 +0200 + + Fixes Gemfile.lock ruby version + +commit ce8d50f1300e020f924d95739a69e5c7c897d2da +Author: Damian Legawiec +Date: Thu Aug 11 12:55:09 2016 +0200 + + Utilising Heroku Release Phase to run migrations + + Thanks to Release Phase + (https://devcenter.heroku.com/articles/release-phase) we don’t need + additional build pack to run migrations on deploys. + +commit 55d3898a9086220fd1ed1ac7ac8498d2e3391456 +Merge: 1c0dc2d 07c12ec +Author: Krzysztof Rybka +Date: Thu Aug 11 12:54:49 2016 +0200 + + Merge pull request #44 from spark-solutions/feature/normalize-api-endpoints + + Normalize API endpoints + +commit 1c0dc2d68cc2f14c029c4db719c8e4bcc584ece8 +Merge: 0ecb48c 0731920 +Author: Damian Legawiec +Date: Thu Aug 11 12:44:12 2016 +0200 + + Merge pull request #37 from spark-solutions/decision_about_sample_data + + ask if load spree data samples + +commit 07c12ec257764dd533b769c224061e407c7422ad +Author: Damian Legawiec +Date: Thu Aug 11 12:35:32 2016 +0200 + + Normalised API endpoints + + * for orders always using RABL template to be consistent with Spree API + * dropping CamelCase to be consistent with Spree API + +commit 87219cca5473b8ef3d9382f0ce77618cf0f90d6f +Author: Damian Legawiec +Date: Tue Aug 9 18:25:41 2016 +0200 + + rubocop fix: TrailingComma -> TrailingCommaInLiteral + +commit 0ecb48cedad4031fe6a237f78c165afb692860fa +Merge: 45076b0 8481c85 +Author: Damian Legawiec +Date: Tue Aug 9 18:19:05 2016 +0200 + + Merge pull request #43 from spark-solutions/hotfix/remove-rack-cache + + Removing rack-cache + +commit 8481c8587c3100eb1e0dd3c7c83b4003ac82c40f +Author: Damian Legawiec +Date: Tue Aug 9 16:54:35 2016 +0200 + + Removing rack-cache + + rack-cache for larger deployments can cause troubles. It’s better to + use a dedicated cache layer like fastly + +commit 45076b03eeaee953513675426f2a1bcb9515f357 +Merge: 8b6ba70 738efa4 +Author: Damian Legawiec +Date: Tue Aug 9 16:47:13 2016 +0200 + + Merge pull request #42 from spark-solutions/upgrade/ruby-2-3-1 + + Use Ruby 2.3 + +commit 738efa42169c12598b847f93fc803ddd1bf53f9c +Author: Damian Legawiec +Date: Tue Aug 9 16:34:40 2016 +0200 + + Use Ruby 2.3 + +commit 8b6ba7040d6249ed849aa911fd43416b79a584c9 +Merge: 99795c4 dc2d4b2 +Author: Damian Legawiec +Date: Tue Aug 9 16:25:56 2016 +0200 + + Merge pull request #40 from spark-solutions/hotfix/rubocop-a + + rubocop -a + +commit 99795c45ebe08565be5aec0b8afe7cc8c0e7e6f2 +Merge: d68246c 868a8c0 +Author: Damian Legawiec +Date: Tue Aug 9 16:13:48 2016 +0200 + + Merge pull request #41 from spark-solutions/hotfix/editorconfig + + Hound fixes + +commit 868a8c0c2f71aba5db03290b212123861e5b5076 +Author: Damian Legawiec +Date: Tue Aug 9 16:10:47 2016 +0200 + + Setting max len at 120 for javascript files + +commit c62c185f7b86d221137e45b658a931b3bf5d40a2 +Author: Damian Legawiec +Date: Tue Aug 9 16:07:56 2016 +0200 + + Adding .rubocop.yml + +commit 712281ecb8047e0db52390b3c8c56e876be1b0a9 +Author: Damian Legawiec +Date: Tue Aug 9 16:03:31 2016 +0200 + + Adding .editorconfig file + +commit dc2d4b270c4c2cfded393ec95b26de31718ce4c5 +Author: Damian Legawiec +Date: Tue Aug 9 15:55:22 2016 +0200 + + rubocop -a + +commit d68246caeeef61878e2d813cc8884ba4e2e0c1d8 +Merge: d740b24 f1b1936 +Author: Damian Legawiec +Date: Tue Aug 9 15:36:11 2016 +0200 + + Merge pull request #39 from spark-solutions/feature/hound-ci + + HoundCI support + +commit f1b193641ca3ab80d3f52b931b50f74ab13dc09f +Author: Damian Legawiec +Date: Tue Aug 9 15:32:10 2016 +0200 + + Removing unused jscs config file + +commit f41ba97a5491290d7a659b327e39cbfae5a62e0d +Author: Damian Legawiec +Date: Tue Aug 9 15:30:47 2016 +0200 + + Adding Hound CI config file + +commit d740b24a8af5ac45db67eb9693260f029d317964 +Merge: 76ae078 6e6db6e +Author: Damian Legawiec +Date: Tue Aug 9 15:15:26 2016 +0200 + + Merge pull request #38 from spark-solutions/feature/redux-action-creator + + Reducing redux boilerplate thanks to generateActionCreator + +commit 6e6db6e8a16b75314c477f03b4c75e4f59d284d9 +Author: Damian Legawiec +Date: Tue Aug 9 15:08:10 2016 +0200 + + Reducing redux boilerplate thanks to generateActionCreator + + Fixes https://github.com/spark-solutions/spark-starter-kit/issues/35 + +commit 76ae078f6dfbbb40b3db764a55568cea49b0099f +Merge: af0cf8c 21e01fe +Author: Damian Legawiec +Date: Tue Aug 9 13:56:15 2016 +0200 + + Merge pull request #33 from spark-solutions/hotfix/env-fixes + + Better handling of ENV variables in production.rb + +commit 07319208cf995d10d5ecea709e73441f9b53c648 +Author: Janek +Date: Fri Aug 5 18:41:53 2016 +0200 + + ask if load spree data samples + +commit af0cf8cced1556981b5cdce2a8a5b8ad39d64d8e +Merge: 7e364b2 d92b096 +Author: Damian Legawiec +Date: Fri Aug 5 11:41:49 2016 +0200 + + Merge pull request #36 from spark-solutions/feature/setup-script + + Added setup script + +commit d92b096fc653e766ecebf6506730f21e650bd4c2 +Author: Damian Legawiec +Date: Fri Aug 5 11:32:51 2016 +0200 + + Added setup script + +commit 21e01fee215ca324ba81df5dcb808d200bbd32fc +Author: Damian Legawiec +Date: Wed Jul 27 08:48:10 2016 +0200 + + Better handling of ENV variables in production.rb + + Fixes https://github.com/spark-solutions/spark-starter-kit/issues/32 + +commit 7e364b2452385cc31e34687801ef7bdbf896855c +Merge: 62988be 4acfdac +Author: Damian Legawiec +Date: Mon Jul 11 00:25:35 2016 +0200 + + Merge pull request #30 from spark-solutions/hotfix/remove-jade-and-express + + removing jade and express + +commit 62988be6e5c2e490232b43b9c671b6b9523fe852 +Author: Damian Legawiec +Date: Mon Jul 11 00:12:49 2016 +0200 + + ignore Routes/I18n JS global variables in ESLint + +commit 4acfdac5bb00600358af1ee0dab15a82be461a86 +Author: Damian Legawiec +Date: Mon Jul 11 00:07:08 2016 +0200 + + removing jade + +commit 4eb2a1c3599e2ae83775b6532f4455135b40ba99 +Author: Damian Legawiec +Date: Mon Jul 11 00:07:01 2016 +0200 + + removing express server + + We didn’t used it anyhow so it’s only a waste of resources. + +commit 564037b8bc3a092ac2deaa599815c98bcb48a1b4 +Merge: 831f600 d2763d9 +Author: Damian Legawiec +Date: Sun Jul 10 13:09:52 2016 +0200 + + Merge pull request #29 from spark-solutions/update-gems + + Update gems & babel packages + +commit d2763d9bf2d8d1b0b002e7c1c5ce50decd9b9d43 +Author: Krzysztof Rybka +Date: Sat Jul 9 16:53:57 2016 +0200 + + update babel packages and postcss-loader + +commit 716a92d020254e15594548a8bfa8efcff9896acf +Author: Krzysztof Rybka +Date: Sat Jul 9 16:28:09 2016 +0200 + + update gems + +commit 831f600bb63fc50ea7cdfcb3d8002e7d2bf094da +Author: Damian Legawiec +Date: Mon Jun 20 10:27:32 2016 -0400 + + Update README.md + +commit a09d98d45f2a1e77680107b515ae70c54d2b46f2 +Merge: 60f15c7 326bb45 +Author: Damian Legawiec +Date: Mon Jun 20 16:27:14 2016 +0200 + + Merge pull request #26 from spark-solutions/update_to_newest + + update spree to 3.1 + +commit 326bb455bb74a64b88c895fce3dc5d0e29eca859 +Author: Krzysztof Rybka +Date: Mon Jun 20 13:30:29 2016 +0200 + + update babel-core to fix path bug + +commit d4427c9440aac07292bd6c8a26c2c88931913b3e +Author: Krzysztof Rybka +Date: Mon Jun 20 13:28:22 2016 +0200 + + update spree to 3.1 + +commit 60f15c7d8026f2985cec1e5de9ea2db35ad9cf48 +Merge: 9e939c0 11c9cd6 +Author: Damian Legawiec +Date: Mon Apr 11 10:08:05 2016 +0200 + + Merge pull request #25 from spark-solutions/include_png_in_assets_compilation + + Include .png file types in webpack precompilation task + +commit 11c9cd626c31898b6aecdb8aef6eab703566c04b +Author: Juliusz Nadberezny +Date: Mon Apr 11 09:52:30 2016 +0200 + + Include .png file types in webpack precompilation task + +commit 9e939c0f67ac78d6e3677e4d352e112d8961c2af +Merge: de4b62a dc0ddca +Author: Damian Legawiec +Date: Wed Mar 16 16:41:15 2016 +0100 + + Merge pull request #16 from spark-solutions/update_react_router_redux + + update react-router-redux to 4.0.0 + +commit de4b62ac7441f8b9d184a34652e2aaa5df1428d0 +Author: Damian Legawiec +Date: Wed Mar 16 16:38:30 2016 +0100 + + Spree 3.0.8 & Rails 4.2.6 & sprockets-rails 3.x + +commit 30686d60408ab112cc11d301da5bdc491b385562 +Merge: aaac50f d392ff4 +Author: Damian Legawiec +Date: Tue Mar 15 15:43:32 2016 +0100 + + Merge pull request #17 from spark-solutions/better_error_handling + + return Promise with error when response status is not OK + +commit aaac50f4e09f61f8173e46ac1e982a169891ce22 +Merge: 400fb6c 0137325 +Author: Damian Legawiec +Date: Tue Mar 15 15:43:18 2016 +0100 + + Merge pull request #18 from spark-solutions/alerts + + add alerts components and functionality + +commit 400fb6c55fe84d05ab1b821999eae509ac1c8cd0 +Merge: 204d23f e180088 +Author: Damian Legawiec +Date: Tue Mar 15 15:42:37 2016 +0100 + + Merge pull request #13 from spark-solutions/api_helper + + ApiHelper improvements + +commit 013732557e364b2074759de758a16a5a1d330045 +Author: Krzysztof Rybka +Date: Fri Mar 11 13:02:43 2016 +0100 + + add alerts components and functionality + +commit 82f338f5405139646096caf049e50dd83bc6a182 +Author: Krzysztof Rybka +Date: Fri Mar 11 12:40:37 2016 +0100 + + populate responds with json on error + +commit dc0ddcacf25c50959045ccd6a8442ba4427bd91b +Author: Krzysztof Rybka +Date: Sun Mar 6 18:14:12 2016 +0100 + + update react-router-redux to 4.0.0 + +commit d392ff4a3840622f658bb52ef2dfbf4610a98cb0 +Author: Krzysztof Rybka +Date: Tue Mar 8 08:23:15 2016 +0100 + + return Promise with error when response status is not OK + +commit 204d23fba864635626371aa11a4444a5a6216abd +Merge: ad809eb 1c2e1ae +Author: Damian Legawiec +Date: Sun Mar 6 13:19:59 2016 +0100 + + Merge pull request #12 from spark-solutions/rspec_devise_mapping + + set devise mapping for controller specs in rspec config + +commit ad809eb582efd082efba4febc8cfb00885e3adb4 +Merge: 62fc2e7 da840e3 +Author: Damian Legawiec +Date: Sat Mar 5 23:25:12 2016 +0100 + + Merge pull request #14 from spark-solutions/path_helpers + + add path helpers + +commit 62fc2e78ea2f434e2d8ad085f44f5d1b1a2b1fc4 +Merge: 42cb20e 144ff60 +Author: Damian Legawiec +Date: Sat Mar 5 23:24:30 2016 +0100 + + Merge pull request #15 from spark-solutions/reducers + + reducers fixes (properly clear state, do not mutate action) + +commit da840e3538ca1015438cfb033150f2de9cbb9dd2 +Author: Krzysztof Rybka +Date: Sat Mar 5 15:39:47 2016 +0100 + + add path helpers + +commit 144ff60fd123a4a7c9d842be56142f684193279c +Author: Krzysztof Rybka +Date: Sat Mar 5 15:27:48 2016 +0100 + + reducers fixes (properly clear state, do not mutate action) + +commit 1c2e1ae06e13baead4aebc10af37a18462dd2833 +Author: Krzysztof Rybka +Date: Sat Mar 5 14:33:41 2016 +0100 + + set devise mapping for controller specs in rspec config + +commit e180088ec06f5a8c627d091c8cf80ce6ff6485b0 +Author: Krzysztof Rybka +Date: Sat Mar 5 14:24:50 2016 +0100 + + set spree_current_user as serialization scope for AMS + +commit 5526dfe94db21bdb362515546a4bf3b38aa8b9a9 +Author: Krzysztof Rybka +Date: Sat Mar 5 14:23:30 2016 +0100 + + allow ApiHelper's methods to receive options + +commit 42cb20e727a7a8b50030c5f459cc5a25779b625e +Author: Damian Legawiec +Date: Wed Feb 24 08:46:12 2016 +0100 + + Spree updated to 3.0.7 + +commit 12af153e2818fb92e1d06899eeba296b7aede8f7 +Merge: 16b22ca 051d1b8 +Author: Damian Legawiec +Date: Sun Feb 21 17:51:35 2016 +0100 + + Merge pull request #11 from spark-solutions/dependencies_update + + Dependencies update + +commit 051d1b8cc37690e53537028ec228a965c3901307 +Author: Krzysztof Rybka +Date: Sun Feb 21 14:51:35 2016 +0100 + + update npm packages + +commit 7805465437cd74378e9fcfa966c56088e95bb962 +Author: Krzysztof Rybka +Date: Sun Feb 21 14:51:19 2016 +0100 + + update gems + +commit 16b22ca4863b133c95de98a479ecca83e059bd92 +Author: Damian Legawiec +Date: Thu Feb 18 14:18:31 2016 +0100 + + Spree updated to 3.0.6.1 + +commit 64a910d536e1a4fea2b793aef94a5166f0429cda +Author: Damian Legawiec +Date: Mon Feb 15 22:41:32 2016 +0100 + + fixes #5 fonts from Cloudfront CORS bug + +commit 0775f72908b80eddf55bc2abe9d56a7cae0590e3 +Author: Damian Legawiec +Date: Mon Feb 15 22:36:28 2016 +0100 + + react-router 2.0 & simple-react-router->react-router-redux + +commit 3097c2e36fea4d10b63ae1af9b3a705dc83829ab +Author: Damian Legawiec +Date: Mon Feb 15 21:23:11 2016 +0100 + + always use stable versions of spree auth devide/gateway from rubygems + +commit 578d9ba265618c5074559dfe688d80d951674d9c +Author: Juliusz Nadberezny +Date: Tue Feb 9 11:18:18 2016 +0100 + + Fix babel + 1. Add babel-register 6.3.13 + 2. Downgrade babel-eslint from 5beta to 4.1.7 + +commit 792ca8810056af95e2a8931255934f818b598f4b +Merge: 161f8bb 0aa280b +Author: Damian Legawiec +Date: Fri Jan 29 16:04:23 2016 +0100 + + Merge branch 'master' of github.com:spark-solutions/spark-starter-kit + +commit 161f8bbc22b065a4ef59901f0bb7d5fa3b96274a +Author: Damian Legawiec +Date: Fri Jan 29 16:04:14 2016 +0100 + + stable spree 3.0.5 release + +commit 0aa280b8a958171a9afac78638c9543a525951d6 +Author: Damian Legawiec +Date: Tue Jan 19 11:04:33 2016 +0100 + + Update README.md + +commit 2da62bc664caa6dffa83c1e1f1bd701a5f2be908 +Author: Damian Legawiec +Date: Mon Jan 18 16:35:29 2016 +0100 + + Update README.md + +commit 98842516b329a9d9b29ff6cc80b35f94fb95d80a +Author: Damian Legawiec +Date: Mon Jan 18 13:08:09 2016 +0100 + + Update README.md + +commit f45c7faa12b425598d24158bdab66cc1490179d2 +Author: Damian Legawiec +Date: Mon Jan 18 12:57:12 2016 +0100 + + gems updated + +commit ca5b040771b30978c77928690e8e5824d083e78c +Merge: c2b8dee 7e2164e +Author: Damian Legawiec +Date: Sun Jan 17 17:55:43 2016 +0100 + + Merge branch 'master' of github.com:spark-solutions/spark-starter-kit + +commit c2b8dee1c039639d2b34d92dea440dec6833cf27 +Author: Damian Legawiec +Date: Sun Jan 17 17:54:29 2016 +0100 + + proper spree::image path/url settings + +commit 7e2164e7f6e53087767ea77929e14cbfc36f46a9 +Author: Damian Legawiec +Date: Sun Jan 17 17:50:42 2016 +0100 + + Update README.md + +commit 58616280e8d98fd4a9ffe10232c9e0e5db4390fa +Merge: d0458f2 ea841c6 +Author: Damian Legawiec +Date: Sun Jan 17 16:26:17 2016 +0100 + + Merge branch 'master' of github.com:spark-solutions/spark-starter-kit + +commit d0458f2bdb9862da37f4aecc037f81d948ff50d3 +Author: Damian Legawiec +Date: Sun Jan 17 16:26:11 2016 +0100 + + typo fix + +commit ea841c63cb1e3a587e32b229c6dc4eef75a0202a +Author: Damian Legawiec +Date: Sun Jan 17 16:25:50 2016 +0100 + + Update README.md + +commit 0a5f8cb29c0aed9f1c47d44504cb8a8b1fdf94de +Author: Damian Legawiec +Date: Sun Jan 17 16:25:02 2016 +0100 + + Update README.md + +commit fae538c9fc8ba086dbc2d2ffd94b89843f279164 +Author: Damian Legawiec +Date: Sun Jan 17 16:23:27 2016 +0100 + + updated README.md + LICENCE.md + +commit 103676dca7a2e6820ae2283fe43345335f50f519 +Merge: e694d8c f00a623 +Author: Damian Legawiec +Date: Sun Jan 17 15:35:05 2016 +0100 + + Merge branch 'master' of github.com:spark-solutions/spark-starter-kit + +commit e694d8c22edbf46c489a5663c376ea08ec450140 +Author: Damian Legawiec +Date: Sun Jan 17 15:34:53 2016 +0100 + + additional CDN for uploaded files - it's much faster to use cloudfront rather than s3 directly + +commit 4b885963e50a125684a8828bd8f0a7a157656bc8 +Author: Damian Legawiec +Date: Fri Jan 15 23:59:23 2016 +0100 + + spree product.js file is not needed anymore + +commit 98fd89818a79123eec4f8b030af9961faab6e07e +Author: Damian Legawiec +Date: Fri Jan 15 23:59:11 2016 +0100 + + linter fixes for environments files + +commit f00a623e34e556052d5cbb1f3dbdcbcdcf2d7e18 +Author: Damian Legawiec +Date: Thu Jan 14 17:32:31 2016 +0100 + + Update and rename README.rdoc to README.md + +commit cb45bac1c56d402aec0420308f95718c823d080f +Merge: 5f49111 3a68882 +Author: Damian Legawiec +Date: Sun Jan 10 19:48:20 2016 +0100 + + Merge pull request #8 from spark-solutions/react-router + + React router + redux powered SPA + option to have classic rails views, all with server side rendering + +commit 3a68882dc3e982fa2237226d7dfd8feb7408ae3e +Author: Damian Legawiec +Date: Sun Jan 10 19:39:23 2016 +0100 + + Product Page with images, properties and cart form + +commit 047f341aa180979e3d4a407a1f8cd263f18cefd0 +Author: Damian Legawiec +Date: Sun Jan 10 11:20:50 2016 +0100 + + much better header (cart, account) handling + +commit 85feca632d8b0d12bfb7ce113370fc3510836e75 +Author: Damian Legawiec +Date: Sun Jan 10 00:21:47 2016 +0100 + + a little bit of refactoring - api & react helpers methods + +commit 75ec10aadd0ad99fe472c369fc9853cef362605a +Author: Damian Legawiec +Date: Sat Jan 9 23:40:21 2016 +0100 + + currency based products list (cont.) + +commit f06aaebf83aa20a2ecdce0c107e95b3c70f97dbd +Author: Damian Legawiec +Date: Sat Jan 9 23:39:35 2016 +0100 + + currency based products list + +commit e7d26ced336398bc6d5baaf4a16535623fba9311 +Author: Damian Legawiec +Date: Sat Jan 9 23:37:16 2016 +0100 + + json helper methods extracted to api helper + +commit 364a21ea816783d0d20344690cae436371b2aa8d +Author: Damian Legawiec +Date: Sat Jan 9 13:34:07 2016 +0100 + + universal link refactoring + +commit a542edea769f2514707410a937c67a0123638211 +Author: Damian Legawiec +Date: Sat Jan 9 13:02:30 2016 +0100 + + pages/ web pack alias for page components + +commit c01359a65e9c3d63a64dc7bb84a671aaf5d5b2ff +Author: Damian Legawiec +Date: Thu Jan 7 15:55:49 2016 +0100 + + locking babel at 6.3, 6.4 a little buggy right now + +commit 5f49111e3a46f939edd68aca396e476cda1c6de3 +Merge: c5aef68 0c7ce58 +Author: Damian Legawiec +Date: Mon Jan 4 22:09:04 2016 +0100 + + Merge pull request #7 from spark-solutions/specs_setup_fix + + Move out specs from component directory + +commit 41a57dd8114755fc1ca7371f7e3a3fff86628741 +Author: Damian Legawiec +Date: Mon Jan 4 08:43:57 2016 +0100 + + loading indicator on products list + +commit e8faa16b23181e9c6822207727f12c7b2aecc51d +Author: Damian Legawiec +Date: Sun Jan 3 20:01:28 2016 +0100 + + production store fix + +commit dcedd461c8388300358df9186acfe68bfe96050a +Author: Damian Legawiec +Date: Sun Jan 3 19:45:44 2016 +0100 + + products list fixes + +commit f577190c8a00b9c57617afeabaafd3888a75b97c +Author: Damian Legawiec +Date: Sun Jan 3 18:26:58 2016 +0100 + + a little bit of refactoring for products list + +commit 0c3dd030e40ce94097b68fafcf4b498ead14a22a +Author: Damian Legawiec +Date: Sun Jan 3 12:54:55 2016 +0100 + + integration tests fix + +commit b90af92e50191e53397661c3ae251155c0abefd0 +Author: Damian Legawiec +Date: Sun Jan 3 12:50:30 2016 +0100 + + universal bootstrap pagination + +commit 006e1566b57779f7a329f05018920dfe4cec2394 +Author: Damian Legawiec +Date: Sat Jan 2 18:48:20 2016 +0100 + + super simple products list pagination + +commit b3b4a1a067811727f5b3d85d0e9f93512b33960a +Author: Damian Legawiec +Date: Sat Jan 2 17:24:26 2016 +0100 + + fixed: clearing products list on exit + +commit 51d209204b721b29390bb8af63af5d1e1871fbea +Author: Damian Legawiec +Date: Sat Jan 2 16:40:43 2016 +0100 + + Footer component for SPA & classic views + +commit ed5512c13117ea35b4247c394cf047335467a043 +Author: Damian Legawiec +Date: Sat Jan 2 16:36:07 2016 +0100 + + react-router + redux powered SPA prototype + +commit c5aef68f09184dd37fe9b93bd0b64046b0642678 +Author: Damian Legawiec +Date: Fri Jan 1 16:25:09 2016 +0100 + + LoginFrom moved to components/ + +commit b3d5864ebac8887eb401158bc3a5b703897ee963 +Author: Damian Legawiec +Date: Fri Jan 1 16:24:36 2016 +0100 + + unnecessary file removed + +commit 0c7ce5880f4867ceb1a576c4e2429a4b17d8d419 +Author: Krzysztof Rybka +Date: Fri Jan 1 15:51:43 2016 +0100 + + fix eslint + +commit 55b08187315010b716e4a2f675818ee4c40ef1cc +Author: Krzysztof Rybka +Date: Fri Jan 1 15:38:16 2016 +0100 + + Move out specs from component directory + +commit f7eed43e657d28b8387a8922474137af383bdff3 +Author: Damian Legawiec +Date: Fri Jan 1 11:42:21 2016 +0100 + + LoginForm error fix + +commit efc73ae5fd99450ad28bd8e384cf9346af9d5f29 +Author: Damian Legawiec +Date: Fri Jan 1 10:44:05 2016 +0100 + + react 0.14.5 and react-router 2.x + +commit 73959282288424b4ab00d5f050c30a932c777571 +Author: Damian Legawiec +Date: Thu Dec 31 18:59:41 2015 +0100 + + simple server rendered react products list + +commit d492856a88e8423a636bc86fc273854263a9bfc9 +Author: Damian Legawiec +Date: Mon Dec 28 18:03:15 2015 +0100 + + eslint comma config fix + +commit eeafa775c6a5173b01a57b723c7bf8dfff38d15a +Author: Damian Legawiec +Date: Mon Dec 28 16:32:39 2015 +0100 + + integration tests fix - ensure the web pack assets are precompiled + +commit bda96f2262f55164055cd5a9ade06b8e6f46f45e +Author: Damian Legawiec +Date: Mon Dec 28 11:33:25 2015 +0100 + + adding rake buildpack for triggering rake task like db:migrate at deploy + +commit ea3ddc4fb1a4a976f1f2a8e20943715abcb856e5 +Author: Damian Legawiec +Date: Sun Dec 27 23:17:13 2015 +0100 + + spree feature specs support + +commit 825e508d24f0e83082fa7bf14b0961474706a97c +Author: Damian Legawiec +Date: Sun Dec 27 22:34:59 2015 +0100 + + use connection pool for database connections on production + +commit d3b603fc4cee9b67092034f75504f5a29d5f0061 +Author: Damian Legawiec +Date: Sun Dec 27 22:33:08 2015 +0100 + + use camel case convention for react components props + +commit 3bef92d9311066e42d39742113c4e83ecf43f86c +Merge: 01194ca 7bb0a09 +Author: Damian Legawiec +Date: Sun Dec 27 18:46:55 2015 +0100 + + Merge pull request #3 from spark-solutions/webpack + + Moving to Webpack for asset handling + +commit 7bb0a09c8068cd52f06b9b7381bd7e0919a97c69 +Author: Damian Legawiec +Date: Sun Dec 27 13:40:47 2015 +0100 + + redux dev tools + +commit 8fa44575902201406b79f8ef565e6bbc19dac1e5 +Author: Damian Legawiec +Date: Sun Dec 27 13:20:43 2015 +0100 + + sass images path fix + +commit 2142d0a15fad6450d30d06607d1e7ffb7bc320fb +Author: Damian Legawiec +Date: Sun Dec 27 12:48:03 2015 +0100 + + linter fixes + +commit 7c6dea1c19f29618ea28b9d47c5645dfe8a8bbd2 +Author: Damian Legawiec +Date: Sun Dec 27 11:41:48 2015 +0100 + + redux-logger added to packages.json + +commit 630774673b0518a5c7ac7de5dae3a0ec614df8c1 +Author: Damian Legawiec +Date: Sun Dec 27 10:20:47 2015 +0100 + + node/circle gcc version fix + +commit 85d29b7c64f60aa93c111cf0c8cc1aae5e565eff +Author: Damian Legawiec +Date: Sun Dec 27 10:11:52 2015 +0100 + + proper circle.yml config for npm + +commit 31bdb8578988f6531c148982b66f00ffbae8d0f6 +Author: Damian Legawiec +Date: Sun Dec 27 10:05:52 2015 +0100 + + circle node settings? + +commit 3a87f4fa610d413023c495cb7ac85cd04b8d804f +Author: Damian Legawiec +Date: Sun Dec 27 09:11:18 2015 +0100 + + proper node version for circle ci? + +commit 0d88cd5340092208df3eb576866ede0e99951720 +Author: Damian Legawiec +Date: Sun Dec 27 01:44:13 2015 +0100 + + proper node version for circle ci? + +commit fd50184f8857ac131ef034ee0e20b85c6a1fc7a5 +Author: Damian Legawiec +Date: Sun Dec 27 01:19:42 2015 +0100 + + js/node test fix? + +commit 2800c21d5462a928935e6076fc6a3d50f5788e82 +Author: Damian Legawiec +Date: Sun Dec 27 01:01:24 2015 +0100 + + unnused gems removed from gemfile + +commit 64fb435260b0fb2c672257bd69f9c2c74bf08796 +Author: Damian Legawiec +Date: Sun Dec 27 00:49:56 2015 +0100 + + added foreman to gemfile + +commit 7ca49509a266c38be856e6c78c9ced9b122d9628 +Author: Damian Legawiec +Date: Sun Dec 27 00:48:06 2015 +0100 + + node/JS tests are passing + +commit be154553cef210572586327ee0c7575c3eef7c7f +Author: Damian Legawiec +Date: Sat Dec 26 12:02:44 2015 +0100 + + proper version number.. + +commit e4a54c02fe763a6a9336e793798c692f7763ce1f +Author: Damian Legawiec +Date: Sat Dec 26 11:58:30 2015 +0100 + + proper package.son description :) + +commit c17dca38ffa2ce53d2d03a3e4778f90302c5c935 +Author: Damian Legawiec +Date: Sat Dec 26 11:56:57 2015 +0100 + + moving back to react-rails and fixed server side rendering also for redux! + +commit 5b5ffcaf35bf0ada306a568af7d134692ac35e7e +Author: Damian Legawiec +Date: Fri Dec 25 23:58:34 2015 +0100 + + example of css modules + fix for missing app-bundle.css :) + +commit 28e03e09b63f2917aeb1b21138a18cfe0e9f55f8 +Author: Damian Legawiec +Date: Fri Dec 25 23:32:11 2015 +0100 + + removing sassc - not needed anymore + +commit c173e7acebc75b9bf7e14326a5eb24419a263efb +Author: Damian Legawiec +Date: Fri Dec 25 23:13:48 2015 +0100 + + reorganization of directory structure + stylesheets and images moved to webpack + +commit ae9f4c74d651095010809ebb71d516ce3eb453e8 +Author: Damian Legawiec +Date: Fri Dec 25 16:54:52 2015 +0100 + + server-side rendering of react components works + +commit 7dc11e4b461640e594f07b4ef6f6a8f8ee4c5223 +Author: Damian Legawiec +Date: Fri Dec 25 13:30:44 2015 +0100 + + removed unnecessary node packaged & updated rest + +commit 184cb90911ece197866edb322bbf14dda47582ae +Author: Damian Legawiec +Date: Fri Dec 25 13:22:59 2015 +0100 + + unused rake task removed + +commit cdd0d7903c541efb520e0fc9e2edc5e405b30008 +Author: Damian Legawiec +Date: Fri Dec 25 12:59:56 2015 +0100 + + redux-form added and account works :) + +commit bc8e5a0209d11fa7bb041810c9fb3ce69262f1ce +Author: Damian Legawiec +Date: Fri Dec 25 12:48:18 2015 +0100 + + typo fix + +commit b9d821591c90765d8c9d3d4e3272b54ea45788fb +Author: Damian Legawiec +Date: Fri Dec 25 12:41:46 2015 +0100 + + DOMAIN is reserved on heroku, switchint to ENV['APP_DOMAIN'] + +commit 5c14877d9a0e21ed612aa3df5402fafd0f7710de +Author: Damian Legawiec +Date: Fri Dec 25 12:33:36 2015 +0100 + + proper production domain/cdn settings + +commit b55e4cd3068aa46d022668d54f968fdb11bde476 +Author: Damian Legawiec +Date: Fri Dec 25 11:55:16 2015 +0100 + + removing asset_sync + +commit c63c80a9ac5c59f38e17e921e023faf44277cdaa +Author: Damian Legawiec +Date: Fri Dec 25 11:53:09 2015 +0100 + + working react_on_rails/webpack/babel6 + +commit b81098534cf4d699ed2e3721e4599c756217ffcd +Author: Damian Legawiec +Date: Thu Dec 24 09:42:57 2015 +0100 + + removing browserify-rails & react-rails + +commit 4f395fb6004ae81eb0ddad537c91701f2f41eea1 +Author: Damian Legawiec +Date: Wed Dec 23 23:53:24 2015 +0100 + + heroku buildpacks (node+ruby) + +commit 01194ca134132422d72356f93080efb51bafc69d +Author: Damian Legawiec +Date: Tue Dec 22 23:41:02 2015 +0100 + + therubyracer for JS server side rendering + +commit f3e25f19fbf425779c2cf803a3c4512b64e00286 +Author: Damian Legawiec +Date: Sun Dec 20 22:12:10 2015 +0100 + + Redux Login Form + +commit 2de471ddf543d1368314429a9b0fc1c5d5432840 +Author: Damian Legawiec +Date: Sat Dec 19 22:40:42 2015 +0100 + + node packages updated + +commit 33d09a144c712b3ce989eae27d6e977fef9c3e29 +Author: Damian Legawiec +Date: Sat Dec 19 22:13:57 2015 +0100 + + gems update + +commit 456f15699b494fc3726cdbe7cc81b5078976f6fd +Author: Damian Legawiec +Date: Sat Dec 19 21:52:16 2015 +0100 + + upgraded to ruby 2.2.4 + +commit 68a3e04fc42906790075c4f629090bd682ed44d6 +Author: Damian Legawiec +Date: Fri Dec 11 15:12:59 2015 +0100 + + gems update + +commit d36df2f25495743165406a8cf53d965df5bf5ff4 +Author: Damian Legawiec +Date: Fri Dec 11 15:12:47 2015 +0100 + + turn on cloudflare fix only on production + +commit 02d527cf159fb33f7d3f3aef8fda3ba5861e5b10 +Author: Damian Legawiec +Date: Fri Dec 11 15:12:29 2015 +0100 + + should matchers support + +commit a84787dbc2afe2a3d88330339dcb59b8330e2361 +Author: Damian Legawiec +Date: Wed Dec 9 15:59:50 2015 +0100 + + test env cache & active job fix + +commit f744b563aea104c072f17c2ddb008b1d20832a17 +Author: Damian Legawiec +Date: Wed Dec 9 15:59:28 2015 +0100 + + sass gems + +commit 47416e1cea4cf4c08c985fdbd9a0a6962b7f7823 +Author: Damian Legawiec +Date: Wed Dec 9 15:56:08 2015 +0100 + + add envify to package.json - capybara fix + +commit f1d6c5715fbfe5fe446af5907ef69ded8cd7fec0 +Author: Damian Legawiec +Date: Tue Dec 8 13:37:30 2015 +0100 + + custom seed rake task + +commit d6300ef969f086200314e6053feb92fe84a2ec5c +Author: Damian Legawiec +Date: Tue Dec 8 13:36:50 2015 +0100 + + use selected S3 region if defined + +commit 5eaf9f14f06cea92c61e43fffba604f664547751 +Author: Damian Legawiec +Date: Tue Dec 8 13:36:32 2015 +0100 + + naming fix + +commit 2cfbc4bb137082bb2d5ca3b78bef2d1cb68e1cbe +Author: Damian Legawiec +Date: Tue Dec 8 13:36:23 2015 +0100 + + cloud flare middleware for proper IP addresses + +commit 97fcafe44899477458a5808c5aa181f480343dba +Author: Damian Legawiec +Date: Tue Dec 8 13:29:04 2015 +0100 + + updated test env + +commit 19da9831ddf685a2a0518dc06001c4b4265df2c3 +Author: Damian Legawiec +Date: Tue Dec 8 13:23:09 2015 +0100 + + proper production config for memcached & email assets + +commit a8ea97d09db8a0236705dcc5cce1bb47566e29e9 +Author: Damian Legawiec +Date: Tue Dec 8 13:11:01 2015 +0100 + + redux dev tools prod fix + +commit cb18f619e6a9e4df73d80d330541c7adec808bcc +Author: Damian Legawiec +Date: Tue Dec 8 12:19:47 2015 +0100 + + browserify/node env fixes + +commit b79018a0969b9dd43e4a4bc3e66afe0d9999197f +Author: Damian Legawiec +Date: Tue Dec 8 11:41:16 2015 +0100 + + redux dev tools fixes + +commit 631d586aedb8ef55d0fa4ce91fa340e44f2f79f2 +Author: Damian Legawiec +Date: Tue Dec 8 11:24:30 2015 +0100 + + gems update + +commit bfb723f96673496e5279f1af56c114f659379c49 +Merge: 45a8ab5 9d0248c +Author: Damian Legawiec +Date: Tue Dec 8 11:22:01 2015 +0100 + + Merge pull request #1 from spark-solutions/redux + + Redux starter kit + +commit 9d0248c83e10dd66ccde3ea24bcdaf01c39d2d6a +Author: Damian Legawiec +Date: Tue Dec 8 11:19:08 2015 +0100 + + redux dev tools added + +commit 7a533029bf47f3b35bef76e98ddcc7c6767eed49 +Author: Damian Legawiec +Date: Sun Dec 6 21:57:40 2015 +0100 + + faster browserify compiling + +commit eb8b75f5f02de89aaaf177895422fb9f806720f2 +Author: Damian Legawiec +Date: Sun Dec 6 21:57:28 2015 +0100 + + proper naming conventions for React components and other JS files + +commit cf76cca1325742c89adbd1f14d3e3f7ccb617eca +Merge: ed246b2 fd17f75 +Author: Damian Legawiec +Date: Sun Dec 6 20:04:46 2015 +0100 + + Merge branch 'master' into redux + +commit fd17f75296d21f30e5adbab4c012d0c6834df042 +Author: Damian Legawiec +Date: Sun Dec 6 20:01:18 2015 +0100 + + naming change + +commit ed246b2d095ab01a30264d0793cfde99e30c10f4 +Author: Damian Legawiec +Date: Sun Dec 6 20:00:26 2015 +0100 + + i18n for client side translations + +commit cba4c5f9e6a540a8f659ae145c257ecc1dff692b +Author: Damian Legawiec +Date: Sun Dec 6 15:16:31 2015 +0100 + + fixed: send cookies in fetchCart/fetchAccount + +commit c2e13a5dc6a33ca0466b125a05981552bdde8068 +Author: Damian Legawiec +Date: Sun Dec 6 11:35:25 2015 +0100 + + flashes as bootstrap alerts + +commit c393299dd3eefba3276d4e48105be6a8e6e8f285 +Author: Damian Legawiec +Date: Sun Dec 6 11:35:05 2015 +0100 + + new simplified layout (WIP) + +commit 16d7ba931fb028f44ad6ec6ccf6be48c09ecde9b +Author: Damian Legawiec +Date: Sun Dec 6 11:34:40 2015 +0100 + + use spark logo as site/admin logo + +commit 45a8ab5c34d66a03657c2922f56712a04717a459 +Author: Damian Legawiec +Date: Sat Dec 5 21:57:21 2015 +0100 + + we don't need stripe, use braintree :) + +commit cf36a0096f30cbca0535f33493d8c1e82418b533 +Author: Damian Legawiec +Date: Sat Dec 5 21:23:11 2015 +0100 + + componentDidMount -> componentWillMount fetching data + some nicer props for dumb components + +commit aaa9a0046d10a8fea9285e614c5685952cad18fb +Author: Damian Legawiec +Date: Sat Dec 5 21:22:34 2015 +0100 + + old dummy components removed + +commit f12156cf52675a883df5a72c8b58cccd68075691 +Author: Damian Legawiec +Date: Sat Dec 5 20:53:04 2015 +0100 + + active model serialisers + JSON API 1.0 + +commit 9a785936474e4e9201b0a3c1edb303f8e9a8c705 +Author: Damian Legawiec +Date: Sat Dec 5 19:51:24 2015 +0100 + + updated babel npm packages + +commit d1b2a71a55cdc83adc841093d97478e69f818a5c +Author: Damian Legawiec +Date: Sun Nov 22 14:49:42 2015 +0100 + + redux boilerplate + some first containers/actions/reducers + +commit da86e7617590e0fcf9e7090fcc36e74ffde7eeb0 +Author: Damian Legawiec +Date: Sun Nov 15 16:58:30 2015 +0100 + + little cleanup + +commit 230e23c8ed3eec71ea4ad7f471d43e66312bf92f +Author: Damian Legawiec +Date: Sun Nov 15 16:06:43 2015 +0100 + + Use LibSass for Sass compilation + Rails 4.2.5 update + +commit ea246e2ae222f32e143ab8e137f1c3048cd32767 +Author: Damian Legawiec +Date: Sun Nov 15 15:46:43 2015 +0100 + + Babel 6 + moving javascripts from javascripts/spree/frontend to just javascripts/ + +commit f30a32464e8e5a99c127e3bd2d9aec0647c8df54 +Author: Damian Legawiec +Date: Sun Nov 15 13:53:27 2015 +0100 + + react-dom updated + +commit 26a29927e50675a9145e5a751135d6ba23146725 +Author: Damian Legawiec +Date: Fri Nov 6 20:22:47 2015 +0100 + + babelify & node version upgrade + +commit 2a3b7cf99166dd9b88298181cce0ebafd1beca87 +Author: Damian Legawiec +Date: Tue Nov 3 19:35:24 2015 +0100 + + js-routes added + +commit d1750df0754251445ce6700a9107d9f74b54b6a3 +Author: Damian Legawiec +Date: Tue Nov 3 19:35:13 2015 +0100 + + deprecated code removed + +commit 7a475bc1f28f9275e058739c6f7a162032d1e17f +Author: Damian Legawiec +Date: Tue Nov 3 19:34:55 2015 +0100 + + naming fix + +commit 2c03fb5aaafd959cfc0b1a610fc665a9ed1fb198 +Author: Damian Legawiec +Date: Tue Nov 3 18:39:36 2015 +0100 + + react 0.14.2 + +commit 6ca151fe782c1e42106ff8ba1ab00d270a0300ac +Author: Damian Legawiec +Date: Mon Nov 2 18:55:57 2015 +0100 + + rack-cache & dalli fix for large cache objects + +commit e70e159ce9c2a6bfaeef16c9d94c79b5a817f136 +Author: Damian Legawiec +Date: Sun Nov 1 20:36:14 2015 +0100 + + spec boilerplate + +commit 878de636402e24d712296965bce997b493685fc2 +Author: Damian Legawiec +Date: Sun Nov 1 20:36:05 2015 +0100 + + roller added + +commit 346c9687fa42024f626d0a4cc5743591bdb22877 +Author: Damian Legawiec +Date: Sun Nov 1 20:35:57 2015 +0100 + + rack-timeout for production/staging + +commit 8fc7c301278a2c585a0a9fab2676b45e07fd7977 +Author: Damian Legawiec +Date: Sun Nov 1 20:05:23 2015 +0100 + + Order & User serialisers + +commit d8700df1aba7604c49cc82cdc4e126ea9eddfcbf +Author: Damian Legawiec +Date: Sun Nov 1 19:58:51 2015 +0100 + + serializers & services support + +commit 41828db4b68d4864fc7ddfd7dcc57824ed51f8e6 +Author: Damian Legawiec +Date: Sun Nov 1 19:51:08 2015 +0100 + + Spree 3.0.5beta added + +commit cd2313515e3629db9f7753d3e963c717081b6d1d +Author: Damian Legawiec +Date: Sun Nov 1 19:03:59 2015 +0100 + + react-bootstrap added + +commit fa2b61d26c6d223ad8f404f4322a1a1009cd38f7 +Author: Damian Legawiec +Date: Sun Nov 1 19:03:49 2015 +0100 + + using .js for components and additional one + +commit 9a7138739a6388a6d7357d10cc0a45bc90d93118 +Author: Damian Legawiec +Date: Sun Nov 1 19:03:25 2015 +0100 + + deprecated js file removed + +commit 5cb8983f08100c5775e681ca4db1e6fe59ce9b40 +Author: Damian Legawiec +Date: Sun Nov 1 15:55:41 2015 +0100 + + react cleanup + +commit 2664e5f36fff0b3664c60c1a4dec28817888c181 +Author: Damian Legawiec +Date: Sun Nov 1 15:07:27 2015 +0100 + + isomorphic react + +commit 7be1c66c162ddccb8e744a3bf718b5d28f01f857 +Author: Damian Legawiec +Date: Sun Nov 1 14:01:08 2015 +0100 + + moving to haml + +commit 290da5b5004b9fc41247079c9af6998565132ef5 +Author: Damian Legawiec +Date: Sun Nov 1 14:00:23 2015 +0100 + + secrets with sidekiq, stripe, mailchimp & AWS + +commit 89333cad93d5af1181631bd12c1d981b7c4e908d +Author: Damian Legawiec +Date: Sun Nov 1 13:59:59 2015 +0100 + + proper development config + +commit f392e19d521aeff64b047cbacc1acd07acdca52c +Author: Damian Legawiec +Date: Sun Nov 1 13:24:57 2015 +0100 + + server assets from CDN + +commit 46959d7061ab27c1e858730a44e0ac7dbaad004a +Author: Damian Legawiec +Date: Sun Nov 1 13:01:49 2015 +0100 + + asset sync on + +commit e5f6e0e15b6b2e045031ef5540c305c72fda009b +Author: Damian Legawiec +Date: Sun Nov 1 13:01:28 2015 +0100 + + Revert "disabling asset_sync for testing" + + This reverts commit 5b8026082e3b8605858be74d91b2528b79808dfc. + +commit 5b8026082e3b8605858be74d91b2528b79808dfc +Author: Damian Legawiec +Date: Sun Nov 1 12:49:20 2015 +0100 + + disabling asset_sync for testing + +commit a8e3e460d9964bb3d6a64fedaa274526587542b5 +Author: Damian Legawiec +Date: Sun Nov 1 12:33:26 2015 +0100 + + rails + browserify + ES6 diff --git a/lib/assets/.keep b/lib/assets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/lib/spree/authentication_helpers.rb b/lib/spree/authentication_helpers.rb new file mode 100644 index 0000000..d8f62db --- /dev/null +++ b/lib/spree/authentication_helpers.rb @@ -0,0 +1,50 @@ +module Spree + module AuthenticationHelpers + def self.included(receiver) + receiver.helper_method( + :spree_current_user, + :spree_login_path, + :spree_signup_path, + :spree_logout_path, + :spree_forgot_password_path, + :spree_edit_password_path, + :spree_admin_login_path, + :spree_admin_logout_path + ) + end + + def spree_current_user + send("current_#{Spree.user_class.model_name.singular_route_key}") + end + + def spree_login_path(opts = {}) + new_session_path(Spree.user_class.model_name.singular_route_key, opts) + end + + def spree_signup_path(opts = {}) + new_registration_path(Spree.user_class.model_name.singular_route_key, opts) + end + + def spree_logout_path(opts = {}) + destroy_session_path(Spree.user_class.model_name.singular_route_key, opts) + end + + def spree_forgot_password_path(opts = {}) + new_password_path(Spree.user_class.model_name.singular_route_key, opts) + end + + def spree_edit_password_path(opts = {}) + edit_registration_path(Spree.user_class.model_name.singular_route_key, opts) + end + + def spree_admin_login_path(opts = {}) + new_admin_user_session_path(opts) + end + + def spree_admin_logout_path(opts = {}) + destroy_admin_user_session_path(opts) + end + end +end + +ApplicationController.include Spree::AuthenticationHelpers if defined?(ApplicationController) diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 0000000..e69de29 diff --git a/log/.keep b/log/.keep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/.bin/yarn b/node_modules/.bin/yarn new file mode 120000 index 0000000..f4bf725 --- /dev/null +++ b/node_modules/.bin/yarn @@ -0,0 +1 @@ +../yarn/bin/yarn.js \ No newline at end of file diff --git a/node_modules/.bin/yarnpkg b/node_modules/.bin/yarnpkg new file mode 120000 index 0000000..f4bf725 --- /dev/null +++ b/node_modules/.bin/yarnpkg @@ -0,0 +1 @@ +../yarn/bin/yarn.js \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000..57da775 --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,21 @@ +{ + "name": "spree_starter", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/yarn": { + "version": "1.22.22", + "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.22.tgz", + "integrity": "sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg==", + "hasInstallScript": true, + "license": "BSD-2-Clause", + "bin": { + "yarn": "bin/yarn.js", + "yarnpkg": "bin/yarn.js" + }, + "engines": { + "node": ">=4.0.0" + } + } + } +} diff --git a/node_modules/yarn/LICENSE b/node_modules/yarn/LICENSE new file mode 100644 index 0000000..e32914e --- /dev/null +++ b/node_modules/yarn/LICENSE @@ -0,0 +1,26 @@ +BSD 2-Clause License + +For Yarn software + +Copyright (c) 2016-present, Yarn Contributors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/yarn/README.md b/node_modules/yarn/README.md new file mode 100644 index 0000000..1305b93 --- /dev/null +++ b/node_modules/yarn/README.md @@ -0,0 +1,60 @@ +

+ + Yarn + +

+ +

+ Fast, reliable, and secure dependency management. +

+ +

+ Circle Status + Appveyor Status + Azure Pipelines status + Discord Chat + Commitizen friendly +

+ +--- + +**Fast:** Yarn caches every package it has downloaded, so it never needs to download the same package again. It also does almost everything concurrently to maximize resource utilization. This means even faster installs. + +**Reliable:** Using a detailed but concise lockfile format and a deterministic algorithm for install operations, Yarn is able to guarantee that any installation that works on one system will work exactly the same on another system. + +**Secure:** Yarn uses checksums to verify the integrity of every installed package before its code is executed. + +## Features + +* **Offline Mode.** If you've installed a package before, then you can install it again without an internet connection. +* **Deterministic.** The same dependencies will be installed in the same exact way on any machine, regardless of installation order. +* **Network Performance.** Yarn efficiently queues requests and avoids request waterfalls in order to maximize network utilization. +* **Network Resilience.** A single request that fails will not cause the entire installation to fail. Requests are automatically retried upon failure. +* **Flat Mode.** Yarn resolves mismatched versions of dependencies to a single version to avoid creating duplicates. +* **More emojis.** 🐈 + +## Installing Yarn + +Read the [Installation Guide](https://yarnpkg.com/en/docs/install) on our website for detailed instructions on how to install Yarn. + +## Using Yarn + +Read the [Usage Guide](https://yarnpkg.com/en/docs/usage) on our website for detailed instructions on how to use Yarn. + +## Contributing to Yarn + +Contributions are always welcome, no matter how large or small. Substantial feature requests should be proposed as an [RFC](https://github.com/yarnpkg/rfcs). Before contributing, please read the [code of conduct](CODE_OF_CONDUCT.md). + +See [Contributing](https://yarnpkg.com/org/contributing/). + +## Prior art + +Yarn wouldn't exist if it wasn't for excellent prior art. Yarn has been inspired by the following projects: + + - [Bundler](https://github.com/bundler/bundler) + - [Cargo](https://github.com/rust-lang/cargo) + - [npm](https://github.com/npm/cli) + +## Credits + +Thanks to [Sam Holmes](https://github.com/samholmes) for donating the npm package name! diff --git a/node_modules/yarn/bin/yarn b/node_modules/yarn/bin/yarn new file mode 100755 index 0000000..35ad517 --- /dev/null +++ b/node_modules/yarn/bin/yarn @@ -0,0 +1,35 @@ +#!/bin/sh +argv0=$(echo "$0" | sed -e 's,\\,/,g') +basedir=$(dirname "$(readlink "$0" || echo "$argv0")") + +case "$(uname -s)" in + Darwin) basedir="$( cd "$( dirname "$argv0" )" && pwd )";; + Linux) basedir=$(dirname "$(readlink -f "$0" || echo "$argv0")");; + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; + *MSYS*) basedir=`cygpath -w "$basedir"`;; +esac + +command_exists() { + command -v "$1" >/dev/null 2>&1; +} + +if command_exists node; then + if [ "$YARN_FORCE_WINPTY" = 1 ] || command_exists winpty && test -t 1; then + winpty node "$basedir/yarn.js" "$@" + else + exec node "$basedir/yarn.js" "$@" + fi + ret=$? +# Debian and Ubuntu use "nodejs" as the name of the binary, not "node", so we +# search for that too. See: +# https://lists.debian.org/debian-devel-announce/2012/07/msg00002.html +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=614907 +elif command_exists nodejs; then + exec nodejs "$basedir/yarn.js" "$@" + ret=$? +else + >&2 echo 'Yarn requires Node.js 4.0 or higher to be installed.' + ret=1 +fi + +exit $ret diff --git a/node_modules/yarn/bin/yarn.cmd b/node_modules/yarn/bin/yarn.cmd new file mode 100755 index 0000000..79c1896 --- /dev/null +++ b/node_modules/yarn/bin/yarn.cmd @@ -0,0 +1,2 @@ +@echo off +node "%~dp0\yarn.js" %* diff --git a/node_modules/yarn/bin/yarn.js b/node_modules/yarn/bin/yarn.js new file mode 100755 index 0000000..b34883e --- /dev/null +++ b/node_modules/yarn/bin/yarn.js @@ -0,0 +1,31 @@ +#!/usr/bin/env node + +/* eslint-disable no-var */ +/* eslint-disable flowtype/require-valid-file-annotation */ +'use strict'; + +var ver = process.versions.node; +var majorVer = parseInt(ver.split('.')[0], 10); + +if (majorVer < 4) { + console.error('Node version ' + ver + ' is not supported, please use Node.js 4.0 or higher.'); + process.exit(1); // eslint-disable-line no-process-exit +} else { + try { + require(__dirname + '/../lib/v8-compile-cache.js'); + } catch (err) { + // We don't have/need this on legacy builds and dev builds + } + + // Just requiring this package will trigger a yarn run since the + // `require.main === module` check inside `cli/index.js` will always + // be truthy when built with webpack :( + // `lib/cli` may be `lib/cli/index.js` or `lib/cli.js` depending on the build. + var cli = require(__dirname + '/../lib/cli'); + if (!cli.autoRun) { + cli.default().catch(function(error) { + console.error(error.stack || error.message || error); + process.exitCode = 1; + }); + } +} diff --git a/node_modules/yarn/bin/yarnpkg b/node_modules/yarn/bin/yarnpkg new file mode 100755 index 0000000..f6129c5 --- /dev/null +++ b/node_modules/yarn/bin/yarnpkg @@ -0,0 +1,2 @@ +#!/usr/bin/env node +require('./yarn.js'); diff --git a/node_modules/yarn/bin/yarnpkg.cmd b/node_modules/yarn/bin/yarnpkg.cmd new file mode 100755 index 0000000..66ee751 --- /dev/null +++ b/node_modules/yarn/bin/yarnpkg.cmd @@ -0,0 +1,2 @@ +@echo off +"%~dp0\yarn.cmd" %* diff --git a/node_modules/yarn/lib/cli.js b/node_modules/yarn/lib/cli.js new file mode 100755 index 0000000..dfd1510 --- /dev/null +++ b/node_modules/yarn/lib/cli.js @@ -0,0 +1,154071 @@ +#!/usr/bin/env node +module.exports = +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 504); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export (immutable) */ __webpack_exports__["a"] = __extends; +/* unused harmony export __assign */ +/* unused harmony export __rest */ +/* unused harmony export __decorate */ +/* unused harmony export __param */ +/* unused harmony export __metadata */ +/* unused harmony export __awaiter */ +/* unused harmony export __generator */ +/* unused harmony export __exportStar */ +/* unused harmony export __values */ +/* unused harmony export __read */ +/* unused harmony export __spread */ +/* unused harmony export __await */ +/* unused harmony export __asyncGenerator */ +/* unused harmony export __asyncDelegator */ +/* unused harmony export __asyncValues */ +/* unused harmony export __makeTemplateObject */ +/* unused harmony export __importStar */ +/* unused harmony export __importDefault */ +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ +/* global Reflect, Promise */ + +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + } + return __assign.apply(this, arguments); +} + +function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +} + +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} + +function __param(paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +} + +function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} + +function __awaiter(thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + +function __exportStar(m, exports) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} + +function __values(o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; + if (m) return m.call(o); + return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; +} + +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +} + +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; +} + +function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); +} + +function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +} + +function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } +} + +function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +} + +function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; +}; + +function __importStar(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result.default = mod; + return result; +} + +function __importDefault(mod) { + return (mod && mod.__esModule) ? mod : { default: mod }; +} + + +/***/ }), +/* 1 */ +/***/ (function(module, exports) { + +module.exports = require("path"); + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _promise = __webpack_require__(7); + +var _promise2 = _interopRequireDefault(_promise); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = function (fn) { + return function () { + var gen = fn.apply(this, arguments); + return new _promise2.default(function (resolve, reject) { + function step(key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + + if (info.done) { + resolve(value); + } else { + return _promise2.default.resolve(value).then(function (value) { + step("next", value); + }, function (err) { + step("throw", err); + }); + } + } + + return step("next"); + }); + }; +}; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +exports.default = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } +}; + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(591), __esModule: true }; + +/***/ }), +/* 5 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Subscriber; }); +/* unused harmony export SafeSubscriber */ +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_tslib__ = __webpack_require__(0); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_isFunction__ = __webpack_require__(143); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Observer__ = __webpack_require__(390); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Subscription__ = __webpack_require__(31); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__internal_symbol_rxSubscriber__ = __webpack_require__(262); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__config__ = __webpack_require__(176); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__util_hostReportError__ = __webpack_require__(264); +/** PURE_IMPORTS_START tslib,_util_isFunction,_Observer,_Subscription,_internal_symbol_rxSubscriber,_config,_util_hostReportError PURE_IMPORTS_END */ + + + + + + + +var Subscriber = /*@__PURE__*/ (function (_super) { + __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](Subscriber, _super); + function Subscriber(destinationOrNext, error, complete) { + var _this = _super.call(this) || this; + _this.syncErrorValue = null; + _this.syncErrorThrown = false; + _this.syncErrorThrowable = false; + _this.isStopped = false; + _this._parentSubscription = null; + switch (arguments.length) { + case 0: + _this.destination = __WEBPACK_IMPORTED_MODULE_2__Observer__["a" /* empty */]; + break; + case 1: + if (!destinationOrNext) { + _this.destination = __WEBPACK_IMPORTED_MODULE_2__Observer__["a" /* empty */]; + break; + } + if (typeof destinationOrNext === 'object') { + if (destinationOrNext instanceof Subscriber) { + _this.syncErrorThrowable = destinationOrNext.syncErrorThrowable; + _this.destination = destinationOrNext; + destinationOrNext.add(_this); + } + else { + _this.syncErrorThrowable = true; + _this.destination = new SafeSubscriber(_this, destinationOrNext); + } + break; + } + default: + _this.syncErrorThrowable = true; + _this.destination = new SafeSubscriber(_this, destinationOrNext, error, complete); + break; + } + return _this; + } + Subscriber.prototype[__WEBPACK_IMPORTED_MODULE_4__internal_symbol_rxSubscriber__["a" /* rxSubscriber */]] = function () { return this; }; + Subscriber.create = function (next, error, complete) { + var subscriber = new Subscriber(next, error, complete); + subscriber.syncErrorThrowable = false; + return subscriber; + }; + Subscriber.prototype.next = function (value) { + if (!this.isStopped) { + this._next(value); + } + }; + Subscriber.prototype.error = function (err) { + if (!this.isStopped) { + this.isStopped = true; + this._error(err); + } + }; + Subscriber.prototype.complete = function () { + if (!this.isStopped) { + this.isStopped = true; + this._complete(); + } + }; + Subscriber.prototype.unsubscribe = function () { + if (this.closed) { + return; + } + this.isStopped = true; + _super.prototype.unsubscribe.call(this); + }; + Subscriber.prototype._next = function (value) { + this.destination.next(value); + }; + Subscriber.prototype._error = function (err) { + this.destination.error(err); + this.unsubscribe(); + }; + Subscriber.prototype._complete = function () { + this.destination.complete(); + this.unsubscribe(); + }; + Subscriber.prototype._unsubscribeAndRecycle = function () { + var _a = this, _parent = _a._parent, _parents = _a._parents; + this._parent = null; + this._parents = null; + this.unsubscribe(); + this.closed = false; + this.isStopped = false; + this._parent = _parent; + this._parents = _parents; + this._parentSubscription = null; + return this; + }; + return Subscriber; +}(__WEBPACK_IMPORTED_MODULE_3__Subscription__["a" /* Subscription */])); + +var SafeSubscriber = /*@__PURE__*/ (function (_super) { + __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](SafeSubscriber, _super); + function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) { + var _this = _super.call(this) || this; + _this._parentSubscriber = _parentSubscriber; + var next; + var context = _this; + if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__util_isFunction__["a" /* isFunction */])(observerOrNext)) { + next = observerOrNext; + } + else if (observerOrNext) { + next = observerOrNext.next; + error = observerOrNext.error; + complete = observerOrNext.complete; + if (observerOrNext !== __WEBPACK_IMPORTED_MODULE_2__Observer__["a" /* empty */]) { + context = Object.create(observerOrNext); + if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__util_isFunction__["a" /* isFunction */])(context.unsubscribe)) { + _this.add(context.unsubscribe.bind(context)); + } + context.unsubscribe = _this.unsubscribe.bind(_this); + } + } + _this._context = context; + _this._next = next; + _this._error = error; + _this._complete = complete; + return _this; + } + SafeSubscriber.prototype.next = function (value) { + if (!this.isStopped && this._next) { + var _parentSubscriber = this._parentSubscriber; + if (!__WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(this._next, value); + } + else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) { + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var _parentSubscriber = this._parentSubscriber; + var useDeprecatedSynchronousErrorHandling = __WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling; + if (this._error) { + if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(this._error, err); + this.unsubscribe(); + } + else { + this.__tryOrSetError(_parentSubscriber, this._error, err); + this.unsubscribe(); + } + } + else if (!_parentSubscriber.syncErrorThrowable) { + this.unsubscribe(); + if (useDeprecatedSynchronousErrorHandling) { + throw err; + } + __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_6__util_hostReportError__["a" /* hostReportError */])(err); + } + else { + if (useDeprecatedSynchronousErrorHandling) { + _parentSubscriber.syncErrorValue = err; + _parentSubscriber.syncErrorThrown = true; + } + else { + __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_6__util_hostReportError__["a" /* hostReportError */])(err); + } + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.complete = function () { + var _this = this; + if (!this.isStopped) { + var _parentSubscriber = this._parentSubscriber; + if (this._complete) { + var wrappedComplete = function () { return _this._complete.call(_this._context); }; + if (!__WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(wrappedComplete); + this.unsubscribe(); + } + else { + this.__tryOrSetError(_parentSubscriber, wrappedComplete); + this.unsubscribe(); + } + } + else { + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) { + try { + fn.call(this._context, value); + } + catch (err) { + this.unsubscribe(); + if (__WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling) { + throw err; + } + else { + __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_6__util_hostReportError__["a" /* hostReportError */])(err); + } + } + }; + SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) { + if (!__WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling) { + throw new Error('bad call'); + } + try { + fn.call(this._context, value); + } + catch (err) { + if (__WEBPACK_IMPORTED_MODULE_5__config__["a" /* config */].useDeprecatedSynchronousErrorHandling) { + parent.syncErrorValue = err; + parent.syncErrorThrown = true; + return true; + } + else { + __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_6__util_hostReportError__["a" /* hostReportError */])(err); + return true; + } + } + return false; + }; + SafeSubscriber.prototype._unsubscribe = function () { + var _parentSubscriber = this._parentSubscriber; + this._context = null; + this._parentSubscriber = null; + _parentSubscriber.unsubscribe(); + }; + return SafeSubscriber; +}(Subscriber)); + +//# sourceMappingURL=Subscriber.js.map + + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.OneTimePasswordError = exports.ResponseError = exports.ProcessTermError = exports.SecurityError = exports.ProcessSpawnError = exports.MessageError = undefined; + +var _create; + +function _load_create() { + return _create = _interopRequireDefault(__webpack_require__(210)); +} + +var _getPrototypeOf; + +function _load_getPrototypeOf() { + return _getPrototypeOf = _interopRequireDefault(__webpack_require__(550)); +} + +var _setPrototypeOf; + +function _load_setPrototypeOf() { + return _setPrototypeOf = _interopRequireDefault(__webpack_require__(211)); +} + +var _from; + +function _load_from() { + return _from = _interopRequireDefault(__webpack_require__(53)); +} + +var _construct; + +function _load_construct() { + return _construct = _interopRequireDefault(__webpack_require__(552)); +} + +var _classCallCheck2; + +function _load_classCallCheck() { + return _classCallCheck2 = _interopRequireDefault(__webpack_require__(3)); +} + +var _possibleConstructorReturn2; + +function _load_possibleConstructorReturn() { + return _possibleConstructorReturn2 = _interopRequireDefault(__webpack_require__(11)); +} + +var _inherits2; + +function _load_inherits() { + return _inherits2 = _interopRequireDefault(__webpack_require__(10)); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _extendableBuiltin5(cls) { + function ExtendableBuiltin() { + var instance = (0, (_construct || _load_construct()).default)(cls, (0, (_from || _load_from()).default)(arguments)); + (0, (_setPrototypeOf || _load_setPrototypeOf()).default)(instance, (0, (_getPrototypeOf || _load_getPrototypeOf()).default)(this)); + return instance; + } + + ExtendableBuiltin.prototype = (0, (_create || _load_create()).default)(cls.prototype, { + constructor: { + value: cls, + enumerable: false, + writable: true, + configurable: true + } + }); + + if ((_setPrototypeOf || _load_setPrototypeOf()).default) { + (0, (_setPrototypeOf || _load_setPrototypeOf()).default)(ExtendableBuiltin, cls); + } else { + ExtendableBuiltin.__proto__ = cls; + } + + return ExtendableBuiltin; +} + +function _extendableBuiltin3(cls) { + function ExtendableBuiltin() { + var instance = (0, (_construct || _load_construct()).default)(cls, (0, (_from || _load_from()).default)(arguments)); + (0, (_setPrototypeOf || _load_setPrototypeOf()).default)(instance, (0, (_getPrototypeOf || _load_getPrototypeOf()).default)(this)); + return instance; + } + + ExtendableBuiltin.prototype = (0, (_create || _load_create()).default)(cls.prototype, { + constructor: { + value: cls, + enumerable: false, + writable: true, + configurable: true + } + }); + + if ((_setPrototypeOf || _load_setPrototypeOf()).default) { + (0, (_setPrototypeOf || _load_setPrototypeOf()).default)(ExtendableBuiltin, cls); + } else { + ExtendableBuiltin.__proto__ = cls; + } + + return ExtendableBuiltin; +} + +function _extendableBuiltin(cls) { + function ExtendableBuiltin() { + var instance = (0, (_construct || _load_construct()).default)(cls, (0, (_from || _load_from()).default)(arguments)); + (0, (_setPrototypeOf || _load_setPrototypeOf()).default)(instance, (0, (_getPrototypeOf || _load_getPrototypeOf()).default)(this)); + return instance; + } + + ExtendableBuiltin.prototype = (0, (_create || _load_create()).default)(cls.prototype, { + constructor: { + value: cls, + enumerable: false, + writable: true, + configurable: true + } + }); + + if ((_setPrototypeOf || _load_setPrototypeOf()).default) { + (0, (_setPrototypeOf || _load_setPrototypeOf()).default)(ExtendableBuiltin, cls); + } else { + ExtendableBuiltin.__proto__ = cls; + } + + return ExtendableBuiltin; +} + +var MessageError = exports.MessageError = function (_extendableBuiltin2) { + (0, (_inherits2 || _load_inherits()).default)(MessageError, _extendableBuiltin2); + + function MessageError(msg, code) { + (0, (_classCallCheck2 || _load_classCallCheck()).default)(this, MessageError); + + var _this = (0, (_possibleConstructorReturn2 || _load_possibleConstructorReturn()).default)(this, _extendableBuiltin2.call(this, msg)); + + _this.code = code; + return _this; + } + + return MessageError; +}(_extendableBuiltin(Error)); + +var ProcessSpawnError = exports.ProcessSpawnError = function (_MessageError) { + (0, (_inherits2 || _load_inherits()).default)(ProcessSpawnError, _MessageError); + + function ProcessSpawnError(msg, code, process) { + (0, (_classCallCheck2 || _load_classCallCheck()).default)(this, ProcessSpawnError); + + var _this2 = (0, (_possibleConstructorReturn2 || _load_possibleConstructorReturn()).default)(this, _MessageError.call(this, msg, code)); + + _this2.process = process; + return _this2; + } + + return ProcessSpawnError; +}(MessageError); + +var SecurityError = exports.SecurityError = function (_MessageError2) { + (0, (_inherits2 || _load_inherits()).default)(SecurityError, _MessageError2); + + function SecurityError() { + (0, (_classCallCheck2 || _load_classCallCheck()).default)(this, SecurityError); + return (0, (_possibleConstructorReturn2 || _load_possibleConstructorReturn()).default)(this, _MessageError2.apply(this, arguments)); + } + + return SecurityError; +}(MessageError); + +var ProcessTermError = exports.ProcessTermError = function (_MessageError3) { + (0, (_inherits2 || _load_inherits()).default)(ProcessTermError, _MessageError3); + + function ProcessTermError() { + (0, (_classCallCheck2 || _load_classCallCheck()).default)(this, ProcessTermError); + return (0, (_possibleConstructorReturn2 || _load_possibleConstructorReturn()).default)(this, _MessageError3.apply(this, arguments)); + } + + return ProcessTermError; +}(MessageError); + +var ResponseError = exports.ResponseError = function (_extendableBuiltin4) { + (0, (_inherits2 || _load_inherits()).default)(ResponseError, _extendableBuiltin4); + + function ResponseError(msg, responseCode) { + (0, (_classCallCheck2 || _load_classCallCheck()).default)(this, ResponseError); + + var _this5 = (0, (_possibleConstructorReturn2 || _load_possibleConstructorReturn()).default)(this, _extendableBuiltin4.call(this, msg)); + + _this5.responseCode = responseCode; + return _this5; + } + + return ResponseError; +}(_extendableBuiltin3(Error)); + +var OneTimePasswordError = exports.OneTimePasswordError = function (_extendableBuiltin6) { + (0, (_inherits2 || _load_inherits()).default)(OneTimePasswordError, _extendableBuiltin6); + + function OneTimePasswordError(notice) { + (0, (_classCallCheck2 || _load_classCallCheck()).default)(this, OneTimePasswordError); + + var _this6 = (0, (_possibleConstructorReturn2 || _load_possibleConstructorReturn()).default)(this, _extendableBuiltin6.call(this)); + + _this6.notice = notice; + return _this6; + } + + return OneTimePasswordError; +}(_extendableBuiltin5(Error)); + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(600), __esModule: true }; + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getFirstSuitableFolder = exports.readFirstAvailableStream = exports.makeTempDir = exports.hardlinksWork = exports.writeFilePreservingEol = exports.getFileSizeOnDisk = exports.walk = exports.symlink = exports.find = exports.readJsonAndFile = exports.readJson = exports.readFileAny = exports.hardlinkBulk = exports.copyBulk = exports.unlink = exports.glob = exports.link = exports.chmod = exports.lstat = exports.exists = exports.mkdirp = exports.stat = exports.access = exports.rename = exports.readdir = exports.realpath = exports.readlink = exports.writeFile = exports.open = exports.readFileBuffer = exports.lockQueue = exports.constants = undefined; + +var _map; + +function _load_map() { + return _map = _interopRequireDefault(__webpack_require__(42)); +} + +var _getIterator2; + +function _load_getIterator() { + return _getIterator2 = _interopRequireDefault(__webpack_require__(4)); +} + +var _promise; + +function _load_promise() { + return _promise = _interopRequireDefault(__webpack_require__(7)); +} + +var _set; + +function _load_set() { + return _set = _interopRequireDefault(__webpack_require__(16)); +} + +var _asyncToGenerator2; + +function _load_asyncToGenerator() { + return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(2)); +} + +var buildActionsForCopy = function () { + var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { + + // + var build = function () { + var _ref5 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + var src = data.src, + dest = data.dest, + type = data.type; + + var onFresh = data.onFresh || noop; + var onDone = data.onDone || noop; + + // TODO https://github.com/yarnpkg/yarn/issues/3751 + // related to bundled dependencies handling + if (files.has(dest.toLowerCase())) { + reporter.verbose(`The case-insensitive file ${dest} shouldn't be copied twice in one bulk copy`); + } else { + files.add(dest.toLowerCase()); + } + + if (type === 'symlink') { + yield mkdirp((_path2 || _load_path()).default.dirname(dest)); + onFresh(); + actions.symlink.push({ + dest, + linkname: src + }); + onDone(); + return; + } + + if (events.ignoreBasenames.indexOf((_path2 || _load_path()).default.basename(src)) >= 0) { + // ignored file + return; + } + + var srcStat = yield lstat(src); + var srcFiles = void 0; + + if (srcStat.isDirectory()) { + srcFiles = yield readdir(src); + } + + var destStat = void 0; + try { + // try accessing the destination + destStat = yield lstat(dest); + } catch (e) { + // proceed if destination doesn't exist, otherwise error + if (e.code !== 'ENOENT') { + throw e; + } + } + + // if destination exists + if (destStat) { + var bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); + var bothFolders = srcStat.isDirectory() && destStat.isDirectory(); + var bothFiles = srcStat.isFile() && destStat.isFile(); + + // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving + // us modes that aren't valid. investigate this, it's generally safe to proceed. + + /* if (srcStat.mode !== destStat.mode) { + try { + await access(dest, srcStat.mode); + } catch (err) {} + } */ + + if (bothFiles && artifactFiles.has(dest)) { + // this file gets changed during build, likely by a custom install script. Don't bother checking it. + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); + return; + } + + if (bothFiles && srcStat.size === destStat.size && (0, (_fsNormalized || _load_fsNormalized()).fileDatesEqual)(srcStat.mtime, destStat.mtime)) { + // we can safely assume this is the same file + onDone(); + reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.size, +srcStat.mtime)); + return; + } + + if (bothSymlinks) { + var srcReallink = yield readlink(src); + if (srcReallink === (yield readlink(dest))) { + // if both symlinks are the same then we can continue on + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); + return; + } + } + + if (bothFolders) { + // mark files that aren't in this folder as possibly extraneous + var destFiles = yield readdir(dest); + invariant(srcFiles, 'src files not initialised'); + + for (var _iterator4 = destFiles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator4);;) { + var _ref6; + + if (_isArray4) { + if (_i4 >= _iterator4.length) break; + _ref6 = _iterator4[_i4++]; + } else { + _i4 = _iterator4.next(); + if (_i4.done) break; + _ref6 = _i4.value; + } + + var _file2 = _ref6; + + if (srcFiles.indexOf(_file2) < 0) { + var _loc = (_path2 || _load_path()).default.join(dest, _file2); + possibleExtraneous.add(_loc); + + if ((yield lstat(_loc)).isDirectory()) { + for (var _iterator5 = yield readdir(_loc), _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator5);;) { + var _ref7; + + if (_isArray5) { + if (_i5 >= _iterator5.length) break; + _ref7 = _iterator5[_i5++]; + } else { + _i5 = _iterator5.next(); + if (_i5.done) break; + _ref7 = _i5.value; + } + + var _file3 = _ref7; + + possibleExtraneous.add((_path2 || _load_path()).default.join(_loc, _file3)); + } + } + } + } + } + } + + if (destStat && destStat.isSymbolicLink()) { + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); + destStat = null; + } + + if (srcStat.isSymbolicLink()) { + onFresh(); + var _linkname = yield readlink(src); + actions.symlink.push({ + dest, + linkname: _linkname + }); + onDone(); + } else if (srcStat.isDirectory()) { + yield* function* () { + if (!destStat) { + reporter.verbose(reporter.lang('verboseFileFolder', dest)); + yield mkdirp(dest); + } + + var destParts = dest.split((_path2 || _load_path()).default.sep); + while (destParts.length) { + files.add(destParts.join((_path2 || _load_path()).default.sep).toLowerCase()); + destParts.pop(); + } + + // push all files to queue + invariant(srcFiles, 'src files not initialised'); + var remaining = srcFiles.length; + if (!remaining) { + onDone(); + } + for (var _iterator6 = srcFiles, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator6);;) { + var _ref8; + + if (_isArray6) { + if (_i6 >= _iterator6.length) break; + _ref8 = _iterator6[_i6++]; + } else { + _i6 = _iterator6.next(); + if (_i6.done) break; + _ref8 = _i6.value; + } + + var _file4 = _ref8; + + queue.push({ + dest: (_path2 || _load_path()).default.join(dest, _file4), + onFresh, + onDone: function (_onDone) { + function onDone() { + return _onDone.apply(this, arguments); + } + + onDone.toString = function () { + return _onDone.toString(); + }; + + return onDone; + }(function () { + if (--remaining === 0) { + onDone(); + } + }), + src: (_path2 || _load_path()).default.join(src, _file4) + }); + } + }(); + } else if (srcStat.isFile()) { + onFresh(); + actions.file.push({ + src, + dest, + atime: srcStat.atime, + mtime: srcStat.mtime, + mode: srcStat.mode + }); + onDone(); + } else { + throw new Error(`unsure how to copy this: ${src}`); + } + }); + + return function build(_x5) { + return _ref5.apply(this, arguments); + }; + }(); + + var artifactFiles = new (_set || _load_set()).default(events.artifactFiles || []); + var files = new (_set || _load_set()).default(); + + // initialise events + + var _loop = function _loop(item) { + var onDone = item.onDone; + item.onDone = function () { + events.onProgress(item.dest); + if (onDone) { + onDone(); + } + }; + }; + + for (var _iterator = queue, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : (0, (_getIterator2 || _load_getIterator()).default)(_iterator);;) { + var _ref2; + + if (_isArray) { + if (_i >= _iterator.length) break; + _ref2 = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref2 = _i.value; + } + + var item = _ref2; + + _loop(item); + } + events.onStart(queue.length); + + // start building actions + var actions = { + file: [], + symlink: [], + link: [] + }; + + // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items + // at a time due to the requirement to push items onto the queue + while (queue.length) { + var items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); + yield (_promise || _load_promise()).default.all(items.map(build)); + } + + // simulate the existence of some files to prevent considering them extraneous + for (var _iterator2 = artifactFiles, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator2);;) { + var _ref3; + + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref3 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref3 = _i2.value; + } + + var _file = _ref3; + + if (possibleExtraneous.has(_file)) { + reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', _file)); + possibleExtraneous.delete(_file); + } + } + + for (var _iterator3 = possibleExtraneous, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator3);;) { + var _ref4; + + if (_isArray3) { + if (_i3 >= _iterator3.length) break; + _ref4 = _iterator3[_i3++]; + } else { + _i3 = _iterator3.next(); + if (_i3.done) break; + _ref4 = _i3.value; + } + + var loc = _ref4; + + if (files.has(loc.toLowerCase())) { + possibleExtraneous.delete(loc); + } + } + + return actions; + }); + + return function buildActionsForCopy(_x, _x2, _x3, _x4) { + return _ref.apply(this, arguments); + }; +}(); + +var buildActionsForHardlink = function () { + var _ref9 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { + + // + var build = function () { + var _ref13 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + var src = data.src, + dest = data.dest; + + var onFresh = data.onFresh || noop; + var onDone = data.onDone || noop; + if (files.has(dest.toLowerCase())) { + // Fixes issue https://github.com/yarnpkg/yarn/issues/2734 + // When bulk hardlinking we have A -> B structure that we want to hardlink to A1 -> B1, + // package-linker passes that modules A1 and B1 need to be hardlinked, + // the recursive linking algorithm of A1 ends up scheduling files in B1 to be linked twice which will case + // an exception. + onDone(); + return; + } + files.add(dest.toLowerCase()); + + if (events.ignoreBasenames.indexOf((_path2 || _load_path()).default.basename(src)) >= 0) { + // ignored file + return; + } + + var srcStat = yield lstat(src); + var srcFiles = void 0; + + if (srcStat.isDirectory()) { + srcFiles = yield readdir(src); + } + + var destExists = yield exists(dest); + if (destExists) { + var destStat = yield lstat(dest); + + var bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); + var bothFolders = srcStat.isDirectory() && destStat.isDirectory(); + var bothFiles = srcStat.isFile() && destStat.isFile(); + + if (srcStat.mode !== destStat.mode) { + try { + yield access(dest, srcStat.mode); + } catch (err) { + // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving + // us modes that aren't valid. investigate this, it's generally safe to proceed. + reporter.verbose(err); + } + } + + if (bothFiles && artifactFiles.has(dest)) { + // this file gets changed during build, likely by a custom install script. Don't bother checking it. + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); + return; + } + + // correct hardlink + if (bothFiles && srcStat.ino !== null && srcStat.ino === destStat.ino) { + onDone(); + reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.ino)); + return; + } + + if (bothSymlinks) { + var srcReallink = yield readlink(src); + if (srcReallink === (yield readlink(dest))) { + // if both symlinks are the same then we can continue on + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); + return; + } + } + + if (bothFolders) { + // mark files that aren't in this folder as possibly extraneous + var destFiles = yield readdir(dest); + invariant(srcFiles, 'src files not initialised'); + + for (var _iterator10 = destFiles, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator10);;) { + var _ref14; + + if (_isArray10) { + if (_i10 >= _iterator10.length) break; + _ref14 = _iterator10[_i10++]; + } else { + _i10 = _iterator10.next(); + if (_i10.done) break; + _ref14 = _i10.value; + } + + var _file6 = _ref14; + + if (srcFiles.indexOf(_file6) < 0) { + var _loc2 = (_path2 || _load_path()).default.join(dest, _file6); + possibleExtraneous.add(_loc2); + + if ((yield lstat(_loc2)).isDirectory()) { + for (var _iterator11 = yield readdir(_loc2), _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator11);;) { + var _ref15; + + if (_isArray11) { + if (_i11 >= _iterator11.length) break; + _ref15 = _iterator11[_i11++]; + } else { + _i11 = _iterator11.next(); + if (_i11.done) break; + _ref15 = _i11.value; + } + + var _file7 = _ref15; + + possibleExtraneous.add((_path2 || _load_path()).default.join(_loc2, _file7)); + } + } + } + } + } + } + + if (srcStat.isSymbolicLink()) { + onFresh(); + var _linkname2 = yield readlink(src); + actions.symlink.push({ + dest, + linkname: _linkname2 + }); + onDone(); + } else if (srcStat.isDirectory()) { + yield* function* () { + reporter.verbose(reporter.lang('verboseFileFolder', dest)); + yield mkdirp(dest); + + var destParts = dest.split((_path2 || _load_path()).default.sep); + while (destParts.length) { + files.add(destParts.join((_path2 || _load_path()).default.sep).toLowerCase()); + destParts.pop(); + } + + // push all files to queue + invariant(srcFiles, 'src files not initialised'); + var remaining = srcFiles.length; + if (!remaining) { + onDone(); + } + for (var _iterator12 = srcFiles, _isArray12 = Array.isArray(_iterator12), _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator12);;) { + var _ref16; + + if (_isArray12) { + if (_i12 >= _iterator12.length) break; + _ref16 = _iterator12[_i12++]; + } else { + _i12 = _iterator12.next(); + if (_i12.done) break; + _ref16 = _i12.value; + } + + var _file8 = _ref16; + + queue.push({ + onFresh, + src: (_path2 || _load_path()).default.join(src, _file8), + dest: (_path2 || _load_path()).default.join(dest, _file8), + onDone: function (_onDone2) { + function onDone() { + return _onDone2.apply(this, arguments); + } + + onDone.toString = function () { + return _onDone2.toString(); + }; + + return onDone; + }(function () { + if (--remaining === 0) { + onDone(); + } + }) + }); + } + }(); + } else if (srcStat.isFile()) { + onFresh(); + actions.link.push({ + src, + dest, + removeDest: destExists + }); + onDone(); + } else { + throw new Error(`unsure how to copy this: ${src}`); + } + }); + + return function build(_x10) { + return _ref13.apply(this, arguments); + }; + }(); + + var artifactFiles = new (_set || _load_set()).default(events.artifactFiles || []); + var files = new (_set || _load_set()).default(); + + // initialise events + + var _loop2 = function _loop2(item) { + var onDone = item.onDone || noop; + item.onDone = function () { + events.onProgress(item.dest); + onDone(); + }; + }; + + for (var _iterator7 = queue, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator7);;) { + var _ref10; + + if (_isArray7) { + if (_i7 >= _iterator7.length) break; + _ref10 = _iterator7[_i7++]; + } else { + _i7 = _iterator7.next(); + if (_i7.done) break; + _ref10 = _i7.value; + } + + var item = _ref10; + + _loop2(item); + } + events.onStart(queue.length); + + // start building actions + var actions = { + file: [], + symlink: [], + link: [] + }; + + // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items + // at a time due to the requirement to push items onto the queue + while (queue.length) { + var items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); + yield (_promise || _load_promise()).default.all(items.map(build)); + } + + // simulate the existence of some files to prevent considering them extraneous + for (var _iterator8 = artifactFiles, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator8);;) { + var _ref11; + + if (_isArray8) { + if (_i8 >= _iterator8.length) break; + _ref11 = _iterator8[_i8++]; + } else { + _i8 = _iterator8.next(); + if (_i8.done) break; + _ref11 = _i8.value; + } + + var _file5 = _ref11; + + if (possibleExtraneous.has(_file5)) { + reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', _file5)); + possibleExtraneous.delete(_file5); + } + } + + for (var _iterator9 = possibleExtraneous, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator9);;) { + var _ref12; + + if (_isArray9) { + if (_i9 >= _iterator9.length) break; + _ref12 = _iterator9[_i9++]; + } else { + _i9 = _iterator9.next(); + if (_i9.done) break; + _ref12 = _i9.value; + } + + var loc = _ref12; + + if (files.has(loc.toLowerCase())) { + possibleExtraneous.delete(loc); + } + } + + return actions; + }); + + return function buildActionsForHardlink(_x6, _x7, _x8, _x9) { + return _ref9.apply(this, arguments); + }; +}(); + +var copyBulk = exports.copyBulk = function () { + var _ref17 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { + var events = { + onStart: _events && _events.onStart || noop, + onProgress: _events && _events.onProgress || noop, + possibleExtraneous: _events ? _events.possibleExtraneous : new (_set || _load_set()).default(), + ignoreBasenames: _events && _events.ignoreBasenames || [], + artifactFiles: _events && _events.artifactFiles || [] + }; + + var actions = yield buildActionsForCopy(queue, events, events.possibleExtraneous, reporter); + events.onStart(actions.file.length + actions.symlink.length + actions.link.length); + + var fileActions = actions.file; + + var currentlyWriting = new (_map || _load_map()).default(); + + yield (_promise2 || _load_promise2()).queue(fileActions, function () { + var _ref18 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + var writePromise = void 0; + while (writePromise = currentlyWriting.get(data.dest)) { + yield writePromise; + } + + reporter.verbose(reporter.lang('verboseFileCopy', data.src, data.dest)); + var copier = (0, (_fsNormalized || _load_fsNormalized()).copyFile)(data, function () { + return currentlyWriting.delete(data.dest); + }); + currentlyWriting.set(data.dest, copier); + events.onProgress(data.dest); + return copier; + }); + + return function (_x14) { + return _ref18.apply(this, arguments); + }; + }(), CONCURRENT_QUEUE_ITEMS); + + // we need to copy symlinks last as they could reference files we were copying + var symlinkActions = actions.symlink; + yield (_promise2 || _load_promise2()).queue(symlinkActions, function (data) { + var linkname = (_path2 || _load_path()).default.resolve((_path2 || _load_path()).default.dirname(data.dest), data.linkname); + reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); + return symlink(linkname, data.dest); + }); + }); + + return function copyBulk(_x11, _x12, _x13) { + return _ref17.apply(this, arguments); + }; +}(); + +var hardlinkBulk = exports.hardlinkBulk = function () { + var _ref19 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { + var events = { + onStart: _events && _events.onStart || noop, + onProgress: _events && _events.onProgress || noop, + possibleExtraneous: _events ? _events.possibleExtraneous : new (_set || _load_set()).default(), + artifactFiles: _events && _events.artifactFiles || [], + ignoreBasenames: [] + }; + + var actions = yield buildActionsForHardlink(queue, events, events.possibleExtraneous, reporter); + events.onStart(actions.file.length + actions.symlink.length + actions.link.length); + + var fileActions = actions.link; + + yield (_promise2 || _load_promise2()).queue(fileActions, function () { + var _ref20 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + reporter.verbose(reporter.lang('verboseFileLink', data.src, data.dest)); + if (data.removeDest) { + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(data.dest); + } + yield link(data.src, data.dest); + }); + + return function (_x18) { + return _ref20.apply(this, arguments); + }; + }(), CONCURRENT_QUEUE_ITEMS); + + // we need to copy symlinks last as they could reference files we were copying + var symlinkActions = actions.symlink; + yield (_promise2 || _load_promise2()).queue(symlinkActions, function (data) { + var linkname = (_path2 || _load_path()).default.resolve((_path2 || _load_path()).default.dirname(data.dest), data.linkname); + reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); + return symlink(linkname, data.dest); + }); + }); + + return function hardlinkBulk(_x15, _x16, _x17) { + return _ref19.apply(this, arguments); + }; +}(); + +var readFileAny = exports.readFileAny = function () { + var _ref21 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (files) { + for (var _iterator13 = files, _isArray13 = Array.isArray(_iterator13), _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator13);;) { + var _ref22; + + if (_isArray13) { + if (_i13 >= _iterator13.length) break; + _ref22 = _iterator13[_i13++]; + } else { + _i13 = _iterator13.next(); + if (_i13.done) break; + _ref22 = _i13.value; + } + + var _file9 = _ref22; + + if (yield exists(_file9)) { + return readFile(_file9); + } + } + return null; + }); + + return function readFileAny(_x19) { + return _ref21.apply(this, arguments); + }; +}(); + +var readJson = exports.readJson = function () { + var _ref23 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { + return (yield readJsonAndFile(loc)).object; + }); + + return function readJson(_x20) { + return _ref23.apply(this, arguments); + }; +}(); + +var readJsonAndFile = exports.readJsonAndFile = function () { + var _ref24 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { + var file = yield readFile(loc); + try { + return { + object: (0, (_map2 || _load_map2()).default)(JSON.parse(stripBOM(file))), + content: file + }; + } catch (err) { + err.message = `${loc}: ${err.message}`; + throw err; + } + }); + + return function readJsonAndFile(_x21) { + return _ref24.apply(this, arguments); + }; +}(); + +var find = exports.find = function () { + var _ref25 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (filename, dir) { + var parts = dir.split((_path2 || _load_path()).default.sep); + + while (parts.length) { + var loc = parts.concat(filename).join((_path2 || _load_path()).default.sep); + + if (yield exists(loc)) { + return loc; + } else { + parts.pop(); + } + } + + return false; + }); + + return function find(_x22, _x23) { + return _ref25.apply(this, arguments); + }; +}(); + +var symlink = exports.symlink = function () { + var _ref26 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (src, dest) { + if (process.platform !== 'win32') { + // use relative paths otherwise which will be retained if the directory is moved + src = (_path2 || _load_path()).default.relative((_path2 || _load_path()).default.dirname(dest), src); + // When path.relative returns an empty string for the current directory, we should instead use + // '.', which is a valid fs.symlink target. + src = src || '.'; + } + + try { + var stats = yield lstat(dest); + if (stats.isSymbolicLink()) { + var resolved = dest; + if (resolved === src) { + return; + } + } + } catch (err) { + if (err.code !== 'ENOENT') { + throw err; + } + } + + // We use rimraf for unlink which never throws an ENOENT on missing target + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); + + if (process.platform === 'win32') { + // use directory junctions if possible on win32, this requires absolute paths + yield fsSymlink(src, dest, 'junction'); + } else { + yield fsSymlink(src, dest); + } + }); + + return function symlink(_x24, _x25) { + return _ref26.apply(this, arguments); + }; +}(); + +var walk = exports.walk = function () { + var _ref27 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir, relativeDir) { + var ignoreBasenames = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new (_set || _load_set()).default(); + + var files = []; + + var filenames = yield readdir(dir); + if (ignoreBasenames.size) { + filenames = filenames.filter(function (name) { + return !ignoreBasenames.has(name); + }); + } + + for (var _iterator14 = filenames, _isArray14 = Array.isArray(_iterator14), _i14 = 0, _iterator14 = _isArray14 ? _iterator14 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator14);;) { + var _ref28; + + if (_isArray14) { + if (_i14 >= _iterator14.length) break; + _ref28 = _iterator14[_i14++]; + } else { + _i14 = _iterator14.next(); + if (_i14.done) break; + _ref28 = _i14.value; + } + + var name = _ref28; + + var _relative = relativeDir ? (_path2 || _load_path()).default.join(relativeDir, name) : name; + var loc = (_path2 || _load_path()).default.join(dir, name); + var _stat = yield lstat(loc); + + files.push({ + relative: _relative, + basename: name, + absolute: loc, + mtime: +_stat.mtime + }); + + if (_stat.isDirectory()) { + files = files.concat((yield walk(loc, _relative, ignoreBasenames))); + } + } + + return files; + }); + + return function walk(_x26, _x27) { + return _ref27.apply(this, arguments); + }; +}(); + +var getFileSizeOnDisk = exports.getFileSizeOnDisk = function () { + var _ref29 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { + var stat = yield lstat(loc); + var size = stat.size, + blockSize = stat.blksize; + + + return Math.ceil(size / blockSize) * blockSize; + }); + + return function getFileSizeOnDisk(_x29) { + return _ref29.apply(this, arguments); + }; +}(); + +var getEolFromFile = function () { + var _ref30 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path) { + if (!(yield exists(path))) { + return undefined; + } + + var buffer = yield readFileBuffer(path); + + for (var i = 0; i < buffer.length; ++i) { + if (buffer[i] === cr) { + return '\r\n'; + } + if (buffer[i] === lf) { + return '\n'; + } + } + return undefined; + }); + + return function getEolFromFile(_x30) { + return _ref30.apply(this, arguments); + }; +}(); + +var writeFilePreservingEol = exports.writeFilePreservingEol = function () { + var _ref31 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path, data) { + var eol = (yield getEolFromFile(path)) || (_os || _load_os()).default.EOL; + if (eol !== '\n') { + data = data.replace(/\n/g, eol); + } + yield writeFile(path, data); + }); + + return function writeFilePreservingEol(_x31, _x32) { + return _ref31.apply(this, arguments); + }; +}(); + +var hardlinksWork = exports.hardlinksWork = function () { + var _ref32 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir) { + var filename = 'test-file' + Math.random(); + var file = (_path2 || _load_path()).default.join(dir, filename); + var fileLink = (_path2 || _load_path()).default.join(dir, filename + '-link'); + try { + yield writeFile(file, 'test'); + yield link(file, fileLink); + } catch (err) { + return false; + } finally { + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(file); + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(fileLink); + } + return true; + }); + + return function hardlinksWork(_x33) { + return _ref32.apply(this, arguments); + }; +}(); + +// not a strict polyfill for Node's fs.mkdtemp + + +var makeTempDir = exports.makeTempDir = function () { + var _ref33 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (prefix) { + var dir = (_path2 || _load_path()).default.join((_os || _load_os()).default.tmpdir(), `yarn-${prefix || ''}-${Date.now()}-${Math.random()}`); + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dir); + yield mkdirp(dir); + return dir; + }); + + return function makeTempDir(_x34) { + return _ref33.apply(this, arguments); + }; +}(); + +var readFirstAvailableStream = exports.readFirstAvailableStream = function () { + var _ref34 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths) { + for (var _iterator15 = paths, _isArray15 = Array.isArray(_iterator15), _i15 = 0, _iterator15 = _isArray15 ? _iterator15 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator15);;) { + var _ref35; + + if (_isArray15) { + if (_i15 >= _iterator15.length) break; + _ref35 = _iterator15[_i15++]; + } else { + _i15 = _iterator15.next(); + if (_i15.done) break; + _ref35 = _i15.value; + } + + var _path = _ref35; + + try { + var fd = yield open(_path, 'r'); + return (_fs || _load_fs()).default.createReadStream(_path, { fd }); + } catch (err) { + // Try the next one + } + } + return null; + }); + + return function readFirstAvailableStream(_x35) { + return _ref34.apply(this, arguments); + }; +}(); + +var getFirstSuitableFolder = exports.getFirstSuitableFolder = function () { + var _ref36 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths) { + var mode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : constants.W_OK | constants.X_OK; + + var result = { + skipped: [], + folder: null + }; + + for (var _iterator16 = paths, _isArray16 = Array.isArray(_iterator16), _i16 = 0, _iterator16 = _isArray16 ? _iterator16 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator16);;) { + var _ref37; + + if (_isArray16) { + if (_i16 >= _iterator16.length) break; + _ref37 = _iterator16[_i16++]; + } else { + _i16 = _iterator16.next(); + if (_i16.done) break; + _ref37 = _i16.value; + } + + var _folder = _ref37; + + try { + yield mkdirp(_folder); + yield access(_folder, mode); + + result.folder = _folder; + + return result; + } catch (error) { + result.skipped.push({ + error, + folder: _folder + }); + } + } + return result; + }); + + return function getFirstSuitableFolder(_x36) { + return _ref36.apply(this, arguments); + }; +}(); + +exports.copy = copy; +exports.readFile = readFile; +exports.readFileRaw = readFileRaw; +exports.normalizeOS = normalizeOS; + +var _fs; + +function _load_fs() { + return _fs = _interopRequireDefault(__webpack_require__(12)); +} + +var _glob; + +function _load_glob() { + return _glob = _interopRequireDefault(__webpack_require__(234)); +} + +var _os; + +function _load_os() { + return _os = _interopRequireDefault(__webpack_require__(66)); +} + +var _path2; + +function _load_path() { + return _path2 = _interopRequireDefault(__webpack_require__(1)); +} + +var _blockingQueue; + +function _load_blockingQueue() { + return _blockingQueue = _interopRequireDefault(__webpack_require__(157)); +} + +var _promise2; + +function _load_promise2() { + return _promise2 = _interopRequireWildcard(__webpack_require__(86)); +} + +var _promise3; + +function _load_promise3() { + return _promise3 = __webpack_require__(86); +} + +var _map2; + +function _load_map2() { + return _map2 = _interopRequireDefault(__webpack_require__(51)); +} + +var _fsNormalized; + +function _load_fsNormalized() { + return _fsNormalized = __webpack_require__(535); +} + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var constants = exports.constants = typeof (_fs || _load_fs()).default.constants !== 'undefined' ? (_fs || _load_fs()).default.constants : { + R_OK: (_fs || _load_fs()).default.R_OK, + W_OK: (_fs || _load_fs()).default.W_OK, + X_OK: (_fs || _load_fs()).default.X_OK +}; + +var lockQueue = exports.lockQueue = new (_blockingQueue || _load_blockingQueue()).default('fs lock'); + +var readFileBuffer = exports.readFileBuffer = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.readFile); +var open = exports.open = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.open); +var writeFile = exports.writeFile = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.writeFile); +var readlink = exports.readlink = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.readlink); +var realpath = exports.realpath = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.realpath); +var readdir = exports.readdir = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.readdir); +var rename = exports.rename = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.rename); +var access = exports.access = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.access); +var stat = exports.stat = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.stat); +var mkdirp = exports.mkdirp = (0, (_promise3 || _load_promise3()).promisify)(__webpack_require__(241)); +var exists = exports.exists = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.exists, true); +var lstat = exports.lstat = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.lstat); +var chmod = exports.chmod = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.chmod); +var link = exports.link = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.link); +var glob = exports.glob = (0, (_promise3 || _load_promise3()).promisify)((_glob || _load_glob()).default); +exports.unlink = (_fsNormalized || _load_fsNormalized()).unlink; + +// fs.copyFile uses the native file copying instructions on the system, performing much better +// than any JS-based solution and consumes fewer resources. Repeated testing to fine tune the +// concurrency level revealed 128 as the sweet spot on a quad-core, 16 CPU Intel system with SSD. + +var CONCURRENT_QUEUE_ITEMS = (_fs || _load_fs()).default.copyFile ? 128 : 4; + +var fsSymlink = (0, (_promise3 || _load_promise3()).promisify)((_fs || _load_fs()).default.symlink); +var invariant = __webpack_require__(15); +var stripBOM = __webpack_require__(429); + +var noop = function noop() {}; + +function copy(src, dest, reporter) { + return copyBulk([{ src, dest }], reporter); +} + +function _readFile(loc, encoding) { + return new (_promise || _load_promise()).default(function (resolve, reject) { + (_fs || _load_fs()).default.readFile(loc, encoding, function (err, content) { + if (err) { + reject(err); + } else { + resolve(content); + } + }); + }); +} + +function readFile(loc) { + return _readFile(loc, 'utf8').then(normalizeOS); +} + +function readFileRaw(loc) { + return _readFile(loc, 'binary'); +} + +function normalizeOS(body) { + return body.replace(/\r\n/g, '\n'); +} + +var cr = '\r'.charCodeAt(0); +var lf = '\n'.charCodeAt(0); + +/***/ }), +/* 9 */ +/***/ (function(module, exports) { + +module.exports = require("util"); + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _setPrototypeOf = __webpack_require__(211); + +var _setPrototypeOf2 = _interopRequireDefault(_setPrototypeOf); + +var _create = __webpack_require__(210); + +var _create2 = _interopRequireDefault(_create); + +var _typeof2 = __webpack_require__(316); + +var _typeof3 = _interopRequireDefault(_typeof2); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = function (subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === "undefined" ? "undefined" : (0, _typeof3.default)(superClass))); + } + + subClass.prototype = (0, _create2.default)(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) _setPrototypeOf2.default ? (0, _setPrototypeOf2.default)(subClass, superClass) : subClass.__proto__ = superClass; +}; + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _typeof2 = __webpack_require__(316); + +var _typeof3 = _interopRequireDefault(_typeof2); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = function (self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && ((typeof call === "undefined" ? "undefined" : (0, _typeof3.default)(call)) === "object" || typeof call === "function") ? call : self; +}; + +/***/ }), +/* 12 */ +/***/ (function(module, exports) { + +module.exports = require("fs"); + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getPathKey = getPathKey; +var os = __webpack_require__(66); +var path = __webpack_require__(1); +var userHome = __webpack_require__(101).default; + +var _require = __webpack_require__(549), + getCacheDir = _require.getCacheDir, + getConfigDir = _require.getConfigDir, + getDataDir = _require.getDataDir; + +var isWebpackBundle = __webpack_require__(792); + +var DEPENDENCY_TYPES = exports.DEPENDENCY_TYPES = ['devDependencies', 'dependencies', 'optionalDependencies', 'peerDependencies']; +var OWNED_DEPENDENCY_TYPES = exports.OWNED_DEPENDENCY_TYPES = ['devDependencies', 'dependencies', 'optionalDependencies']; + +var RESOLUTIONS = exports.RESOLUTIONS = 'resolutions'; +var MANIFEST_FIELDS = exports.MANIFEST_FIELDS = [RESOLUTIONS].concat(DEPENDENCY_TYPES); + +var SUPPORTED_NODE_VERSIONS = exports.SUPPORTED_NODE_VERSIONS = '^4.8.0 || ^5.7.0 || ^6.2.2 || >=8.0.0'; + +var YARN_REGISTRY = exports.YARN_REGISTRY = 'https://registry.yarnpkg.com'; +var NPM_REGISTRY_RE = exports.NPM_REGISTRY_RE = /https?:\/\/registry\.npmjs\.org/g; + +var YARN_DOCS = exports.YARN_DOCS = 'https://yarnpkg.com/en/docs/cli/'; +var YARN_INSTALLER_SH = exports.YARN_INSTALLER_SH = 'https://yarnpkg.com/install.sh'; +var YARN_INSTALLER_MSI = exports.YARN_INSTALLER_MSI = 'https://yarnpkg.com/latest.msi'; + +var SELF_UPDATE_VERSION_URL = exports.SELF_UPDATE_VERSION_URL = 'https://yarnpkg.com/latest-version'; + +// cache version, bump whenever we make backwards incompatible changes +var CACHE_VERSION = exports.CACHE_VERSION = 6; + +// lockfile version, bump whenever we make backwards incompatible changes +var LOCKFILE_VERSION = exports.LOCKFILE_VERSION = 1; + +// max amount of network requests to perform concurrently +var NETWORK_CONCURRENCY = exports.NETWORK_CONCURRENCY = 8; + +// HTTP timeout used when downloading packages +var NETWORK_TIMEOUT = exports.NETWORK_TIMEOUT = 30 * 1000; // in milliseconds + +// max amount of child processes to execute concurrently +var CHILD_CONCURRENCY = exports.CHILD_CONCURRENCY = 5; + +var REQUIRED_PACKAGE_KEYS = exports.REQUIRED_PACKAGE_KEYS = ['name', 'version', '_uid']; + +function getPreferredCacheDirectories() { + var preferredCacheDirectories = [getCacheDir()]; + + if (process.getuid) { + // $FlowFixMe: process.getuid exists, dammit + preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache-${process.getuid()}`)); + } + + preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache`)); + + return preferredCacheDirectories; +} + +var PREFERRED_MODULE_CACHE_DIRECTORIES = exports.PREFERRED_MODULE_CACHE_DIRECTORIES = getPreferredCacheDirectories(); +var CONFIG_DIRECTORY = exports.CONFIG_DIRECTORY = getConfigDir(); +var DATA_DIRECTORY = exports.DATA_DIRECTORY = getDataDir(); +var LINK_REGISTRY_DIRECTORY = exports.LINK_REGISTRY_DIRECTORY = path.join(DATA_DIRECTORY, 'link'); +var GLOBAL_MODULE_DIRECTORY = exports.GLOBAL_MODULE_DIRECTORY = path.join(DATA_DIRECTORY, 'global'); + +var NODE_BIN_PATH = exports.NODE_BIN_PATH = process.execPath; +var YARN_BIN_PATH = exports.YARN_BIN_PATH = getYarnBinPath(); + +// Webpack needs to be configured with node.__dirname/__filename = false +function getYarnBinPath() { + if (isWebpackBundle) { + return __filename; + } else { + return path.join(__dirname, '..', 'bin', 'yarn.js'); + } +} + +var NODE_MODULES_FOLDER = exports.NODE_MODULES_FOLDER = 'node_modules'; +var NODE_PACKAGE_JSON = exports.NODE_PACKAGE_JSON = 'package.json'; + +var PNP_FILENAME = exports.PNP_FILENAME = '.pnp.js'; + +var POSIX_GLOBAL_PREFIX = exports.POSIX_GLOBAL_PREFIX = `${process.env.DESTDIR || ''}/usr/local`; +var FALLBACK_GLOBAL_PREFIX = exports.FALLBACK_GLOBAL_PREFIX = path.join(userHome, '.yarn'); + +var META_FOLDER = exports.META_FOLDER = '.yarn-meta'; +var INTEGRITY_FILENAME = exports.INTEGRITY_FILENAME = '.yarn-integrity'; +var LOCKFILE_FILENAME = exports.LOCKFILE_FILENAME = 'yarn.lock'; +var METADATA_FILENAME = exports.METADATA_FILENAME = '.yarn-metadata.json'; +var TARBALL_FILENAME = exports.TARBALL_FILENAME = '.yarn-tarball.tgz'; +var CLEAN_FILENAME = exports.CLEAN_FILENAME = '.yarnclean'; + +var NPM_LOCK_FILENAME = exports.NPM_LOCK_FILENAME = 'package-lock.json'; +var NPM_SHRINKWRAP_FILENAME = exports.NPM_SHRINKWRAP_FILENAME = 'npm-shrinkwrap.json'; + +var DEFAULT_INDENT = exports.DEFAULT_INDENT = ' '; +var SINGLE_INSTANCE_PORT = exports.SINGLE_INSTANCE_PORT = 31997; +var SINGLE_INSTANCE_FILENAME = exports.SINGLE_INSTANCE_FILENAME = '.yarn-single-instance'; + +var ENV_PATH_KEY = exports.ENV_PATH_KEY = getPathKey(process.platform, process.env); + +function getPathKey(platform, env) { + var pathKey = 'PATH'; + + // windows calls its path "Path" usually, but this is not guaranteed. + if (platform === 'win32') { + pathKey = 'Path'; + + for (var _key in env) { + if (_key.toLowerCase() === 'path') { + pathKey = _key; + } + } + } + + return pathKey; +} + +var VERSION_COLOR_SCHEME = exports.VERSION_COLOR_SCHEME = { + major: 'red', + premajor: 'red', + minor: 'yellow', + preminor: 'yellow', + patch: 'green', + prepatch: 'green', + prerelease: 'red', + unchanged: 'white', + unknown: 'red' +}; + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(597), __esModule: true }; + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + + +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + +var NODE_ENV = process.env.NODE_ENV; + +var invariant = function(condition, format, a, b, c, d, e, f) { + if (NODE_ENV !== 'production') { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + } + + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + error.name = 'Invariant Violation'; + } + + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } +}; + +module.exports = invariant; + + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(602), __esModule: true }; + +/***/ }), +/* 17 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Observable; }); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_canReportError__ = __webpack_require__(263); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_toSubscriber__ = __webpack_require__(1005); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__internal_symbol_observable__ = __webpack_require__(112); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_pipe__ = __webpack_require__(265); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__config__ = __webpack_require__(176); +/** PURE_IMPORTS_START _util_canReportError,_util_toSubscriber,_internal_symbol_observable,_util_pipe,_config PURE_IMPORTS_END */ + + + + + +var Observable = /*@__PURE__*/ (function () { + function Observable(subscribe) { + this._isScalar = false; + if (subscribe) { + this._subscribe = subscribe; + } + } + Observable.prototype.lift = function (operator) { + var observable = new Observable(); + observable.source = this; + observable.operator = operator; + return observable; + }; + Observable.prototype.subscribe = function (observerOrNext, error, complete) { + var operator = this.operator; + var sink = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__util_toSubscriber__["a" /* toSubscriber */])(observerOrNext, error, complete); + if (operator) { + operator.call(sink, this.source); + } + else { + sink.add(this.source || (__WEBPACK_IMPORTED_MODULE_4__config__["a" /* config */].useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ? + this._subscribe(sink) : + this._trySubscribe(sink)); + } + if (__WEBPACK_IMPORTED_MODULE_4__config__["a" /* config */].useDeprecatedSynchronousErrorHandling) { + if (sink.syncErrorThrowable) { + sink.syncErrorThrowable = false; + if (sink.syncErrorThrown) { + throw sink.syncErrorValue; + } + } + } + return sink; + }; + Observable.prototype._trySubscribe = function (sink) { + try { + return this._subscribe(sink); + } + catch (err) { + if (__WEBPACK_IMPORTED_MODULE_4__config__["a" /* config */].useDeprecatedSynchronousErrorHandling) { + sink.syncErrorThrown = true; + sink.syncErrorValue = err; + } + if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__util_canReportError__["a" /* canReportError */])(sink)) { + sink.error(err); + } + else { + console.warn(err); + } + } + }; + Observable.prototype.forEach = function (next, promiseCtor) { + var _this = this; + promiseCtor = getPromiseCtor(promiseCtor); + return new promiseCtor(function (resolve, reject) { + var subscription; + subscription = _this.subscribe(function (value) { + try { + next(value); + } + catch (err) { + reject(err); + if (subscription) { + subscription.unsubscribe(); + } + } + }, reject, resolve); + }); + }; + Observable.prototype._subscribe = function (subscriber) { + var source = this.source; + return source && source.subscribe(subscriber); + }; + Observable.prototype[__WEBPACK_IMPORTED_MODULE_2__internal_symbol_observable__["a" /* observable */]] = function () { + return this; + }; + Observable.prototype.pipe = function () { + var operations = []; + for (var _i = 0; _i < arguments.length; _i++) { + operations[_i] = arguments[_i]; + } + if (operations.length === 0) { + return this; + } + return __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__util_pipe__["b" /* pipeFromArray */])(operations)(this); + }; + Observable.prototype.toPromise = function (promiseCtor) { + var _this = this; + promiseCtor = getPromiseCtor(promiseCtor); + return new promiseCtor(function (resolve, reject) { + var value; + _this.subscribe(function (x) { return value = x; }, function (err) { return reject(err); }, function () { return resolve(value); }); + }); + }; + Observable.create = function (subscribe) { + return new Observable(subscribe); + }; + return Observable; +}()); + +function getPromiseCtor(promiseCtor) { + if (!promiseCtor) { + promiseCtor = __WEBPACK_IMPORTED_MODULE_4__config__["a" /* config */].Promise || Promise; + } + if (!promiseCtor) { + throw new Error('no Promise impl found'); + } + return promiseCtor; +} +//# sourceMappingURL=Observable.js.map + + +/***/ }), +/* 18 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return OuterSubscriber; }); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_tslib__ = __webpack_require__(0); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Subscriber__ = __webpack_require__(5); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +var OuterSubscriber = /*@__PURE__*/ (function (_super) { + __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](OuterSubscriber, _super); + function OuterSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + OuterSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.destination.next(innerValue); + }; + OuterSubscriber.prototype.notifyError = function (error, innerSub) { + this.destination.error(error); + }; + OuterSubscriber.prototype.notifyComplete = function (innerSub) { + this.destination.complete(); + }; + return OuterSubscriber; +}(__WEBPACK_IMPORTED_MODULE_1__Subscriber__["a" /* Subscriber */])); + +//# sourceMappingURL=OuterSubscriber.js.map + + +/***/ }), +/* 19 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export (immutable) */ __webpack_exports__["a"] = subscribeToResult; +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__InnerSubscriber__ = __webpack_require__(80); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__subscribeTo__ = __webpack_require__(416); +/** PURE_IMPORTS_START _InnerSubscriber,_subscribeTo PURE_IMPORTS_END */ + + +function subscribeToResult(outerSubscriber, result, outerValue, outerIndex, destination) { + if (destination === void 0) { + destination = new __WEBPACK_IMPORTED_MODULE_0__InnerSubscriber__["a" /* InnerSubscriber */](outerSubscriber, outerValue, outerIndex); + } + if (destination.closed) { + return; + } + return __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__subscribeTo__["a" /* subscribeTo */])(result)(destination); +} +//# sourceMappingURL=subscribeToResult.js.map + + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/* eslint-disable node/no-deprecated-api */ + + + +var buffer = __webpack_require__(94) +var Buffer = buffer.Buffer + +var safer = {} + +var key + +for (key in buffer) { + if (!buffer.hasOwnProperty(key)) continue + if (key === 'SlowBuffer' || key === 'Buffer') continue + safer[key] = buffer[key] +} + +var Safer = safer.Buffer = {} +for (key in Buffer) { + if (!Buffer.hasOwnProperty(key)) continue + if (key === 'allocUnsafe' || key === 'allocUnsafeSlow') continue + Safer[key] = Buffer[key] +} + +safer.Buffer.prototype = Buffer.prototype + +if (!Safer.from || Safer.from === Uint8Array.from) { + Safer.from = function (value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('The "value" argument must not be of type number. Received type ' + typeof value) + } + if (value && typeof value.length === 'undefined') { + throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type ' + typeof value) + } + return Buffer(value, encodingOrOffset, length) + } +} + +if (!Safer.alloc) { + Safer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('The "size" argument must be of type number. Received type ' + typeof size) + } + if (size < 0 || size >= 2 * (1 << 30)) { + throw new RangeError('The value "' + size + '" is invalid for option "size"') + } + var buf = Buffer(size) + if (!fill || fill.length === 0) { + buf.fill(0) + } else if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + return buf + } +} + +if (!safer.kStringMaxLength) { + try { + safer.kStringMaxLength = process.binding('buffer').kStringMaxLength + } catch (e) { + // we can't determine kStringMaxLength in environments where process.binding + // is unsupported, so let's not set it + } +} + +if (!safer.constants) { + safer.constants = { + MAX_LENGTH: safer.kMaxLength + } + if (safer.kStringMaxLength) { + safer.constants.MAX_STRING_LENGTH = safer.kStringMaxLength + } +} + +module.exports = safer + + +/***/ }), +/* 21 */ +/***/ (function(module, exports) { + +module.exports = require("crypto"); + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { + +// Copyright (c) 2012, Mark Cavage. All rights reserved. +// Copyright 2015 Joyent, Inc. + +var assert = __webpack_require__(50); +var Stream = __webpack_require__(36).Stream; +var util = __webpack_require__(9); + + +///--- Globals + +/* JSSTYLED */ +var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; + + +///--- Internal + +function _capitalize(str) { + return (str.charAt(0).toUpperCase() + str.slice(1)); +} + +function _toss(name, expected, oper, arg, actual) { + throw new assert.AssertionError({ + message: util.format('%s (%s) is required', name, expected), + actual: (actual === undefined) ? typeof (arg) : actual(arg), + expected: expected, + operator: oper || '===', + stackStartFunction: _toss.caller + }); +} + +function _getClass(arg) { + return (Object.prototype.toString.call(arg).slice(8, -1)); +} + +function noop() { + // Why even bother with asserts? +} + + +///--- Exports + +var types = { + bool: { + check: function (arg) { return typeof (arg) === 'boolean'; } + }, + func: { + check: function (arg) { return typeof (arg) === 'function'; } + }, + string: { + check: function (arg) { return typeof (arg) === 'string'; } + }, + object: { + check: function (arg) { + return typeof (arg) === 'object' && arg !== null; + } + }, + number: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg); + } + }, + finite: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); + } + }, + buffer: { + check: function (arg) { return Buffer.isBuffer(arg); }, + operator: 'Buffer.isBuffer' + }, + array: { + check: function (arg) { return Array.isArray(arg); }, + operator: 'Array.isArray' + }, + stream: { + check: function (arg) { return arg instanceof Stream; }, + operator: 'instanceof', + actual: _getClass + }, + date: { + check: function (arg) { return arg instanceof Date; }, + operator: 'instanceof', + actual: _getClass + }, + regexp: { + check: function (arg) { return arg instanceof RegExp; }, + operator: 'instanceof', + actual: _getClass + }, + uuid: { + check: function (arg) { + return typeof (arg) === 'string' && UUID_REGEXP.test(arg); + }, + operator: 'isUUID' + } +}; + +function _setExports(ndebug) { + var keys = Object.keys(types); + var out; + + /* re-export standard assert */ + if (process.env.NODE_NDEBUG) { + out = noop; + } else { + out = function (arg, msg) { + if (!arg) { + _toss(msg, 'true', arg); + } + }; + } + + /* standard checks */ + keys.forEach(function (k) { + if (ndebug) { + out[k] = noop; + return; + } + var type = types[k]; + out[k] = function (arg, msg) { + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* optional checks */ + keys.forEach(function (k) { + var name = 'optional' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* arrayOf checks */ + keys.forEach(function (k) { + var name = 'arrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* optionalArrayOf checks */ + keys.forEach(function (k) { + var name = 'optionalArrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* re-export built-in assertions */ + Object.keys(assert).forEach(function (k) { + if (k === 'AssertionError') { + out[k] = assert[k]; + return; + } + if (ndebug) { + out[k] = noop; + return; + } + out[k] = assert[k]; + }); + + /* export ourselves (for unit tests _only_) */ + out._setExports = _setExports; + + return out; +} + +module.exports = _setExports(process.env.NODE_NDEBUG); + + +/***/ }), +/* 23 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(594), __esModule: true }; + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +exports.__esModule = true; + +var _assign = __webpack_require__(23); + +var _assign2 = _interopRequireDefault(_assign); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = _assign2.default || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; +}; + +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.stringify = exports.parse = undefined; + +var _getIterator2; + +function _load_getIterator() { + return _getIterator2 = _interopRequireDefault(__webpack_require__(4)); +} + +var _map; + +function _load_map() { + return _map = _interopRequireDefault(__webpack_require__(42)); +} + +var _asyncToGenerator2; + +function _load_asyncToGenerator() { + return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(2)); +} + +var _classCallCheck2; + +function _load_classCallCheck() { + return _classCallCheck2 = _interopRequireDefault(__webpack_require__(3)); +} + +var _keys; + +function _load_keys() { + return _keys = _interopRequireDefault(__webpack_require__(14)); +} + +var _parse; + +function _load_parse() { + return _parse = __webpack_require__(301); +} + +Object.defineProperty(exports, 'parse', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_parse || _load_parse()).default; + } +}); + +var _stringify; + +function _load_stringify() { + return _stringify = __webpack_require__(510); +} + +Object.defineProperty(exports, 'stringify', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_stringify || _load_stringify()).default; + } +}); +exports.implodeEntry = implodeEntry; +exports.explodeEntry = explodeEntry; + +var _misc; + +function _load_misc() { + return _misc = __webpack_require__(28); +} + +var _normalizePattern; + +function _load_normalizePattern() { + return _normalizePattern = __webpack_require__(52); +} + +var _parse2; + +function _load_parse2() { + return _parse2 = _interopRequireDefault(__webpack_require__(301)); +} + +var _constants; + +function _load_constants() { + return _constants = __webpack_require__(13); +} + +var _fs; + +function _load_fs() { + return _fs = _interopRequireWildcard(__webpack_require__(8)); +} + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var invariant = __webpack_require__(15); + +var path = __webpack_require__(1); +var ssri = __webpack_require__(93); + +function getName(pattern) { + return (0, (_normalizePattern || _load_normalizePattern()).normalizePattern)(pattern).name; +} + +function blankObjectUndefined(obj) { + return obj && (0, (_keys || _load_keys()).default)(obj).length ? obj : undefined; +} + +function keyForRemote(remote) { + return remote.resolved || (remote.reference && remote.hash ? `${remote.reference}#${remote.hash}` : null); +} + +function serializeIntegrity(integrity) { + // We need this because `Integrity.toString()` does not use sorting to ensure a stable string output + // See https://git.io/vx2Hy + return integrity.toString().split(' ').sort().join(' '); +} + +function implodeEntry(pattern, obj) { + var inferredName = getName(pattern); + var integrity = obj.integrity ? serializeIntegrity(obj.integrity) : ''; + var imploded = { + name: inferredName === obj.name ? undefined : obj.name, + version: obj.version, + uid: obj.uid === obj.version ? undefined : obj.uid, + resolved: obj.resolved, + registry: obj.registry === 'npm' ? undefined : obj.registry, + dependencies: blankObjectUndefined(obj.dependencies), + optionalDependencies: blankObjectUndefined(obj.optionalDependencies), + permissions: blankObjectUndefined(obj.permissions), + prebuiltVariants: blankObjectUndefined(obj.prebuiltVariants) + }; + if (integrity) { + imploded.integrity = integrity; + } + return imploded; +} + +function explodeEntry(pattern, obj) { + obj.optionalDependencies = obj.optionalDependencies || {}; + obj.dependencies = obj.dependencies || {}; + obj.uid = obj.uid || obj.version; + obj.permissions = obj.permissions || {}; + obj.registry = obj.registry || 'npm'; + obj.name = obj.name || getName(pattern); + var integrity = obj.integrity; + if (integrity && integrity.isIntegrity) { + obj.integrity = ssri.parse(integrity); + } + return obj; +} + +var Lockfile = function () { + function Lockfile() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + cache = _ref.cache, + source = _ref.source, + parseResultType = _ref.parseResultType; + + (0, (_classCallCheck2 || _load_classCallCheck()).default)(this, Lockfile); + + this.source = source || ''; + this.cache = cache; + this.parseResultType = parseResultType; + } + + // source string if the `cache` was parsed + + + // if true, we're parsing an old yarn file and need to update integrity fields + Lockfile.prototype.hasEntriesExistWithoutIntegrity = function hasEntriesExistWithoutIntegrity() { + if (!this.cache) { + return false; + } + + for (var _key in this.cache) { + // $FlowFixMe - `this.cache` is clearly defined at this point + if (!/^.*@(file:|http)/.test(_key) && this.cache[_key] && !this.cache[_key].integrity) { + return true; + } + } + + return false; + }; + + Lockfile.fromDirectory = function () { + var _ref2 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir, reporter) { + // read the manifest in this directory + var lockfileLoc = path.join(dir, (_constants || _load_constants()).LOCKFILE_FILENAME); + + var lockfile = void 0; + var rawLockfile = ''; + var parseResult = void 0; + + if (yield (_fs || _load_fs()).exists(lockfileLoc)) { + rawLockfile = yield (_fs || _load_fs()).readFile(lockfileLoc); + parseResult = (0, (_parse2 || _load_parse2()).default)(rawLockfile, lockfileLoc); + + if (reporter) { + if (parseResult.type === 'merge') { + reporter.info(reporter.lang('lockfileMerged')); + } else if (parseResult.type === 'conflict') { + reporter.warn(reporter.lang('lockfileConflict')); + } + } + + lockfile = parseResult.object; + } else if (reporter) { + reporter.info(reporter.lang('noLockfileFound')); + } + + if (lockfile && lockfile.__metadata) { + var lockfilev2 = lockfile; + lockfile = {}; + } + + return new Lockfile({ cache: lockfile, source: rawLockfile, parseResultType: parseResult && parseResult.type }); + }); + + function fromDirectory(_x2, _x3) { + return _ref2.apply(this, arguments); + } + + return fromDirectory; + }(); + + Lockfile.prototype.getLocked = function getLocked(pattern) { + var cache = this.cache; + if (!cache) { + return undefined; + } + + var shrunk = pattern in cache && cache[pattern]; + + if (typeof shrunk === 'string') { + return this.getLocked(shrunk); + } else if (shrunk) { + explodeEntry(pattern, shrunk); + return shrunk; + } + + return undefined; + }; + + Lockfile.prototype.removePattern = function removePattern(pattern) { + var cache = this.cache; + if (!cache) { + return; + } + delete cache[pattern]; + }; + + Lockfile.prototype.getLockfile = function getLockfile(patterns) { + var lockfile = {}; + var seen = new (_map || _load_map()).default(); + + // order by name so that lockfile manifest is assigned to the first dependency with this manifest + // the others that have the same remoteKey will just refer to the first + // ordering allows for consistency in lockfile when it is serialized + var sortedPatternsKeys = (0, (_keys || _load_keys()).default)(patterns).sort((_misc || _load_misc()).sortAlpha); + + for (var _iterator = sortedPatternsKeys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : (0, (_getIterator2 || _load_getIterator()).default)(_iterator);;) { + var _ref3; + + if (_isArray) { + if (_i >= _iterator.length) break; + _ref3 = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref3 = _i.value; + } + + var pattern = _ref3; + + var pkg = patterns[pattern]; + var remote = pkg._remote, + ref = pkg._reference; + + invariant(ref, 'Package is missing a reference'); + invariant(remote, 'Package is missing a remote'); + + var remoteKey = keyForRemote(remote); + var pkgName = getName(pattern); + + var seenKey = remoteKey ? `${remoteKey}#${pkgName}` : null; + var seenPattern = seenKey ? seen.get(seenKey) : null; + + if (seenPattern) { + // no point in duplicating it + lockfile[pattern] = seenPattern; + continue; + } + + var obj = implodeEntry(pattern, { + name: pkgName, + version: pkg.version, + uid: pkg._uid, + resolved: remote.resolved, + integrity: remote.integrity, + registry: remote.registry, + dependencies: pkg.dependencies, + peerDependencies: pkg.peerDependencies, + optionalDependencies: pkg.optionalDependencies, + permissions: ref.permissions, + prebuiltVariants: pkg.prebuiltVariants + }); + + lockfile[pattern] = obj; + + if (seenKey) { + seen.set(seenKey, obj); + } + } + + return lockfile; + }; + + return Lockfile; +}(); + +exports.default = Lockfile; + +/***/ }), +/* 26 */ +/***/ (function(module, exports) { + +var core = module.exports = { version: '2.5.7' }; +if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef + + +/***/ }), +/* 27 */ +/***/ (function(module, exports) { + +exports = module.exports = SemVer; + +// The debug function is excluded entirely from the minified version. +/* nomin */ var debug; +/* nomin */ if (typeof process === 'object' && + /* nomin */ process.env && + /* nomin */ process.env.NODE_DEBUG && + /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG)) + /* nomin */ debug = function() { + /* nomin */ var args = Array.prototype.slice.call(arguments, 0); + /* nomin */ args.unshift('SEMVER'); + /* nomin */ console.log.apply(console, args); + /* nomin */ }; +/* nomin */ else + /* nomin */ debug = function() {}; + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0'; + +var MAX_LENGTH = 256; +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; + +// Max safe segment length for coercion. +var MAX_SAFE_COMPONENT_LENGTH = 16; + +// The actual regexps go on exports.re +var re = exports.re = []; +var src = exports.src = []; +var R = 0; + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +var NUMERICIDENTIFIER = R++; +src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'; +var NUMERICIDENTIFIERLOOSE = R++; +src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'; + + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +var NONNUMERICIDENTIFIER = R++; +src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'; + + +// ## Main Version +// Three dot-separated numeric identifiers. + +var MAINVERSION = R++; +src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')'; + +var MAINVERSIONLOOSE = R++; +src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')'; + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. + +var PRERELEASEIDENTIFIER = R++; +src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + +var PRERELEASEIDENTIFIERLOOSE = R++; +src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +var PRERELEASE = R++; +src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'; + +var PRERELEASELOOSE = R++; +src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'; + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +var BUILDIDENTIFIER = R++; +src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'; + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +var BUILD = R++; +src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))'; + + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +var FULL = R++; +var FULLPLAIN = 'v?' + src[MAINVERSION] + + src[PRERELEASE] + '?' + + src[BUILD] + '?'; + +src[FULL] = '^' + FULLPLAIN + '$'; + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + + src[PRERELEASELOOSE] + '?' + + src[BUILD] + '?'; + +var LOOSE = R++; +src[LOOSE] = '^' + LOOSEPLAIN + '$'; + +var GTLT = R++; +src[GTLT] = '((?:<|>)?=?)'; + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +var XRANGEIDENTIFIERLOOSE = R++; +src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'; +var XRANGEIDENTIFIER = R++; +src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'; + +var XRANGEPLAIN = R++; +src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:' + src[PRERELEASE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + +var XRANGEPLAINLOOSE = R++; +src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[PRERELEASELOOSE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + +var XRANGE = R++; +src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'; +var XRANGELOOSE = R++; +src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'; + +// Coercion. +// Extract anything that could conceivably be a part of a valid semver +var COERCE = R++; +src[COERCE] = '(?:^|[^\\d])' + + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:$|[^\\d])'; + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +var LONETILDE = R++; +src[LONETILDE] = '(?:~>?)'; + +var TILDETRIM = R++; +src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; +re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); +var tildeTrimReplace = '$1~'; + +var TILDE = R++; +src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; +var TILDELOOSE = R++; +src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +var LONECARET = R++; +src[LONECARET] = '(?:\\^)'; + +var CARETTRIM = R++; +src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; +re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); +var caretTrimReplace = '$1^'; + +var CARET = R++; +src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; +var CARETLOOSE = R++; +src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +var COMPARATORLOOSE = R++; +src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'; +var COMPARATOR = R++; +src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'; + + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +var COMPARATORTRIM = R++; +src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'; + +// this one has to use the /g flag +re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g'); +var comparatorTrimReplace = '$1$2$3'; + + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +var HYPHENRANGE = R++; +src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAIN] + ')' + + '\\s*$'; + +var HYPHENRANGELOOSE = R++; +src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s*$'; + +// Star ranges basically just allow anything at all. +var STAR = R++; +src[STAR] = '(<|>)?=?\\s*\\*'; + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]); + if (!re[i]) + re[i] = new RegExp(src[i]); +} + +exports.parse = parse; +function parse(version, loose) { + if (version instanceof SemVer) + return version; + + if (typeof version !== 'string') + return null; + + if (version.length > MAX_LENGTH) + return null; + + var r = loose ? re[LOOSE] : re[FULL]; + if (!r.test(version)) + return null; + + try { + return new SemVer(version, loose); + } catch (er) { + return null; + } +} + +exports.valid = valid; +function valid(version, loose) { + var v = parse(version, loose); + return v ? v.version : null; +} + + +exports.clean = clean; +function clean(version, loose) { + var s = parse(version.trim().replace(/^[=v]+/, ''), loose); + return s ? s.version : null; +} + +exports.SemVer = SemVer; + +function SemVer(version, loose) { + if (version instanceof SemVer) { + if (version.loose === loose) + return version; + else + version = version.version; + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version); + } + + if (version.length > MAX_LENGTH) + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') + + if (!(this instanceof SemVer)) + return new SemVer(version, loose); + + debug('SemVer', version, loose); + this.loose = loose; + var m = version.trim().match(loose ? re[LOOSE] : re[FULL]); + + if (!m) + throw new TypeError('Invalid Version: ' + version); + + this.raw = version; + + // these are actually numbers + this.major = +m[1]; + this.minor = +m[2]; + this.patch = +m[3]; + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) + throw new TypeError('Invalid major version') + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) + throw new TypeError('Invalid minor version') + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) + throw new TypeError('Invalid patch version') + + // numberify any prerelease numeric ids + if (!m[4]) + this.prerelease = []; + else + this.prerelease = m[4].split('.').map(function(id) { + if (/^[0-9]+$/.test(id)) { + var num = +id; + if (num >= 0 && num < MAX_SAFE_INTEGER) + return num; + } + return id; + }); + + this.build = m[5] ? m[5].split('.') : []; + this.format(); +} + +SemVer.prototype.format = function() { + this.version = this.major + '.' + this.minor + '.' + this.patch; + if (this.prerelease.length) + this.version += '-' + this.prerelease.join('.'); + return this.version; +}; + +SemVer.prototype.toString = function() { + return this.version; +}; + +SemVer.prototype.compare = function(other) { + debug('SemVer.compare', this.version, this.loose, other); + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + return this.compareMain(other) || this.comparePre(other); +}; + +SemVer.prototype.compareMain = function(other) { + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch); +}; + +SemVer.prototype.comparePre = function(other) { + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) + return -1; + else if (!this.prerelease.length && other.prerelease.length) + return 1; + else if (!this.prerelease.length && !other.prerelease.length) + return 0; + + var i = 0; + do { + var a = this.prerelease[i]; + var b = other.prerelease[i]; + debug('prerelease compare', i, a, b); + if (a === undefined && b === undefined) + return 0; + else if (b === undefined) + return 1; + else if (a === undefined) + return -1; + else if (a === b) + continue; + else + return compareIdentifiers(a, b); + } while (++i); +}; + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function(release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0; + this.patch = 0; + this.minor = 0; + this.major++; + this.inc('pre', identifier); + break; + case 'preminor': + this.prerelease.length = 0; + this.patch = 0; + this.minor++; + this.inc('pre', identifier); + break; + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0; + this.inc('patch', identifier); + this.inc('pre', identifier); + break; + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) + this.inc('patch', identifier); + this.inc('pre', identifier); + break; + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) + this.major++; + this.minor = 0; + this.patch = 0; + this.prerelease = []; + break; + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) + this.minor++; + this.patch = 0; + this.prerelease = []; + break; + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) + this.patch++; + this.prerelease = []; + break; + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) + this.prerelease = [0]; + else { + var i = this.prerelease.length; + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++; + i = -2; + } + } + if (i === -1) // didn't increment anything + this.prerelease.push(0); + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) + this.prerelease = [identifier, 0]; + } else + this.prerelease = [identifier, 0]; + } + break; + + default: + throw new Error('invalid increment argument: ' + release); + } + this.format(); + this.raw = this.version; + return this; +}; + +exports.inc = inc; +function inc(version, release, loose, identifier) { + if (typeof(loose) === 'string') { + identifier = loose; + loose = undefined; + } + + try { + return new SemVer(version, loose).inc(release, identifier).version; + } catch (er) { + return null; + } +} + +exports.diff = diff; +function diff(version1, version2) { + if (eq(version1, version2)) { + return null; + } else { + var v1 = parse(version1); + var v2 = parse(version2); + if (v1.prerelease.length || v2.prerelease.length) { + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return 'pre'+key; + } + } + } + return 'prerelease'; + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return key; + } + } + } + } +} + +exports.compareIdentifiers = compareIdentifiers; + +var numeric = /^[0-9]+$/; +function compareIdentifiers(a, b) { + var anum = numeric.test(a); + var bnum = numeric.test(b); + + if (anum && bnum) { + a = +a; + b = +b; + } + + return (anum && !bnum) ? -1 : + (bnum && !anum) ? 1 : + a < b ? -1 : + a > b ? 1 : + 0; +} + +exports.rcompareIdentifiers = rcompareIdentifiers; +function rcompareIdentifiers(a, b) { + return compareIdentifiers(b, a); +} + +exports.major = major; +function major(a, loose) { + return new SemVer(a, loose).major; +} + +exports.minor = minor; +function minor(a, loose) { + return new SemVer(a, loose).minor; +} + +exports.patch = patch; +function patch(a, loose) { + return new SemVer(a, loose).patch; +} + +exports.compare = compare; +function compare(a, b, loose) { + return new SemVer(a, loose).compare(new SemVer(b, loose)); +} + +exports.compareLoose = compareLoose; +function compareLoose(a, b) { + return compare(a, b, true); +} + +exports.rcompare = rcompare; +function rcompare(a, b, loose) { + return compare(b, a, loose); +} + +exports.sort = sort; +function sort(list, loose) { + return list.sort(function(a, b) { + return exports.compare(a, b, loose); + }); +} + +exports.rsort = rsort; +function rsort(list, loose) { + return list.sort(function(a, b) { + return exports.rcompare(a, b, loose); + }); +} + +exports.gt = gt; +function gt(a, b, loose) { + return compare(a, b, loose) > 0; +} + +exports.lt = lt; +function lt(a, b, loose) { + return compare(a, b, loose) < 0; +} + +exports.eq = eq; +function eq(a, b, loose) { + return compare(a, b, loose) === 0; +} + +exports.neq = neq; +function neq(a, b, loose) { + return compare(a, b, loose) !== 0; +} + +exports.gte = gte; +function gte(a, b, loose) { + return compare(a, b, loose) >= 0; +} + +exports.lte = lte; +function lte(a, b, loose) { + return compare(a, b, loose) <= 0; +} + +exports.cmp = cmp; +function cmp(a, op, b, loose) { + var ret; + switch (op) { + case '===': + if (typeof a === 'object') a = a.version; + if (typeof b === 'object') b = b.version; + ret = a === b; + break; + case '!==': + if (typeof a === 'object') a = a.version; + if (typeof b === 'object') b = b.version; + ret = a !== b; + break; + case '': case '=': case '==': ret = eq(a, b, loose); break; + case '!=': ret = neq(a, b, loose); break; + case '>': ret = gt(a, b, loose); break; + case '>=': ret = gte(a, b, loose); break; + case '<': ret = lt(a, b, loose); break; + case '<=': ret = lte(a, b, loose); break; + default: throw new TypeError('Invalid operator: ' + op); + } + return ret; +} + +exports.Comparator = Comparator; +function Comparator(comp, loose) { + if (comp instanceof Comparator) { + if (comp.loose === loose) + return comp; + else + comp = comp.value; + } + + if (!(this instanceof Comparator)) + return new Comparator(comp, loose); + + debug('comparator', comp, loose); + this.loose = loose; + this.parse(comp); + + if (this.semver === ANY) + this.value = ''; + else + this.value = this.operator + this.semver.version; + + debug('comp', this); +} + +var ANY = {}; +Comparator.prototype.parse = function(comp) { + var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var m = comp.match(r); + + if (!m) + throw new TypeError('Invalid comparator: ' + comp); + + this.operator = m[1]; + if (this.operator === '=') + this.operator = ''; + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) + this.semver = ANY; + else + this.semver = new SemVer(m[2], this.loose); +}; + +Comparator.prototype.toString = function() { + return this.value; +}; + +Comparator.prototype.test = function(version) { + debug('Comparator.test', version, this.loose); + + if (this.semver === ANY) + return true; + + if (typeof version === 'string') + version = new SemVer(version, this.loose); + + return cmp(version, this.operator, this.semver, this.loose); +}; + +Comparator.prototype.intersects = function(comp, loose) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required'); + } + + var rangeTmp; + + if (this.operator === '') { + rangeTmp = new Range(comp.value, loose); + return satisfies(this.value, rangeTmp, loose); + } else if (comp.operator === '') { + rangeTmp = new Range(this.value, loose); + return satisfies(comp.semver, rangeTmp, loose); + } + + var sameDirectionIncreasing = + (this.operator === '>=' || this.operator === '>') && + (comp.operator === '>=' || comp.operator === '>'); + var sameDirectionDecreasing = + (this.operator === '<=' || this.operator === '<') && + (comp.operator === '<=' || comp.operator === '<'); + var sameSemVer = this.semver.version === comp.semver.version; + var differentDirectionsInclusive = + (this.operator === '>=' || this.operator === '<=') && + (comp.operator === '>=' || comp.operator === '<='); + var oppositeDirectionsLessThan = + cmp(this.semver, '<', comp.semver, loose) && + ((this.operator === '>=' || this.operator === '>') && + (comp.operator === '<=' || comp.operator === '<')); + var oppositeDirectionsGreaterThan = + cmp(this.semver, '>', comp.semver, loose) && + ((this.operator === '<=' || this.operator === '<') && + (comp.operator === '>=' || comp.operator === '>')); + + return sameDirectionIncreasing || sameDirectionDecreasing || + (sameSemVer && differentDirectionsInclusive) || + oppositeDirectionsLessThan || oppositeDirectionsGreaterThan; +}; + + +exports.Range = Range; +function Range(range, loose) { + if (range instanceof Range) { + if (range.loose === loose) { + return range; + } else { + return new Range(range.raw, loose); + } + } + + if (range instanceof Comparator) { + return new Range(range.value, loose); + } + + if (!(this instanceof Range)) + return new Range(range, loose); + + this.loose = loose; + + // First, split based on boolean or || + this.raw = range; + this.set = range.split(/\s*\|\|\s*/).map(function(range) { + return this.parseRange(range.trim()); + }, this).filter(function(c) { + // throw out any that are not relevant for whatever reason + return c.length; + }); + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range); + } + + this.format(); +} + +Range.prototype.format = function() { + this.range = this.set.map(function(comps) { + return comps.join(' ').trim(); + }).join('||').trim(); + return this.range; +}; + +Range.prototype.toString = function() { + return this.range; +}; + +Range.prototype.parseRange = function(range) { + var loose = this.loose; + range = range.trim(); + debug('range', range, loose); + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]; + range = range.replace(hr, hyphenReplace); + debug('hyphen replace', range); + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace); + debug('comparator trim', range, re[COMPARATORTRIM]); + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[TILDETRIM], tildeTrimReplace); + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace); + + // normalize spaces + range = range.split(/\s+/).join(' '); + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var set = range.split(' ').map(function(comp) { + return parseComparator(comp, loose); + }).join(' ').split(/\s+/); + if (this.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function(comp) { + return !!comp.match(compRe); + }); + } + set = set.map(function(comp) { + return new Comparator(comp, loose); + }); + + return set; +}; + +Range.prototype.intersects = function(range, loose) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required'); + } + + return this.set.some(function(thisComparators) { + return thisComparators.every(function(thisComparator) { + return range.set.some(function(rangeComparators) { + return rangeComparators.every(function(rangeComparator) { + return thisComparator.intersects(rangeComparator, loose); + }); + }); + }); + }); +}; + +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators; +function toComparators(range, loose) { + return new Range(range, loose).set.map(function(comp) { + return comp.map(function(c) { + return c.value; + }).join(' ').trim().split(' '); + }); +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator(comp, loose) { + debug('comp', comp); + comp = replaceCarets(comp, loose); + debug('caret', comp); + comp = replaceTildes(comp, loose); + debug('tildes', comp); + comp = replaceXRanges(comp, loose); + debug('xrange', comp); + comp = replaceStars(comp, loose); + debug('stars', comp); + return comp; +} + +function isX(id) { + return !id || id.toLowerCase() === 'x' || id === '*'; +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceTilde(comp, loose); + }).join(' '); +} + +function replaceTilde(comp, loose) { + var r = loose ? re[TILDELOOSE] : re[TILDE]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + ret = ''; + else if (isX(m)) + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + else if (isX(p)) + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + else if (pr) { + debug('replaceTilde pr', pr); + if (pr.charAt(0) !== '-') + pr = '-' + pr; + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; + + debug('tilde return', ret); + return ret; + }); +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceCaret(comp, loose); + }).join(' '); +} + +function replaceCaret(comp, loose) { + debug('caret', comp, loose); + var r = loose ? re[CARETLOOSE] : re[CARET]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + ret = ''; + else if (isX(m)) + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + else if (isX(p)) { + if (M === '0') + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + else + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; + } else if (pr) { + debug('replaceCaret pr', pr); + if (pr.charAt(0) !== '-') + pr = '-' + pr; + if (M === '0') { + if (m === '0') + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + m + '.' + (+p + 1); + else + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + (+M + 1) + '.0.0'; + } else { + debug('no pr'); + if (M === '0') { + if (m === '0') + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1); + else + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0'; + } + + debug('caret return', ret); + return ret; + }); +} + +function replaceXRanges(comp, loose) { + debug('replaceXRanges', comp, loose); + return comp.split(/\s+/).map(function(comp) { + return replaceXRange(comp, loose); + }).join(' '); +} + +function replaceXRange(comp, loose) { + comp = comp.trim(); + var r = loose ? re[XRANGELOOSE] : re[XRANGE]; + return comp.replace(r, function(ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr); + var xM = isX(M); + var xm = xM || isX(m); + var xp = xm || isX(p); + var anyX = xp; + + if (gtlt === '=' && anyX) + gtlt = ''; + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0'; + } else { + // nothing is forbidden + ret = '*'; + } + } else if (gtlt && anyX) { + // replace X with 0 + if (xm) + m = 0; + if (xp) + p = 0; + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>='; + if (xm) { + M = +M + 1; + m = 0; + p = 0; + } else if (xp) { + m = +m + 1; + p = 0; + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<'; + if (xm) + M = +M + 1; + else + m = +m + 1; + } + + ret = gtlt + M + '.' + m + '.' + p; + } else if (xm) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + } else if (xp) { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + } + + debug('xRange return', ret); + + return ret; + }); +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars(comp, loose) { + debug('replaceStars', comp, loose); + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[STAR], ''); +} + +// This function is passed to string.replace(re[HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + + if (isX(fM)) + from = ''; + else if (isX(fm)) + from = '>=' + fM + '.0.0'; + else if (isX(fp)) + from = '>=' + fM + '.' + fm + '.0'; + else + from = '>=' + from; + + if (isX(tM)) + to = ''; + else if (isX(tm)) + to = '<' + (+tM + 1) + '.0.0'; + else if (isX(tp)) + to = '<' + tM + '.' + (+tm + 1) + '.0'; + else if (tpr) + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; + else + to = '<=' + to; + + return (from + ' ' + to).trim(); +} + + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function(version) { + if (!version) + return false; + + if (typeof version === 'string') + version = new SemVer(version, this.loose); + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version)) + return true; + } + return false; +}; + +function testSet(set, version) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) + return false; + } + + if (version.prerelease.length) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (var i = 0; i < set.length; i++) { + debug(set[i].semver); + if (set[i].semver === ANY) + continue; + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver; + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) + return true; + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false; + } + + return true; +} + +exports.satisfies = satisfies; +function satisfies(version, range, loose) { + try { + range = new Range(range, loose); + } catch (er) { + return false; + } + return range.test(version); +} + +exports.maxSatisfying = maxSatisfying; +function maxSatisfying(versions, range, loose) { + var max = null; + var maxSV = null; + try { + var rangeObj = new Range(range, loose); + } catch (er) { + return null; + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { // satisfies(v, range, loose) + if (!max || maxSV.compare(v) === -1) { // compare(max, v, true) + max = v; + maxSV = new SemVer(max, loose); + } + } + }) + return max; +} + +exports.minSatisfying = minSatisfying; +function minSatisfying(versions, range, loose) { + var min = null; + var minSV = null; + try { + var rangeObj = new Range(range, loose); + } catch (er) { + return null; + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { // satisfies(v, range, loose) + if (!min || minSV.compare(v) === 1) { // compare(min, v, true) + min = v; + minSV = new SemVer(min, loose); + } + } + }) + return min; +} + +exports.validRange = validRange; +function validRange(range, loose) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, loose).range || '*'; + } catch (er) { + return null; + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr; +function ltr(version, range, loose) { + return outside(version, range, '<', loose); +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr; +function gtr(version, range, loose) { + return outside(version, range, '>', loose); +} + +exports.outside = outside; +function outside(version, range, hilo, loose) { + version = new SemVer(version, loose); + range = new Range(range, loose); + + var gtfn, ltefn, ltfn, comp, ecomp; + switch (hilo) { + case '>': + gtfn = gt; + ltefn = lte; + ltfn = lt; + comp = '>'; + ecomp = '>='; + break; + case '<': + gtfn = lt; + ltefn = gte; + ltfn = gt; + comp = '<'; + ecomp = '<='; + break; + default: + throw new TypeError('Must provide a hilo val of "<" or ">"'); + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, loose)) { + return false; + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i]; + + var high = null; + var low = null; + + comparators.forEach(function(comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator; + low = low || comparator; + if (gtfn(comparator.semver, high.semver, loose)) { + high = comparator; + } else if (ltfn(comparator.semver, low.semver, loose)) { + low = comparator; + } + }); + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false; + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false; + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false; + } + } + return true; +} + +exports.prerelease = prerelease; +function prerelease(version, loose) { + var parsed = parse(version, loose); + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null; +} + +exports.intersects = intersects; +function intersects(r1, r2, loose) { + r1 = new Range(r1, loose) + r2 = new Range(r2, loose) + return r1.intersects(r2) +} + +exports.coerce = coerce; +function coerce(version) { + if (version instanceof SemVer) + return version; + + if (typeof version !== 'string') + return null; + + var match = version.match(re[COERCE]); + + if (match == null) + return null; + + return parse((match[1] || '0') + '.' + (match[2] || '0') + '.' + (match[3] || '0')); +} + + +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _promise; + +function _load_promise() { + return _promise = _interopRequireDefault(__webpack_require__(7)); +} + +exports.sortAlpha = sortAlpha; +exports.sortOptionsByFlags = sortOptionsByFlags; +exports.entries = entries; +exports.removePrefix = removePrefix; +exports.removeSuffix = removeSuffix; +exports.addSuffix = addSuffix; +exports.hyphenate = hyphenate; +exports.camelCase = camelCase; +exports.compareSortedArrays = compareSortedArrays; +exports.sleep = sleep; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _camelCase = __webpack_require__(562); + +function sortAlpha(a, b) { + // sort alphabetically in a deterministic way + var shortLen = Math.min(a.length, b.length); + for (var i = 0; i < shortLen; i++) { + var aChar = a.charCodeAt(i); + var bChar = b.charCodeAt(i); + if (aChar !== bChar) { + return aChar - bChar; + } + } + return a.length - b.length; +} + +function sortOptionsByFlags(a, b) { + var aOpt = a.flags.replace(/-/g, ''); + var bOpt = b.flags.replace(/-/g, ''); + return sortAlpha(aOpt, bOpt); +} + +function entries(obj) { + var entries = []; + if (obj) { + for (var _key in obj) { + entries.push([_key, obj[_key]]); + } + } + return entries; +} + +function removePrefix(pattern, prefix) { + if (pattern.startsWith(prefix)) { + pattern = pattern.slice(prefix.length); + } + + return pattern; +} + +function removeSuffix(pattern, suffix) { + if (pattern.endsWith(suffix)) { + return pattern.slice(0, -suffix.length); + } + + return pattern; +} + +function addSuffix(pattern, suffix) { + if (!pattern.endsWith(suffix)) { + return pattern + suffix; + } + + return pattern; +} + +function hyphenate(str) { + return str.replace(/[A-Z]/g, function (match) { + return '-' + match.charAt(0).toLowerCase(); + }); +} + +function camelCase(str) { + if (/[A-Z]/.test(str)) { + return null; + } else { + return _camelCase(str); + } +} + +function compareSortedArrays(array1, array2) { + if (array1.length !== array2.length) { + return false; + } + for (var i = 0, len = array1.length; i < len; i++) { + if (array1[i] !== array2[i]) { + return false; + } + } + return true; +} + +function sleep(ms) { + return new (_promise || _load_promise()).default(function (resolve) { + setTimeout(resolve, ms); + }); +} + +/***/ }), +/* 29 */ +/***/ (function(module, exports) { + +module.exports = require("url"); + +/***/ }), +/* 30 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var YAMLException = __webpack_require__(132); + +var TYPE_CONSTRUCTOR_OPTIONS = [ + 'kind', + 'resolve', + 'construct', + 'instanceOf', + 'predicate', + 'represent', + 'defaultStyle', + 'styleAliases' +]; + +var YAML_NODE_KINDS = [ + 'scalar', + 'sequence', + 'mapping' +]; + +function compileStyleAliases(map) { + var result = {}; + + if (map !== null) { + Object.keys(map).forEach(function (style) { + map[style].forEach(function (alias) { + result[String(alias)] = style; + }); + }); + } + + return result; +} + +function Type(tag, options) { + options = options || {}; + + Object.keys(options).forEach(function (name) { + if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { + throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); + } + }); + + // TODO: Add tag format check. + this.tag = tag; + this.kind = options['kind'] || null; + this.resolve = options['resolve'] || function () { return true; }; + this.construct = options['construct'] || function (data) { return data; }; + this.instanceOf = options['instanceOf'] || null; + this.predicate = options['predicate'] || null; + this.represent = options['represent'] || null; + this.defaultStyle = options['defaultStyle'] || null; + this.styleAliases = compileStyleAliases(options['styleAliases'] || null); + + if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { + throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); + } +} + +module.exports = Type; + + +/***/ }), +/* 31 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Subscription; }); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_isArray__ = __webpack_require__(48); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__util_isObject__ = __webpack_require__(414); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_isFunction__ = __webpack_require__(143); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_tryCatch__ = __webpack_require__(59); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_errorObject__ = __webpack_require__(55); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__util_UnsubscriptionError__ = __webpack_require__(411); +/** PURE_IMPORTS_START _util_isArray,_util_isObject,_util_isFunction,_util_tryCatch,_util_errorObject,_util_UnsubscriptionError PURE_IMPORTS_END */ + + + + + + +var Subscription = /*@__PURE__*/ (function () { + function Subscription(unsubscribe) { + this.closed = false; + this._parent = null; + this._parents = null; + this._subscriptions = null; + if (unsubscribe) { + this._unsubscribe = unsubscribe; + } + } + Subscription.prototype.unsubscribe = function () { + var hasErrors = false; + var errors; + if (this.closed) { + return; + } + var _a = this, _parent = _a._parent, _parents = _a._parents, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions; + this.closed = true; + this._parent = null; + this._parents = null; + this._subscriptions = null; + var index = -1; + var len = _parents ? _parents.length : 0; + while (_parent) { + _parent.remove(this); + _parent = ++index < len && _parents[index] || null; + } + if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_2__util_isFunction__["a" /* isFunction */])(_unsubscribe)) { + var trial = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__util_tryCatch__["a" /* tryCatch */])(_unsubscribe).call(this); + if (trial === __WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */]) { + hasErrors = true; + errors = errors || (__WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */].e instanceof __WEBPACK_IMPORTED_MODULE_5__util_UnsubscriptionError__["a" /* UnsubscriptionError */] ? + flattenUnsubscriptionErrors(__WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */].e.errors) : [__WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */].e]); + } + } + if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0__util_isArray__["a" /* isArray */])(_subscriptions)) { + index = -1; + len = _subscriptions.length; + while (++index < len) { + var sub = _subscriptions[index]; + if (__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_1__util_isObject__["a" /* isObject */])(sub)) { + var trial = __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_3__util_tryCatch__["a" /* tryCatch */])(sub.unsubscribe).call(sub); + if (trial === __WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */]) { + hasErrors = true; + errors = errors || []; + var err = __WEBPACK_IMPORTED_MODULE_4__util_errorObject__["a" /* errorObject */].e; + if (err instanceof __WEBPACK_IMPORTED_MODULE_5__util_UnsubscriptionError__["a" /* UnsubscriptionError */]) { + errors = errors.concat(flattenUnsubscriptionErrors(err.errors)); + } + else { + errors.push(err); + } + } + } + } + } + if (hasErrors) { + throw new __WEBPACK_IMPORTED_MODULE_5__util_UnsubscriptionError__["a" /* UnsubscriptionError */](errors); + } + }; + Subscription.prototype.add = function (teardown) { + if (!teardown || (teardown === Subscription.EMPTY)) { + return Subscription.EMPTY; + } + if (teardown === this) { + return this; + } + var subscription = teardown; + switch (typeof teardown) { + case 'function': + subscription = new Subscription(teardown); + case 'object': + if (subscription.closed || typeof subscription.unsubscribe !== 'function') { + return subscription; + } + else if (this.closed) { + subscription.unsubscribe(); + return subscription; + } + else if (typeof subscription._addParent !== 'function') { + var tmp = subscription; + subscription = new Subscription(); + subscription._subscriptions = [tmp]; + } + break; + default: + throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.'); + } + var subscriptions = this._subscriptions || (this._subscriptions = []); + subscriptions.push(subscription); + subscription._addParent(this); + return subscription; + }; + Subscription.prototype.remove = function (subscription) { + var subscriptions = this._subscriptions; + if (subscriptions) { + var subscriptionIndex = subscriptions.indexOf(subscription); + if (subscriptionIndex !== -1) { + subscriptions.splice(subscriptionIndex, 1); + } + } + }; + Subscription.prototype._addParent = function (parent) { + var _a = this, _parent = _a._parent, _parents = _a._parents; + if (!_parent || _parent === parent) { + this._parent = parent; + } + else if (!_parents) { + this._parents = [parent]; + } + else if (_parents.indexOf(parent) === -1) { + _parents.push(parent); + } + }; + Subscription.EMPTY = (function (empty) { + empty.closed = true; + return empty; + }(new Subscription())); + return Subscription; +}()); + +function flattenUnsubscriptionErrors(errors) { + return errors.reduce(function (errs, err) { return errs.concat((err instanceof __WEBPACK_IMPORTED_MODULE_5__util_UnsubscriptionError__["a" /* UnsubscriptionError */]) ? err.errors : err); }, []); +} +//# sourceMappingURL=Subscription.js.map + + +/***/ }), +/* 32 */ +/***/ (function(module, exports, __webpack_require__) { + +// Copyright 2015 Joyent, Inc. + +module.exports = { + bufferSplit: bufferSplit, + addRSAMissing: addRSAMissing, + calculateDSAPublic: calculateDSAPublic, + calculateED25519Public: calculateED25519Public, + calculateX25519Public: calculateX25519Public, + mpNormalize: mpNormalize, + mpDenormalize: mpDenormalize, + ecNormalize: ecNormalize, + countZeros: countZeros, + assertCompatible: assertCompatible, + isCompatible: isCompatible, + opensslKeyDeriv: opensslKeyDeriv, + opensshCipherInfo: opensshCipherInfo, + publicFromPrivateECDSA: publicFromPrivateECDSA, + zeroPadToLength: zeroPadToLength, + writeBitString: writeBitString, + readBitString: readBitString +}; + +var assert = __webpack_require__(22); +var Buffer = __webpack_require__(20).Buffer; +var PrivateKey = __webpack_require__(40); +var Key = __webpack_require__(35); +var crypto = __webpack_require__(21); +var algs = __webpack_require__(39); +var asn1 = __webpack_require__(67); + +var ec, jsbn; +var nacl; + +var MAX_CLASS_DEPTH = 3; + +function isCompatible(obj, klass, needVer) { + if (obj === null || typeof (obj) !== 'object') + return (false); + if (needVer === undefined) + needVer = klass.prototype._sshpkApiVersion; + if (obj instanceof klass && + klass.prototype._sshpkApiVersion[0] == needVer[0]) + return (true); + var proto = Object.getPrototypeOf(obj); + var depth = 0; + while (proto.constructor.name !== klass.name) { + proto = Object.getPrototypeOf(proto); + if (!proto || ++depth > MAX_CLASS_DEPTH) + return (false); + } + if (proto.constructor.name !== klass.name) + return (false); + var ver = proto._sshpkApiVersion; + if (ver === undefined) + ver = klass._oldVersionDetect(obj); + if (ver[0] != needVer[0] || ver[1] < needVer[1]) + return (false); + return (true); +} + +function assertCompatible(obj, klass, needVer, name) { + if (name === undefined) + name = 'object'; + assert.ok(obj, name + ' must not be null'); + assert.object(obj, name + ' must be an object'); + if (needVer === undefined) + needVer = klass.prototype._sshpkApiVersion; + if (obj instanceof klass && + klass.prototype._sshpkApiVersion[0] == needVer[0]) + return; + var proto = Object.getPrototypeOf(obj); + var depth = 0; + while (proto.constructor.name !== klass.name) { + proto = Object.getPrototypeOf(proto); + assert.ok(proto && ++depth <= MAX_CLASS_DEPTH, + name + ' must be a ' + klass.name + ' instance'); + } + assert.strictEqual(proto.constructor.name, klass.name, + name + ' must be a ' + klass.name + ' instance'); + var ver = proto._sshpkApiVersion; + if (ver === undefined) + ver = klass._oldVersionDetect(obj); + assert.ok(ver[0] == needVer[0] && ver[1] >= needVer[1], + name + ' must be compatible with ' + klass.name + ' klass ' + + 'version ' + needVer[0] + '.' + needVer[1]); +} + +var CIPHER_LEN = { + 'des-ede3-cbc': { key: 7, iv: 8 }, + 'aes-128-cbc': { key: 16, iv: 16 } +}; +var PKCS5_SALT_LEN = 8; + +function opensslKeyDeriv(cipher, salt, passphrase, count) { + assert.buffer(salt, 'salt'); + assert.buffer(passphrase, 'passphrase'); + assert.number(count, 'iteration count'); + + var clen = CIPHER_LEN[cipher]; + assert.object(clen, 'supported cipher'); + + salt = salt.slice(0, PKCS5_SALT_LEN); + + var D, D_prev, bufs; + var material = Buffer.alloc(0); + while (material.length < clen.key + clen.iv) { + bufs = []; + if (D_prev) + bufs.push(D_prev); + bufs.push(passphrase); + bufs.push(salt); + D = Buffer.concat(bufs); + for (var j = 0; j < count; ++j) + D = crypto.createHash('md5').update(D).digest(); + material = Buffer.concat([material, D]); + D_prev = D; + } + + return ({ + key: material.slice(0, clen.key), + iv: material.slice(clen.key, clen.key + clen.iv) + }); +} + +/* Count leading zero bits on a buffer */ +function countZeros(buf) { + var o = 0, obit = 8; + while (o < buf.length) { + var mask = (1 << obit); + if ((buf[o] & mask) === mask) + break; + obit--; + if (obit < 0) { + o++; + obit = 8; + } + } + return (o*8 + (8 - obit) - 1); +} + +function bufferSplit(buf, chr) { + assert.buffer(buf); + assert.string(chr); + + var parts = []; + var lastPart = 0; + var matches = 0; + for (var i = 0; i < buf.length; ++i) { + if (buf[i] === chr.charCodeAt(matches)) + ++matches; + else if (buf[i] === chr.charCodeAt(0)) + matches = 1; + else + matches = 0; + + if (matches >= chr.length) { + var newPart = i + 1; + parts.push(buf.slice(lastPart, newPart - matches)); + lastPart = newPart; + matches = 0; + } + } + if (lastPart <= buf.length) + parts.push(buf.slice(lastPart, buf.length)); + + return (parts); +} + +function ecNormalize(buf, addZero) { + assert.buffer(buf); + if (buf[0] === 0x00 && buf[1] === 0x04) { + if (addZero) + return (buf); + return (buf.slice(1)); + } else if (buf[0] === 0x04) { + if (!addZero) + return (buf); + } else { + while (buf[0] === 0x00) + buf = buf.slice(1); + if (buf[0] === 0x02 || buf[0] === 0x03) + throw (new Error('Compressed elliptic curve points ' + + 'are not supported')); + if (buf[0] !== 0x04) + throw (new Error('Not a valid elliptic curve point')); + if (!addZero) + return (buf); + } + var b = Buffer.alloc(buf.length + 1); + b[0] = 0x0; + buf.copy(b, 1); + return (b); +} + +function readBitString(der, tag) { + if (tag === undefined) + tag = asn1.Ber.BitString; + var buf = der.readString(tag, true); + assert.strictEqual(buf[0], 0x00, 'bit strings with unused bits are ' + + 'not supported (0x' + buf[0].toString(16) + ')'); + return (buf.slice(1)); +} + +function writeBitString(der, buf, tag) { + if (tag === undefined) + tag = asn1.Ber.BitString; + var b = Buffer.alloc(buf.length + 1); + b[0] = 0x00; + buf.copy(b, 1); + der.writeBuffer(b, tag); +} + +function mpNormalize(buf) { + assert.buffer(buf); + while (buf.length > 1 && buf[0] === 0x00 && (buf[1] & 0x80) === 0x00) + buf = buf.slice(1); + if ((buf[0] & 0x80) === 0x80) { + var b = Buffer.alloc(buf.length + 1); + b[0] = 0x00; + buf.copy(b, 1); + buf = b; + } + return (buf); +} + +function mpDenormalize(buf) { + assert.buffer(buf); + while (buf.length > 1 && buf[0] === 0x00) + buf = buf.slice(1); + return (buf); +} + +function zeroPadToLength(buf, len) { + assert.buffer(buf); + assert.number(len); + while (buf.length > len) { + assert.equal(buf[0], 0x00); + buf = buf.slice(1); + } + while (buf.length < len) { + var b = Buffer.alloc(buf.length + 1); + b[0] = 0x00; + buf.copy(b, 1); + buf = b; + } + return (buf); +} + +function bigintToMpBuf(bigint) { + var buf = Buffer.from(bigint.toByteArray()); + buf = mpNormalize(buf); + return (buf); +} + +function calculateDSAPublic(g, p, x) { + assert.buffer(g); + assert.buffer(p); + assert.buffer(x); + try { + var bigInt = __webpack_require__(79).BigInteger; + } catch (e) { + throw (new Error('To load a PKCS#8 format DSA private key, ' + + 'the node jsbn library is required.')); + } + g = new bigInt(g); + p = new bigInt(p); + x = new bigInt(x); + var y = g.modPow(x, p); + var ybuf = bigintToMpBuf(y); + return (ybuf); +} + +function calculateED25519Public(k) { + assert.buffer(k); + + if (nacl === undefined) + nacl = __webpack_require__(72); + + var kp = nacl.sign.keyPair.fromSeed(new Uint8Array(k)); + return (Buffer.from(kp.publicKey)); +} + +function calculateX25519Public(k) { + assert.buffer(k); + + if (nacl === undefined) + nacl = __webpack_require__(72); + + var kp = nacl.box.keyPair.fromSeed(new Uint8Array(k)); + return (Buffer.from(kp.publicKey)); +} + +function addRSAMissing(key) { + assert.object(key); + assertCompatible(key, PrivateKey, [1, 1]); + try { + var bigInt = __webpack_require__(79).BigInteger; + } catch (e) { + throw (new Error('To write a PEM private key from ' + + 'this source, the node jsbn lib is required.')); + } + + var d = new bigInt(key.part.d.data); + var buf; + + if (!key.part.dmodp) { + var p = new bigInt(key.part.p.data); + var dmodp = d.mod(p.subtract(1)); + + buf = bigintToMpBuf(dmodp); + key.part.dmodp = {name: 'dmodp', data: buf}; + key.parts.push(key.part.dmodp); + } + if (!key.part.dmodq) { + var q = new bigInt(key.part.q.data); + var dmodq = d.mod(q.subtract(1)); + + buf = bigintToMpBuf(dmodq); + key.part.dmodq = {name: 'dmodq', data: buf}; + key.parts.push(key.part.dmodq); + } +} + +function publicFromPrivateECDSA(curveName, priv) { + assert.string(curveName, 'curveName'); + assert.buffer(priv); + if (ec === undefined) + ec = __webpack_require__(130); + if (jsbn === undefined) + jsbn = __webpack_require__(79).BigInteger; + var params = algs.curves[curveName]; + var p = new jsbn(params.p); + var a = new jsbn(params.a); + var b = new jsbn(params.b); + var curve = new ec.ECCurveFp(p, a, b); + var G = curve.decodePointHex(params.G.toString('hex')); + + var d = new jsbn(mpNormalize(priv)); + var pub = G.multiply(d); + pub = Buffer.from(curve.encodePointHex(pub), 'hex'); + + var parts = []; + parts.push({name: 'curve', data: Buffer.from(curveName)}); + parts.push({name: 'Q', data: pub}); + + var key = new Key({type: 'ecdsa', curve: curve, parts: parts}); + return (key); +} + +function opensshCipherInfo(cipher) { + var inf = {}; + switch (cipher) { + case '3des-cbc': + inf.keySize = 24; + inf.blockSize = 8; + inf.opensslName = 'des-ede3-cbc'; + break; + case 'blowfish-cbc': + inf.keySize = 16; + inf.blockSize = 8; + inf.opensslName = 'bf-cbc'; + break; + case 'aes128-cbc': + case 'aes128-ctr': + case 'aes128-gcm@openssh.com': + inf.keySize = 16; + inf.blockSize = 16; + inf.opensslName = 'aes-128-' + cipher.slice(7, 10); + break; + case 'aes192-cbc': + case 'aes192-ctr': + case 'aes192-gcm@openssh.com': + inf.keySize = 24; + inf.blockSize = 16; + inf.opensslName = 'aes-192-' + cipher.slice(7, 10); + break; + case 'aes256-cbc': + case 'aes256-ctr': + case 'aes256-gcm@openssh.com': + inf.keySize = 32; + inf.blockSize = 16; + inf.opensslName = 'aes-256-' + cipher.slice(7, 10); + break; + default: + throw (new Error( + 'Unsupported openssl cipher "' + cipher + '"')); + } + return (inf); +} + + +/***/ }), +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const escapeStringRegexp = __webpack_require__(351); +const ansiStyles = __webpack_require__(447); +const stdoutColor = __webpack_require__(564).stdout; + +const template = __webpack_require__(565); + +const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); + +// `supportsColor.level` → `ansiStyles.color[name]` mapping +const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; + +// `color-convert` models to exclude from the Chalk API due to conflicts and such +const skipModels = new Set(['gray']); + +const styles = Object.create(null); + +function applyOptions(obj, options) { + options = options || {}; + + // Detect level if not set manually + const scLevel = stdoutColor ? stdoutColor.level : 0; + obj.level = options.level === undefined ? scLevel : options.level; + obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; +} + +function Chalk(options) { + // We check for this.template here since calling `chalk.constructor()` + // by itself will have a `this` of a previously constructed chalk object + if (!this || !(this instanceof Chalk) || this.template) { + const chalk = {}; + applyOptions(chalk, options); + + chalk.template = function () { + const args = [].slice.call(arguments); + return chalkTag.apply(null, [chalk.template].concat(args)); + }; + + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); + + chalk.template.constructor = Chalk; + + return chalk.template; + } + + applyOptions(this, options); +} + +// Use bright blue on Windows as the normal blue color is illegible +if (isSimpleWindowsTerm) { + ansiStyles.blue.open = '\u001B[94m'; +} + +for (const key of Object.keys(ansiStyles)) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + + styles[key] = { + get() { + const codes = ansiStyles[key]; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + } + }; +} + +styles.visible = { + get() { + return build.call(this, this._styles || [], true, 'visible'); + } +}; + +ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); +for (const model of Object.keys(ansiStyles.color.ansi)) { + if (skipModels.has(model)) { + continue; + } + + styles[model] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.color.close, + closeRe: ansiStyles.color.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; +} + +ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); +for (const model of Object.keys(ansiStyles.bgColor.ansi)) { + if (skipModels.has(model)) { + continue; + } + + const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); + styles[bgModel] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.bgColor.close, + closeRe: ansiStyles.bgColor.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; +} + +const proto = Object.defineProperties(() => {}, styles); + +function build(_styles, _empty, key) { + const builder = function () { + return applyStyle.apply(builder, arguments); + }; + + builder._styles = _styles; + builder._empty = _empty; + + const self = this; + + Object.defineProperty(builder, 'level', { + enumerable: true, + get() { + return self.level; + }, + set(level) { + self.level = level; + } + }); + + Object.defineProperty(builder, 'enabled', { + enumerable: true, + get() { + return self.enabled; + }, + set(enabled) { + self.enabled = enabled; + } + }); + + // See below for fix regarding invisible grey/dim combination on Windows + builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; + + // `__proto__` is used because we must return a function, but there is + // no way to create a function with a different prototype + builder.__proto__ = proto; // eslint-disable-line no-proto + + return builder; +} + +function applyStyle() { + // Support varags, but simply cast to string in case there's only one arg + const args = arguments; + const argsLen = args.length; + let str = String(arguments[0]); + + if (argsLen === 0) { + return ''; + } + + if (argsLen > 1) { + // Don't slice `arguments`, it prevents V8 optimizations + for (let a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } + + if (!this.enabled || this.level <= 0 || !str) { + return this._empty ? '' : str; + } + + // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, + // see https://github.com/chalk/chalk/issues/58 + // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. + const originalDim = ansiStyles.dim.open; + if (isSimpleWindowsTerm && this.hasGrey) { + ansiStyles.dim.open = ''; + } + + for (const code of this._styles.slice().reverse()) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + str = code.open + str.replace(code.closeRe, code.open) + code.close; + + // Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS + // https://github.com/chalk/chalk/pull/92 + str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); + } + + // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue + ansiStyles.dim.open = originalDim; + + return str; +} + +function chalkTag(chalk, strings) { + if (!Array.isArray(strings)) { + // If chalk() was called by itself or with a string, + // return the string itself as a string. + return [].slice.call(arguments, 1).join(' '); + } + + const args = [].slice.call(arguments, 2); + const parts = [strings.raw[0]]; + + for (let i = 1; i < strings.length; i++) { + parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); + parts.push(String(strings.raw[i])); + } + + return template(chalk, parts.join('')); +} + +Object.defineProperties(Chalk.prototype, styles); + +module.exports = Chalk(); // eslint-disable-line new-cap +module.exports.supportsColor = stdoutColor; +module.exports.default = module.exports; // For TypeScript + + +/***/ }), +/* 34 */ +/***/ (function(module, exports, __webpack_require__) { + +var global = __webpack_require__(38); +var core = __webpack_require__(26); +var ctx = __webpack_require__(68); +var hide = __webpack_require__(77); +var has = __webpack_require__(89); +var PROTOTYPE = 'prototype'; + +var $export = function (type, name, source) { + var IS_FORCED = type & $export.F; + var IS_GLOBAL = type & $export.G; + var IS_STATIC = type & $export.S; + var IS_PROTO = type & $export.P; + var IS_BIND = type & $export.B; + var IS_WRAP = type & $export.W; + var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); + var expProto = exports[PROTOTYPE]; + var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]; + var key, own, out; + if (IS_GLOBAL) source = name; + for (key in source) { + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + if (own && has(exports, key)) continue; + // export native or passed + out = own ? target[key] : source[key]; + // prevent global pollution for namespaces + exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] + // bind timers to global for call from export context + : IS_BIND && own ? ctx(out, global) + // wrap global constructors for prevent change them in library + : IS_WRAP && target[key] == out ? (function (C) { + var F = function (a, b, c) { + if (this instanceof C) { + switch (arguments.length) { + case 0: return new C(); + case 1: return new C(a); + case 2: return new C(a, b); + } return new C(a, b, c); + } return C.apply(this, arguments); + }; + F[PROTOTYPE] = C[PROTOTYPE]; + return F; + // make static versions for prototype methods + })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; + // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% + if (IS_PROTO) { + (exports.virtual || (exports.virtual = {}))[key] = out; + // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% + if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out); + } + } +}; +// type bitmap +$export.F = 1; // forced +$export.G = 2; // global +$export.S = 4; // static +$export.P = 8; // proto +$export.B = 16; // bind +$export.W = 32; // wrap +$export.U = 64; // safe +$export.R = 128; // real proto method for `library` +module.exports = $export; + + +/***/ }), +/* 35 */ +/***/ (function(module, exports, __webpack_require__) { + +// Copyright 2017 Joyent, Inc. + +module.exports = Key; + +var assert = __webpack_require__(22); +var algs = __webpack_require__(39); +var crypto = __webpack_require__(21); +var Fingerprint = __webpack_require__(145); +var Signature = __webpack_require__(71); +var DiffieHellman = __webpack_require__(266).DiffieHellman; +var errs = __webpack_require__(70); +var utils = __webpack_require__(32); +var PrivateKey = __webpack_require__(40); +var edCompat; + +try { + edCompat = __webpack_require__(424); +} catch (e) { + /* Just continue through, and bail out if we try to use it. */ +} + +var InvalidAlgorithmError = errs.InvalidAlgorithmError; +var KeyParseError = errs.KeyParseError; + +var formats = {}; +formats['auto'] = __webpack_require__(425); +formats['pem'] = __webpack_require__(82); +formats['pkcs1'] = __webpack_require__(268); +formats['pkcs8'] = __webpack_require__(146); +formats['rfc4253'] = __webpack_require__(92); +formats['ssh'] = __webpack_require__(426); +formats['ssh-private'] = __webpack_require__(183); +formats['openssh'] = formats['ssh-private']; +formats['dnssec'] = __webpack_require__(267); + +function Key(opts) { + assert.object(opts, 'options'); + assert.arrayOfObject(opts.parts, 'options.parts'); + assert.string(opts.type, 'options.type'); + assert.optionalString(opts.comment, 'options.comment'); + + var algInfo = algs.info[opts.type]; + if (typeof (algInfo) !== 'object') + throw (new InvalidAlgorithmError(opts.type)); + + var partLookup = {}; + for (var i = 0; i < opts.parts.length; ++i) { + var part = opts.parts[i]; + partLookup[part.name] = part; + } + + this.type = opts.type; + this.parts = opts.parts; + this.part = partLookup; + this.comment = undefined; + this.source = opts.source; + + /* for speeding up hashing/fingerprint operations */ + this._rfc4253Cache = opts._rfc4253Cache; + this._hashCache = {}; + + var sz; + this.curve = undefined; + if (this.type === 'ecdsa') { + var curve = this.part.curve.data.toString(); + this.curve = curve; + sz = algs.curves[curve].size; + } else if (this.type === 'ed25519' || this.type === 'curve25519') { + sz = 256; + this.curve = 'curve25519'; + } else { + var szPart = this.part[algInfo.sizePart]; + sz = szPart.data.length; + sz = sz * 8 - utils.countZeros(szPart.data); + } + this.size = sz; +} + +Key.formats = formats; + +Key.prototype.toBuffer = function (format, options) { + if (format === undefined) + format = 'ssh'; + assert.string(format, 'format'); + assert.object(formats[format], 'formats[format]'); + assert.optionalObject(options, 'options'); + + if (format === 'rfc4253') { + if (this._rfc4253Cache === undefined) + this._rfc4253Cache = formats['rfc4253'].write(this); + return (this._rfc4253Cache); + } + + return (formats[format].write(this, options)); +}; + +Key.prototype.toString = function (format, options) { + return (this.toBuffer(format, options).toString()); +}; + +Key.prototype.hash = function (algo) { + assert.string(algo, 'algorithm'); + algo = algo.toLowerCase(); + if (algs.hashAlgs[algo] === undefined) + throw (new InvalidAlgorithmError(algo)); + + if (this._hashCache[algo]) + return (this._hashCache[algo]); + var hash = crypto.createHash(algo). + update(this.toBuffer('rfc4253')).digest(); + this._hashCache[algo] = hash; + return (hash); +}; + +Key.prototype.fingerprint = function (algo) { + if (algo === undefined) + algo = 'sha256'; + assert.string(algo, 'algorithm'); + var opts = { + type: 'key', + hash: this.hash(algo), + algorithm: algo + }; + return (new Fingerprint(opts)); +}; + +Key.prototype.defaultHashAlgorithm = function () { + var hashAlgo = 'sha1'; + if (this.type === 'rsa') + hashAlgo = 'sha256'; + if (this.type === 'dsa' && this.size > 1024) + hashAlgo = 'sha256'; + if (this.type === 'ed25519') + hashAlgo = 'sha512'; + if (this.type === 'ecdsa') { + if (this.size <= 256) + hashAlgo = 'sha256'; + else if (this.size <= 384) + hashAlgo = 'sha384'; + else + hashAlgo = 'sha512'; + } + return (hashAlgo); +}; + +Key.prototype.createVerify = function (hashAlgo) { + if (hashAlgo === undefined) + hashAlgo = this.defaultHashAlgorithm(); + assert.string(hashAlgo, 'hash algorithm'); + + /* ED25519 is not supported by OpenSSL, use a javascript impl. */ + if (this.type === 'ed25519' && edCompat !== undefined) + return (new edCompat.Verifier(this, hashAlgo)); + if (this.type === 'curve25519') + throw (new Error('Curve25519 keys are not suitable for ' + + 'signing or verification')); + + var v, nm, err; + try { + nm = hashAlgo.toUpperCase(); + v = crypto.createVerify(nm); + } catch (e) { + err = e; + } + if (v === undefined || (err instanceof Error && + err.message.match(/Unknown message digest/))) { + nm = 'RSA-'; + nm += hashAlgo.toUpperCase(); + v = crypto.createVerify(nm); + } + assert.ok(v, 'failed to create verifier'); + var oldVerify = v.verify.bind(v); + var key = this.toBuffer('pkcs8'); + var curve = this.curve; + var self = this; + v.verify = function (signature, fmt) { + if (Signature.isSignature(signature, [2, 0])) { + if (signature.type !== self.type) + return (false); + if (signature.hashAlgorithm && + signature.hashAlgorithm !== hashAlgo) + return (false); + if (signature.curve && self.type === 'ecdsa' && + signature.curve !== curve) + return (false); + return (oldVerify(key, signature.toBuffer('asn1'))); + + } else if (typeof (signature) === 'string' || + Buffer.isBuffer(signature)) { + return (oldVerify(key, signature, fmt)); + + /* + * Avoid doing this on valid arguments, walking the prototype + * chain can be quite slow. + */ + } else if (Signature.isSignature(signature, [1, 0])) { + throw (new Error('signature was created by too old ' + + 'a version of sshpk and cannot be verified')); + + } else { + throw (new TypeError('signature must be a string, ' + + 'Buffer, or Signature object')); + } + }; + return (v); +}; + +Key.prototype.createDiffieHellman = function () { + if (this.type === 'rsa') + throw (new Error('RSA keys do not support Diffie-Hellman')); + + return (new DiffieHellman(this)); +}; +Key.prototype.createDH = Key.prototype.createDiffieHellman; + +Key.parse = function (data, format, options) { + if (typeof (data) !== 'string') + assert.buffer(data, 'data'); + if (format === undefined) + format = 'auto'; + assert.string(format, 'format'); + if (typeof (options) === 'string') + options = { filename: options }; + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalString(options.filename, 'options.filename'); + if (options.filename === undefined) + options.filename = '(unnamed)'; + + assert.object(formats[format], 'formats[format]'); + + try { + var k = formats[format].read(data, options); + if (k instanceof PrivateKey) + k = k.toPublic(); + if (!k.comment) + k.comment = options.filename; + return (k); + } catch (e) { + if (e.name === 'KeyEncryptedError') + throw (e); + throw (new KeyParseError(options.filename, format, e)); + } +}; + +Key.isKey = function (obj, ver) { + return (utils.isCompatible(obj, Key, ver)); +}; + +/* + * API versions for Key: + * [1,0] -- initial ver, may take Signature for createVerify or may not + * [1,1] -- added pkcs1, pkcs8 formats + * [1,2] -- added auto, ssh-private, openssh formats + * [1,3] -- added defaultHashAlgorithm + * [1,4] -- added ed support, createDH + * [1,5] -- first explicitly tagged version + * [1,6] -- changed ed25519 part names + */ +Key.prototype._sshpkApiVersion = [1, 6]; + +Key._oldVersionDetect = function (obj) { + assert.func(obj.toBuffer); + assert.func(obj.fingerprint); + if (obj.createDH) + return ([1, 4]); + if (obj.defaultHashAlgorithm) + return ([1, 3]); + if (obj.formats['auto']) + return ([1, 2]); + if (obj.formats['pkcs1']) + return ([1, 1]); + return ([1, 0]); +}; + + +/***/ }), +/* 36 */ +/***/ (function(module, exports) { + +module.exports = require("stream"); + +/***/ }), +/* 37 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(592), __esModule: true }; + +/***/ }), +/* 38 */ +/***/ (function(module, exports) { + +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self + // eslint-disable-next-line no-new-func + : Function('return this')(); +if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef + + +/***/ }), +/* 39 */ +/***/ (function(module, exports, __webpack_require__) { + +// Copyright 2015 Joyent, Inc. + +var Buffer = __webpack_require__(20).Buffer; + +var algInfo = { + 'dsa': { + parts: ['p', 'q', 'g', 'y'], + sizePart: 'p' + }, + 'rsa': { + parts: ['e', 'n'], + sizePart: 'n' + }, + 'ecdsa': { + parts: ['curve', 'Q'], + sizePart: 'Q' + }, + 'ed25519': { + parts: ['A'], + sizePart: 'A' + } +}; +algInfo['curve25519'] = algInfo['ed25519']; + +var algPrivInfo = { + 'dsa': { + parts: ['p', 'q', 'g', 'y', 'x'] + }, + 'rsa': { + parts: ['n', 'e', 'd', 'iqmp', 'p', 'q'] + }, + 'ecdsa': { + parts: ['curve', 'Q', 'd'] + }, + 'ed25519': { + parts: ['A', 'k'] + } +}; +algPrivInfo['curve25519'] = algPrivInfo['ed25519']; + +var hashAlgs = { + 'md5': true, + 'sha1': true, + 'sha256': true, + 'sha384': true, + 'sha512': true +}; + +/* + * Taken from + * http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf + */ +var curves = { + 'nistp256': { + size: 256, + pkcs8oid: '1.2.840.10045.3.1.7', + p: Buffer.from(('00' + + 'ffffffff 00000001 00000000 00000000' + + '00000000 ffffffff ffffffff ffffffff'). + replace(/ /g, ''), 'hex'), + a: Buffer.from(('00' + + 'FFFFFFFF 00000001 00000000 00000000' + + '00000000 FFFFFFFF FFFFFFFF FFFFFFFC'). + replace(/ /g, ''), 'hex'), + b: Buffer.from(( + '5ac635d8 aa3a93e7 b3ebbd55 769886bc' + + '651d06b0 cc53b0f6 3bce3c3e 27d2604b'). + replace(/ /g, ''), 'hex'), + s: Buffer.from(('00' + + 'c49d3608 86e70493 6a6678e1 139d26b7' + + '819f7e90'). + replace(/ /g, ''), 'hex'), + n: Buffer.from(('00' + + 'ffffffff 00000000 ffffffff ffffffff' + + 'bce6faad a7179e84 f3b9cac2 fc632551'). + replace(/ /g, ''), 'hex'), + G: Buffer.from(('04' + + '6b17d1f2 e12c4247 f8bce6e5 63a440f2' + + '77037d81 2deb33a0 f4a13945 d898c296' + + '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16' + + '2bce3357 6b315ece cbb64068 37bf51f5'). + replace(/ /g, ''), 'hex') + }, + 'nistp384': { + size: 384, + pkcs8oid: '1.3.132.0.34', + p: Buffer.from(('00' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff fffffffe' + + 'ffffffff 00000000 00000000 ffffffff'). + replace(/ /g, ''), 'hex'), + a: Buffer.from(('00' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE' + + 'FFFFFFFF 00000000 00000000 FFFFFFFC'). + replace(/ /g, ''), 'hex'), + b: Buffer.from(( + 'b3312fa7 e23ee7e4 988e056b e3f82d19' + + '181d9c6e fe814112 0314088f 5013875a' + + 'c656398d 8a2ed19d 2a85c8ed d3ec2aef'). + replace(/ /g, ''), 'hex'), + s: Buffer.from(('00' + + 'a335926a a319a27a 1d00896a 6773a482' + + '7acdac73'). + replace(/ /g, ''), 'hex'), + n: Buffer.from(('00' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff c7634d81 f4372ddf' + + '581a0db2 48b0a77a ecec196a ccc52973'). + replace(/ /g, ''), 'hex'), + G: Buffer.from(('04' + + 'aa87ca22 be8b0537 8eb1c71e f320ad74' + + '6e1d3b62 8ba79b98 59f741e0 82542a38' + + '5502f25d bf55296c 3a545e38 72760ab7' + + '3617de4a 96262c6f 5d9e98bf 9292dc29' + + 'f8f41dbd 289a147c e9da3113 b5f0b8c0' + + '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'). + replace(/ /g, ''), 'hex') + }, + 'nistp521': { + size: 521, + pkcs8oid: '1.3.132.0.35', + p: Buffer.from(( + '01ffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffff').replace(/ /g, ''), 'hex'), + a: Buffer.from(('01FF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF' + + 'FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFC'). + replace(/ /g, ''), 'hex'), + b: Buffer.from(('51' + + '953eb961 8e1c9a1f 929a21a0 b68540ee' + + 'a2da725b 99b315f3 b8b48991 8ef109e1' + + '56193951 ec7e937b 1652c0bd 3bb1bf07' + + '3573df88 3d2c34f1 ef451fd4 6b503f00'). + replace(/ /g, ''), 'hex'), + s: Buffer.from(('00' + + 'd09e8800 291cb853 96cc6717 393284aa' + + 'a0da64ba').replace(/ /g, ''), 'hex'), + n: Buffer.from(('01ff' + + 'ffffffff ffffffff ffffffff ffffffff' + + 'ffffffff ffffffff ffffffff fffffffa' + + '51868783 bf2f966b 7fcc0148 f709a5d0' + + '3bb5c9b8 899c47ae bb6fb71e 91386409'). + replace(/ /g, ''), 'hex'), + G: Buffer.from(('04' + + '00c6 858e06b7 0404e9cd 9e3ecb66 2395b442' + + '9c648139 053fb521 f828af60 6b4d3dba' + + 'a14b5e77 efe75928 fe1dc127 a2ffa8de' + + '3348b3c1 856a429b f97e7e31 c2e5bd66' + + '0118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9' + + '98f54449 579b4468 17afbd17 273e662c' + + '97ee7299 5ef42640 c550b901 3fad0761' + + '353c7086 a272c240 88be9476 9fd16650'). + replace(/ /g, ''), 'hex') + } +}; + +module.exports = { + info: algInfo, + privInfo: algPrivInfo, + hashAlgs: hashAlgs, + curves: curves +}; + + +/***/ }), +/* 40 */ +/***/ (function(module, exports, __webpack_require__) { + +// Copyright 2017 Joyent, Inc. + +module.exports = PrivateKey; + +var assert = __webpack_require__(22); +var Buffer = __webpack_require__(20).Buffer; +var algs = __webpack_require__(39); +var crypto = __webpack_require__(21); +var Fingerprint = __webpack_require__(145); +var Signature = __webpack_require__(71); +var errs = __webpack_require__(70); +var util = __webpack_require__(9); +var utils = __webpack_require__(32); +var dhe = __webpack_require__(266); +var generateECDSA = dhe.generateECDSA; +var generateED25519 = dhe.generateED25519; +var edCompat; +var nacl; + +try { + edCompat = __webpack_require__(424); +} catch (e) { + /* Just continue through, and bail out if we try to use it. */ +} + +var Key = __webpack_require__(35); + +var InvalidAlgorithmError = errs.InvalidAlgorithmError; +var KeyParseError = errs.KeyParseError; +var KeyEncryptedError = errs.KeyEncryptedError; + +var formats = {}; +formats['auto'] = __webpack_require__(425); +formats['pem'] = __webpack_require__(82); +formats['pkcs1'] = __webpack_require__(268); +formats['pkcs8'] = __webpack_require__(146); +formats['rfc4253'] = __webpack_require__(92); +formats['ssh-private'] = __webpack_require__(183); +formats['openssh'] = formats['ssh-private']; +formats['ssh'] = formats['ssh-private']; +formats['dnssec'] = __webpack_require__(267); + +function PrivateKey(opts) { + assert.object(opts, 'options'); + Key.call(this, opts); + + this._pubCache = undefined; +} +util.inherits(PrivateKey, Key); + +PrivateKey.formats = formats; + +PrivateKey.prototype.toBuffer = function (format, options) { + if (format === undefined) + format = 'pkcs1'; + assert.string(format, 'format'); + assert.object(formats[format], 'formats[format]'); + assert.optionalObject(options, 'options'); + + return (formats[format].write(this, options)); +}; + +PrivateKey.prototype.hash = function (algo) { + return (this.toPublic().hash(algo)); +}; + +PrivateKey.prototype.toPublic = function () { + if (this._pubCache) + return (this._pubCache); + + var algInfo = algs.info[this.type]; + var pubParts = []; + for (var i = 0; i < algInfo.parts.length; ++i) { + var p = algInfo.parts[i]; + pubParts.push(this.part[p]); + } + + this._pubCache = new Key({ + type: this.type, + source: this, + parts: pubParts + }); + if (this.comment) + this._pubCache.comment = this.comment; + return (this._pubCache); +}; + +PrivateKey.prototype.derive = function (newType) { + assert.string(newType, 'type'); + var priv, pub, pair; + + if (this.type === 'ed25519' && newType === 'curve25519') { + if (nacl === undefined) + nacl = __webpack_require__(72); + + priv = this.part.k.data; + if (priv[0] === 0x00) + priv = priv.slice(1); + + pair = nacl.box.keyPair.fromSecretKey(new Uint8Array(priv)); + pub = Buffer.from(pair.publicKey); + + return (new PrivateKey({ + type: 'curve25519', + parts: [ + { name: 'A', data: utils.mpNormalize(pub) }, + { name: 'k', data: utils.mpNormalize(priv) } + ] + })); + } else if (this.type === 'curve25519' && newType === 'ed25519') { + if (nacl === undefined) + nacl = __webpack_require__(72); + + priv = this.part.k.data; + if (priv[0] === 0x00) + priv = priv.slice(1); + + pair = nacl.sign.keyPair.fromSeed(new Uint8Array(priv)); + pub = Buffer.from(pair.publicKey); + + return (new PrivateKey({ + type: 'ed25519', + parts: [ + { name: 'A', data: utils.mpNormalize(pub) }, + { name: 'k', data: utils.mpNormalize(priv) } + ] + })); + } + throw (new Error('Key derivation not supported from ' + this.type + + ' to ' + newType)); +}; + +PrivateKey.prototype.createVerify = function (hashAlgo) { + return (this.toPublic().createVerify(hashAlgo)); +}; + +PrivateKey.prototype.createSign = function (hashAlgo) { + if (hashAlgo === undefined) + hashAlgo = this.defaultHashAlgorithm(); + assert.string(hashAlgo, 'hash algorithm'); + + /* ED25519 is not supported by OpenSSL, use a javascript impl. */ + if (this.type === 'ed25519' && edCompat !== undefined) + return (new edCompat.Signer(this, hashAlgo)); + if (this.type === 'curve25519') + throw (new Error('Curve25519 keys are not suitable for ' + + 'signing or verification')); + + var v, nm, err; + try { + nm = hashAlgo.toUpperCase(); + v = crypto.createSign(nm); + } catch (e) { + err = e; + } + if (v === undefined || (err instanceof Error && + err.message.match(/Unknown message digest/))) { + nm = 'RSA-'; + nm += hashAlgo.toUpperCase(); + v = crypto.createSign(nm); + } + assert.ok(v, 'failed to create verifier'); + var oldSign = v.sign.bind(v); + var key = this.toBuffer('pkcs1'); + var type = this.type; + var curve = this.curve; + v.sign = function () { + var sig = oldSign(key); + if (typeof (sig) === 'string') + sig = Buffer.from(sig, 'binary'); + sig = Signature.parse(sig, type, 'asn1'); + sig.hashAlgorithm = hashAlgo; + sig.curve = curve; + return (sig); + }; + return (v); +}; + +PrivateKey.parse = function (data, format, options) { + if (typeof (data) !== 'string') + assert.buffer(data, 'data'); + if (format === undefined) + format = 'auto'; + assert.string(format, 'format'); + if (typeof (options) === 'string') + options = { filename: options }; + assert.optionalObject(options, 'options'); + if (options === undefined) + options = {}; + assert.optionalString(options.filename, 'options.filename'); + if (options.filename === undefined) + options.filename = '(unnamed)'; + + assert.object(formats[format], 'formats[format]'); + + try { + var k = formats[format].read(data, options); + assert.ok(k instanceof PrivateKey, 'key is not a private key'); + if (!k.comment) + k.comment = options.filename; + return (k); + } catch (e) { + if (e.name === 'KeyEncryptedError') + throw (e); + throw (new KeyParseError(options.filename, format, e)); + } +}; + +PrivateKey.isPrivateKey = function (obj, ver) { + return (utils.isCompatible(obj, PrivateKey, ver)); +}; + +PrivateKey.generate = function (type, options) { + if (options === undefined) + options = {}; + assert.object(options, 'options'); + + switch (type) { + case 'ecdsa': + if (options.curve === undefined) + options.curve = 'nistp256'; + assert.string(options.curve, 'options.curve'); + return (generateECDSA(options.curve)); + case 'ed25519': + return (generateED25519()); + default: + throw (new Error('Key generation not supported with key ' + + 'type "' + type + '"')); + } +}; + +/* + * API versions for PrivateKey: + * [1,0] -- initial ver + * [1,1] -- added auto, pkcs[18], openssh/ssh-private formats + * [1,2] -- added defaultHashAlgorithm + * [1,3] -- added derive, ed, createDH + * [1,4] -- first tagged version + * [1,5] -- changed ed25519 part names and format + */ +PrivateKey.prototype._sshpkApiVersion = [1, 5]; + +PrivateKey._oldVersionDetect = function (obj) { + assert.func(obj.toPublic); + assert.func(obj.createSign); + if (obj.derive) + return ([1, 3]); + if (obj.defaultHashAlgorithm) + return ([1, 2]); + if (obj.formats['auto']) + return ([1, 1]); + return ([1, 0]); +}; + + +/***/ }), +/* 41 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.wrapLifecycle = exports.run = exports.install = exports.Install = undefined; + +var _set; + +function _load_set() { + return _set = _interopRequireDefault(__webpack_require__(16)); +} + +var _promise; + +function _load_promise() { + return _promise = _interopRequireDefault(__webpack_require__(7)); +} + +var _values; + +function _load_values() { + return _values = _interopRequireDefault(__webpack_require__(551)); +} + +var _extends2; + +function _load_extends() { + return _extends2 = _interopRequireDefault(__webpack_require__(24)); +} + +var _assign; + +function _load_assign() { + return _assign = _interopRequireDefault(__webpack_require__(23)); +} + +var _keys; + +function _load_keys() { + return _keys = _interopRequireDefault(__webpack_require__(14)); +} + +var _getIterator2; + +function _load_getIterator() { + return _getIterator2 = _interopRequireDefault(__webpack_require__(4)); +} + +var _asyncToGenerator2; + +function _load_asyncToGenerator() { + return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(2)); +} + +var _classCallCheck2; + +function _load_classCallCheck() { + return _classCallCheck2 = _interopRequireDefault(__webpack_require__(3)); +} + +var install = exports.install = function () { + var _ref43 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (config, reporter, flags, lockfile) { + yield wrapLifecycle(config, flags, (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + var install = new Install(flags, config, reporter, lockfile); + yield install.init(); + })); + }); + + return function install(_x16, _x17, _x18, _x19) { + return _ref43.apply(this, arguments); + }; +}(); + +var run = exports.run = function () { + var _ref45 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (config, reporter, flags, args) { + var lockfile = void 0; + var error = 'installCommandRenamed'; + if (flags.lockfile === false) { + lockfile = new (_lockfile || _load_lockfile()).default(); + } else { + lockfile = yield (_lockfile || _load_lockfile()).default.fromDirectory(config.lockfileFolder, reporter); + } + + if (args.length) { + var exampleArgs = args.slice(); + + if (flags.saveDev) { + exampleArgs.push('--dev'); + } + if (flags.savePeer) { + exampleArgs.push('--peer'); + } + if (flags.saveOptional) { + exampleArgs.push('--optional'); + } + if (flags.saveExact) { + exampleArgs.push('--exact'); + } + if (flags.saveTilde) { + exampleArgs.push('--tilde'); + } + var command = 'add'; + if (flags.global) { + error = 'globalFlagRemoved'; + command = 'global add'; + } + throw new (_errors || _load_errors()).MessageError(reporter.lang(error, `yarn ${command} ${exampleArgs.join(' ')}`)); + } + + yield install(config, reporter, flags, lockfile); + }); + + return function run(_x20, _x21, _x22, _x23) { + return _ref45.apply(this, arguments); + }; +}(); + +var wrapLifecycle = exports.wrapLifecycle = function () { + var _ref46 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (config, flags, factory) { + yield config.executeLifecycleScript('preinstall'); + + yield factory(); + + // npm behaviour, seems kinda funky but yay compatibility + yield config.executeLifecycleScript('install'); + yield config.executeLifecycleScript('postinstall'); + + if (!config.production) { + if (!config.disablePrepublish) { + yield config.executeLifecycleScript('prepublish'); + } + yield config.executeLifecycleScript('prepare'); + } + }); + + return function wrapLifecycle(_x24, _x25, _x26) { + return _ref46.apply(this, arguments); + }; +}(); + +exports.hasWrapper = hasWrapper; +exports.setFlags = setFlags; + +var _objectPath; + +function _load_objectPath() { + return _objectPath = _interopRequireDefault(__webpack_require__(244)); +} + +var _hooks; + +function _load_hooks() { + return _hooks = __webpack_require__(311); +} + +var _index; + +function _load_index() { + return _index = _interopRequireDefault(__webpack_require__(206)); +} + +var _errors; + +function _load_errors() { + return _errors = __webpack_require__(6); +} + +var _integrityChecker; + +function _load_integrityChecker() { + return _integrityChecker = _interopRequireDefault(__webpack_require__(195)); +} + +var _lockfile; + +function _load_lockfile() { + return _lockfile = _interopRequireDefault(__webpack_require__(25)); +} + +var _lockfile2; + +function _load_lockfile2() { + return _lockfile2 = __webpack_require__(25); +} + +var _packageFetcher; + +function _load_packageFetcher() { + return _packageFetcher = _interopRequireWildcard(__webpack_require__(197)); +} + +var _packageInstallScripts; + +function _load_packageInstallScripts() { + return _packageInstallScripts = _interopRequireDefault(__webpack_require__(513)); +} + +var _packageCompatibility; + +function _load_packageCompatibility() { + return _packageCompatibility = _interopRequireWildcard(__webpack_require__(196)); +} + +var _packageResolver; + +function _load_packageResolver() { + return _packageResolver = _interopRequireDefault(__webpack_require__(303)); +} + +var _packageLinker; + +function _load_packageLinker() { + return _packageLinker = _interopRequireDefault(__webpack_require__(198)); +} + +var _index2; + +function _load_index2() { + return _index2 = __webpack_require__(61); +} + +var _index3; + +function _load_index3() { + return _index3 = __webpack_require__(75); +} + +var _autoclean; + +function _load_autoclean() { + return _autoclean = __webpack_require__(290); +} + +var _constants; + +function _load_constants() { + return _constants = _interopRequireWildcard(__webpack_require__(13)); +} + +var _normalizePattern; + +function _load_normalizePattern() { + return _normalizePattern = __webpack_require__(52); +} + +var _fs; + +function _load_fs() { + return _fs = _interopRequireWildcard(__webpack_require__(8)); +} + +var _map; + +function _load_map() { + return _map = _interopRequireDefault(__webpack_require__(51)); +} + +var _yarnVersion; + +function _load_yarnVersion() { + return _yarnVersion = __webpack_require__(96); +} + +var _generatePnpMap; + +function _load_generatePnpMap() { + return _generatePnpMap = __webpack_require__(536); +} + +var _workspaceLayout; + +function _load_workspaceLayout() { + return _workspaceLayout = _interopRequireDefault(__webpack_require__(87)); +} + +var _resolutionMap; + +function _load_resolutionMap() { + return _resolutionMap = _interopRequireDefault(__webpack_require__(201)); +} + +var _guessName; + +function _load_guessName() { + return _guessName = _interopRequireDefault(__webpack_require__(159)); +} + +var _audit; + +function _load_audit() { + return _audit = _interopRequireDefault(__webpack_require__(289)); +} + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var deepEqual = __webpack_require__(654); + +var emoji = __webpack_require__(242); +var invariant = __webpack_require__(15); +var path = __webpack_require__(1); +var semver = __webpack_require__(27); +var uuid = __webpack_require__(114); +var ssri = __webpack_require__(93); + +var ONE_DAY = 1000 * 60 * 60 * 24; + +/** + * Try and detect the installation method for Yarn and provide a command to update it with. + */ + +function getUpdateCommand(installationMethod) { + if (installationMethod === 'tar') { + return `curl --compressed -o- -L ${(_constants || _load_constants()).YARN_INSTALLER_SH} | bash`; + } + + if (installationMethod === 'homebrew') { + return 'brew upgrade yarn'; + } + + if (installationMethod === 'deb') { + return 'sudo apt-get update && sudo apt-get install yarn'; + } + + if (installationMethod === 'rpm') { + return 'sudo yum install yarn'; + } + + if (installationMethod === 'npm') { + return 'npm install --global yarn'; + } + + if (installationMethod === 'chocolatey') { + return 'choco upgrade yarn'; + } + + if (installationMethod === 'apk') { + return 'apk update && apk add -u yarn'; + } + + if (installationMethod === 'portage') { + return 'sudo emerge --sync && sudo emerge -au sys-apps/yarn'; + } + + return null; +} + +function getUpdateInstaller(installationMethod) { + // Windows + if (installationMethod === 'msi') { + return (_constants || _load_constants()).YARN_INSTALLER_MSI; + } + + return null; +} + +function normalizeFlags(config, rawFlags) { + var flags = { + // install + har: !!rawFlags.har, + ignorePlatform: !!rawFlags.ignorePlatform, + ignoreEngines: !!rawFlags.ignoreEngines, + ignoreScripts: !!rawFlags.ignoreScripts, + ignoreOptional: !!rawFlags.ignoreOptional, + force: !!rawFlags.force, + flat: !!rawFlags.flat, + lockfile: rawFlags.lockfile !== false, + pureLockfile: !!rawFlags.pureLockfile, + updateChecksums: !!rawFlags.updateChecksums, + skipIntegrityCheck: !!rawFlags.skipIntegrityCheck, + frozenLockfile: !!rawFlags.frozenLockfile, + linkDuplicates: !!rawFlags.linkDuplicates, + checkFiles: !!rawFlags.checkFiles, + audit: !!rawFlags.audit, + + // add + peer: !!rawFlags.peer, + dev: !!rawFlags.dev, + optional: !!rawFlags.optional, + exact: !!rawFlags.exact, + tilde: !!rawFlags.tilde, + ignoreWorkspaceRootCheck: !!rawFlags.ignoreWorkspaceRootCheck, + + // outdated, update-interactive + includeWorkspaceDeps: !!rawFlags.includeWorkspaceDeps, + + // add, remove, update + workspaceRootIsCwd: rawFlags.workspaceRootIsCwd !== false + }; + + if (config.getOption('ignore-scripts')) { + flags.ignoreScripts = true; + } + + if (config.getOption('ignore-platform')) { + flags.ignorePlatform = true; + } + + if (config.getOption('ignore-engines')) { + flags.ignoreEngines = true; + } + + if (config.getOption('ignore-optional')) { + flags.ignoreOptional = true; + } + + if (config.getOption('force')) { + flags.force = true; + } + + return flags; +} + +var Install = exports.Install = function () { + function Install(flags, config, reporter, lockfile) { + (0, (_classCallCheck2 || _load_classCallCheck()).default)(this, Install); + + this.rootManifestRegistries = []; + this.rootPatternsToOrigin = (0, (_map || _load_map()).default)(); + this.lockfile = lockfile; + this.reporter = reporter; + this.config = config; + this.flags = normalizeFlags(config, flags); + this.resolutions = (0, (_map || _load_map()).default)(); // Legacy resolutions field used for flat install mode + this.resolutionMap = new (_resolutionMap || _load_resolutionMap()).default(config); // Selective resolutions for nested dependencies + this.resolver = new (_packageResolver || _load_packageResolver()).default(config, lockfile, this.resolutionMap); + this.integrityChecker = new (_integrityChecker || _load_integrityChecker()).default(config); + this.linker = new (_packageLinker || _load_packageLinker()).default(config, this.resolver); + this.scripts = new (_packageInstallScripts || _load_packageInstallScripts()).default(config, this.resolver, this.flags.force); + } + + /** + * Create a list of dependency requests from the current directories manifests. + */ + + Install.prototype.fetchRequestFromCwd = function () { + var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + var _this = this; + + var excludePatterns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + var ignoreUnusedPatterns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var patterns = []; + var deps = []; + var resolutionDeps = []; + var manifest = {}; + + var ignorePatterns = []; + var usedPatterns = []; + var workspaceLayout = void 0; + + // some commands should always run in the context of the entire workspace + var cwd = this.flags.includeWorkspaceDeps || this.flags.workspaceRootIsCwd ? this.config.lockfileFolder : this.config.cwd; + + // non-workspaces are always root, otherwise check for workspace root + var cwdIsRoot = !this.config.workspaceRootFolder || this.config.lockfileFolder === cwd; + + // exclude package names that are in install args + var excludeNames = []; + for (var _iterator = excludePatterns, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : (0, (_getIterator2 || _load_getIterator()).default)(_iterator);;) { + var _ref2; + + if (_isArray) { + if (_i >= _iterator.length) break; + _ref2 = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref2 = _i.value; + } + + var _pattern = _ref2; + + if ((0, (_index3 || _load_index3()).getExoticResolver)(_pattern)) { + excludeNames.push((0, (_guessName || _load_guessName()).default)(_pattern)); + } else { + // extract the name + var parts = (0, (_normalizePattern || _load_normalizePattern()).normalizePattern)(_pattern); + excludeNames.push(parts.name); + } + } + + var stripExcluded = function stripExcluded(manifest) { + for (var _iterator2 = excludeNames, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator2);;) { + var _ref3; + + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref3 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref3 = _i2.value; + } + + var exclude = _ref3; + + if (manifest.dependencies && manifest.dependencies[exclude]) { + delete manifest.dependencies[exclude]; + } + if (manifest.devDependencies && manifest.devDependencies[exclude]) { + delete manifest.devDependencies[exclude]; + } + if (manifest.optionalDependencies && manifest.optionalDependencies[exclude]) { + delete manifest.optionalDependencies[exclude]; + } + } + }; + + var _loop = function* _loop(registry) { + var filename = (_index2 || _load_index2()).registries[registry].filename; + + var loc = path.join(cwd, filename); + if (!(yield (_fs || _load_fs()).exists(loc))) { + return 'continue'; + } + + _this.rootManifestRegistries.push(registry); + + var projectManifestJson = yield _this.config.readJson(loc); + yield (0, (_index || _load_index()).default)(projectManifestJson, cwd, _this.config, cwdIsRoot); + + (0, (_assign || _load_assign()).default)(_this.resolutions, projectManifestJson.resolutions); + (0, (_assign || _load_assign()).default)(manifest, projectManifestJson); + + _this.resolutionMap.init(_this.resolutions); + for (var _iterator4 = (0, (_keys || _load_keys()).default)(_this.resolutionMap.resolutionsByPackage), _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator4);;) { + var _ref5; + + if (_isArray4) { + if (_i4 >= _iterator4.length) break; + _ref5 = _iterator4[_i4++]; + } else { + _i4 = _iterator4.next(); + if (_i4.done) break; + _ref5 = _i4.value; + } + + var _packageName = _ref5; + + var _optional = (_objectPath || _load_objectPath()).default.has(manifest.optionalDependencies, _packageName) && _this.flags.ignoreOptional; + for (var _iterator8 = _this.resolutionMap.resolutionsByPackage[_packageName], _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator8);;) { + var _ref11; + + if (_isArray8) { + if (_i8 >= _iterator8.length) break; + _ref11 = _iterator8[_i8++]; + } else { + _i8 = _iterator8.next(); + if (_i8.done) break; + _ref11 = _i8.value; + } + + var _ref10 = _ref11; + var _pattern3 = _ref10.pattern; + + resolutionDeps = [].concat(resolutionDeps, [{ registry, pattern: _pattern3, optional: _optional, hint: 'resolution' }]); + } + } + + var pushDeps = function pushDeps(depType, manifest, _ref6, isUsed) { + var hint = _ref6.hint, + optional = _ref6.optional; + + if (ignoreUnusedPatterns && !isUsed) { + return; + } + // We only take unused dependencies into consideration to get deterministic hoisting. + // Since flat mode doesn't care about hoisting and everything is top level and specified then we can safely + // leave these out. + if (_this.flags.flat && !isUsed) { + return; + } + var depMap = manifest[depType]; + for (var name in depMap) { + if (excludeNames.indexOf(name) >= 0) { + continue; + } + + var _pattern2 = name; + if (!_this.lockfile.getLocked(_pattern2)) { + // when we use --save we save the dependency to the lockfile with just the name rather than the + // version combo + _pattern2 += '@' + depMap[name]; + } + + // normalization made sure packages are mentioned only once + if (isUsed) { + usedPatterns.push(_pattern2); + } else { + ignorePatterns.push(_pattern2); + } + + _this.rootPatternsToOrigin[_pattern2] = depType; + patterns.push(_pattern2); + deps.push({ pattern: _pattern2, registry, hint, optional, workspaceName: manifest.name, workspaceLoc: manifest._loc }); + } + }; + + if (cwdIsRoot) { + pushDeps('dependencies', projectManifestJson, { hint: null, optional: false }, true); + pushDeps('devDependencies', projectManifestJson, { hint: 'dev', optional: false }, !_this.config.production); + pushDeps('optionalDependencies', projectManifestJson, { hint: 'optional', optional: true }, true); + } + + if (_this.config.workspaceRootFolder) { + var workspaceLoc = cwdIsRoot ? loc : path.join(_this.config.lockfileFolder, filename); + var workspacesRoot = path.dirname(workspaceLoc); + + var workspaceManifestJson = projectManifestJson; + if (!cwdIsRoot) { + // the manifest we read before was a child workspace, so get the root + workspaceManifestJson = yield _this.config.readJson(workspaceLoc); + yield (0, (_index || _load_index()).default)(workspaceManifestJson, workspacesRoot, _this.config, true); + } + + var workspaces = yield _this.config.resolveWorkspaces(workspacesRoot, workspaceManifestJson); + workspaceLayout = new (_workspaceLayout || _load_workspaceLayout()).default(workspaces, _this.config); + + // add virtual manifest that depends on all workspaces, this way package hoisters and resolvers will work fine + var workspaceDependencies = (0, (_extends2 || _load_extends()).default)({}, workspaceManifestJson.dependencies); + for (var _iterator5 = (0, (_keys || _load_keys()).default)(workspaces), _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator5);;) { + var _ref7; + + if (_isArray5) { + if (_i5 >= _iterator5.length) break; + _ref7 = _iterator5[_i5++]; + } else { + _i5 = _iterator5.next(); + if (_i5.done) break; + _ref7 = _i5.value; + } + + var workspaceName = _ref7; + + var workspaceManifest = workspaces[workspaceName].manifest; + workspaceDependencies[workspaceName] = workspaceManifest.version; + + // include dependencies from all workspaces + if (_this.flags.includeWorkspaceDeps) { + pushDeps('dependencies', workspaceManifest, { hint: null, optional: false }, true); + pushDeps('devDependencies', workspaceManifest, { hint: 'dev', optional: false }, !_this.config.production); + pushDeps('optionalDependencies', workspaceManifest, { hint: 'optional', optional: true }, true); + } + } + var virtualDependencyManifest = { + _uid: '', + name: `workspace-aggregator-${uuid.v4()}`, + version: '1.0.0', + _registry: 'npm', + _loc: workspacesRoot, + dependencies: workspaceDependencies, + devDependencies: (0, (_extends2 || _load_extends()).default)({}, workspaceManifestJson.devDependencies), + optionalDependencies: (0, (_extends2 || _load_extends()).default)({}, workspaceManifestJson.optionalDependencies), + private: workspaceManifestJson.private, + workspaces: workspaceManifestJson.workspaces + }; + workspaceLayout.virtualManifestName = virtualDependencyManifest.name; + var virtualDep = {}; + virtualDep[virtualDependencyManifest.name] = virtualDependencyManifest.version; + workspaces[virtualDependencyManifest.name] = { loc: workspacesRoot, manifest: virtualDependencyManifest }; + + // ensure dependencies that should be excluded are stripped from the correct manifest + stripExcluded(cwdIsRoot ? virtualDependencyManifest : workspaces[projectManifestJson.name].manifest); + + pushDeps('workspaces', { workspaces: virtualDep }, { hint: 'workspaces', optional: false }, true); + + var implicitWorkspaceDependencies = (0, (_extends2 || _load_extends()).default)({}, workspaceDependencies); + + for (var _iterator6 = (_constants || _load_constants()).OWNED_DEPENDENCY_TYPES, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator6);;) { + var _ref8; + + if (_isArray6) { + if (_i6 >= _iterator6.length) break; + _ref8 = _iterator6[_i6++]; + } else { + _i6 = _iterator6.next(); + if (_i6.done) break; + _ref8 = _i6.value; + } + + var type = _ref8; + + for (var _iterator7 = (0, (_keys || _load_keys()).default)(projectManifestJson[type] || {}), _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator7);;) { + var _ref9; + + if (_isArray7) { + if (_i7 >= _iterator7.length) break; + _ref9 = _iterator7[_i7++]; + } else { + _i7 = _iterator7.next(); + if (_i7.done) break; + _ref9 = _i7.value; + } + + var dependencyName = _ref9; + + delete implicitWorkspaceDependencies[dependencyName]; + } + } + + pushDeps('dependencies', { dependencies: implicitWorkspaceDependencies }, { hint: 'workspaces', optional: false }, true); + } + + return 'break'; + }; + + _loop2: for (var _iterator3 = (0, (_keys || _load_keys()).default)((_index2 || _load_index2()).registries), _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator3);;) { + var _ref4; + + if (_isArray3) { + if (_i3 >= _iterator3.length) break; + _ref4 = _iterator3[_i3++]; + } else { + _i3 = _iterator3.next(); + if (_i3.done) break; + _ref4 = _i3.value; + } + + var registry = _ref4; + + var _ret = yield* _loop(registry); + + switch (_ret) { + case 'continue': + continue; + + case 'break': + break _loop2;} + } + + // inherit root flat flag + + + if (manifest.flat) { + this.flags.flat = true; + } + + return { + requests: [].concat(resolutionDeps, deps), + patterns, + manifest, + usedPatterns, + ignorePatterns, + workspaceLayout + }; + }); + + function fetchRequestFromCwd() { + return _ref.apply(this, arguments); + } + + return fetchRequestFromCwd; + }(); + + /** + * TODO description + */ + + Install.prototype.prepareRequests = function prepareRequests(requests) { + return requests; + }; + + Install.prototype.preparePatterns = function preparePatterns(patterns) { + return patterns; + }; + + Install.prototype.preparePatternsForLinking = function preparePatternsForLinking(patterns, cwdManifest, cwdIsRoot) { + return patterns; + }; + + Install.prototype.prepareManifests = function () { + var _ref12 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + var manifests = yield this.config.getRootManifests(); + return manifests; + }); + + function prepareManifests() { + return _ref12.apply(this, arguments); + } + + return prepareManifests; + }(); + + Install.prototype.bailout = function () { + var _ref13 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (patterns, workspaceLayout) { + // We don't want to skip the audit - it could yield important errors + if (this.flags.audit) { + return false; + } + // PNP is so fast that the integrity check isn't pertinent + if (this.config.plugnplayEnabled) { + return false; + } + if (this.flags.skipIntegrityCheck || this.flags.force) { + return false; + } + var lockfileCache = this.lockfile.cache; + if (!lockfileCache) { + return false; + } + var lockfileClean = this.lockfile.parseResultType === 'success'; + var match = yield this.integrityChecker.check(patterns, lockfileCache, this.flags, workspaceLayout); + if (this.flags.frozenLockfile && (!lockfileClean || match.missingPatterns.length > 0)) { + throw new (_errors || _load_errors()).MessageError(this.reporter.lang('frozenLockfileError')); + } + + var haveLockfile = yield (_fs || _load_fs()).exists(path.join(this.config.lockfileFolder, (_constants || _load_constants()).LOCKFILE_FILENAME)); + + var lockfileIntegrityPresent = !this.lockfile.hasEntriesExistWithoutIntegrity(); + var integrityBailout = lockfileIntegrityPresent || !this.config.autoAddIntegrity; + + if (match.integrityMatches && haveLockfile && lockfileClean && integrityBailout) { + this.reporter.success(this.reporter.lang('upToDate')); + return true; + } + + if (match.integrityFileMissing && haveLockfile) { + // Integrity file missing, force script installations + this.scripts.setForce(true); + return false; + } + + if (match.hardRefreshRequired) { + // e.g. node version doesn't match, force script installations + this.scripts.setForce(true); + return false; + } + + if (!patterns.length && !match.integrityFileMissing) { + this.reporter.success(this.reporter.lang('nothingToInstall')); + yield this.createEmptyManifestFolders(); + yield this.saveLockfileAndIntegrity(patterns, workspaceLayout); + return true; + } + + return false; + }); + + function bailout(_x3, _x4) { + return _ref13.apply(this, arguments); + } + + return bailout; + }(); + + /** + * Produce empty folders for all used root manifests. + */ + + Install.prototype.createEmptyManifestFolders = function () { + var _ref14 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + if (this.config.modulesFolder) { + // already created + return; + } + + for (var _iterator9 = this.rootManifestRegistries, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator9);;) { + var _ref15; + + if (_isArray9) { + if (_i9 >= _iterator9.length) break; + _ref15 = _iterator9[_i9++]; + } else { + _i9 = _iterator9.next(); + if (_i9.done) break; + _ref15 = _i9.value; + } + + var registryName = _ref15; + var folder = this.config.registries[registryName].folder; + + yield (_fs || _load_fs()).mkdirp(path.join(this.config.lockfileFolder, folder)); + } + }); + + function createEmptyManifestFolders() { + return _ref14.apply(this, arguments); + } + + return createEmptyManifestFolders; + }(); + + /** + * TODO description + */ + + Install.prototype.markIgnored = function markIgnored(patterns) { + for (var _iterator10 = patterns, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator10);;) { + var _ref16; + + if (_isArray10) { + if (_i10 >= _iterator10.length) break; + _ref16 = _iterator10[_i10++]; + } else { + _i10 = _iterator10.next(); + if (_i10.done) break; + _ref16 = _i10.value; + } + + var _pattern4 = _ref16; + + var _manifest = this.resolver.getStrictResolvedPattern(_pattern4); + var ref = _manifest._reference; + invariant(ref, 'expected package reference'); + + // just mark the package as ignored. if the package is used by a required package, the hoister + // will take care of that. + ref.ignore = true; + } + }; + + /** + * helper method that gets only recent manifests + * used by global.ls command + */ + + + Install.prototype.getFlattenedDeps = function () { + var _ref17 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + var _ref18 = yield this.fetchRequestFromCwd(), + depRequests = _ref18.requests, + rawPatterns = _ref18.patterns; + + yield this.resolver.init(depRequests, {}); + + var manifests = yield (_packageFetcher || _load_packageFetcher()).fetch(this.resolver.getManifests(), this.config); + this.resolver.updateManifests(manifests); + + return this.flatten(rawPatterns); + }); + + function getFlattenedDeps() { + return _ref17.apply(this, arguments); + } + + return getFlattenedDeps; + }(); + + /** + * TODO description + */ + + Install.prototype.init = function () { + var _ref19 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + var _this2 = this; + + this.checkUpdate(); + + // warn if we have a shrinkwrap + if (yield (_fs || _load_fs()).exists(path.join(this.config.lockfileFolder, (_constants || _load_constants()).NPM_SHRINKWRAP_FILENAME))) { + this.reporter.warn(this.reporter.lang('shrinkwrapWarning')); + } + + // warn if we have an npm lockfile + if (yield (_fs || _load_fs()).exists(path.join(this.config.lockfileFolder, (_constants || _load_constants()).NPM_LOCK_FILENAME))) { + this.reporter.warn(this.reporter.lang('npmLockfileWarning')); + } + + if (this.config.plugnplayEnabled) { + this.reporter.info(this.reporter.lang('plugnplaySuggestV2L1')); + this.reporter.info(this.reporter.lang('plugnplaySuggestV2L2')); + } + + var flattenedTopLevelPatterns = []; + var steps = []; + + var _ref20 = yield this.fetchRequestFromCwd(), + depRequests = _ref20.requests, + rawPatterns = _ref20.patterns, + ignorePatterns = _ref20.ignorePatterns, + workspaceLayout = _ref20.workspaceLayout, + manifest = _ref20.manifest; + + var topLevelPatterns = []; + + var artifacts = yield this.integrityChecker.getArtifacts(); + if (artifacts) { + this.linker.setArtifacts(artifacts); + this.scripts.setArtifacts(artifacts); + } + + if ((_packageCompatibility || _load_packageCompatibility()).shouldCheck(manifest, this.flags)) { + steps.push(function () { + var _ref21 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (curr, total) { + _this2.reporter.step(curr, total, _this2.reporter.lang('checkingManifest'), emoji.get('mag')); + yield _this2.checkCompatibility(); + }); + + return function (_x5, _x6) { + return _ref21.apply(this, arguments); + }; + }()); + } + + var audit = new (_audit || _load_audit()).default(this.config, this.reporter, { groups: (_constants || _load_constants()).OWNED_DEPENDENCY_TYPES }); + var auditFoundProblems = false; + + steps.push(function (curr, total) { + return (0, (_hooks || _load_hooks()).callThroughHook)('resolveStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + _this2.reporter.step(curr, total, _this2.reporter.lang('resolvingPackages'), emoji.get('mag')); + yield _this2.resolver.init(_this2.prepareRequests(depRequests), { + isFlat: _this2.flags.flat, + isFrozen: _this2.flags.frozenLockfile, + workspaceLayout + }); + topLevelPatterns = _this2.preparePatterns(rawPatterns); + flattenedTopLevelPatterns = yield _this2.flatten(topLevelPatterns); + return { bailout: !_this2.flags.audit && (yield _this2.bailout(topLevelPatterns, workspaceLayout)) }; + })); + }); + + if (this.flags.audit) { + steps.push(function (curr, total) { + return (0, (_hooks || _load_hooks()).callThroughHook)('auditStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + _this2.reporter.step(curr, total, _this2.reporter.lang('auditRunning'), emoji.get('mag')); + if (_this2.flags.offline) { + _this2.reporter.warn(_this2.reporter.lang('auditOffline')); + return { bailout: false }; + } + var preparedManifests = yield _this2.prepareManifests(); + // $FlowFixMe - Flow considers `m` in the map operation to be "mixed", so does not recognize `m.object` + var mergedManifest = (_assign || _load_assign()).default.apply(Object, [{}].concat((0, (_values || _load_values()).default)(preparedManifests).map(function (m) { + return m.object; + }))); + var auditVulnerabilityCounts = yield audit.performAudit(mergedManifest, _this2.lockfile, _this2.resolver, _this2.linker, topLevelPatterns); + auditFoundProblems = auditVulnerabilityCounts.info || auditVulnerabilityCounts.low || auditVulnerabilityCounts.moderate || auditVulnerabilityCounts.high || auditVulnerabilityCounts.critical; + return { bailout: yield _this2.bailout(topLevelPatterns, workspaceLayout) }; + })); + }); + } + + steps.push(function (curr, total) { + return (0, (_hooks || _load_hooks()).callThroughHook)('fetchStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + _this2.markIgnored(ignorePatterns); + _this2.reporter.step(curr, total, _this2.reporter.lang('fetchingPackages'), emoji.get('truck')); + var manifests = yield (_packageFetcher || _load_packageFetcher()).fetch(_this2.resolver.getManifests(), _this2.config); + _this2.resolver.updateManifests(manifests); + yield (_packageCompatibility || _load_packageCompatibility()).check(_this2.resolver.getManifests(), _this2.config, _this2.flags.ignoreEngines); + })); + }); + + steps.push(function (curr, total) { + return (0, (_hooks || _load_hooks()).callThroughHook)('linkStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + // remove integrity hash to make this operation atomic + yield _this2.integrityChecker.removeIntegrityFile(); + _this2.reporter.step(curr, total, _this2.reporter.lang('linkingDependencies'), emoji.get('link')); + flattenedTopLevelPatterns = _this2.preparePatternsForLinking(flattenedTopLevelPatterns, manifest, _this2.config.lockfileFolder === _this2.config.cwd); + yield _this2.linker.init(flattenedTopLevelPatterns, workspaceLayout, { + linkDuplicates: _this2.flags.linkDuplicates, + ignoreOptional: _this2.flags.ignoreOptional + }); + })); + }); + + if (this.config.plugnplayEnabled) { + steps.push(function (curr, total) { + return (0, (_hooks || _load_hooks()).callThroughHook)('pnpStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + var pnpPath = `${_this2.config.lockfileFolder}/${(_constants || _load_constants()).PNP_FILENAME}`; + + var code = yield (0, (_generatePnpMap || _load_generatePnpMap()).generatePnpMap)(_this2.config, flattenedTopLevelPatterns, { + resolver: _this2.resolver, + reporter: _this2.reporter, + targetPath: pnpPath, + workspaceLayout + }); + + try { + var file = yield (_fs || _load_fs()).readFile(pnpPath); + if (file === code) { + return; + } + } catch (error) {} + + yield (_fs || _load_fs()).writeFile(pnpPath, code); + yield (_fs || _load_fs()).chmod(pnpPath, 0o755); + })); + }); + } + + steps.push(function (curr, total) { + return (0, (_hooks || _load_hooks()).callThroughHook)('buildStep', (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + _this2.reporter.step(curr, total, _this2.flags.force ? _this2.reporter.lang('rebuildingPackages') : _this2.reporter.lang('buildingFreshPackages'), emoji.get('hammer')); + + if (_this2.config.ignoreScripts) { + _this2.reporter.warn(_this2.reporter.lang('ignoredScripts')); + } else { + yield _this2.scripts.init(flattenedTopLevelPatterns); + } + })); + }); + + if (this.flags.har) { + steps.push(function () { + var _ref28 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (curr, total) { + var formattedDate = new Date().toISOString().replace(/:/g, '-'); + var filename = `yarn-install_${formattedDate}.har`; + _this2.reporter.step(curr, total, _this2.reporter.lang('savingHar', filename), emoji.get('black_circle_for_record')); + yield _this2.config.requestManager.saveHar(filename); + }); + + return function (_x7, _x8) { + return _ref28.apply(this, arguments); + }; + }()); + } + + if (yield this.shouldClean()) { + steps.push(function () { + var _ref29 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (curr, total) { + _this2.reporter.step(curr, total, _this2.reporter.lang('cleaningModules'), emoji.get('recycle')); + yield (0, (_autoclean || _load_autoclean()).clean)(_this2.config, _this2.reporter); + }); + + return function (_x9, _x10) { + return _ref29.apply(this, arguments); + }; + }()); + } + + var currentStep = 0; + for (var _iterator11 = steps, _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator11);;) { + var _ref30; + + if (_isArray11) { + if (_i11 >= _iterator11.length) break; + _ref30 = _iterator11[_i11++]; + } else { + _i11 = _iterator11.next(); + if (_i11.done) break; + _ref30 = _i11.value; + } + + var step = _ref30; + + var stepResult = yield step(++currentStep, steps.length); + if (stepResult && stepResult.bailout) { + if (this.flags.audit) { + audit.summary(); + } + if (auditFoundProblems) { + this.reporter.warn(this.reporter.lang('auditRunAuditForDetails')); + } + this.maybeOutputUpdate(); + return flattenedTopLevelPatterns; + } + } + + // fin! + if (this.flags.audit) { + audit.summary(); + } + if (auditFoundProblems) { + this.reporter.warn(this.reporter.lang('auditRunAuditForDetails')); + } + yield this.saveLockfileAndIntegrity(topLevelPatterns, workspaceLayout); + yield this.persistChanges(); + this.maybeOutputUpdate(); + this.config.requestManager.clearCache(); + return flattenedTopLevelPatterns; + }); + + function init() { + return _ref19.apply(this, arguments); + } + + return init; + }(); + + Install.prototype.checkCompatibility = function () { + var _ref31 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + var _ref32 = yield this.fetchRequestFromCwd(), + manifest = _ref32.manifest; + + yield (_packageCompatibility || _load_packageCompatibility()).checkOne(manifest, this.config, this.flags.ignoreEngines); + }); + + function checkCompatibility() { + return _ref31.apply(this, arguments); + } + + return checkCompatibility; + }(); + + Install.prototype.persistChanges = function () { + var _ref33 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + // get all the different registry manifests in this folder + var manifests = yield this.config.getRootManifests(); + + if (yield this.applyChanges(manifests)) { + yield this.config.saveRootManifests(manifests); + } + }); + + function persistChanges() { + return _ref33.apply(this, arguments); + } + + return persistChanges; + }(); + + Install.prototype.applyChanges = function applyChanges(manifests) { + var hasChanged = false; + + if (this.config.plugnplayPersist) { + var object = manifests.npm.object; + + + if (typeof object.installConfig !== 'object') { + object.installConfig = {}; + } + + if (this.config.plugnplayEnabled && object.installConfig.pnp !== true) { + object.installConfig.pnp = true; + hasChanged = true; + } else if (!this.config.plugnplayEnabled && typeof object.installConfig.pnp !== 'undefined') { + delete object.installConfig.pnp; + hasChanged = true; + } + + if ((0, (_keys || _load_keys()).default)(object.installConfig).length === 0) { + delete object.installConfig; + } + } + + return (_promise || _load_promise()).default.resolve(hasChanged); + }; + + /** + * Check if we should run the cleaning step. + */ + + Install.prototype.shouldClean = function shouldClean() { + return (_fs || _load_fs()).exists(path.join(this.config.lockfileFolder, (_constants || _load_constants()).CLEAN_FILENAME)); + }; + + /** + * TODO + */ + + Install.prototype.flatten = function () { + var _ref34 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (patterns) { + var _this3 = this; + + if (!this.flags.flat) { + return patterns; + } + + var flattenedPatterns = []; + + for (var _iterator12 = this.resolver.getAllDependencyNamesByLevelOrder(patterns), _isArray12 = Array.isArray(_iterator12), _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator12);;) { + var _ref35; + + if (_isArray12) { + if (_i12 >= _iterator12.length) break; + _ref35 = _iterator12[_i12++]; + } else { + _i12 = _iterator12.next(); + if (_i12.done) break; + _ref35 = _i12.value; + } + + var name = _ref35; + + var infos = this.resolver.getAllInfoForPackageName(name).filter(function (manifest) { + var ref = manifest._reference; + invariant(ref, 'expected package reference'); + return !ref.ignore; + }); + + if (infos.length === 0) { + continue; + } + + if (infos.length === 1) { + // single version of this package + // take out a single pattern as multiple patterns may have resolved to this package + flattenedPatterns.push(this.resolver.patternsByPackage[name][0]); + continue; + } + + var options = infos.map(function (info) { + var ref = info._reference; + invariant(ref, 'expected reference'); + return { + // TODO `and is required by {PARENT}`, + name: _this3.reporter.lang('manualVersionResolutionOption', ref.patterns.join(', '), info.version), + + value: info.version + }; + }); + var versions = infos.map(function (info) { + return info.version; + }); + var version = void 0; + + var resolutionVersion = this.resolutions[name]; + if (resolutionVersion && versions.indexOf(resolutionVersion) >= 0) { + // use json `resolution` version + version = resolutionVersion; + } else { + version = yield this.reporter.select(this.reporter.lang('manualVersionResolution', name), this.reporter.lang('answer'), options); + this.resolutions[name] = version; + } + + flattenedPatterns.push(this.resolver.collapseAllVersionsOfPackage(name, version)); + } + + // save resolutions to their appropriate root manifest + if ((0, (_keys || _load_keys()).default)(this.resolutions).length) { + var manifests = yield this.config.getRootManifests(); + + for (var _name in this.resolutions) { + var version = this.resolutions[_name]; + + var _patterns = this.resolver.patternsByPackage[_name]; + if (!_patterns) { + continue; + } + + var _manifest2 = void 0; + for (var _iterator13 = _patterns, _isArray13 = Array.isArray(_iterator13), _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator13);;) { + var _ref36; + + if (_isArray13) { + if (_i13 >= _iterator13.length) break; + _ref36 = _iterator13[_i13++]; + } else { + _i13 = _iterator13.next(); + if (_i13.done) break; + _ref36 = _i13.value; + } + + var _pattern5 = _ref36; + + _manifest2 = this.resolver.getResolvedPattern(_pattern5); + if (_manifest2) { + break; + } + } + invariant(_manifest2, 'expected manifest'); + + var ref = _manifest2._reference; + invariant(ref, 'expected reference'); + + var object = manifests[ref.registry].object; + object.resolutions = object.resolutions || {}; + object.resolutions[_name] = version; + } + + yield this.config.saveRootManifests(manifests); + } + + return flattenedPatterns; + }); + + function flatten(_x11) { + return _ref34.apply(this, arguments); + } + + return flatten; + }(); + + /** + * Remove offline tarballs that are no longer required + */ + + Install.prototype.pruneOfflineMirror = function () { + var _ref37 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (lockfile) { + var mirror = this.config.getOfflineMirrorPath(); + if (!mirror) { + return; + } + + var requiredTarballs = new (_set || _load_set()).default(); + for (var dependency in lockfile) { + var resolved = lockfile[dependency].resolved; + if (resolved) { + var basename = path.basename(resolved.split('#')[0]); + if (dependency[0] === '@' && basename[0] !== '@') { + requiredTarballs.add(`${dependency.split('/')[0]}-${basename}`); + } + requiredTarballs.add(basename); + } + } + + var mirrorFiles = yield (_fs || _load_fs()).walk(mirror); + for (var _iterator14 = mirrorFiles, _isArray14 = Array.isArray(_iterator14), _i14 = 0, _iterator14 = _isArray14 ? _iterator14 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator14);;) { + var _ref38; + + if (_isArray14) { + if (_i14 >= _iterator14.length) break; + _ref38 = _iterator14[_i14++]; + } else { + _i14 = _iterator14.next(); + if (_i14.done) break; + _ref38 = _i14.value; + } + + var file = _ref38; + + var isTarball = path.extname(file.basename) === '.tgz'; + // if using experimental-pack-script-packages-in-mirror flag, don't unlink prebuilt packages + var hasPrebuiltPackage = file.relative.startsWith('prebuilt/'); + if (isTarball && !hasPrebuiltPackage && !requiredTarballs.has(file.basename)) { + yield (_fs || _load_fs()).unlink(file.absolute); + } + } + }); + + function pruneOfflineMirror(_x12) { + return _ref37.apply(this, arguments); + } + + return pruneOfflineMirror; + }(); + + /** + * Save updated integrity and lockfiles. + */ + + Install.prototype.saveLockfileAndIntegrity = function () { + var _ref39 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (patterns, workspaceLayout) { + var _this4 = this; + + var resolvedPatterns = {}; + (0, (_keys || _load_keys()).default)(this.resolver.patterns).forEach(function (pattern) { + if (!workspaceLayout || !workspaceLayout.getManifestByPattern(pattern)) { + resolvedPatterns[pattern] = _this4.resolver.patterns[pattern]; + } + }); + + // TODO this code is duplicated in a few places, need a common way to filter out workspace patterns from lockfile + patterns = patterns.filter(function (p) { + return !workspaceLayout || !workspaceLayout.getManifestByPattern(p); + }); + + var lockfileBasedOnResolver = this.lockfile.getLockfile(resolvedPatterns); + + if (this.config.pruneOfflineMirror) { + yield this.pruneOfflineMirror(lockfileBasedOnResolver); + } + + // write integrity hash + if (!this.config.plugnplayEnabled) { + yield this.integrityChecker.save(patterns, lockfileBasedOnResolver, this.flags, workspaceLayout, this.scripts.getArtifacts()); + } + + // --no-lockfile or --pure-lockfile or --frozen-lockfile + if (this.flags.lockfile === false || this.flags.pureLockfile || this.flags.frozenLockfile) { + return; + } + + var lockFileHasAllPatterns = patterns.every(function (p) { + return _this4.lockfile.getLocked(p); + }); + var lockfilePatternsMatch = (0, (_keys || _load_keys()).default)(this.lockfile.cache || {}).every(function (p) { + return lockfileBasedOnResolver[p]; + }); + var resolverPatternsAreSameAsInLockfile = (0, (_keys || _load_keys()).default)(lockfileBasedOnResolver).every(function (pattern) { + var manifest = _this4.lockfile.getLocked(pattern); + return manifest && manifest.resolved === lockfileBasedOnResolver[pattern].resolved && deepEqual(manifest.prebuiltVariants, lockfileBasedOnResolver[pattern].prebuiltVariants); + }); + var integrityPatternsAreSameAsInLockfile = (0, (_keys || _load_keys()).default)(lockfileBasedOnResolver).every(function (pattern) { + var existingIntegrityInfo = lockfileBasedOnResolver[pattern].integrity; + if (!existingIntegrityInfo) { + // if this entry does not have an integrity, no need to re-write the lockfile because of it + return true; + } + var manifest = _this4.lockfile.getLocked(pattern); + if (manifest && manifest.integrity) { + var manifestIntegrity = ssri.stringify(manifest.integrity); + return manifestIntegrity === existingIntegrityInfo; + } + return false; + }); + + // remove command is followed by install with force, lockfile will be rewritten in any case then + if (!this.flags.force && this.lockfile.parseResultType === 'success' && lockFileHasAllPatterns && lockfilePatternsMatch && resolverPatternsAreSameAsInLockfile && integrityPatternsAreSameAsInLockfile && patterns.length) { + return; + } + + // build lockfile location + var loc = path.join(this.config.lockfileFolder, (_constants || _load_constants()).LOCKFILE_FILENAME); + + // write lockfile + var lockSource = (0, (_lockfile2 || _load_lockfile2()).stringify)(lockfileBasedOnResolver, false, this.config.enableLockfileVersions); + yield (_fs || _load_fs()).writeFilePreservingEol(loc, lockSource); + + this._logSuccessSaveLockfile(); + }); + + function saveLockfileAndIntegrity(_x13, _x14) { + return _ref39.apply(this, arguments); + } + + return saveLockfileAndIntegrity; + }(); + + Install.prototype._logSuccessSaveLockfile = function _logSuccessSaveLockfile() { + this.reporter.success(this.reporter.lang('savedLockfile')); + }; + + /** + * Load the dependency graph of the current install. Only does package resolving and wont write to the cwd. + */ + + + Install.prototype.hydrate = function () { + var _ref40 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (ignoreUnusedPatterns) { + var request = yield this.fetchRequestFromCwd([], ignoreUnusedPatterns); + var depRequests = request.requests, + rawPatterns = request.patterns, + ignorePatterns = request.ignorePatterns, + workspaceLayout = request.workspaceLayout; + + + yield this.resolver.init(depRequests, { + isFlat: this.flags.flat, + isFrozen: this.flags.frozenLockfile, + workspaceLayout + }); + yield this.flatten(rawPatterns); + this.markIgnored(ignorePatterns); + + // fetch packages, should hit cache most of the time + var manifests = yield (_packageFetcher || _load_packageFetcher()).fetch(this.resolver.getManifests(), this.config); + this.resolver.updateManifests(manifests); + yield (_packageCompatibility || _load_packageCompatibility()).check(this.resolver.getManifests(), this.config, this.flags.ignoreEngines); + + // expand minimal manifests + for (var _iterator15 = this.resolver.getManifests(), _isArray15 = Array.isArray(_iterator15), _i15 = 0, _iterator15 = _isArray15 ? _iterator15 : (0, (_getIterator2 || _load_getIterator()).default)(_iterator15);;) { + var _ref41; + + if (_isArray15) { + if (_i15 >= _iterator15.length) break; + _ref41 = _iterator15[_i15++]; + } else { + _i15 = _iterator15.next(); + if (_i15.done) break; + _ref41 = _i15.value; + } + + var _manifest3 = _ref41; + + var ref = _manifest3._reference; + invariant(ref, 'expected reference'); + var type = ref.remote.type; + // link specifier won't ever hit cache + + var _loc = ''; + if (type === 'link') { + continue; + } else if (type === 'workspace') { + if (!ref.remote.reference) { + continue; + } + _loc = ref.remote.reference; + } else { + _loc = this.config.generateModuleCachePath(ref); + } + var newPkg = yield this.config.readManifest(_loc); + yield this.resolver.updateManifest(ref, newPkg); + } + + return request; + }); + + function hydrate(_x15) { + return _ref40.apply(this, arguments); + } + + return hydrate; + }(); + + /** + * Check for updates every day and output a nag message if there's a newer version. + */ + + Install.prototype.checkUpdate = function checkUpdate() { + if (this.config.nonInteractive) { + // don't show upgrade dialog on CI or non-TTY terminals + return; + } + + // don't check if disabled + if (this.config.getOption('disable-self-update-check')) { + return; + } + + // only check for updates once a day + var lastUpdateCheck = Number(this.config.getOption('lastUpdateCheck')) || 0; + if (lastUpdateCheck && Date.now() - lastUpdateCheck < ONE_DAY) { + return; + } + + // don't bug for updates on tagged releases + if ((_yarnVersion || _load_yarnVersion()).version.indexOf('-') >= 0) { + return; + } + + this._checkUpdate().catch(function () { + // swallow errors + }); + }; + + Install.prototype._checkUpdate = function () { + var _ref42 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + var _this5 = this; + + var latestVersion = yield this.config.requestManager.request({ + url: (_constants || _load_constants()).SELF_UPDATE_VERSION_URL + }); + invariant(typeof latestVersion === 'string', 'expected string'); + latestVersion = latestVersion.trim(); + if (!semver.valid(latestVersion)) { + return; + } + + // ensure we only check for updates periodically + this.config.registries.yarn.saveHomeConfig({ + lastUpdateCheck: Date.now() + }); + + if (semver.gt(latestVersion, (_yarnVersion || _load_yarnVersion()).version)) { + var installationMethod = yield (0, (_yarnVersion || _load_yarnVersion()).getInstallationMethod)(); + this.maybeOutputUpdate = function () { + _this5.reporter.warn(_this5.reporter.lang('yarnOutdated', latestVersion, (_yarnVersion || _load_yarnVersion()).version)); + + var command = getUpdateCommand(installationMethod); + if (command) { + _this5.reporter.info(_this5.reporter.lang('yarnOutdatedCommand')); + _this5.reporter.command(command); + } else { + var installer = getUpdateInstaller(installationMethod); + if (installer) { + _this5.reporter.info(_this5.reporter.lang('yarnOutdatedInstaller', installer)); + } + } + }; + } + }); + + function _checkUpdate() { + return _ref42.apply(this, arguments); + } + + return _checkUpdate; + }(); + + /** + * Method to override with a possible upgrade message. + */ + + Install.prototype.maybeOutputUpdate = function maybeOutputUpdate() {}; + + return Install; +}(); + +function hasWrapper(commander, args) { + return true; +} + +function setFlags(commander) { + commander.description('Yarn install is used to install all dependencies for a project.'); + commander.usage('install [flags]'); + commander.option('-A, --audit', 'Run vulnerability audit on installed packages'); + commander.option('-g, --global', 'DEPRECATED'); + commander.option('-S, --save', 'DEPRECATED - save package to your `dependencies`'); + commander.option('-D, --save-dev', 'DEPRECATED - save package to your `devDependencies`'); + commander.option('-P, --save-peer', 'DEPRECATED - save package to your `peerDependencies`'); + commander.option('-O, --save-optional', 'DEPRECATED - save package to your `optionalDependencies`'); + commander.option('-E, --save-exact', 'DEPRECATED'); + commander.option('-T, --save-tilde', 'DEPRECATED'); +} + +/***/ }), +/* 42 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = { "default": __webpack_require__(593), __esModule: true }; + +/***/ }), +/* 43 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return SubjectSubscriber; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Subject; }); +/* unused harmony export AnonymousSubject */ +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_tslib__ = __webpack_require__(0); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Observable__ = __webpack_require__(17); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Subscriber__ = __webpack_require__(5); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Subscription__ = __webpack_require__(31); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__ = __webpack_require__(180); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__SubjectSubscription__ = __webpack_require__(392); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__internal_symbol_rxSubscriber__ = __webpack_require__(262); +/** PURE_IMPORTS_START tslib,_Observable,_Subscriber,_Subscription,_util_ObjectUnsubscribedError,_SubjectSubscription,_internal_symbol_rxSubscriber PURE_IMPORTS_END */ + + + + + + + +var SubjectSubscriber = /*@__PURE__*/ (function (_super) { + __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](SubjectSubscriber, _super); + function SubjectSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.destination = destination; + return _this; + } + return SubjectSubscriber; +}(__WEBPACK_IMPORTED_MODULE_2__Subscriber__["a" /* Subscriber */])); + +var Subject = /*@__PURE__*/ (function (_super) { + __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](Subject, _super); + function Subject() { + var _this = _super.call(this) || this; + _this.observers = []; + _this.closed = false; + _this.isStopped = false; + _this.hasError = false; + _this.thrownError = null; + return _this; + } + Subject.prototype[__WEBPACK_IMPORTED_MODULE_6__internal_symbol_rxSubscriber__["a" /* rxSubscriber */]] = function () { + return new SubjectSubscriber(this); + }; + Subject.prototype.lift = function (operator) { + var subject = new AnonymousSubject(this, this); + subject.operator = operator; + return subject; + }; + Subject.prototype.next = function (value) { + if (this.closed) { + throw new __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__["a" /* ObjectUnsubscribedError */](); + } + if (!this.isStopped) { + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].next(value); + } + } + }; + Subject.prototype.error = function (err) { + if (this.closed) { + throw new __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__["a" /* ObjectUnsubscribedError */](); + } + this.hasError = true; + this.thrownError = err; + this.isStopped = true; + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].error(err); + } + this.observers.length = 0; + }; + Subject.prototype.complete = function () { + if (this.closed) { + throw new __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__["a" /* ObjectUnsubscribedError */](); + } + this.isStopped = true; + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].complete(); + } + this.observers.length = 0; + }; + Subject.prototype.unsubscribe = function () { + this.isStopped = true; + this.closed = true; + this.observers = null; + }; + Subject.prototype._trySubscribe = function (subscriber) { + if (this.closed) { + throw new __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__["a" /* ObjectUnsubscribedError */](); + } + else { + return _super.prototype._trySubscribe.call(this, subscriber); + } + }; + Subject.prototype._subscribe = function (subscriber) { + if (this.closed) { + throw new __WEBPACK_IMPORTED_MODULE_4__util_ObjectUnsubscribedError__["a" /* ObjectUnsubscribedError */](); + } + else if (this.hasError) { + subscriber.error(this.thrownError); + return __WEBPACK_IMPORTED_MODULE_3__Subscription__["a" /* Subscription */].EMPTY; + } + else if (this.isStopped) { + subscriber.complete(); + return __WEBPACK_IMPORTED_MODULE_3__Subscription__["a" /* Subscription */].EMPTY; + } + else { + this.observers.push(subscriber); + return new __WEBPACK_IMPORTED_MODULE_5__SubjectSubscription__["a" /* SubjectSubscription */](this, subscriber); + } + }; + Subject.prototype.asObservable = function () { + var observable = new __WEBPACK_IMPORTED_MODULE_1__Observable__["a" /* Observable */](); + observable.source = this; + return observable; + }; + Subject.create = function (destination, source) { + return new AnonymousSubject(destination, source); + }; + return Subject; +}(__WEBPACK_IMPORTED_MODULE_1__Observable__["a" /* Observable */])); + +var AnonymousSubject = /*@__PURE__*/ (function (_super) { + __WEBPACK_IMPORTED_MODULE_0_tslib__["a" /* __extends */](AnonymousSubject, _super); + function AnonymousSubject(destination, source) { + var _this = _super.call(this) || this; + _this.destination = destination; + _this.source = source; + return _this; + } + AnonymousSubject.prototype.next = function (value) { + var destination = this.destination; + if (destination && destination.next) { + destination.next(value); + } + }; + AnonymousSubject.prototype.error = function (err) { + var destination = this.destination; + if (destination && destination.error) { + this.destination.error(err); + } + }; + AnonymousSubject.prototype.complete = function () { + var destination = this.destination; + if (destination && destination.complete) { + this.destination.complete(); + } + }; + AnonymousSubject.prototype._subscribe = function (subscriber) { + var source = this.source; + if (source) { + return this.source.subscribe(subscriber); + } + else { + return __WEBPACK_IMPORTED_MODULE_3__Subscription__["a" /* Subscription */].EMPTY; + } + }; + return AnonymousSubject; +}(Subject)); + +//# sourceMappingURL=Subject.js.map + + +/***/ }), +/* 44 */ +/***/ (function(module, exports, __webpack_require__) { + +var store = __webpack_require__(225)('wks'); +var uid = __webpack_require__(162); +var Symbol = __webpack_require__(38).Symbol; +var USE_SYMBOL = typeof Symbol == 'function'; + +var $exports = module.exports = function (name) { + return store[name] || (store[name] = + USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); +}; + +$exports.store = store; + + +/***/ }), +/* 45 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_RESULT__;/** + * @license + * Lodash + * Copyright JS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '4.17.10'; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Error message constants. */ + var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', + FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** Used to compose bitmasks for cloning. */ + var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + + /** Used to compose bitmasks for function metadata. */ + var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_BOUND_FLAG = 4, + WRAP_CURRY_FLAG = 8, + WRAP_CURRY_RIGHT_FLAG = 16, + WRAP_PARTIAL_FLAG = 32, + WRAP_PARTIAL_RIGHT_FLAG = 64, + WRAP_ARY_FLAG = 128, + WRAP_REARG_FLAG = 256, + WRAP_FLIP_FLAG = 512; + + /** Used as default options for `_.truncate`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + var HOT_COUNT = 800, + HOT_SPAN = 16; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2, + LAZY_WHILE_FLAG = 3; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** Used to associate wrap methods with their bit flags. */ + var wrapFlags = [ + ['ary', WRAP_ARY_FLAG], + ['bind', WRAP_BIND_FLAG], + ['bindKey', WRAP_BIND_KEY_FLAG], + ['curry', WRAP_CURRY_FLAG], + ['curryRight', WRAP_CURRY_RIGHT_FLAG], + ['flip', WRAP_FLIP_FLAG], + ['partial', WRAP_PARTIAL_FLAG], + ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], + ['rearg', WRAP_REARG_FLAG] + ]; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + asyncTag = '[object AsyncFunction]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + domExcTag = '[object DOMException]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + nullTag = '[object Null]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + proxyTag = '[object Proxy]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + undefinedTag = '[object Undefined]', + weakMapTag = '[object WeakMap]', + weakSetTag = '[object WeakSet]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g, + reUnescapedHtml = /[&<>"']/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, + reHasRegExpChar = RegExp(reRegExpChar.source); + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g, + reTrimStart = /^\s+/, + reTrimEnd = /\s+$/; + + /** Used to match wrap detail comments. */ + var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, + reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, + reSplitDetails = /,? & /; + + /** Used to match words composed of alphanumeric characters. */ + var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** + * Used to match + * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components). + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to match Latin Unicode letters (excluding mathematical operators). */ + var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsDingbatRange = '\\u2700-\\u27bf', + rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', + rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', + rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', + rsPunctuationRange = '\\u2000-\\u206f', + rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', + rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + rsVarRange = '\\ufe0e\\ufe0f', + rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; + + /** Used to compose unicode capture groups. */ + var rsApos = "['\u2019]", + rsAstral = '[' + rsAstralRange + ']', + rsBreak = '[' + rsBreakRange + ']', + rsCombo = '[' + rsComboRange + ']', + rsDigits = '\\d+', + rsDingbat = '[' + rsDingbatRange + ']', + rsLower = '[' + rsLowerRange + ']', + rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsUpper = '[' + rsUpperRange + ']', + rsZWJ = '\\u200d'; + + /** Used to compose unicode regexes. */ + var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')', + rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')', + rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', + rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', + rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** Used to match apostrophes. */ + var reApos = RegExp(rsApos, 'g'); + + /** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ + var reComboMark = RegExp(rsCombo, 'g'); + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** Used to match complex or compound words. */ + var reUnicodeWord = RegExp([ + rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', + rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')', + rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower, + rsUpper + '+' + rsOptContrUpper, + rsOrdUpper, + rsOrdLower, + rsDigits, + rsEmoji + ].join('|'), 'g'); + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + + /** Used to detect strings that need a more robust regexp to match words. */ + var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', + 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', + '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = + typedArrayTags[errorTag] = typedArrayTags[funcTag] = + typedArrayTags[mapTag] = typedArrayTags[numberTag] = + typedArrayTags[objectTag] = typedArrayTags[regexpTag] = + typedArrayTags[setTag] = typedArrayTags[stringTag] = + typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map Latin Unicode letters to basic Latin letters. */ + var deburredLetters = { + // Latin-1 Supplement block. + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss', + // Latin Extended-A block. + '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', + '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', + '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', + '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', + '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', + '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', + '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', + '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', + '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', + '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', + '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', + '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', + '\u0134': 'J', '\u0135': 'j', + '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', + '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', + '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', + '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', + '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', + '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', + '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', + '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', + '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', + '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', + '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', + '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', + '\u0163': 't', '\u0165': 't', '\u0167': 't', + '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', + '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', + '\u0174': 'W', '\u0175': 'w', + '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', + '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', + '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', + '\u0132': 'IJ', '\u0133': 'ij', + '\u0152': 'Oe', '\u0153': 'oe', + '\u0149': "'n", '\u017f': 's' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'" + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Built-in method references without a dependency on `root`. */ + var freeParseFloat = parseFloat, + freeParseInt = parseInt; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports && freeGlobal.process; + + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }()); + + /* Node.js helper references. */ + var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, + nodeIsDate = nodeUtil && nodeUtil.isDate, + nodeIsMap = nodeUtil && nodeUtil.isMap, + nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, + nodeIsSet = nodeUtil && nodeUtil.isSet, + nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + + /*--------------------------------------------------------------------------*/ + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + return accumulator; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array == null ? 0 : array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && baseIndexOf(array, value, 0) > -1; + } + + /** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the last element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initAccum) { + var length = array == null ? 0 : array.length; + if (initAccum && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ + var asciiSize = baseProperty('length'); + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } + + /** + * Splits an ASCII `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ + function asciiWords(string) { + return string.match(reAsciiWord) || []; + } + + /** + * The base implementation of methods like `_.findKey` and `_.findLastKey`, + * without support for iteratee shorthands, which iterates over `collection` + * using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFindKey(collection, predicate, eachFunc) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = key; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + /** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @param {Function} comparator The comparator invoked per element. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOfWith(array, value, fromIndex, comparator) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (comparator(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ + function baseIsNaN(value) { + return value !== value; + } + + /** + * The base implementation of `_.mean` and `_.meanBy` without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the mean. + */ + function baseMean(array, iteratee) { + var length = array == null ? 0 : array.length; + return length ? (baseSum(array, iteratee) / length) : NAN; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.propertyOf` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyOf(object) { + return function(key) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.sum` and `_.sumBy` without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(array, iteratee) { + var result, + index = -1, + length = array.length; + + while (++index < length) { + var current = iteratee(array[index]); + if (current !== undefined) { + result = result === undefined ? current : (result + current); + } + } + return result; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array + * of key-value pairs for `object` corresponding to the property names of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the key-value pairs. + */ + function baseToPairs(object, props) { + return arrayMap(props, function(key) { + return [key, object[key]]; + }); + } + + /** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); + } + + /** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function cacheHas(cache, key) { + return cache.has(key); + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ + function countHolders(array, placeholder) { + var length = array.length, + result = 0; + + while (length--) { + if (array[length] === placeholder) { + ++result; + } + } + return result; + } + + /** + * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A + * letters to basic Latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + var deburrLetter = basePropertyOf(deburredLetters); + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + var escapeHtmlChar = basePropertyOf(htmlEscapes); + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** + * Checks if `string` contains a word composed of Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a word is found, else `false`. + */ + function hasUnicodeWord(string) { + return reHasUnicodeWord.test(string); + } + + /** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value === placeholder || value === PLACEHOLDER) { + array[index] = PLACEHOLDER; + result[resIndex++] = index; + } + } + return result; + } + + /** + * Gets the value at `key`, unless `key` is "__proto__". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function safeGet(object, key) { + return key == '__proto__' + ? undefined + : object[key]; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** + * Converts `set` to its value-value pairs. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the value-value pairs. + */ + function setToPairs(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = [value, value]; + }); + return result; + } + + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * A specialized version of `_.lastIndexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictLastIndexOf(array, value, fromIndex) { + var index = fromIndex + 1; + while (index--) { + if (array[index] === value) { + return index; + } + } + return index; + } + + /** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ + function stringSize(string) { + return hasUnicode(string) + ? unicodeSize(string) + : asciiSize(string); + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + var unescapeHtmlChar = basePropertyOf(htmlUnescapes); + + /** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ + function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; + } + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + + /** + * Splits a Unicode `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ + function unicodeWords(string) { + return string.match(reUnicodeWord) || []; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the `context` object. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Util + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // Create a suped-up `defer` in Node.js. + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + var runInContext = (function runInContext(context) { + context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps)); + + /** Built-in constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = context['__core-js_shared__']; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? context.Buffer : undefined, + Symbol = context.Symbol, + Uint8Array = context.Uint8Array, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice, + spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, + symIterator = Symbol ? Symbol.iterator : undefined, + symToStringTag = Symbol ? Symbol.toStringTag : undefined; + + var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }()); + + /** Mocked built-ins. */ + var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, + ctxNow = Date && Date.now !== root.Date.now && Date.now, + ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeFloor = Math.floor, + nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeIsFinite = context.isFinite, + nativeJoin = arrayProto.join, + nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = Date.now, + nativeParseInt = context.parseInt, + nativeRandom = Math.random, + nativeReverse = arrayProto.reverse; + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(context, 'DataView'), + Map = getNative(context, 'Map'), + Promise = getNative(context, 'Promise'), + Set = getNative(context, 'Set'), + WeakMap = getNative(context, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chain sequences. Methods that operate on and return arrays, collections, + * and functions can be chained together. Methods that retrieve a single value + * or may return a primitive value will automatically end the chain sequence + * and return the unwrapped value. Otherwise, the value must be unwrapped + * with `_#value`. + * + * Explicit chain sequences, which must be unwrapped with `_#value`, may be + * enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. + * Shortcut fusion is an optimization to merge iteratee calls; this avoids + * the creation of intermediate arrays and can greatly reduce the number of + * iteratee executions. Sections of a chain sequence qualify for shortcut + * fusion if the section is applied to an array and iteratees accept only + * one argument. The heuristic for whether a section qualifies for shortcut + * fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, + * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, + * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, + * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, + * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, + * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, + * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, + * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, + * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, + * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, + * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, + * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, + * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, + * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, + * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, + * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, + * `zipObject`, `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, + * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, + * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, + * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, + * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, + * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, + * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, + * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, + * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, + * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, + * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, + * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, + * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, + * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, + * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, + * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, + * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, + * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, + * `upperFirst`, `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + /** + * The function whose prototype chain sequence wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable explicit method chain sequences. + */ + function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; + } + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB) as well as ES2015 template strings. Change the + * following template settings to use alternative delimiters. + * + * @static + * @memberOf _ + * @type {Object} + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type {string} + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type {Object} + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type {Function} + */ + '_': lodash + } + }; + + // Ensure wrappers are instances of `baseLodash`. + lodash.prototype = baseLodash.prototype; + lodash.prototype.constructor = lodash; + + LodashWrapper.prototype = baseCreate(baseLodash.prototype); + LodashWrapper.prototype.constructor = LodashWrapper; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = copyArray(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = copyArray(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = copyArray(this.__views__); + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || (!isRight && arrLength == length && takeCount == length)) { + return baseWrapperValue(array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } + + // Ensure `LazyWrapper` is an instance of `baseLodash`. + LazyWrapper.prototype = baseCreate(baseLodash.prototype); + LazyWrapper.prototype.constructor = LazyWrapper; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } + } + + /** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ + function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; + } + + /** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ + function setCacheHas(value) { + return this.__data__.has(value); + } + + // Add methods to `SetCache`. + SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; + SetCache.prototype.has = setCacheHas; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + this.size = 0; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; + } + + /** + * A specialized version of `_.sample` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @returns {*} Returns the random element. + */ + function arraySample(array) { + var length = array.length; + return length ? array[baseRandom(0, length - 1)] : undefined; + } + + /** + * A specialized version of `_.sampleSize` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ + function arraySampleSize(array, n) { + return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); + } + + /** + * A specialized version of `_.shuffle` for arrays. + * + * @private + * @param {Array} array The array to shuffle. + * @returns {Array} Returns the new shuffled array. + */ + function arrayShuffle(array) { + return shuffleSelf(copyArray(array)); + } + + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function(value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssignIn(object, source) { + return object && copyObject(source, keysIn(source), object); + } + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + /** + * The base implementation of `_.at` without support for individual paths. + * + * @private + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths to pick. + * @returns {Array} Returns the picked elements. + */ + function baseAt(object, paths) { + var index = -1, + length = paths.length, + result = Array(length), + skip = object == null; + + while (++index < length) { + result[index] = skip ? undefined : get(object, paths[index]); + } + return result; + } + + /** + * The base implementation of `_.clamp` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ + function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } + } + return number; + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : initCloneObject(value); + if (!isDeep) { + return isFlat + ? copySymbolsIn(value, baseAssignIn(result, value)) + : copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + + return result; + } + + if (isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + + return result; + } + + var keysFunc = isFull + ? (isFlat ? getAllKeysIn : getAllKeys) + : (isFlat ? keysIn : keys); + + var props = isArr ? undefined : keysFunc(value); + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.conforms` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new spec function. + */ + function baseConforms(source) { + var props = keys(source); + return function(object) { + return baseConformsTo(object, source, props); + }; + } + + /** + * The base implementation of `_.conformsTo` which accepts `props` to check. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + */ + function baseConformsTo(object, source, props) { + var length = props.length; + if (object == null) { + return !length; + } + object = Object(object); + while (length--) { + var key = props[length], + predicate = source[key], + value = object[key]; + + if ((value === undefined && !(key in object)) || !predicate(value)) { + return false; + } + } + return true; + } + + /** + * The base implementation of `_.delay` and `_.defer` which accepts `args` + * to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Array} args The arguments to provide to `func`. + * @returns {number|Object} Returns the timer id or timeout object. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of methods like `_.difference` without support + * for excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; + + if (!length) { + return result; + } + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } + else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee == null ? value : iteratee(value); + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } + result.push(value); + } + else if (!includes(values, computed, comparator)) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.forEachRight` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !isSymbol(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; + } + + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; + + start = toInteger(start); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : toInteger(end); + if (end < 0) { + end += length; + } + end = start > end ? 0 : toLength(end); + while (start < end) { + array[start++] = value; + } + return array; + } + + /** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return object && baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the function names. + */ + function baseFunctions(object, props) { + return arrayFilter(props, function(key) { + return isFunction(object[key]); + }); + } + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); + } + + /** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ + function baseGt(value, other) { + return value > other; + } + + /** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHas(object, key) { + return object != null && hasOwnProperty.call(object, key); + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return object != null && key in Object(object); + } + + /** + * The base implementation of `_.inRange` which doesn't coerce arguments. + * + * @private + * @param {number} number The number to check. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + */ + function baseInRange(number, start, end) { + return number >= nativeMin(start, end) && number < nativeMax(start, end); + } + + /** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ + function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; + + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; + + var index = -1, + seen = caches[0]; + + outer: + while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ + function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function(value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; + } + + /** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function baseInvoke(object, path, args) { + path = castPath(path, object); + object = parent(object, path); + var func = object == null ? object : object[toKey(last(path))]; + return func == null ? undefined : apply(func, object, args); + } + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; + } + + /** + * The base implementation of `_.isArrayBuffer` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + */ + function baseIsArrayBuffer(value) { + return isObjectLike(value) && baseGetTag(value) == arrayBufferTag; + } + + /** + * The base implementation of `_.isDate` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + */ + function baseIsDate(value) { + return isObjectLike(value) && baseGetTag(value) == dateTag; + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag : getTag(object), + othTag = othIsArr ? arrayTag : getTag(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); + } + + /** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ + function baseIsMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; + } + + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.isRegExp` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + */ + function baseIsRegExp(value) { + return isObjectLike(value) && baseGetTag(value) == regexpTag; + } + + /** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ + function baseIsSet(value) { + return isObjectLike(value) && getTag(value) == setTag; + } + + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ + function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ + function baseLt(value, other) { + return value < other; + } + + /** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); + }; + } + + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + baseFor(source, function(srcValue, key) { + if (isObject(srcValue)) { + stack || (stack = new Stack); + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = safeGet(object, key), + srcValue = safeGet(source, key), + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { + newValue = initCloneObject(srcValue); + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.nth` which doesn't coerce arguments. + * + * @private + * @param {Array} array The array to query. + * @param {number} n The index of the element to return. + * @returns {*} Returns the nth element of `array`. + */ + function baseNth(array, n) { + var length = array.length; + if (!length) { + return; + } + n += n < 0 ? length : 0; + return isIndex(n, length) ? array[n] : undefined; + } + + /** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseOrderBy(collection, iteratees, orders) { + var index = -1; + iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee())); + + var result = baseMap(collection, function(value, key, collection) { + var criteria = arrayMap(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, paths) { + return basePickBy(object, paths, function(value, path) { + return hasIn(object, path); + }); + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + + if (predicate(value, path)) { + baseSet(result, castPath(path, object), value); + } + } + return result; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; + } + + /** + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + */ + function basePullAll(array, values, iteratee, comparator) { + var indexOf = comparator ? baseIndexOfWith : baseIndexOf, + index = -1, + length = values.length, + seen = array; + + if (array === values) { + values = copyArray(values); + } + if (iteratee) { + seen = arrayMap(array, baseUnary(iteratee)); + } + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; + + while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * indexes or capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0, + lastIndex = length - 1; + + while (length--) { + var index = indexes[length]; + if (length == lastIndex || index !== previous) { + var previous = index; + if (isIndex(index)) { + splice.call(array, index, 1); + } else { + baseUnset(array, index); + } + } + } + return array; + } + + /** + * The base implementation of `_.random` without support for returning + * floating-point numbers. + * + * @private + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the random number. + */ + function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); + } + + /** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ + function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; + } + + /** + * The base implementation of `_.repeat` which doesn't coerce arguments. + * + * @private + * @param {string} string The string to repeat. + * @param {number} n The number of times to repeat the string. + * @returns {string} Returns the repeated string. + */ + function baseRepeat(string, n) { + var result = ''; + if (!string || n < 1 || n > MAX_SAFE_INTEGER) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + if (n) { + string += string; + } + } while (n); + + return result; + } + + /** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ + function baseRest(func, start) { + return setToString(overRest(func, start, identity), func + ''); + } + + /** + * The base implementation of `_.sample`. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + */ + function baseSample(collection) { + return arraySample(values(collection)); + } + + /** + * The base implementation of `_.sampleSize` without param guards. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ + function baseSampleSize(collection, n) { + var array = values(collection); + return shuffleSelf(array, baseClamp(n, 0, array.length)); + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `setData` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); + }; + + /** + * The base implementation of `_.shuffle`. + * + * @private + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + */ + function baseShuffle(collection) { + return shuffleSelf(values(collection)); + } + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which + * performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function baseSortedIndex(array, value, retHighest) { + var low = 0, + high = array == null ? low : array.length; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if (computed !== null && !isSymbol(computed) && + (retHighest ? (computed <= value) : (computed < value))) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return baseSortedIndexBy(array, value, identity, retHighest); + } + + /** + * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` + * which invokes `iteratee` for `value` and each element of `array` to compute + * their sort ranking. The iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The iteratee invoked per element. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function baseSortedIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array == null ? 0 : array.length, + valIsNaN = value !== value, + valIsNull = value === null, + valIsSymbol = isSymbol(value), + valIsUndefined = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + othIsDefined = computed !== undefined, + othIsNull = computed === null, + othIsReflexive = computed === computed, + othIsSymbol = isSymbol(computed); + + if (valIsNaN) { + var setLow = retHighest || othIsReflexive; + } else if (valIsUndefined) { + setLow = othIsReflexive && (retHighest || othIsDefined); + } else if (valIsNull) { + setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); + } else if (valIsSymbol) { + setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); + } else if (othIsNull || othIsSymbol) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseSortedUniq(array, iteratee) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!index || !eq(computed, seen)) { + var seen = computed; + result[resIndex++] = value === 0 ? 0 : value; + } + } + return result; + } + + /** + * The base implementation of `_.toNumber` which doesn't ensure correct + * conversions of binary, hexadecimal, or octal string values. + * + * @private + * @param {*} value The value to process. + * @returns {number} Returns the number. + */ + function baseToNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + return +value; + } + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.unset`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The property path to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ + function baseUnset(object, path) { + path = castPath(path, object); + object = parent(object, path); + return object == null || delete object[toKey(last(path))]; + } + + /** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to update. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseUpdate(object, path, updater, customizer) { + return baseSet(object, path, updater(baseGet(object, path)), customizer); + } + + /** + * The base implementation of methods like `_.dropWhile` and `_.takeWhile` + * without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && + predicate(array[index], index, array)) {} + + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + return arrayReduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + + /** + * The base implementation of methods like `_.xor`, without support for + * iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + */ + function baseXor(arrays, iteratee, comparator) { + var length = arrays.length; + if (length < 2) { + return length ? baseUniq(arrays[0]) : []; + } + var index = -1, + result = Array(length); + + while (++index < length) { + var array = arrays[index], + othIndex = -1; + + while (++othIndex < length) { + if (othIndex != index) { + result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); + } + } + } + return baseUniq(baseFlatten(result, 1), iteratee, comparator); + } + + /** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ + function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; + } + + /** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array|Object} Returns the cast array-like object. + */ + function castArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } + + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ + function castFunction(value) { + return typeof value == 'function' ? value : identity; + } + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); + } + + /** + * A `baseRest` alias which can be replaced with `identity` by module + * replacement plugins. + * + * @private + * @type {Function} + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ + var castRest = baseRest; + + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); + } + + /** + * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout). + * + * @private + * @param {number|Object} id The timer id or timeout object of the timer to clear. + */ + var clearTimeout = ctxClearTimeout || function(id) { + return root.clearTimeout(id); + }; + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = isSymbol(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = isSymbol(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; + } + + /** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, + leftIndex = -1, + leftLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + } + while (rangeLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, + holdersLength = holders.length, + rightIndex = -1, + rightLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; + + while (++argsIndex < rangeLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; + } + + /** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbolsIn(source, object) { + return copyObject(source, getSymbolsIn(source), object); + } + + /** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + + return func(collection, setter, getIteratee(iteratee, 2), accumulator); + }; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createBind(func, bitmask, thisArg) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, arguments); + } + return wrapper; + } + + /** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new case function. + */ + function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = hasUnicode(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols + ? strSymbols[0] + : string.charAt(0); + + var trailing = strSymbols + ? castSlice(strSymbols, 1).join('') + : string.slice(1); + + return chr[methodName]() + trailing; + }; + } + + /** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtor(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. See + // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a function that wraps `func` to enable currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createCurry(func, bitmask, arity) { + var Ctor = createCtor(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getHolder(wrapper); + + while (index--) { + args[index] = arguments[index]; + } + var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) + ? [] + : replaceHolders(args, placeholder); + + length -= holders.length; + if (length < arity) { + return createRecurry( + func, bitmask, createHybrid, wrapper.placeholder, undefined, + args, holders, undefined, undefined, arity - length); + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return apply(fn, this, args); + } + return wrapper; + } + + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ + function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!isArrayLike(collection)) { + var iteratee = getIteratee(predicate, 3); + collection = keys(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; + } + + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return flatRest(function(funcs) { + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; + + if (fromRight) { + funcs.reverse(); + } + while (index--) { + var func = funcs[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? index : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && + data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) + ? wrapper[funcName]() + : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && isArray(value)) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }); + } + + /** + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided + * to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & WRAP_ARY_FLAG, + isBind = bitmask & WRAP_BIND_FLAG, + isBindKey = bitmask & WRAP_BIND_KEY_FLAG, + isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), + isFlip = bitmask & WRAP_FLIP_FLAG, + Ctor = isBindKey ? undefined : createCtor(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length; + + while (index--) { + args[index] = arguments[index]; + } + if (isCurried) { + var placeholder = getHolder(wrapper), + holdersCount = countHolders(args, placeholder); + } + if (partials) { + args = composeArgs(args, partials, holders, isCurried); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); + } + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurry( + func, bitmask, createHybrid, wrapper.placeholder, thisArg, + args, newHolders, argPos, ary, arity - length + ); + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + length = args.length; + if (argPos) { + args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); + } + if (isAry && ary < length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtor(fn); + } + return fn.apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ + function createInverter(setter, toIteratee) { + return function(object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; + } + + /** + * Creates a function that performs a mathematical operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @param {number} [defaultValue] The value used for `undefined` arguments. + * @returns {Function} Returns the new mathematical operation function. + */ + function createMathOperation(operator, defaultValue) { + return function(value, other) { + var result; + if (value === undefined && other === undefined) { + return defaultValue; + } + if (value !== undefined) { + result = value; + } + if (other !== undefined) { + if (result === undefined) { + return other; + } + if (typeof value == 'string' || typeof other == 'string') { + value = baseToString(value); + other = baseToString(other); + } else { + value = baseToNumber(value); + other = baseToNumber(other); + } + result = operator(value, other); + } + return result; + }; + } + + /** + * Creates a function like `_.over`. + * + * @private + * @param {Function} arrayFunc The function to iterate over iteratees. + * @returns {Function} Returns the new over function. + */ + function createOver(arrayFunc) { + return flatRest(function(iteratees) { + iteratees = arrayMap(iteratees, baseUnary(getIteratee())); + return baseRest(function(args) { + var thisArg = this; + return arrayFunc(iteratees, function(iteratee) { + return apply(iteratee, thisArg, args); + }); + }); + }); + } + + /** + * Creates the padding for `string` based on `length`. The `chars` string + * is truncated if the number of characters exceeds `length`. + * + * @private + * @param {number} length The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padding for `string`. + */ + function createPadding(length, chars) { + chars = chars === undefined ? ' ' : baseToString(chars); + + var charsLength = chars.length; + if (charsLength < 2) { + return charsLength ? baseRepeat(chars, length) : chars; + } + var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); + return hasUnicode(chars) + ? castSlice(stringToArray(result), 0, length).join('') + : result.slice(0, length); + } + + /** + * Creates a function that wraps `func` to invoke it with the `this` binding + * of `thisArg` and `partials` prepended to the arguments it receives. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to + * the new function. + * @returns {Function} Returns the new wrapped function. + */ + function createPartial(func, bitmask, thisArg, partials) { + var isBind = bitmask & WRAP_BIND_FLAG, + Ctor = createCtor(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return apply(fn, isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ + function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = toFinite(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); + return baseRange(start, end, step, fromRight); + }; + } + + /** + * Creates a function that performs a relational operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @returns {Function} Returns the new relational operation function. + */ + function createRelationalOperation(operator) { + return function(value, other) { + if (!(typeof value == 'string' && typeof other == 'string')) { + value = toNumber(value); + other = toNumber(other); + } + return operator(value, other); + }; + } + + /** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to + * the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & WRAP_CURRY_FLAG, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); + + if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { + bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); + } + var newData = [ + func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, + newHoldersRight, argPos, ary, arity + ]; + + var result = wrapFunc.apply(undefined, newData); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return setWrapToString(result, func, bitmask); + } + + /** + * Creates a function like `_.round`. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + number = toNumber(number); + precision = precision == null ? 0 : nativeMin(toInteger(precision), 292); + if (precision) { + // Shift with exponential notation to avoid floating-point issues. + // See [MDN](https://mdn.io/round#Examples) for more details. + var pair = (toString(number) + 'e').split('e'), + value = func(pair[0] + 'e' + (+pair[1] + precision)); + + pair = (toString(value) + 'e').split('e'); + return +(pair[0] + 'e' + (+pair[1] - precision)); + } + return func(number); + }; + } + + /** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ + var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { + return new Set(values); + }; + + /** + * Creates a `_.toPairs` or `_.toPairsIn` function. + * + * @private + * @param {Function} keysFunc The function to get the keys of a given object. + * @returns {Function} Returns the new pairs function. + */ + function createToPairs(keysFunc) { + return function(object) { + var tag = getTag(object); + if (tag == mapTag) { + return mapToArray(object); + } + if (tag == setTag) { + return setToPairs(object); + } + return baseToPairs(object, keysFunc(object)); + }; + } + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask flags. + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * 512 - `_.flip` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + + if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; + + if (data) { + mergeData(newData, data); + } + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] === undefined + ? (isBindKey ? 0 : func.length) + : nativeMax(newData[9] - length, 0); + + if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { + bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == WRAP_BIND_FLAG) { + var result = createBind(func, bitmask, thisArg); + } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { + result = createCurry(func, bitmask, arity); + } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { + result = createPartial(func, bitmask, thisArg, partials); + } else { + result = createHybrid.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setWrapToString(setter(result, newData), func, bitmask); + } + + /** + * Used by `_.defaults` to customize its `_.assignIn` use to assign properties + * of source objects to the destination object for all destination properties + * that resolve to `undefined`. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ + function customDefaultsAssignIn(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source + * objects into destination objects that are passed thru. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + * @returns {*} Returns the value to assign. + */ + function customDefaultsMerge(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, objValue); + baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack); + stack['delete'](srcValue); + } + return objValue; + } + + /** + * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain + * objects. + * + * @private + * @param {*} value The value to inspect. + * @param {string} key The key of the property to inspect. + * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. + */ + function customOmitClone(value) { + return isPlainObject(value) ? undefined : value; + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked && stack.get(other)) { + return stacked == other; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked && stack.get(other)) { + return stacked == other; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; + } + + /** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ + function flatRest(func) { + return setToString(overRest(func, undefined, flatten), func + ''); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = (func.name + ''), + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ + function getHolder(func) { + var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; + return object.placeholder; + } + + /** + * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, + * this function returns the custom method, otherwise it returns `baseIteratee`. + * If arguments are provided, the chosen function is invoked with them and + * its result is returned. + * + * @private + * @param {*} [value] The value to convert to an iteratee. + * @param {number} [arity] The arity of the created iteratee. + * @returns {Function} Returns the chosen function or its result. + */ + function getIteratee() { + var result = lodash.iteratee || iteratee; + result = result === iteratee ? baseIteratee : result; + return arguments.length ? result(arguments[0], arguments[1]) : result; + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = keys(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; + } + return result; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); + }; + + /** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; + }; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = baseGetTag(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Extracts wrapper details from the `source` body comment. + * + * @private + * @param {string} source The source to inspect. + * @returns {Array} Returns the wrapper details. + */ + function getWrapDetails(source) { + var match = source.match(reWrapDetails); + return match ? match[1].split(reSplitDetails) : []; + } + + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + path = castPath(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Inserts wrapper `details` in a comment at the top of the `source` body. + * + * @private + * @param {string} source The source to modify. + * @returns {Array} details The details to insert. + * @returns {string} Returns the modified source. + */ + function insertWrapDetails(source, details) { + var length = details.length; + if (!length) { + return source; + } + var lastIndex = length - 1; + details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; + details = details.join(length > 2 ? ', ' : ' '); + return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); + } + + /** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ + function isFlattenable(value) { + return isArray(value) || isArguments(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, + * else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `func` is capable of being masked. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `func` is maskable, else `false`. + */ + var isMaskable = coreJsData ? isFunction : stubFalse; + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ + function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; + } + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers used to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and + * `_.rearg` modify function arguments, making the order in which they are + * executed important, preventing the merging of metadata. However, we make + * an exception for a safe combined case where curried functions have `_.ary` + * and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); + + var isCombo = + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & WRAP_BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : value; + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = value; + } + // Use source `ary` if it's smaller. + if (srcBitmask & WRAP_ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString.call(value); + } + + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ + function overRest(func, start, transform) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = transform(array); + return apply(func, this, otherArgs); + }; + } + + /** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ + function parent(object, path) { + return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1)); + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = copyArray(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity + * function to avoid garbage collection pauses in V8. See + * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = shortOut(baseSetData); + + /** + * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout). + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @returns {number|Object} Returns the timer id or timeout object. + */ + var setTimeout = ctxSetTimeout || function(func, wait) { + return root.setTimeout(func, wait); + }; + + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var setToString = shortOut(baseSetToString); + + /** + * Sets the `toString` method of `wrapper` to mimic the source of `reference` + * with wrapper details in a comment at the top of the source body. + * + * @private + * @param {Function} wrapper The function to modify. + * @param {Function} reference The reference function. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Function} Returns `wrapper`. + */ + function setWrapToString(wrapper, reference, bitmask) { + var source = (reference + ''); + return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); + } + + /** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ + function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; + } + + /** + * A specialized version of `_.shuffle` which mutates and sets the size of `array`. + * + * @private + * @param {Array} array The array to shuffle. + * @param {number} [size=array.length] The size of `array`. + * @returns {Array} Returns `array`. + */ + function shuffleSelf(array, size) { + var index = -1, + length = array.length, + lastIndex = length - 1; + + size = size === undefined ? length : size; + while (++index < size) { + var rand = baseRandom(index, lastIndex), + value = array[rand]; + + array[rand] = array[index]; + array[index] = value; + } + array.length = size; + return array; + } + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + }); + + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * Updates wrapper `details` based on `bitmask` flags. + * + * @private + * @returns {Array} details The details to modify. + * @param {number} bitmask The bitmask flags. See `createWrap` for more details. + * @returns {Array} Returns `details`. + */ + function updateWrapDetails(details, bitmask) { + arrayEach(wrapFlags, function(pair) { + var value = '_.' + pair[0]; + if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { + details.push(value); + } + }); + return details.sort(); + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `array` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the new array of chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { + size = 1; + } else { + size = nativeMax(toInteger(size), 0); + } + var length = array == null ? 0 : array.length; + if (!length || size < 1) { + return []; + } + var index = 0, + resIndex = 0, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[resIndex++] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + function concat() { + var length = arguments.length; + if (!length) { + return []; + } + var args = Array(length - 1), + array = arguments[0], + index = length; + + while (index--) { + args[index - 1] = arguments[index]; + } + return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)); + } + + /** + * Creates an array of `array` values not included in the other given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * **Note:** Unlike `_.pullAll`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.without, _.xor + * @example + * + * _.difference([2, 1], [2, 3]); + * // => [1] + */ + var difference = baseRest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `iteratee` which + * is invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * **Note:** Unlike `_.pullAllBy`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2] + * + * // The `_.property` iteratee shorthand. + * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var differenceBy = baseRest(function(array, values) { + var iteratee = last(values); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `comparator` + * which is invoked to compare elements of `array` to `values`. The order and + * references of result values are determined by the first array. The comparator + * is invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.pullAllWith`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] + */ + var differenceWith = baseRest(function(array, values) { + var comparator = last(values); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.dropRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney'] + * + * // The `_.matches` iteratee shorthand. + * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropRightWhile(users, ['active', false]); + * // => objects for ['barney'] + * + * // The `_.property` iteratee shorthand. + * _.dropRightWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), true, true) + : []; + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.dropWhile(users, function(o) { return !o.active; }); + * // => objects for ['pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.dropWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropWhile(users, ['active', false]); + * // => objects for ['pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.dropWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), true) + : []; + } + + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @since 3.2.0 + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8, 10], '*', 1, 3); + * // => [4, '*', '*', 10] + */ + function fill(array, value, start, end) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ + function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseFindIndex(array, getIteratee(predicate, 3), index); + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); + * // => 2 + * + * // The `_.matches` iteratee shorthand. + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); + * // => 2 + * + * // The `_.property` iteratee shorthand. + * _.findLastIndex(users, 'active'); + * // => 0 + */ + function findLastIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = length - 1; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = fromIndex < 0 + ? nativeMax(length + index, 0) + : nativeMin(index, length - 1); + } + return baseFindIndex(array, getIteratee(predicate, 3), index, true); + } + + /** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ + function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, 1) : []; + } + + /** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ + function flattenDeep(array) { + var length = array == null ? 0 : array.length; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Array + * @param {Array} array The array to flatten. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] + */ + function flattenDepth(array, depth) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(array, depth); + } + + /** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. + * @example + * + * _.fromPairs([['a', 1], ['b', 2]]); + * // => { 'a': 1, 'b': 2 } + */ + function fromPairs(pairs) { + var index = -1, + length = pairs == null ? 0 : pairs.length, + result = {}; + + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + return result; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ + function head(array) { + return (array && array.length) ? array[0] : undefined; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the + * offset from the end of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ + function indexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return baseIndexOf(array, value, index); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 0, -1) : []; + } + + /** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by the first array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [2, 3]); + * // => [2] + */ + var intersection = baseRest(function(arrays) { + var mapped = arrayMap(arrays, castArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; + }); + + /** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which they're compared. The order and references of result values are + * determined by the first array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ + var intersectionBy = baseRest(function(arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); + + if (iteratee === last(mapped)) { + iteratee = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, getIteratee(iteratee, 2)) + : []; + }); + + /** + * This method is like `_.intersection` except that it accepts `comparator` + * which is invoked to compare elements of `arrays`. The order and references + * of result values are determined by the first array. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ + var intersectionWith = baseRest(function(arrays) { + var comparator = last(arrays), + mapped = arrayMap(arrays, castArrayLikeObject); + + comparator = typeof comparator == 'function' ? comparator : undefined; + if (comparator) { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, undefined, comparator) + : []; + }); + + /** + * Converts all elements in `array` into a string separated by `separator`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to convert. + * @param {string} [separator=','] The element separator. + * @returns {string} Returns the joined string. + * @example + * + * _.join(['a', 'b', 'c'], '~'); + * // => 'a~b~c' + */ + function join(array, separator) { + return array == null ? '' : nativeJoin.call(array, separator); + } + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // Search from the `fromIndex`. + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = length; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); + } + return value === value + ? strictLastIndexOf(array, value, index) + : baseFindIndex(array, baseIsNaN, index, true); + } + + /** + * Gets the element at index `n` of `array`. If `n` is negative, the nth + * element from the end is returned. + * + * @static + * @memberOf _ + * @since 4.11.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=0] The index of the element to return. + * @returns {*} Returns the nth element of `array`. + * @example + * + * var array = ['a', 'b', 'c', 'd']; + * + * _.nth(array, 1); + * // => 'b' + * + * _.nth(array, -2); + * // => 'c'; + */ + function nth(array, n) { + return (array && array.length) ? baseNth(array, toInteger(n)) : undefined; + } + + /** + * Removes all given values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` + * to remove elements from an array by predicate. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = ['a', 'b', 'c', 'a', 'b', 'c']; + * + * _.pull(array, 'a', 'c'); + * console.log(array); + * // => ['b', 'b'] + */ + var pull = baseRest(pullAll); + + /** + * This method is like `_.pull` except that it accepts an array of values to remove. + * + * **Note:** Unlike `_.difference`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = ['a', 'b', 'c', 'a', 'b', 'c']; + * + * _.pullAll(array, ['a', 'c']); + * console.log(array); + * // => ['b', 'b'] + */ + function pullAll(array, values) { + return (array && array.length && values && values.length) + ? basePullAll(array, values) + : array; + } + + /** + * This method is like `_.pullAll` except that it accepts `iteratee` which is + * invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The iteratee is invoked with one argument: (value). + * + * **Note:** Unlike `_.differenceBy`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; + * + * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); + * console.log(array); + * // => [{ 'x': 2 }] + */ + function pullAllBy(array, values, iteratee) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, getIteratee(iteratee, 2)) + : array; + } + + /** + * This method is like `_.pullAll` except that it accepts `comparator` which + * is invoked to compare elements of `array` to `values`. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.differenceWith`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; + * + * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); + * console.log(array); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] + */ + function pullAllWith(array, values, comparator) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, undefined, comparator) + : array; + } + + /** + * Removes elements from `array` corresponding to `indexes` and returns an + * array of removed elements. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = ['a', 'b', 'c', 'd']; + * var pulled = _.pullAt(array, [1, 3]); + * + * console.log(array); + * // => ['a', 'c'] + * + * console.log(pulled); + * // => ['b', 'd'] + */ + var pullAt = flatRest(function(array, indexes) { + var length = array == null ? 0 : array.length, + result = baseAt(array, indexes); + + basePullAt(array, arrayMap(indexes, function(index) { + return isIndex(index, length) ? +index : index; + }).sort(compareAscending)); + + return result; + }); + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is invoked + * with three arguments: (value, index, array). + * + * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` + * to pull elements from an array by value. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Array + * @param {Array} array The array to modify. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getIteratee(predicate, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } + + /** + * Reverses `array` so that the first element becomes the last, the second + * element becomes the second to last, and so on. + * + * **Note:** This method mutates `array` and is based on + * [`Array#reverse`](https://mdn.io/Array/reverse). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to modify. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.reverse(array); + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function reverse(array) { + return array == null ? array : nativeReverse.call(array); + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of + * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are + * returned. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + else { + start = start == null ? 0 : toInteger(start); + end = end === undefined ? length : toInteger(end); + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + */ + function sortedIndex(array, value) { + return baseSortedIndex(array, value); + } + + /** + * This method is like `_.sortedIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * var objects = [{ 'x': 4 }, { 'x': 5 }]; + * + * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); + * // => 0 + */ + function sortedIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); + } + + /** + * This method is like `_.indexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedIndexOf([4, 5, 5, 5, 6], 5); + * // => 1 + */ + function sortedIndexOf(array, value) { + var length = array == null ? 0 : array.length; + if (length) { + var index = baseSortedIndex(array, value); + if (index < length && eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 5, 5, 5, 6], 5); + * // => 4 + */ + function sortedLastIndex(array, value) { + return baseSortedIndex(array, value, true); + } + + /** + * This method is like `_.sortedLastIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * var objects = [{ 'x': 4 }, { 'x': 5 }]; + * + * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); + * // => 1 + * + * // The `_.property` iteratee shorthand. + * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); + * // => 1 + */ + function sortedLastIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); + } + + /** + * This method is like `_.lastIndexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); + * // => 3 + */ + function sortedLastIndexOf(array, value) { + var length = array == null ? 0 : array.length; + if (length) { + var index = baseSortedIndex(array, value, true) - 1; + if (eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.uniq` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniq([1, 1, 2]); + * // => [1, 2] + */ + function sortedUniq(array) { + return (array && array.length) + ? baseSortedUniq(array) + : []; + } + + /** + * This method is like `_.uniqBy` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); + * // => [1.1, 2.3] + */ + function sortedUniqBy(array, iteratee) { + return (array && array.length) + ? baseSortedUniq(array, getIteratee(iteratee, 2)) + : []; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.tail([1, 2, 3]); + * // => [2, 3] + */ + function tail(array) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 1, length) : []; + } + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + if (!(array && array.length)) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array == null ? 0 : array.length; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.takeRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeRightWhile(users, ['active', false]); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.takeRightWhile(users, 'active'); + * // => [] + */ + function takeRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), false, true) + : []; + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Array + * @param {Array} array The array to query. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.takeWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matches` iteratee shorthand. + * _.takeWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeWhile(users, ['active', false]); + * // => objects for ['barney', 'fred'] + * + * // The `_.property` iteratee shorthand. + * _.takeWhile(users, 'active'); + * // => [] + */ + function takeWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3)) + : []; + } + + /** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ + var union = baseRest(function(arrays) { + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); + }); + + /** + * This method is like `_.union` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by + * which uniqueness is computed. Result values are chosen from the first + * array in which the value occurs. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.unionBy([2.1], [1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + var unionBy = baseRest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)); + }); + + /** + * This method is like `_.union` except that it accepts `comparator` which + * is invoked to compare elements of `arrays`. Result values are chosen from + * the first array in which the value occurs. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.unionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var unionWith = baseRest(function(arrays) { + var comparator = last(arrays); + comparator = typeof comparator == 'function' ? comparator : undefined; + return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. The order of result values is determined by the order they occur + * in the array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + */ + function uniq(array) { + return (array && array.length) ? baseUniq(array) : []; + } + + /** + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The order of result values is determined by the + * order they occur in the array. The iteratee is invoked with one argument: + * (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniqBy(array, iteratee) { + return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : []; + } + + /** + * This method is like `_.uniq` except that it accepts `comparator` which + * is invoked to compare elements of `array`. The order of result values is + * determined by the order they occur in the array.The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.uniqWith(objects, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] + */ + function uniqWith(array, comparator) { + comparator = typeof comparator == 'function' ? comparator : undefined; + return (array && array.length) ? baseUniq(array, undefined, comparator) : []; + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @since 1.2.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + * + * _.unzip(zipped); + * // => [['a', 'b'], [1, 2], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var length = 0; + array = arrayFilter(array, function(group) { + if (isArrayLikeObject(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + return baseTimes(length, function(index) { + return arrayMap(array, baseProperty(index)); + }); + } + + /** + * This method is like `_.unzip` except that it accepts `iteratee` to specify + * how regrouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee=_.identity] The function to combine + * regrouped values. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ + function unzipWith(array, iteratee) { + if (!(array && array.length)) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + return arrayMap(result, function(group) { + return apply(iteratee, undefined, group); + }); + } + + /** + * Creates an array excluding all given values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.pull`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @see _.difference, _.xor + * @example + * + * _.without([2, 1, 2, 3], 1, 2); + * // => [3] + */ + var without = baseRest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array of unique values that is the + * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the given arrays. The order of result values is determined by the order + * they occur in the arrays. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of filtered values. + * @see _.difference, _.without + * @example + * + * _.xor([2, 1], [2, 3]); + * // => [1, 3] + */ + var xor = baseRest(function(arrays) { + return baseXor(arrayFilter(arrays, isArrayLikeObject)); + }); + + /** + * This method is like `_.xor` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by + * which by which they're compared. The order of result values is determined + * by the order they occur in the arrays. The iteratee is invoked with one + * argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); + * // => [1.2, 3.4] + * + * // The `_.property` iteratee shorthand. + * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var xorBy = baseRest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2)); + }); + + /** + * This method is like `_.xor` except that it accepts `comparator` which is + * invoked to compare elements of `arrays`. The order of result values is + * determined by the order they occur in the arrays. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.xorWith(objects, others, _.isEqual); + * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var xorWith = baseRest(function(arrays) { + var comparator = last(arrays); + comparator = typeof comparator == 'function' ? comparator : undefined; + return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); + }); + + /** + * Creates an array of grouped elements, the first of which contains the + * first elements of the given arrays, the second of which contains the + * second elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['a', 'b'], [1, 2], [true, false]); + * // => [['a', 1, true], ['b', 2, false]] + */ + var zip = baseRest(unzip); + + /** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ + function zipObject(props, values) { + return baseZipObject(props || [], values || [], assignValue); + } + + /** + * This method is like `_.zipObject` except that it supports property paths. + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); + * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } + */ + function zipObjectDeep(props, values) { + return baseZipObject(props || [], values || [], baseSet); + } + + /** + * This method is like `_.zip` except that it accepts `iteratee` to specify + * how grouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee=_.identity] The function to combine + * grouped values. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { + * return a + b + c; + * }); + * // => [111, 222] + */ + var zipWith = baseRest(function(arrays) { + var length = arrays.length, + iteratee = length > 1 ? arrays[length - 1] : undefined; + + iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; + return unzipWith(arrays, iteratee); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` wrapper instance that wraps `value` with explicit method + * chain sequences enabled. The result of such sequences must be unwrapped + * with `_#value`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain sequence in order to modify intermediate results. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * // Mutate input array. + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain sequence. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor) { + return interceptor(value); + } + + /** + * This method is the wrapper version of `_.at`. + * + * @name at + * @memberOf _ + * @since 1.0.0 + * @category Seq + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _(object).at(['a[0].b.c', 'a[1]']).value(); + * // => [3, 4] + */ + var wrapperAt = flatRest(function(paths) { + var length = paths.length, + start = length ? paths[0] : 0, + value = this.__wrapped__, + interceptor = function(object) { return baseAt(object, paths); }; + + if (length > 1 || this.__actions__.length || + !(value instanceof LazyWrapper) || !isIndex(start)) { + return this.thru(interceptor); + } + value = value.slice(start, +start + (length ? 1 : 0)); + value.__actions__.push({ + 'func': thru, + 'args': [interceptor], + 'thisArg': undefined + }); + return new LodashWrapper(value, this.__chain__).thru(function(array) { + if (length && !array.length) { + array.push(undefined); + } + return array; + }); + }); + + /** + * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. + * + * @name chain + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // A sequence without explicit chaining. + * _(users).head(); + * // => { 'user': 'barney', 'age': 36 } + * + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chain sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * Gets the next value on a wrapped object following the + * [iterator protocol](https://mdn.io/iteration_protocols#iterator). + * + * @name next + * @memberOf _ + * @since 4.0.0 + * @category Seq + * @returns {Object} Returns the next iterator value. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped.next(); + * // => { 'done': false, 'value': 1 } + * + * wrapped.next(); + * // => { 'done': false, 'value': 2 } + * + * wrapped.next(); + * // => { 'done': true, 'value': undefined } + */ + function wrapperNext() { + if (this.__values__ === undefined) { + this.__values__ = toArray(this.value()); + } + var done = this.__index__ >= this.__values__.length, + value = done ? undefined : this.__values__[this.__index__++]; + + return { 'done': done, 'value': value }; + } + + /** + * Enables the wrapper to be iterable. + * + * @name Symbol.iterator + * @memberOf _ + * @since 4.0.0 + * @category Seq + * @returns {Object} Returns the wrapper object. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped[Symbol.iterator]() === wrapped; + * // => true + * + * Array.from(wrapped); + * // => [1, 2] + */ + function wrapperToIterator() { + return this; + } + + /** + * Creates a clone of the chain sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @since 3.2.0 + * @category Seq + * @param {*} value The value to plant. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2]).map(square); + * var other = wrapped.plant([3, 4]); + * + * other.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + clone.__index__ = 0; + clone.__values__ = undefined; + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * This method is the wrapper version of `_.reverse`. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @since 0.1.0 + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ + 'func': thru, + 'args': [reverse], + 'thisArg': undefined + }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(reverse); + } + + /** + * Executes the chain sequence to resolve the unwrapped value. + * + * @name value + * @memberOf _ + * @since 0.1.0 + * @alias toJSON, valueOf + * @category Seq + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the number of times the key was returned by `iteratee`. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': 1, '6': 2 } + * + * // The `_.property` iteratee shorthand. + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + ++result[key]; + } else { + baseAssignValue(result, key, 1); + } + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * **Note:** This method returns `true` for + * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because + * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of + * elements of empty collections. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, guard) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + */ + function filter(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ + var find = createFind(findIndex); + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=collection.length-1] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + var findLast = createFind(findLastIndex); + + /** + * Creates a flattened array of values by running each element in `collection` + * thru `iteratee` and flattening the mapped results. The iteratee is invoked + * with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _.flatMap([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ + function flatMap(collection, iteratee) { + return baseFlatten(map(collection, iteratee), 1); + } + + /** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDeep([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ + function flatMapDeep(collection, iteratee) { + return baseFlatten(map(collection, iteratee), INFINITY); + } + + /** + * This method is like `_.flatMap` except that it recursively flattens the + * mapped results up to `depth` times. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [[[n, n]]]; + * } + * + * _.flatMapDepth([1, 2], duplicate, 2); + * // => [[1, 1], [2, 2]] + */ + function flatMapDepth(collection, iteratee, depth) { + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(map(collection, iteratee), depth); + } + + /** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forEach(collection, iteratee) { + var func = isArray(collection) ? arrayEach : baseEach; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @alias eachRight + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEach + * @example + * + * _.forEachRight([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `2` then `1`. + */ + function forEachRight(collection, iteratee) { + var func = isArray(collection) ? arrayEachRight : baseEachRight; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The order of grouped values + * is determined by the order they occur in `collection`. The corresponding + * value of each key is an array of elements responsible for generating the + * key. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } + * + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + baseAssignValue(result, key, [value]); + } + }); + + /** + * Checks if `value` is in `collection`. If `collection` is a string, it's + * checked for a substring of `value`, otherwise + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'a': 1, 'b': 2 }, 1); + * // => true + * + * _.includes('abcd', 'bc'); + * // => true + */ + function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); + } + + /** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `path` is a function, it's invoked + * for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke each method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invokeMap([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + var invokeMap = baseRest(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args); + }); + return result; + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` thru `iteratee`. The corresponding value of + * each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ + var keyBy = createAggregator(function(result, value, key) { + baseAssignValue(result, key, value); + }); + + /** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee) { + var func = isArray(collection) ? arrayMap : baseMap; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.sortBy` except that it allows specifying the sort + * orders of the iteratees to sort by. If `orders` is unspecified, all values + * are sorted in ascending order. Otherwise, specify an order of "desc" for + * descending or "asc" for ascending sort order of corresponding values. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] + * The iteratees to sort by. + * @param {string[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // Sort by `user` in ascending order and by `age` in descending order. + * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] + */ + function orderBy(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + orders = guard ? undefined : orders; + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseOrderBy(collection, iteratees, orders); + } + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, the second of which + * contains elements `predicate` returns falsey for. The predicate is + * invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * _.partition(users, function(o) { return o.active; }); + * // => objects for [['fred'], ['barney', 'pebbles']] + * + * // The `_.matches` iteratee shorthand. + * _.partition(users, { 'age': 1, 'active': false }); + * // => objects for [['pebbles'], ['barney', 'fred']] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.partition(users, ['active', false]); + * // => objects for [['barney', 'pebbles'], ['fred']] + * + * // The `_.property` iteratee shorthand. + * _.partition(users, 'active'); + * // => objects for [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ + function reduce(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduce : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); + } + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduce + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduceRight : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); + } + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.filter + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * _.reject(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.reject(users, { 'age': 40, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.reject(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.reject(users, 'active'); + * // => objects for ['barney'] + */ + function reject(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, negate(getIteratee(predicate, 3))); + } + + /** + * Gets a random element from `collection`. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + */ + function sample(collection) { + var func = isArray(collection) ? arraySample : baseSample; + return func(collection); + } + + /** + * Gets `n` random elements at unique keys from `collection` up to the + * size of `collection`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @param {number} [n=1] The number of elements to sample. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the random elements. + * @example + * + * _.sampleSize([1, 2, 3], 2); + * // => [3, 1] + * + * _.sampleSize([1, 2, 3], 4); + * // => [2, 3, 1] + */ + function sampleSize(collection, n, guard) { + if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) { + n = 1; + } else { + n = toInteger(n); + } + var func = isArray(collection) ? arraySampleSize : baseSampleSize; + return func(collection, n); + } + + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + var func = isArray(collection) ? arrayShuffle : baseShuffle; + return func(collection); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + if (collection == null) { + return 0; + } + if (isArrayLike(collection)) { + return isString(collection) ? stringSize(collection) : collection.length; + } + var tag = getTag(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return baseKeys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, guard) { + var func = isArray(collection) ? arraySome : baseSome; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] + */ + var sortBy = baseRest(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return baseOrderBy(collection, baseFlatten(iteratees, 1), []); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ + var now = ctxNow || function() { + return root.Date.now(); + }; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => Logs 'done saving!' after the two async saves have completed. + */ + function after(n, func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that invokes `func`, with up to `n` arguments, + * ignoring any additional arguments. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new capped function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + n = guard ? undefined : n; + n = (func && n == null) ? func.length : n; + return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => Allows adding up to 4 contacts to the list. + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and `partials` prepended to the arguments it receives. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * function greet(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = baseRest(function(func, thisArg, partials) { + var bitmask = WRAP_BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bind)); + bitmask |= WRAP_PARTIAL_FLAG; + } + return createWrap(func, bitmask, thisArg, partials, holders); + }); + + /** + * Creates a function that invokes the method at `object[key]` with `partials` + * prepended to the arguments it receives. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. See + * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Function + * @param {Object} object The object to invoke the method on. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // Bound with placeholders. + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = baseRest(function(object, key, partials) { + var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bindKey)); + bitmask |= WRAP_PARTIAL_FLAG; + } + return createWrap(key, bitmask, object, partials, holders); + }); + + /** + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + function curry(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curry.placeholder; + return result; + } + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + function curryRight(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryRight.placeholder; + return result; + } + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + timeWaiting = wait - timeSinceLastCall; + + return maxing + ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) + : timeWaiting; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => Logs 'deferred' after one millisecond. + */ + var defer = baseRest(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => Logs 'later' after one second. + */ + var delay = baseRest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); + }); + + /** + * Creates a function that invokes `func` with arguments reversed. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to flip arguments for. + * @returns {Function} Returns the new flipped function. + * @example + * + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + */ + function flip(func) { + return createWrap(func, WRAP_FLIP_FLAG); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Expose `MapCache`. + memoize.Cache = MapCache; + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new negated function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + var args = arguments; + switch (args.length) { + case 0: return !predicate.call(this); + case 1: return !predicate.call(this, args[0]); + case 2: return !predicate.call(this, args[0], args[1]); + case 3: return !predicate.call(this, args[0], args[1], args[2]); + } + return !predicate.apply(this, args); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // => `createApplication` is invoked once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with its arguments transformed. + * + * @static + * @since 4.0.0 + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms=[_.identity]] + * The argument transforms. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var func = _.overArgs(function(x, y) { + * return [x, y]; + * }, [square, doubled]); + * + * func(9, 3); + * // => [81, 6] + * + * func(10, 5); + * // => [100, 10] + */ + var overArgs = castRest(function(func, transforms) { + transforms = (transforms.length == 1 && isArray(transforms[0])) + ? arrayMap(transforms[0], baseUnary(getIteratee())) + : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); + + var funcsLength = transforms.length; + return baseRest(function(args) { + var index = -1, + length = nativeMin(args.length, funcsLength); + + while (++index < length) { + args[index] = transforms[index].call(this, args[index]); + } + return apply(func, this, args); + }); + }); + + /** + * Creates a function that invokes `func` with `partials` prepended to the + * arguments it receives. This method is like `_.bind` except it does **not** + * alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @since 0.2.0 + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * function greet(greeting, name) { + * return greeting + ' ' + name; + * } + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // Partially applied with placeholders. + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + var partial = baseRest(function(func, partials) { + var holders = replaceHolders(partials, getHolder(partial)); + return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders); + }); + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to the arguments it receives. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * function greet(greeting, name) { + * return greeting + ' ' + name; + * } + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // Partially applied with placeholders. + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + var partialRight = baseRest(function(func, partials) { + var holders = replaceHolders(partials, getHolder(partialRight)); + return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders); + }); + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified `indexes` where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, [2, 0, 1]); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + */ + var rearg = flatRest(function(func, indexes) { + return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes); + }); + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as + * an array. + * + * **Note:** This method is based on the + * [rest parameter](https://mdn.io/rest_parameters). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.rest(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function rest(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = start === undefined ? start : toInteger(start); + return baseRest(func, start); + } + + /** + * Creates a function that invokes `func` with the `this` binding of the + * create function and an array of arguments much like + * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply). + * + * **Note:** This method is based on the + * [spread operator](https://mdn.io/spread_operator). + * + * @static + * @memberOf _ + * @since 3.2.0 + * @category Function + * @param {Function} func The function to spread arguments over. + * @param {number} [start=0] The start position of the spread. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ + function spread(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = start == null ? 0 : nativeMax(toInteger(start), 0); + return baseRest(function(args) { + var array = args[start], + otherArgs = castSlice(args, 0, start); + + if (array) { + arrayPush(otherArgs, array); + } + return apply(func, this, otherArgs); + }); + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide `options` to indicate whether `func` + * should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the throttled function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=true] + * Specify invoking on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } + + /** + * Creates a function that accepts up to one argument, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + * @example + * + * _.map(['6', '8', '10'], _.unary(parseInt)); + * // => [6, 8, 10] + */ + function unary(func) { + return ary(func, 1); + } + + /** + * Creates a function that provides `value` to `wrapper` as its first + * argument. Any additional arguments provided to the function are appended + * to those provided to the `wrapper`. The wrapper is invoked with the `this` + * binding of the created function. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {*} value The value to wrap. + * @param {Function} [wrapper=identity] The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

fred, barney, & pebbles

' + */ + function wrap(value, wrapper) { + return partial(castFunction(wrapper), value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @since 4.4.0 + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + return baseClone(value, CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined`, + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @see _.cloneDeepWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ + function cloneWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseClone(value, CLONE_SYMBOLS_FLAG, customizer); + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); + } + + /** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @see _.cloneWith + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ + function cloneDeepWith(value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer); + } + + /** + * Checks if `object` conforms to `source` by invoking the predicate + * properties of `source` with the corresponding property values of `object`. + * + * **Note:** This method is equivalent to `_.conforms` when `source` is + * partially applied. + * + * @static + * @memberOf _ + * @since 4.14.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property predicates to conform to. + * @returns {boolean} Returns `true` if `object` conforms, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); + * // => true + * + * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); + * // => false + */ + function conformsTo(object, source) { + return source == null || baseConformsTo(object, source, keys(source)); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + * @see _.lt + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + var gt = createRelationalOperation(baseGt); + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to + * `other`, else `false`. + * @see _.lte + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + var gte = createRelationalOperation(function(value, other) { + return value >= other; + }); + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ + var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && baseGetTag(value) == boolTag); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a date object, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; + + /** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value); + } + + /** + * Checks if `value` is an empty object, collection, map, or set. + * + * Objects are considered empty if they have no own enumerable string keyed + * properties. + * + * Array-like values such as `arguments` objects, arrays, buffers, strings, or + * jQuery-like collections are considered empty if they have a `length` of `0`. + * Similarly, maps and sets are considered empty if they have a `size` of `0`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && + (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || + isBuffer(value) || isTypedArray(value) || isArguments(value))) { + return !value.length; + } + var tag = getTag(value); + if (tag == mapTag || tag == setTag) { + return !value.size; + } + if (isPrototype(value)) { + return !baseKeys(value).length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ + function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + if (!isObjectLike(value)) { + return false; + } + var tag = baseGetTag(value); + return tag == errorTag || tag == domExcTag || + (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on + * [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MIN_VALUE); + * // => true + * + * _.isFinite(Infinity); + * // => false + * + * _.isFinite('3'); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** + * Checks if `value` is an integer. + * + * **Note:** This method is based on + * [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ + function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ + var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + + /** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. + * + * **Note:** This method is equivalent to `_.matches` when `source` is + * partially applied. + * + * Partial comparisons will match empty array and empty object `source` + * values against any array or object value, respectively. See `_.isEqual` + * for a list of supported value comparisons. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * + * _.isMatch(object, { 'b': 2 }); + * // => true + * + * _.isMatch(object, { 'b': 1 }); + * // => false + */ + function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); + } + + /** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined`, comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ + function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseIsMatch(object, source, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is based on + * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as + * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for + * `undefined` and other non-number values. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some + // ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a pristine native function. + * + * **Note:** This method can't reliably detect native functions in the presence + * of the core-js package because core-js circumvents this kind of detection. + * Despite multiple requests, the core-js maintainer has made it clear: any + * attempt to fix the detection will be obstructed. As a result, we're left + * with little choice but to throw an error. Unfortunately, this also affects + * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), + * which rely on core-js. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (isMaskable(value)) { + throw new Error(CORE_ERROR_TEXT); + } + return baseIsNative(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ + function isNil(value) { + return value == null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are + * classified as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a number, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && baseGetTag(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + + /** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on + * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ + function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ + var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag); + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ + function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; + } + + /** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ + function isWeakSet(value) { + return isObjectLike(value) && baseGetTag(value) == weakSetTag; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + * @see _.gt + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + var lt = createRelationalOperation(baseLt); + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @since 3.9.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to + * `other`, else `false`. + * @see _.gte + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + var lte = createRelationalOperation(function(value, other) { + return value <= other; + }); + + /** + * Converts `value` to an array. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!value) { + return []; + } + if (isArrayLike(value)) { + return isString(value) ? stringToArray(value) : copyArray(value); + } + if (symIterator && value[symIterator]) { + return iteratorToArray(value[symIterator]()); + } + var tag = getTag(value), + func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); + + return func(value); + } + + /** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + + /** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ + function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; + } + + /** + * Converts `value` to an integer suitable for use as the length of an + * array-like object. + * + * **Note:** This method is based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toLength(3.2); + * // => 3 + * + * _.toLength(Number.MIN_VALUE); + * // => 0 + * + * _.toLength(Infinity); + * // => 4294967295 + * + * _.toLength('3.2'); + * // => 3 + */ + function toLength(value) { + return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * Converts `value` to a safe integer. A safe integer can be compared and + * represented correctly. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toSafeInteger(3.2); + * // => 3 + * + * _.toSafeInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toSafeInteger(Infinity); + * // => 9007199254740991 + * + * _.toSafeInteger('3.2'); + * // => 3 + */ + function toSafeInteger(value) { + return value + ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) + : (value === 0 ? value : 0); + } + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assign({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3 } + */ + var assign = createAssigner(function(object, source) { + if (isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } + }); + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assign + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assignIn({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } + */ + var assignIn = createAssigner(function(object, source) { + copyObject(source, keysIn(source), object); + }); + + /** + * This method is like `_.assignIn` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keysIn(source), object, customizer); + }); + + /** + * This method is like `_.assign` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignInWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keys(source), object, customizer); + }); + + /** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Array} Returns the picked values. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + */ + var at = flatRest(baseAt); + + /** + * Creates an object that inherits from the `prototype` object. If a + * `properties` object is given, its own enumerable string keyed properties + * are assigned to the created object. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties == null ? result : baseAssign(result, properties); + } + + /** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var defaults = baseRest(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = keysIn(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; + }); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaults + * @example + * + * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); + * // => { 'a': { 'b': 2, 'c': 3 } } + */ + var defaultsDeep = baseRest(function(args) { + args.push(undefined, customDefaultsMerge); + return apply(mergeWith, undefined, args); + }); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); + } + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, + * else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + function findLastKey(object, predicate) { + return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); + } + + /** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ + function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, getIteratee(iteratee, 3), keysIn); + } + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forIn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. + */ + function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, getIteratee(iteratee, 3), keysIn); + } + + /** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forOwn(object, iteratee) { + return object && baseForOwn(object, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @since 2.0.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwn + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. + */ + function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, getIteratee(iteratee, 3)); + } + + /** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functionsIn + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ + function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); + } + + /** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the function names. + * @see _.functions + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ + function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return object != null && hasPath(object, path, baseHas); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite + * property assignments of previous values. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ + var invert = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + result[value] = key; + }, constant(identity)); + + /** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` thru `iteratee`. The + * corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.1.0 + * @category Object + * @param {Object} object The object to invert. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ + var invertBy = createInverter(function(result, value, key) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + }, getIteratee); + + /** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ + var invoke = baseRest(baseInvoke); + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * string keyed property of `object` thru `iteratee`. The iteratee is invoked + * with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @since 3.8.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapValues + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, iteratee(value, key, object), value); + }); + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + baseAssignValue(result, key, iteratee(value, key, object)); + }); + return result; + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable string keyed properties of source objects into the + * destination object. Source properties that resolve to `undefined` are + * skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 0.5.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var object = { + * 'a': [{ 'b': 2 }, { 'd': 4 }] + * }; + * + * var other = { + * 'a': [{ 'c': 3 }, { 'e': 5 }] + * }; + * + * _.merge(object, other); + * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined`, merging is handled by the + * method instead. The `customizer` is invoked with six arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { 'a': [1], 'b': [2] }; + * var other = { 'a': [3], 'b': [4] }; + * + * _.mergeWith(object, other, customizer); + * // => { 'a': [1, 3], 'b': [2, 4] } + */ + var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); + }); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable property paths of `object` that are not omitted. + * + * **Note:** This method is considerably slower than `_.pick`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to omit. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } + */ + var omit = flatRest(function(object, paths) { + var result = {}; + if (object == null) { + return result; + } + var isDeep = false; + paths = arrayMap(paths, function(path) { + path = castPath(path, object); + isDeep || (isDeep = path.length > 1); + return path; + }); + copyObject(object, getAllKeysIn(object), result); + if (isDeep) { + result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); + } + var length = paths.length; + while (length--) { + baseUnset(result, paths[length]); + } + return result; + }); + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable string keyed properties of `object` that + * `predicate` doesn't return truthy for. The predicate is invoked with two + * arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + return pickBy(object, negate(getIteratee(predicate))); + } + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = flatRest(function(object, paths) { + return object == null ? {} : basePick(object, paths); + }); + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The source object. + * @param {Function} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = getIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); + } + + /** + * This method is like `_.get` except that if the resolved value is a + * function it's invoked with the `this` binding of its parent object and + * its result is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + path = castPath(path, object); + + var index = -1, + length = path.length; + + // Ensure the loop is entered when path is empty. + if (!length) { + length = 1; + object = undefined; + } + while (++index < length) { + var value = object == null ? undefined : object[toKey(path[index])]; + if (value === undefined) { + index = length; + value = defaultValue; + } + object = isFunction(value) ? value.call(object) : value; + } + return object; + } + + /** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, ['x', '0', 'y', 'z'], 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); + } + + /** + * This method is like `_.set` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.setWith(object, '[0][1]', 'a', Object); + * // => { '0': { '1': 'a' } } + */ + function setWith(object, path, value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseSet(object, path, value, customizer); + } + + /** + * Creates an array of own enumerable string keyed-value pairs for `object` + * which can be consumed by `_.fromPairs`. If `object` is a map or set, its + * entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entries + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairs(new Foo); + * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) + */ + var toPairs = createToPairs(keys); + + /** + * Creates an array of own and inherited enumerable string keyed-value pairs + * for `object` which can be consumed by `_.fromPairs`. If `object` is a map + * or set, its entries are returned. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @alias entriesIn + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairsIn(new Foo); + * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) + */ + var toPairsIn = createToPairs(keysIn); + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable string keyed properties thru `iteratee`, with each invocation + * potentially mutating the `accumulator` object. If `accumulator` is not + * provided, a new object with the same `[[Prototype]]` will be used. The + * iteratee is invoked with four arguments: (accumulator, value, key, object). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 1.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }, []); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function transform(object, iteratee, accumulator) { + var isArr = isArray(object), + isArrLike = isArr || isBuffer(object) || isTypedArray(object); + + iteratee = getIteratee(iteratee, 4); + if (accumulator == null) { + var Ctor = object && object.constructor; + if (isArrLike) { + accumulator = isArr ? new Ctor : []; + } + else if (isObject(object)) { + accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; + } + else { + accumulator = {}; + } + } + (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Removes the property at `path` of `object`. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 7 } }] }; + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + * + * _.unset(object, ['a', '0', 'b', 'c']); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + */ + function unset(object, path) { + return object == null ? true : baseUnset(object, path); + } + + /** + * This method is like `_.set` except that accepts `updater` to produce the + * value to set. Use `_.updateWith` to customize `path` creation. The `updater` + * is invoked with one argument: (value). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.update(object, 'a[0].b.c', function(n) { return n * n; }); + * console.log(object.a[0].b.c); + * // => 9 + * + * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); + * console.log(object.x[0].y.z); + * // => 0 + */ + function update(object, path, updater) { + return object == null ? object : baseUpdate(object, path, castFunction(updater)); + } + + /** + * This method is like `_.update` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.6.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.updateWith(object, '[0][1]', _.constant('a'), Object); + * // => { '0': { '1': 'a' } } + */ + function updateWith(object, path, updater, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); + } + + /** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object == null ? [] : baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable string keyed property + * values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return object == null ? [] : baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ + function clamp(number, lower, upper) { + if (upper === undefined) { + upper = lower; + lower = undefined; + } + if (upper !== undefined) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); + } + + /** + * Checks if `n` is between `start` and up to, but not including, `end`. If + * `end` is not specified, it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @since 3.3.0 + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @see _.range, _.rangeRight + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ + function inRange(number, start, end) { + start = toFinite(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = toFinite(end); + } + number = toNumber(number); + return baseInRange(number, start, end); + } + + /** + * Produces a random number between the inclusive `lower` and `upper` bounds. + * If only one argument is provided a number between `0` and the given number + * is returned. If `floating` is `true`, or either `lower` or `upper` are + * floats, a floating-point number is returned instead of an integer. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @memberOf _ + * @since 0.7.0 + * @category Number + * @param {number} [lower=0] The lower bound. + * @param {number} [upper=1] The upper bound. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(lower, upper, floating) { + if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { + upper = floating = undefined; + } + if (floating === undefined) { + if (typeof upper == 'boolean') { + floating = upper; + upper = undefined; + } + else if (typeof lower == 'boolean') { + floating = lower; + lower = undefined; + } + } + if (lower === undefined && upper === undefined) { + lower = 0; + upper = 1; + } + else { + lower = toFinite(lower); + if (upper === undefined) { + upper = lower; + lower = 0; + } else { + upper = toFinite(upper); + } + } + if (lower > upper) { + var temp = lower; + lower = upper; + upper = temp; + } + if (floating || lower % 1 || upper % 1) { + var rand = nativeRandom(); + return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); + } + return baseRandom(lower, upper); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar--'); + * // => 'fooBar' + * + * _.camelCase('__FOO_BAR__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); + }); + + /** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ + function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); + } + + /** + * Deburrs `string` by converting + * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) + * letters to basic Latin letters and removing + * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = toString(string); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search up to. + * @returns {boolean} Returns `true` if `string` ends with `target`, + * else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = toString(string); + target = baseToString(target); + + var length = string.length; + position = position === undefined + ? length + : baseClamp(toInteger(position), 0, length); + + var end = position; + position -= target.length; + return position >= 0 && string.slice(position, end) == target; + } + + /** + * Converts the characters "&", "<", ">", '"', and "'" in `string` to their + * corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. See + * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * When working with HTML you should always + * [quote attribute values](http://wonko.com/post/html-escaping) to reduce + * XSS vectors. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ + function escapeRegExp(string) { + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; + } + + /** + * Converts `string` to + * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__FOO_BAR__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Converts `string`, as space separated words, to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the lower cased string. + * @example + * + * _.lowerCase('--Foo-Bar--'); + * // => 'foo bar' + * + * _.lowerCase('fooBar'); + * // => 'foo bar' + * + * _.lowerCase('__FOO_BAR__'); + * // => 'foo bar' + */ + var lowerCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + word.toLowerCase(); + }); + + /** + * Converts the first character of `string` to lower case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.lowerFirst('Fred'); + * // => 'fred' + * + * _.lowerFirst('FRED'); + * // => 'fRED' + */ + var lowerFirst = createCaseFirst('toLowerCase'); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + if (!length || strLength >= length) { + return string; + } + var mid = (length - strLength) / 2; + return ( + createPadding(nativeFloor(mid), chars) + + string + + createPadding(nativeCeil(mid), chars) + ); + } + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padEnd('abc', 6); + * // => 'abc ' + * + * _.padEnd('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padEnd('abc', 3); + * // => 'abc' + */ + function padEnd(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + return (length && strLength < length) + ? (string + createPadding(length - strLength, chars)) + : string; + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padStart('abc', 6); + * // => ' abc' + * + * _.padStart('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padStart('abc', 3); + * // => 'abc' + */ + function padStart(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = length ? stringSize(string) : 0; + return (length && strLength < length) + ? (createPadding(length - strLength, chars) + string) + : string; + } + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a + * hexadecimal, in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the + * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category String + * @param {string} string The string to convert. + * @param {number} [radix=10] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + if (guard || radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=1] The number of times to repeat the string. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n, guard) { + if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) { + n = 1; + } else { + n = toInteger(n); + } + return baseRepeat(toString(string), n); + } + + /** + * Replaces matches for `pattern` in `string` with `replacement`. + * + * **Note:** This method is based on + * [`String#replace`](https://mdn.io/String/replace). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to modify. + * @param {RegExp|string} pattern The pattern to replace. + * @param {Function|string} replacement The match replacement. + * @returns {string} Returns the modified string. + * @example + * + * _.replace('Hi Fred', 'Fred', 'Barney'); + * // => 'Hi Barney' + */ + function replace() { + var args = arguments, + string = toString(args[0]); + + return args.length < 3 ? string : string.replace(args[1], args[2]); + } + + /** + * Converts `string` to + * [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--FOO-BAR--'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Splits `string` by `separator`. + * + * **Note:** This method is based on + * [`String#split`](https://mdn.io/String/split). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to split. + * @param {RegExp|string} separator The separator pattern to split by. + * @param {number} [limit] The length to truncate results to. + * @returns {Array} Returns the string segments. + * @example + * + * _.split('a-b-c', '-', 2); + * // => ['a', 'b'] + */ + function split(string, separator, limit) { + if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { + separator = limit = undefined; + } + limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0; + if (!limit) { + return []; + } + string = toString(string); + if (string && ( + typeof separator == 'string' || + (separator != null && !isRegExp(separator)) + )) { + separator = baseToString(separator); + if (!separator && hasUnicode(string)) { + return castSlice(stringToArray(string), 0, limit); + } + } + return string.split(separator, limit); + } + + /** + * Converts `string` to + * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @since 3.1.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar--'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__FOO_BAR__'); + * // => 'FOO BAR' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + upperFirst(word); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, + * else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = toString(string); + position = position == null + ? 0 + : baseClamp(toInteger(position), 0, string.length); + + target = baseToString(target); + return string.slice(position, position + target.length) == target; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is given, it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options={}] The options object. + * @param {RegExp} [options.escape=_.templateSettings.escape] + * The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] + * The "evaluate" delimiter. + * @param {Object} [options.imports=_.templateSettings.imports] + * An object to import into the template as free variables. + * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] + * The "interpolate" delimiter. + * @param {string} [options.sourceURL='lodash.templateSources[n]'] + * The sourceURL of the compiled template. + * @param {string} [options.variable='obj'] + * The data object variable name. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Function} Returns the compiled template function. + * @example + * + * // Use the "interpolate" delimiter to create a compiled template. + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // Use the HTML "escape" delimiter to escape data property values. + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': '