From 335ead8b38a4bbc142bca115743ed2e967ecd393 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Thu, 30 Oct 2025 12:41:00 +0200 Subject: [PATCH 1/4] added regis notied --- Gemfile | 2 + Gemfile.lock | 21 ++ app/controllers/auctions_controller.rb | 6 + app/models/offer.rb | 12 + .../metrics/unique_user_bidder_tracker.rb | 42 ++++ config/initializers/yabeda.rb | 9 + config/routes.rb | 2 + lib/tasks/generate_test_auction_data.rake | 212 ++++++++++++++++++ 8 files changed, 306 insertions(+) create mode 100644 app/services/metrics/unique_user_bidder_tracker.rb create mode 100644 config/initializers/yabeda.rb create mode 100644 lib/tasks/generate_test_auction_data.rake diff --git a/Gemfile b/Gemfile index 09869fe1c..fa13437d6 100644 --- a/Gemfile +++ b/Gemfile @@ -51,6 +51,8 @@ gem 'turbo-rails' gem 'valvat' gem 'view_component' gem 'webpush' +gem 'yabeda-rails' +gem 'yabeda-prometheus' group :development, :test do gem 'brakeman' diff --git a/Gemfile.lock b/Gemfile.lock index 447db40fa..0d8af9991 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -97,6 +97,8 @@ GEM airbrake-ruby (6.2.2) rbtree3 (~> 0.6) amazing_print (1.8.1) + anyway_config (2.7.2) + ruby-next-core (~> 1.0) ast (2.4.3) attr_required (1.0.2) base64 (0.3.0) @@ -158,6 +160,7 @@ GEM docile (1.4.1) domain_name (0.6.20240107) drb (2.2.3) + dry-initializer (3.2.0) email_validator (2.2.4) activemodel erb (5.0.2) @@ -382,6 +385,8 @@ GEM prettyprint prettyprint (0.2.0) prism (1.5.1) + prometheus-client (4.2.5) + base64 propshaft (1.2.1) actionpack (>= 7.0.0) activesupport (>= 7.0.0) @@ -506,6 +511,7 @@ GEM rbs (>= 3, < 5) ruby-lsp-rails (0.4.8) ruby-lsp (>= 0.26.0, < 0.27.0) + ruby-next-core (1.1.2) ruby-openai (8.3.0) event_stream_parser (>= 0.3.0, < 2.0.0) faraday (>= 1) @@ -606,6 +612,19 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) + yabeda (0.14.0) + anyway_config (>= 1.0, < 3) + concurrent-ruby + dry-initializer + yabeda-prometheus (0.9.1) + prometheus-client (>= 3.0, < 5.0) + rack + yabeda (~> 0.10) + yabeda-rails (0.10.0) + activesupport + anyway_config (>= 1.3, < 3) + railties + yabeda (~> 0.8) zeitwerk (2.7.3) PLATFORMS @@ -694,6 +713,8 @@ DEPENDENCIES web-console (>= 3.3.0) webmock webpush + yabeda-prometheus + yabeda-rails BUNDLED WITH 2.6.2 diff --git a/app/controllers/auctions_controller.rb b/app/controllers/auctions_controller.rb index 519da0e98..0f0bbb1ee 100644 --- a/app/controllers/auctions_controller.rb +++ b/app/controllers/auctions_controller.rb @@ -15,6 +15,8 @@ def index link_extra: 'data-turbo-action="advance"' ) + increment_home_page_total_views + respond_to do |format| format.html format.json @@ -34,6 +36,10 @@ def cors_preflight_check private + def increment_home_page_total_views + Yabeda.auction.home_page_total_views.increment + end + def fetch_auctions_list = Auction.active.search(params, current_user) def per_page_count diff --git a/app/models/offer.rb b/app/models/offer.rb index 335c8b7b9..abe0fe1d4 100644 --- a/app/models/offer.rb +++ b/app/models/offer.rb @@ -23,6 +23,7 @@ class Offer < ApplicationRecord after_create :update_auction_ends_at after_update :update_auction_ends_at + after_create :track_unique_bidder_metric def update_auction_ends_at return if auction.platform == 'blind' || auction.platform.nil? @@ -113,4 +114,15 @@ def total price * (DEFAULT_PRICE_VALUE + (Invoice.find_by(result: result)&.vat_rate || default_vat)) end + + private + + def track_unique_bidder_metric + return if user_id.nil? + + Metrics::UniqueUserBidderTracker.track(user_id) + rescue => e + Rails.logger.error("Failed to track unique bidder metric: #{e.message}") + Sentry.capture_exception(e) if defined?(Sentry) + end end diff --git a/app/services/metrics/unique_user_bidder_tracker.rb b/app/services/metrics/unique_user_bidder_tracker.rb new file mode 100644 index 000000000..b8f7d65f7 --- /dev/null +++ b/app/services/metrics/unique_user_bidder_tracker.rb @@ -0,0 +1,42 @@ +module Metrics + class UniqueUserBidderTracker + REDIS_KEY_PREFIX = "auction:unique_bidders" + TTL_SECONDS = 86400 # 24 hours + + def self.track(user_id, date: Date.current) + redis = redis_connection + key = daily_key(date) + + # Add to Redis set (O(1), idempotent) + was_new_bidder = redis.sadd(key, user_id) + + # Set expiration on key creation + redis.expire(key, TTL_SECONDS) unless redis.ttl(key) > 0 + + # Update Yabeda gauge + current_count = redis.scard(key) + Yabeda.auction.unique_bidders_daily.set({date: date.to_s}, current_count) + + Rails.logger.info("Unique bidder tracked: user_id=#{user_id}, date=#{date}, count=#{current_count}, new=#{was_new_bidder}") + + was_new_bidder + end + + def self.count(date: Date.current) + redis_connection.scard(daily_key(date)) + end + + def self.redis_connection + @redis ||= begin + url = ENV.fetch('REDIS_URL') { AuctionCenter::Application.config.customization[:cable_redis_url] } + Redis.new(url: url, timeout: 1, reconnect_attempts: 1) + end + end + + def self.daily_key(date) + "#{REDIS_KEY_PREFIX}:#{date.strftime('%Y%m%d')}" + end + + private_class_method :daily_key, :redis_connection + end +end diff --git a/config/initializers/yabeda.rb b/config/initializers/yabeda.rb new file mode 100644 index 000000000..2482adf0d --- /dev/null +++ b/config/initializers/yabeda.rb @@ -0,0 +1,9 @@ +Yabeda.configure do + group :auction do + counter :home_page_total_views, comment: 'Total views of the home page' + + gauge :unique_bidders_daily, + comment: 'Number of unique users who placed bids today', + tags: [:date] + end +end diff --git a/config/routes.rb b/config/routes.rb index b27a451cc..bad13864e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,8 @@ require 'constraints/administrator' Rails.application.routes.draw do + mount Yabeda::Prometheus::Exporter, at: "/metrics" if Rails.env.development? || Rails.env.staging? + namespace :admin do get 'finished_auctions/index' end diff --git a/lib/tasks/generate_test_auction_data.rake b/lib/tasks/generate_test_auction_data.rake new file mode 100644 index 000000000..e5f703ea1 --- /dev/null +++ b/lib/tasks/generate_test_auction_data.rake @@ -0,0 +1,212 @@ +namespace :auction do + namespace :test_data do + desc 'Generate test users, auctions, and historical bids for metrics testing' + task generate: :environment do + puts '๐Ÿš€ Starting test data generation...' + + # Configuration + users_count = 30 + auctions_count = 40 + days_back = 30 + min_bids_per_auction = 3 + max_bids_per_auction = 15 + + # Check if we're in development + unless Rails.env.development? + puts 'โŒ This task can only be run in development environment' + exit 1 + end + + # Step 1: Generate Users + puts "\n๐Ÿ“ Creating #{users_count} test users..." + users = [] + + users_count.times do |i| + email = "test_bidder_#{i + 1}@example.com" + + # Skip if user already exists + if User.exists?(email: email) + users << User.find_by(email: email) + next + end + + user = User.create!( + email: email, + password: 'Password123!', + password_confirmation: 'Password123!', + given_names: Faker::Name.first_name, + surname: Faker::Name.last_name, + alpha_two_country_code: 'EE', + mobile_phone: "+372#{rand(50000000..59999999)}", + roles: ['participant'], + terms_and_conditions_accepted_at: Time.zone.now, + confirmed_at: Time.zone.now, + mobile_phone_confirmed_at: Time.zone.now + ) + + users << user + print '.' + end + + puts "\nโœ… Created #{users.count} users" + + # Step 2: Create Billing Profiles for each user + puts "\n๐Ÿ“ Creating billing profiles..." + + users.each do |user| + next if user.billing_profiles.exists? + + BillingProfile.create!( + user: user, + name: user.display_name, + alpha_two_country_code: 'EE', + street: Faker::Address.street_address, + city: Faker::Address.city, + postal_code: rand(10000..99999).to_s + ) + print '.' + end + + puts "\nโœ… Created #{users.count} billing profiles" + + # Step 3: Generate Blind Auctions + puts "\n๐Ÿ“ Creating #{auctions_count} blind auctions..." + auctions = [] + + auctions_count.times do |i| + # Generate auction dates spread over last 30 days + days_ago = rand(0..days_back) + starts_at = days_ago.days.ago.beginning_of_day + rand(8..18).hours + ends_at = starts_at + rand(3..7).days + + domain_name = "test-domain-#{SecureRandom.hex(4)}.ee" + + auction = Auction.create!( + domain_name: domain_name, + platform: :blind, # Blind auction (platform = 0) + starts_at: starts_at, + ends_at: ends_at, + starting_price: rand(100..1000).to_d, + skip_validation: true # Skip overlap validation for test data + ) + + auctions << auction + print '.' + end + + puts "\nโœ… Created #{auctions.count} auctions" + + # Step 4: Generate Historical Bids + puts "\n๐Ÿ“ Generating historical bids..." + total_bids = 0 + + auctions.each do |auction| + # Random number of bidders for this auction + bidders_count = rand(min_bids_per_auction..max_bids_per_auction) + + # Select random unique users for this auction + auction_bidders = users.sample(bidders_count) + + auction_bidders.each do |bidder| + billing_profile = bidder.billing_profiles.first + + # Generate bid price + bid_price = auction.starting_price + rand(50..500) + + # Generate bid timestamp within auction period + bid_time = auction.starts_at + rand(0..(auction.ends_at - auction.starts_at).to_i).seconds + + # Create offer with historical timestamp + offer = Offer.new( + auction: auction, + user: bidder, + billing_profile: billing_profile, + cents: (bid_price * 100).to_i, + skip_validation: true # Skip validation for test data + ) + + # Manually set timestamps to historical dates + offer.created_at = bid_time + offer.updated_at = bid_time + + # Save without callbacks to avoid triggering real-time metrics + offer.save!(validate: false) + + # Now manually trigger the metric tracking with historical date + begin + Metrics::UniqueUserBidderTracker.track(bidder.id, date: bid_time.to_date) + rescue => e + puts "\nโš ๏ธ Warning: Failed to track metric for user #{bidder.id}: #{e.message}" + end + + total_bids += 1 + print '.' + end + end + + puts "\nโœ… Created #{total_bids} historical bids" + + # Step 5: Summary Statistics + puts "\n" + "="*60 + puts "๐Ÿ“Š Test Data Generation Summary" + puts "="*60 + puts "Users created: #{users.count}" + puts "Auctions created: #{auctions.count}" + puts "Total bids created: #{total_bids}" + puts "Date range: #{days_back} days ago to today" + puts "" + + # Unique bidders per day statistics + puts "๐Ÿ“ˆ Unique Bidders by Day:" + (0..days_back).each do |days_ago| + date = days_ago.days.ago.to_date + count = begin + Metrics::UniqueUserBidderTracker.count(date: date) + rescue + 0 + end + + if count > 0 + puts " #{date}: #{count} unique bidders" + end + end + + puts "\nโœ… Test data generation complete!" + puts "\n๐Ÿ’ก View metrics at: http://localhost:3000/metrics" + puts "๐Ÿ’ก Check Prometheus/Grafana for auction_unique_bidders_daily metric" + end + + desc 'Clean up all test auction data' + task clean: :environment do + puts '๐Ÿงน Cleaning up test data...' + + unless Rails.env.development? + puts 'โŒ This task can only be run in development environment' + exit 1 + end + + # Delete test users and their associated data + test_users = User.where('email LIKE ?', 'test_bidder_%@example.com') + puts "Deleting #{test_users.count} test users and their data..." + test_users.destroy_all + + # Delete test auctions + test_auctions = Auction.where('domain_name LIKE ?', 'test-domain-%') + puts "Deleting #{test_auctions.count} test auctions..." + test_auctions.destroy_all + + # Clear Redis metrics + puts "Clearing Redis metrics..." + begin + redis = Redis.current + keys = redis.keys("auction:unique_bidders:*") + redis.del(*keys) if keys.any? + puts "Deleted #{keys.count} Redis keys" + rescue => e + puts "โš ๏ธ Warning: Could not clear Redis: #{e.message}" + end + + puts "โœ… Cleanup complete!" + end + end +end From 3eb9efcb9dd7482b49e34fcc74b7a0c8f79d21e0 Mon Sep 17 00:00:00 2001 From: oleghasjanov Date: Tue, 4 Nov 2025 10:16:08 +0200 Subject: [PATCH 2/4] cleared from mock data --- .../metrics/unique_user_bidder_tracker.rb | 10 +- attractor_output/images/attractor_favicon.png | Bin 2546 -> 0 bytes attractor_output/images/attractor_logo.svg | 15 -- attractor_output/index.js.html | 23 -- attractor_output/index.rb.html | 23 -- attractor_output/javascripts/index.js.js | 4 - attractor_output/javascripts/index.pack.js | 38 ---- attractor_output/javascripts/index.rb.js | 4 - attractor_output/stylesheets/main.css | 6 - config/application.rb | 2 + config/initializers/yabeda.rb | 24 +- lib/request_metrics_middleware.rb | 29 +++ lib/tasks/generate_test_auction_data.rake | 212 ------------------ 13 files changed, 56 insertions(+), 334 deletions(-) delete mode 100644 attractor_output/images/attractor_favicon.png delete mode 100644 attractor_output/images/attractor_logo.svg delete mode 100644 attractor_output/index.js.html delete mode 100644 attractor_output/index.rb.html delete mode 100644 attractor_output/javascripts/index.js.js delete mode 100644 attractor_output/javascripts/index.pack.js delete mode 100644 attractor_output/javascripts/index.rb.js delete mode 100644 attractor_output/stylesheets/main.css create mode 100644 lib/request_metrics_middleware.rb delete mode 100644 lib/tasks/generate_test_auction_data.rake diff --git a/app/services/metrics/unique_user_bidder_tracker.rb b/app/services/metrics/unique_user_bidder_tracker.rb index b8f7d65f7..80ceb97eb 100644 --- a/app/services/metrics/unique_user_bidder_tracker.rb +++ b/app/services/metrics/unique_user_bidder_tracker.rb @@ -13,11 +13,11 @@ def self.track(user_id, date: Date.current) # Set expiration on key creation redis.expire(key, TTL_SECONDS) unless redis.ttl(key) > 0 - # Update Yabeda gauge - current_count = redis.scard(key) - Yabeda.auction.unique_bidders_daily.set({date: date.to_s}, current_count) - - Rails.logger.info("Unique bidder tracked: user_id=#{user_id}, date=#{date}, count=#{current_count}, new=#{was_new_bidder}") + # Increment Prometheus counter only if this is a NEW unique bidder for this day + if was_new_bidder + Yabeda.auction.unique_bidders_total.increment({}) + Rails.logger.info("New unique bidder tracked: user_id=#{user_id}, date=#{date}") + end was_new_bidder end diff --git a/attractor_output/images/attractor_favicon.png b/attractor_output/images/attractor_favicon.png deleted file mode 100644 index 09fffca1169531ab870fe16e9651f0e772a5b8a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2546 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 IM6N<$g7vcjN&o-= diff --git a/attractor_output/images/attractor_logo.svg b/attractor_output/images/attractor_logo.svg deleted file mode 100644 index b10dc6776..000000000 --- a/attractor_output/images/attractor_logo.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - attractor_library - Created with Sketch. - - \ No newline at end of file diff --git a/attractor_output/index.js.html b/attractor_output/index.js.html deleted file mode 100644 index 18a32a753..000000000 --- a/attractor_output/index.js.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - Attractor Output - - - - - - -
- - - diff --git a/attractor_output/index.rb.html b/attractor_output/index.rb.html deleted file mode 100644 index ae63d7013..000000000 --- a/attractor_output/index.rb.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - Attractor Output - - - - - - -
- - - diff --git a/attractor_output/javascripts/index.js.js b/attractor_output/javascripts/index.js.js deleted file mode 100644 index 3b45c067b..000000000 --- a/attractor_output/javascripts/index.js.js +++ /dev/null @@ -1,4 +0,0 @@ -window.type = "js"; -window.serveStatic = true; -window.filePrefix = { file_prefix: "" }; -window.values = [{"file_path":"app/assets/builds/application.js","x":24,"y":2900,"details":{"":30,"":1,"__init":2,"":1,"__require":2,"":1,"":7,"":1,"":5,"":3,"":1,"":1,"":1,"":1,"":24,"":25,"":1,"":1,"":1,"":1,"":2,"":1,"":8,"":1,"":2,"":1,"":4,"":6,"getAxisOffsetAValue":3,"containsClass":5,"":1,"":1,"":2,"createWebSocketURL":4,"":1,"":1,"":1,"":1,"":1,"":1,"":1,"":1,"":1,"":1,"":1,"":1,"createConsumer":1,"getConfig":2,"":4,"HTMLElement2":1,"":2,"":2,"validateSubmitter":4,"raise":1,"findSubmitterFromClickTarget":7,"clickCaptured":3,"":7,"":1,"frameLoadingStyleFromString":2,"expandURL":1,"getAnchor":3,"getAction":5,"getExtension":3,"isHTML":1,"isPrefixedBy":2,"locationIsVisitable":2,"getRequestURL":2,"toCacheKey":1,"urlsAreEqual":1,"getPathComponents":1,"getLastPathComponent":1,"getPrefix":1,"addTrailingSlash":2,"activateScriptElement":3,"copyElementAttributes":1,"createDocumentFragment":1,"dispatch":3,"nextAnimationFrame":1,"":1,"":1,"nextEventLoopTick":1,"":1,"":1,"nextMicrotask":1,"parseHTMLDocument":1,"unindent":2,"":1,"interpolate":1,"":2,"uuid":1,"":7,"getAttribute":2,"hasAttribute":1,"":2,"markAsBusy":2,"clearBusyState":2,"waitForLoad":1,"":1,"":1,"getHistoryMethodForAction":4,"isAction":3,"getVisitAction":2,"getMetaElement":1,"getMetaContent":2,"setMetaContent":2,"findClosestRecursively":6,"":1,"fetchMethodFromString":6,"importStreamElements":1,"":1,"":1,"formEnctypeFromString":3,"buildFormData":7,"getCookieValue":5,"":1,"responseSucceededWithoutRedirect":2,"mergeFormDataEntries":2,"getPermanentElementById":1,"queryPermanentElementsAll":1,"submissionDoesNotDismissDialog":4,"submissionDoesNotTargetIFrame":9,"doesNotTargetIFrame":3,"createPlaceholderForPermanentElement":1,"elementIsFocusable":2,"readScrollLogicalPosition":5,"readScrollBehavior":3,"elementType":3,"elementIsTracked":1,"elementIsScript":1,"elementIsNoscript":1,"elementIsStylesheet":3,"elementIsMetaElementWithName":2,"elementWithoutNonce":2,"":1,"":1,"":1,"":1,"isSuccessful":2,"":1,"getPermanentElementMapForFragment":2,"fetchResponseFromEvent":4,"fetchResponseIsStream":3,"extendURLWithDeprecatedProperties":1,"":3,"":1,"":3,"":1,"":1,"":1,"":1,"start":1,"registerAdapter":1,"visit":1,"connectStreamSource":1,"disconnectStreamSource":1,"renderStreamMessage":1,"clearCache":1,"setProgressBarDelay":1,"setConfirmMethod":1,"setFormMode":1,"getFrameElementById":3,"activateElement":7,"":5,"":1,"":1,"":1,"getConsumer":2,"setConsumer":1,"createConsumer2":1,"":1,"subscribeTo":1,"walk":6,"":1,"":1,"encodeMethodIntoRequestBody":2,"":4,"determineFetchMethod":4,"determineFormMethod":4,"isBodyInit":2,"extendEvent":2,"parseActionDescriptorString":5,"parseEventTarget":3,"parseEventOptions":1,"":1,"stringifyEventTarget":3,"camelize":1,"":1,"namespaceCamelize":1,"capitalize":1,"dasherize":1,"":1,"tokenize":2,"":1,"":1,"":1,"":1,"":2,"":1,"":1,"getDefaultEventNameForElement":2,"error":1,"typecast":1,"add":1,"del":1,"fetch2":2,"prune":3,"parseTokenString":1,"":1,"":1,"zip":1,"":1,"tokensAreEqual":4,"readInheritableStaticArrayValues":1,"":1,"":1,"readInheritableStaticObjectPairs":1,"":1,"getAncestorsForConstructor":2,"getOwnStaticArrayValues":2,"getOwnStaticObjectPairs":2,"":1,"bless":1,"shadow":1,"getBlessedProperties":1,"":2,"getShadowProperties":1,"":2,"getShadowedDescriptor":6,"":2,"":1,"":1,"extendWithReflect":1,"extended":1,"testReflectExtension":1,"":1,"":1,"":1,"blessDefinition":1,"attributeValueContainsToken":1,"":1,"":1,"":1,"":1,"objectFromEntries":1,"":1,"domReady":1,"":2,"":1,"ClassPropertiesBlessing":1,"":1,"propertiesForClassDefinition":2,"OutletPropertiesBlessing":1,"":1,"propertiesForOutletDefinition":5,"":2,"":1,"TargetPropertiesBlessing":1,"":1,"propertiesForTargetDefinition":2,"ValuePropertiesBlessing":1,"":1,"":1,"propertiesForValueDefinitionPair":4,"parseValueDefinitionPair":1,"parseValueTypeConstant":6,"parseValueTypeDefault":6,"parseValueTypeObject":4,"parseValueTypeDefinition":5,"defaultValueForDefinition":3,"valueDescriptorForTokenAndTypeDefinition":2,"writeJSON":1,"writeString":1,"getCookie":4,"":1,"compact":2,"metaContent":2,"stringEntriesFromFormData":1,"":2,"mergeEntries":4,"get":1,"":3,"":1,"":24,"":5,"":1,"":1,"":1,"":1,"c2":2,"u2":1,"":4,"":26,"":1,"":1,"":1,"":48,"":4,"":2,"":3,"":1,"":1,"":2,"":1,"":1,"":1,"":5,"":21,"":1,"":2,"":4,"":3,"":5,"":22,"":3,"":2,"t3":1,"":5,"i2":9,"":1,"":1,"":10,"":5,"":9,"":3,"":3,"":1,"":2,"":9,"":3,"":2,"":2,"":1,"":3,"":1,"":8,"":1,"":5,"":1,"":2,"":3,"":1,"":2,"":16,"":3,"":1,"":23,"":2,"":7,"":8,"":8,"":4,"":1,"":1,"":2,"":2,"":1,"":1,"":1,"":2,"":3,"":3,"":1,"":1,"":1,"":1,"":2,"":1},"history":[["855e716b","remove build directroy"],["0b26d7b0","immutable invoice billing data"]]},{"file_path":"app/javascript/controllers/index.js","x":22,"y":1,"details":{},"history":[["e921a340","fixed issues from feedback"],["21bf69e9","updated phone confirmation page"],["e493b2b6","updated ui, updated new invoices path"],["f9c0cce5","added finished auctions page, added cookies, added timezone localization"],["ca9c7443","added notification modal, added menu in mobile view"],["89f13995","updated modal windows, added new views, config turbo frame"],["3e051c18","implement new wishlish page, billing profile page"],["b9889821","updated profile page, webpush notifications, invoices, offers"],["367e8cb4","updated admin auction view"],["79c1c556","implemented admin auction page, refactor the logic, update ordeable stimulus controller"]]},{"file_path":"app/packs/entrypoints/controllers/index.js","x":18,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["8e79fcbf","added countdown for mobile confirmation"],["8243cff7","include support user timezone in auction information rendrering"],["b08df3f8","customize banner, added logic"],["b0200375","fixed mobile ui"],["eaa8101c","added autoupdated tax calculation by stimulus"],["8849ae0c","Improved indication of user bids"],["b8883bc1","added webpush"],["16532dce","added localization for notifications"],["e8b2968c","added broadcast for flash notifications"]]},{"file_path":"app/packs/entrypoints/application.js","x":12,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["47c20b91","fixed js sidebar error"],["29775fe5","Fixed javascript errors"],["c396629c","updated turbo frame"],["61058298","Fix javascript errors"],["e042113d","fixed webpacker stimulus scss issues"],["4e0de922","fixed tests"],["b4ebbb47","fixed tests"],["ae00b8e1","added filter, search in admin panel, hotwire, pagination, update sorting"],["6d3339f7","webpack updated"]]},{"file_path":"app/javascript/application.js","x":10,"y":7,"details":{"":1,"":1,"":1,"":2,"":1},"history":[["ab2b0eb4","Fixed main menu and implemented static notices"],["e921a340","fixed issues from feedback"],["f9c0cce5","added finished auctions page, added cookies, added timezone localization"],["89f13995","updated modal windows, added new views, config turbo frame"],["6fd59ef4","added timeleft, added deposit, updated view, added new flash"],["f0dc5208","change index ui"]]},{"file_path":"app/packs/entrypoints/controllers/countdown_controller.js","x":9,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["e921a340","fixed issues from feedback"],["407bafdf","add converter timezone for local"],["8849ae0c","Improved indication of user bids"],["b8883bc1","added webpush"],["492001c9","fixed issued from 20-07-22"],["83ffb73e","update feedback from 13-07-2022"],["dadfc37f","fixed timer"],["89c65ca0","added timer, added broadcast for it, fixed minimum bid issue"]]},{"file_path":"app/packs/entrypoints/controllers/push_notification_controller.js","x":5,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["e921a340","fixed issues from feedback"],["c4a90355","updated push notification controller"],["aee3eb9d","added translation"],["b8883bc1","added webpush"]]},{"file_path":"app/javascript/controllers/application.js","x":5,"y":1,"details":{},"history":[["c93e658d","fixed componen priview missing file"],["367e8cb4","updated admin auction view"],["f0dc5208","change index ui"]]},{"file_path":"app/javascript/controllers/countdown_controller.js","x":5,"y":10,"details":{},"history":[["592fec68","remove jquery snippet from countdown code"],["e921a340","fixed issues from feedback"],["6fd59ef4","added timeleft, added deposit, updated view, added new flash"]]},{"file_path":"app/javascript/packs/application.js","x":5,"y":0,"details":{},"history":[["6d3339f7","webpack updated"],["87431f13","Add google geochart"],["22293723","Add chartkick & controller & view"],["d79e1255","Add descriptive tooltip to auction list email button on main page"],["9bed0fef","Add DejaVu Sans Mono font"],["550a2fa0","Add google analytics tracking"],["c623714b","Reorganize application.js"],["d024c56a","Replace local fonts with an NPM package"],["80e90c87","Add sidebar from semantic-ui, not a custom function"],["e416d42d","Remove obosolete src folder"]]},{"file_path":"app/javascript/controllers/hello_controller.js","x":4,"y":0,"details":{},"history":[]},{"file_path":"app/assets/config/manifest.js","x":4,"y":0,"details":{},"history":[["f0dc5208","change index ui"],["8daf64c4","Add empty manifest.js to upgrade sprockerts to 4.0.2"],["b8e52214","Clean up webpacker configuration"],["91b51338","Add webpack"],["e9329ff1","Run rails new."]]},{"file_path":"app/packs/entrypoints/controllers/auction_type_handler_controller.js","x":4,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["0cfe5804","added migrations for deposit enable, added many to many relationship for user and auction associative, added test"],["bde178c2","comment out eventer file update checker in development conf"],["dee1110b","added auction with offerst filter"]]},{"file_path":"app/packs/entrypoints/controllers/submitter_controller.js","x":4,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["61058298","Fix javascript errors"],["0cfe5804","added migrations for deposit enable, added many to many relationship for user and auction associative, added test"],["e042113d","fixed webpacker stimulus scss issues"]]},{"file_path":"app/javascript/controllers/autotax_counter_controller.js","x":4,"y":8,"details":{},"history":[["318b4883","set comma everywhere, fix localize close message"],["285cb82e","move set offer to top level, fixed separator depends of locale"],["e921a340","fixed issues from feedback"],["99f9213f","added stimulus controllers for check for auctions ends and calculate bid with tax"]]},{"file_path":"app/assets/builds/google_analytics.js","x":4,"y":0,"details":{},"history":[["f9c0cce5","added finished auctions page, added cookies, added timezone localization"],["3d1964e7","connect lhv connect"]]},{"file_path":"app/packs/entrypoints/controllers/dropdown_controller.js","x":4,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["7629e27d","mobile design"],["e8b2968c","added broadcast for flash notifications"],["3fee6c49","added offer and auction notifications"]]},{"file_path":"app/packs/entrypoints/controllers/application.js","x":4,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["29775fe5","Fixed javascript errors"],["c396629c","updated turbo frame"],["e042113d","fixed webpacker stimulus scss issues"]]},{"file_path":"app/packs/entrypoints/controllers/debounce_controller.js","x":3,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["0cfe5804","added migrations for deposit enable, added many to many relationship for user and auction associative, added test"],["e042113d","fixed webpacker stimulus scss issues"]]},{"file_path":"app/packs/entrypoints/controllers/english_offers_controller.js","x":3,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["1b8c0c3d","Corrected translation of auction type"],["8849ae0c","Improved indication of user bids"]]},{"file_path":"app/packs/entrypoints/controllers/check_controller.js","x":3,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["e921a340","fixed issues from feedback"],["e042113d","fixed webpacker stimulus scss issues"]]},{"file_path":"app/packs/entrypoints/controllers/hello_controller.js","x":3,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["0cfe5804","added migrations for deposit enable, added many to many relationship for user and auction associative, added test"],["e042113d","fixed webpacker stimulus scss issues"]]},{"file_path":"app/javascript/controllers/modals/offer_modal_controller.js","x":3,"y":3,"details":{},"history":[["89f13995","updated modal windows, added new views, config turbo frame"],["b9889821","updated profile page, webpush notifications, invoices, offers"],["02444a1a","added modals windows"]]},{"file_path":"app/javascript/controllers/table/ordeable_controller.js","x":3,"y":8,"details":{},"history":[["0f970a33","updated admins templates"],["79c1c556","implemented admin auction page, refactor the logic, update ordeable stimulus controller"],["ff28a715","rename stimulus controller by convetion"]]},{"file_path":"app/packs/entrypoints/controllers/checker_controller.js","x":3,"y":0,"details":{},"history":[["79c1c556","implemented admin auction page, refactor the logic, update ordeable stimulus controller"],["0cfe5804","added migrations for deposit enable, added many to many relationship for user and auction associative, added test"],["e042113d","fixed webpacker stimulus scss issues"]]},{"file_path":"app/packs/entrypoints/controllers/timeleft_controller.js","x":3,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["a34e7c3d","fixed translation, improved countdown ui"],["8e79fcbf","added countdown for mobile confirmation"]]},{"file_path":"app/packs/entrypoints/controllers/wishlist_controller.js","x":3,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["0cfe5804","added migrations for deposit enable, added many to many relationship for user and auction associative, added test"],["1f877d3f","added validator for wishlist"]]},{"file_path":"config/webpack/base.js","x":3,"y":0,"details":{},"history":[["f0dc5208","change index ui"],["4e0de922","fixed tests"],["6d3339f7","webpack updated"]]},{"file_path":"config/webpack/production.js","x":3,"y":0,"details":{},"history":[["f0dc5208","change index ui"],["6d3339f7","webpack updated"],["32e21410","Improve LESS file compiling"],["91b51338","Add webpack"]]},{"file_path":"app/packs/entrypoints/google_analytics.js","x":3,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["aa4ac153","Test google analytics"],["6d3339f7","webpack updated"]]},{"file_path":"app/packs/entrypoints/payment_orders.js","x":3,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["29775fe5","Fixed javascript errors"],["6d3339f7","webpack updated"]]},{"file_path":"app/packs/entrypoints/users.js","x":3,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["29775fe5","Fixed javascript errors"],["6d3339f7","webpack updated"]]},{"file_path":"app/packs/entrypoints/wishlist_items.js","x":3,"y":0,"details":{},"history":[["0e0361a4","removed entrypoint webpacker js code"],["29775fe5","Fixed javascript errors"],["6d3339f7","webpack updated"]]},{"file_path":"app/javascript/controllers/table/tab_controller.js","x":3,"y":10,"details":{},"history":[["e921a340","fixed issues from feedback"],["e493b2b6","updated ui, updated new invoices path"],["f4d73637","delegate footer and header to components, implemented notification page, invoices page, offers page, delegate boiler code to the components"]]},{"file_path":"app/javascript/controllers/push_notification_controller.js","x":3,"y":23,"details":{},"history":[["e921a340","fixed issues from feedback"],["ca9c7443","added notification modal, added menu in mobile view"],["b9889821","updated profile page, webpush notifications, invoices, offers"]]}]; diff --git a/attractor_output/javascripts/index.pack.js b/attractor_output/javascripts/index.pack.js deleted file mode 100644 index 009ad1076..000000000 --- a/attractor_output/javascripts/index.pack.js +++ /dev/null @@ -1,38 +0,0 @@ -!function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=73)}([function(t,e,n){"use strict";t.exports=n(58)},function(t,e,n){t.exports=n(69)()},function(t,e,n){var r=n(62),i=n(63),a=n(64);t.exports=function(t,e){return r(t)||i(t,e)||a()}},function(t,e,n){t.exports=n(65)},,function(t,e){function n(t,e,n,r,i,a,o){try{var l=t[a](o),u=l.value}catch(t){return void n(t)}l.done?e(u):Promise.resolve(u).then(r,i)}t.exports=function(t){return function(){var e=this,r=arguments;return new Promise((function(i,a){var o=t.apply(e,r);function l(t){n(o,i,a,l,u,"next",t)}function u(t){n(o,i,a,l,u,"throw",t)}l(void 0)}))}}},,,function(t,e){function n(){return t.exports=n=Object.assign||function(t){for(var e=1;e-1;i--){var a=n[i],o=(a.tagName||"").toUpperCase();["STYLE","LINK"].indexOf(o)>-1&&(r=a)}return y.head.insertBefore(e,r),t}}var tt="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";function et(){for(var t=12,e="";t-- >0;)e+=tt[62*Math.random()|0];return e}function nt(t){return"".concat(t).replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function rt(t){return Object.keys(t||{}).reduce((function(e,n){return e+"".concat(n,": ").concat(t[n],";")}),"")}function it(t){return t.size!==Z.size||t.x!==Z.x||t.y!==Z.y||t.rotate!==Z.rotate||t.flipX||t.flipY}function at(t){var e=t.transform,n=t.containerWidth,r=t.iconWidth,i={transform:"translate(".concat(n/2," 256)")},a="translate(".concat(32*e.x,", ").concat(32*e.y,") "),o="scale(".concat(e.size/16*(e.flipX?-1:1),", ").concat(e.size/16*(e.flipY?-1:1),") "),l="rotate(".concat(e.rotate," 0 0)");return{outer:i,inner:{transform:"".concat(a," ").concat(o," ").concat(l)},path:{transform:"translate(".concat(r/2*-1," -256)")}}}var ot={x:0,y:0,width:"100%",height:"100%"};function lt(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return t.attributes&&(t.attributes.fill||e)&&(t.attributes.fill="black"),t}function ut(t){var e=t.icons,n=e.main,r=e.mask,i=t.prefix,a=t.iconName,o=t.transform,u=t.symbol,s=t.title,c=t.extra,f=t.watchable,h=void 0!==f&&f,p=r.found?r:n,d=p.width,m=p.height,y="fa-w-".concat(Math.ceil(d/m*16)),v=[C.replacementClass,a?"".concat(C.familyPrefix,"-").concat(a):"",y].filter((function(t){return-1===c.classes.indexOf(t)})).concat(c.classes).join(" "),g={children:[],attributes:l({},c.attributes,{"data-prefix":i,"data-icon":a,class:v,role:c.attributes.role||"img",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 ".concat(d," ").concat(m)})};h&&(g.attributes[w]=""),s&&g.children.push({tag:"title",attributes:{id:g.attributes["aria-labelledby"]||"title-".concat(et())},children:[s]});var _=l({},g,{prefix:i,iconName:a,main:n,mask:r,transform:o,symbol:u,styles:c.styles}),b=r.found&&n.found?function(t){var e,n=t.children,r=t.attributes,i=t.main,a=t.mask,o=t.transform,u=i.width,s=i.icon,c=a.width,f=a.icon,h=at({transform:o,containerWidth:c,iconWidth:u}),p={tag:"rect",attributes:l({},ot,{fill:"white"})},d=s.children?{children:s.children.map(lt)}:{},m={tag:"g",attributes:l({},h.inner),children:[lt(l({tag:s.tag,attributes:l({},s.attributes,h.path)},d))]},y={tag:"g",attributes:l({},h.outer),children:[m]},v="mask-".concat(et()),g="clip-".concat(et()),_={tag:"mask",attributes:l({},ot,{id:v,maskUnits:"userSpaceOnUse",maskContentUnits:"userSpaceOnUse"}),children:[p,y]},b={tag:"defs",children:[{tag:"clipPath",attributes:{id:g},children:(e=f,"g"===e.tag?e.children:[e])},_]};return n.push(b,{tag:"rect",attributes:l({fill:"currentColor","clip-path":"url(#".concat(g,")"),mask:"url(#".concat(v,")")},ot)}),{children:n,attributes:r}}(_):function(t){var e=t.children,n=t.attributes,r=t.main,i=t.transform,a=rt(t.styles);if(a.length>0&&(n.style=a),it(i)){var o=at({transform:i,containerWidth:r.width,iconWidth:r.width});e.push({tag:"g",attributes:l({},o.outer),children:[{tag:"g",attributes:l({},o.inner),children:[{tag:r.icon.tag,children:r.icon.children,attributes:l({},r.icon.attributes,o.path)}]}]})}else e.push(r.icon);return{children:e,attributes:n}}(_),x=b.children,k=b.attributes;return _.children=x,_.attributes=k,u?function(t){var e=t.prefix,n=t.iconName,r=t.children,i=t.attributes,a=t.symbol;return[{tag:"svg",attributes:{style:"display: none;"},children:[{tag:"symbol",attributes:l({},i,{id:!0===a?"".concat(e,"-").concat(C.familyPrefix,"-").concat(n):a}),children:r}]}]}(_):function(t){var e=t.children,n=t.main,r=t.mask,i=t.attributes,a=t.styles,o=t.transform;if(it(o)&&n.found&&!r.found){var u={x:n.width/n.height/2,y:.5};i.style=rt(l({},a,{"transform-origin":"".concat(u.x+o.x/16,"em ").concat(u.y+o.y/16,"em")}))}return[{tag:"svg",attributes:i,children:e}]}(_)}var st=function(){},ct=(C.measurePerformance&&v&&v.mark&&v.measure,function(t,e,n,r){var i,a,o,l=Object.keys(t),u=l.length,s=void 0!==r?function(t,e){return function(n,r,i,a){return t.call(e,n,r,i,a)}}(e,r):e;for(void 0===n?(i=1,o=t[l[0]]):(i=0,o=n);i2&&void 0!==arguments[2]?arguments[2]:{}).skipHooks,r=void 0!==n&&n,i=Object.keys(e).reduce((function(t,n){var r=e[n];return!!r.icon?t[r.iconName]=r.icon:t[n]=r,t}),{});"function"!=typeof N.hooks.addPack||r?N.styles[t]=l({},N.styles[t]||{},i):N.hooks.addPack(t,i),"fas"===t&&ft("fa",e)}var ht=N.styles,pt=N.shims,dt=function(){var t=function(t){return ct(ht,(function(e,n,r){return e[r]=ct(n,t,{}),e}),{})};t((function(t,e,n){return e[3]&&(t[e[3]]=n),t})),t((function(t,e,n){var r=e[2];return t[n]=n,r.forEach((function(e){t[e]=n})),t}));var e="far"in ht;ct(pt,(function(t,n){var r=n[0],i=n[1],a=n[2];return"far"!==i||e||(i="fas"),t[r]={prefix:i,iconName:a},t}),{})};dt();N.styles;function mt(t,e,n){if(t&&t[e]&&t[e][n])return{prefix:e,iconName:n,icon:t[e][n]}}function yt(t){var e=t.tag,n=t.attributes,r=void 0===n?{}:n,i=t.children,a=void 0===i?[]:i;return"string"==typeof t?nt(t):"<".concat(e," ").concat(function(t){return Object.keys(t||{}).reduce((function(e,n){return e+"".concat(n,'="').concat(nt(t[n]),'" ')}),"").trim()}(r),">").concat(a.map(yt).join(""),"")}var vt=function(t){var e={size:16,x:0,y:0,flipX:!1,flipY:!1,rotate:0};return t?t.toLowerCase().split(" ").reduce((function(t,e){var n=e.toLowerCase().split("-"),r=n[0],i=n.slice(1).join("-");if(r&&"h"===i)return t.flipX=!0,t;if(r&&"v"===i)return t.flipY=!0,t;if(i=parseFloat(i),isNaN(i))return t;switch(r){case"grow":t.size=t.size+i;break;case"shrink":t.size=t.size-i;break;case"left":t.x=t.x-i;break;case"right":t.x=t.x+i;break;case"up":t.y=t.y-i;break;case"down":t.y=t.y+i;break;case"rotate":t.rotate=t.rotate+i}return t}),e):e};function gt(t){this.name="MissingIcon",this.message=t||"Icon unavailable",this.stack=(new Error).stack}gt.prototype=Object.create(Error.prototype),gt.prototype.constructor=gt;var _t={fill:"currentColor"},bt={attributeType:"XML",repeatCount:"indefinite",dur:"2s"},wt={tag:"path",attributes:l({},_t,{d:"M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z"})},xt=l({},bt,{attributeName:"opacity"});l({},_t,{cx:"256",cy:"364",r:"28"}),l({},bt,{attributeName:"r",values:"28;14;28;28;14;28;"}),l({},xt,{values:"1;0;1;1;0;1;"}),l({},_t,{opacity:"1",d:"M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z"}),l({},xt,{values:"1;0;0;0;0;1;"}),l({},_t,{opacity:"0",d:"M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z"}),l({},xt,{values:"0;0;1;1;0;0;"}),N.styles;function kt(t){var e=t[0],n=t[1],r=u(t.slice(4),1)[0];return{found:!0,width:e,height:n,icon:Array.isArray(r)?{tag:"g",attributes:{class:"".concat(C.familyPrefix,"-").concat(E.GROUP)},children:[{tag:"path",attributes:{class:"".concat(C.familyPrefix,"-").concat(E.SECONDARY),fill:"currentColor",d:r[0]}},{tag:"path",attributes:{class:"".concat(C.familyPrefix,"-").concat(E.PRIMARY),fill:"currentColor",d:r[1]}}]}:{tag:"path",attributes:{fill:"currentColor",d:r}}}}N.styles;var Et='svg:not(:root).svg-inline--fa {\n overflow: visible;\n}\n\n.svg-inline--fa {\n display: inline-block;\n font-size: inherit;\n height: 1em;\n overflow: visible;\n vertical-align: -0.125em;\n}\n.svg-inline--fa.fa-lg {\n vertical-align: -0.225em;\n}\n.svg-inline--fa.fa-w-1 {\n width: 0.0625em;\n}\n.svg-inline--fa.fa-w-2 {\n width: 0.125em;\n}\n.svg-inline--fa.fa-w-3 {\n width: 0.1875em;\n}\n.svg-inline--fa.fa-w-4 {\n width: 0.25em;\n}\n.svg-inline--fa.fa-w-5 {\n width: 0.3125em;\n}\n.svg-inline--fa.fa-w-6 {\n width: 0.375em;\n}\n.svg-inline--fa.fa-w-7 {\n width: 0.4375em;\n}\n.svg-inline--fa.fa-w-8 {\n width: 0.5em;\n}\n.svg-inline--fa.fa-w-9 {\n width: 0.5625em;\n}\n.svg-inline--fa.fa-w-10 {\n width: 0.625em;\n}\n.svg-inline--fa.fa-w-11 {\n width: 0.6875em;\n}\n.svg-inline--fa.fa-w-12 {\n width: 0.75em;\n}\n.svg-inline--fa.fa-w-13 {\n width: 0.8125em;\n}\n.svg-inline--fa.fa-w-14 {\n width: 0.875em;\n}\n.svg-inline--fa.fa-w-15 {\n width: 0.9375em;\n}\n.svg-inline--fa.fa-w-16 {\n width: 1em;\n}\n.svg-inline--fa.fa-w-17 {\n width: 1.0625em;\n}\n.svg-inline--fa.fa-w-18 {\n width: 1.125em;\n}\n.svg-inline--fa.fa-w-19 {\n width: 1.1875em;\n}\n.svg-inline--fa.fa-w-20 {\n width: 1.25em;\n}\n.svg-inline--fa.fa-pull-left {\n margin-right: 0.3em;\n width: auto;\n}\n.svg-inline--fa.fa-pull-right {\n margin-left: 0.3em;\n width: auto;\n}\n.svg-inline--fa.fa-border {\n height: 1.5em;\n}\n.svg-inline--fa.fa-li {\n width: 2em;\n}\n.svg-inline--fa.fa-fw {\n width: 1.25em;\n}\n\n.fa-layers svg.svg-inline--fa {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.fa-layers {\n display: inline-block;\n height: 1em;\n position: relative;\n text-align: center;\n vertical-align: -0.125em;\n width: 1em;\n}\n.fa-layers svg.svg-inline--fa {\n -webkit-transform-origin: center center;\n transform-origin: center center;\n}\n\n.fa-layers-counter, .fa-layers-text {\n display: inline-block;\n position: absolute;\n text-align: center;\n}\n\n.fa-layers-text {\n left: 50%;\n top: 50%;\n -webkit-transform: translate(-50%, -50%);\n transform: translate(-50%, -50%);\n -webkit-transform-origin: center center;\n transform-origin: center center;\n}\n\n.fa-layers-counter {\n background-color: #ff253a;\n border-radius: 1em;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n color: #fff;\n height: 1.5em;\n line-height: 1;\n max-width: 5em;\n min-width: 1.5em;\n overflow: hidden;\n padding: 0.25em;\n right: 0;\n text-overflow: ellipsis;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top right;\n transform-origin: top right;\n}\n\n.fa-layers-bottom-right {\n bottom: 0;\n right: 0;\n top: auto;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: bottom right;\n transform-origin: bottom right;\n}\n\n.fa-layers-bottom-left {\n bottom: 0;\n left: 0;\n right: auto;\n top: auto;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: bottom left;\n transform-origin: bottom left;\n}\n\n.fa-layers-top-right {\n right: 0;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top right;\n transform-origin: top right;\n}\n\n.fa-layers-top-left {\n left: 0;\n right: auto;\n top: 0;\n -webkit-transform: scale(0.25);\n transform: scale(0.25);\n -webkit-transform-origin: top left;\n transform-origin: top left;\n}\n\n.fa-lg {\n font-size: 1.3333333333em;\n line-height: 0.75em;\n vertical-align: -0.0667em;\n}\n\n.fa-xs {\n font-size: 0.75em;\n}\n\n.fa-sm {\n font-size: 0.875em;\n}\n\n.fa-1x {\n font-size: 1em;\n}\n\n.fa-2x {\n font-size: 2em;\n}\n\n.fa-3x {\n font-size: 3em;\n}\n\n.fa-4x {\n font-size: 4em;\n}\n\n.fa-5x {\n font-size: 5em;\n}\n\n.fa-6x {\n font-size: 6em;\n}\n\n.fa-7x {\n font-size: 7em;\n}\n\n.fa-8x {\n font-size: 8em;\n}\n\n.fa-9x {\n font-size: 9em;\n}\n\n.fa-10x {\n font-size: 10em;\n}\n\n.fa-fw {\n text-align: center;\n width: 1.25em;\n}\n\n.fa-ul {\n list-style-type: none;\n margin-left: 2.5em;\n padding-left: 0;\n}\n.fa-ul > li {\n position: relative;\n}\n\n.fa-li {\n left: -2em;\n position: absolute;\n text-align: center;\n width: 2em;\n line-height: inherit;\n}\n\n.fa-border {\n border: solid 0.08em #eee;\n border-radius: 0.1em;\n padding: 0.2em 0.25em 0.15em;\n}\n\n.fa-pull-left {\n float: left;\n}\n\n.fa-pull-right {\n float: right;\n}\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n margin-right: 0.3em;\n}\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n margin-left: 0.3em;\n}\n\n.fa-spin {\n -webkit-animation: fa-spin 2s infinite linear;\n animation: fa-spin 2s infinite linear;\n}\n\n.fa-pulse {\n -webkit-animation: fa-spin 1s infinite steps(8);\n animation: fa-spin 1s infinite steps(8);\n}\n\n@-webkit-keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes fa-spin {\n 0% {\n -webkit-transform: rotate(0deg);\n transform: rotate(0deg);\n }\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.fa-rotate-90 {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";\n -webkit-transform: rotate(90deg);\n transform: rotate(90deg);\n}\n\n.fa-rotate-180 {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg);\n}\n\n.fa-rotate-270 {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";\n -webkit-transform: rotate(270deg);\n transform: rotate(270deg);\n}\n\n.fa-flip-horizontal {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";\n -webkit-transform: scale(-1, 1);\n transform: scale(-1, 1);\n}\n\n.fa-flip-vertical {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";\n -webkit-transform: scale(1, -1);\n transform: scale(1, -1);\n}\n\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\n -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";\n -webkit-transform: scale(-1, -1);\n transform: scale(-1, -1);\n}\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical,\n:root .fa-flip-both {\n -webkit-filter: none;\n filter: none;\n}\n\n.fa-stack {\n display: inline-block;\n height: 2em;\n position: relative;\n width: 2.5em;\n}\n\n.fa-stack-1x,\n.fa-stack-2x {\n bottom: 0;\n left: 0;\n margin: auto;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.svg-inline--fa.fa-stack-1x {\n height: 1em;\n width: 1.25em;\n}\n.svg-inline--fa.fa-stack-2x {\n height: 2em;\n width: 2.5em;\n}\n\n.fa-inverse {\n color: #fff;\n}\n\n.sr-only {\n border: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n width: 1px;\n}\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n clip: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n position: static;\n width: auto;\n}\n\n.svg-inline--fa .fa-primary {\n fill: var(--fa-primary-color, currentColor);\n opacity: 1;\n opacity: var(--fa-primary-opacity, 1);\n}\n\n.svg-inline--fa .fa-secondary {\n fill: var(--fa-secondary-color, currentColor);\n opacity: 0.4;\n opacity: var(--fa-secondary-opacity, 0.4);\n}\n\n.svg-inline--fa.fa-swap-opacity .fa-primary {\n opacity: 0.4;\n opacity: var(--fa-secondary-opacity, 0.4);\n}\n\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\n opacity: 1;\n opacity: var(--fa-primary-opacity, 1);\n}\n\n.svg-inline--fa mask .fa-primary,\n.svg-inline--fa mask .fa-secondary {\n fill: black;\n}\n\n.fad.fa-inverse {\n color: #fff;\n}';function Tt(){var t=_,e=b,n=C.familyPrefix,r=C.replacementClass,i=Et;if(n!==t||r!==e){var a=new RegExp("\\.".concat(t,"\\-"),"g"),o=new RegExp("\\--".concat(t,"\\-"),"g"),l=new RegExp("\\.".concat(e),"g");i=i.replace(a,".".concat(n,"-")).replace(o,"--".concat(n,"-")).replace(l,".".concat(r))}return i}function St(){C.autoAddCss&&!Ot&&(J(Tt()),Ot=!0)}function Ct(t,e){return Object.defineProperty(t,"abstract",{get:e}),Object.defineProperty(t,"html",{get:function(){return t.abstract.map((function(t){return yt(t)}))}}),Object.defineProperty(t,"node",{get:function(){if(g){var e=y.createElement("div");return e.innerHTML=t.html,e.children}}}),t}function Mt(t){var e=t.prefix,n=void 0===e?"fa":e,r=t.iconName;if(r)return mt(Pt.definitions,n,r)||mt(N.styles,n,r)}var Nt,Pt=new(function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.definitions={}}var e,n,r;return e=t,(n=[{key:"add",value:function(){for(var t=this,e=arguments.length,n=new Array(e),r=0;r1&&void 0!==arguments[1]?arguments[1]:{},n=e.transform,r=void 0===n?Z:n,i=e.symbol,a=void 0!==i&&i,o=e.mask,u=void 0===o?null:o,s=e.title,c=void 0===s?null:s,f=e.classes,h=void 0===f?[]:f,p=e.attributes,d=void 0===p?{}:p,m=e.styles,y=void 0===m?{}:m;if(t){var v=t.prefix,g=t.iconName,_=t.icon;return Ct(l({type:"icon"},t),(function(){return St(),C.autoA11y&&(c?d["aria-labelledby"]="".concat(C.replacementClass,"-title-").concat(et()):(d["aria-hidden"]="true",d.focusable="false")),ut({icons:{main:kt(_),mask:u?kt(u.icon):{found:!1,width:null,height:null,icon:{}}},prefix:v,iconName:g,transform:l({},Z,r),symbol:a,title:c,extra:{attributes:d,styles:y,classes:h}})}))}},function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=(t||{}).icon?t:Mt(t||{}),r=e.mask;return r&&(r=(r||{}).icon?r:Mt(r||{})),Nt(n,l({},e,{mask:r}))})}).call(this,n(10),n(66).setImmediate)},,,,,,,,,,,,,,,,,,,,,,,,,,,,function(t,e,n){"use strict"; -/* -object-assign -(c) Sindre Sorhus -@license MIT -*/var r=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;function o(t){if(null==t)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(t)}t.exports=function(){try{if(!Object.assign)return!1;var t=new String("abc");if(t[5]="de","5"===Object.getOwnPropertyNames(t)[0])return!1;for(var e={},n=0;n<10;n++)e["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(e).map((function(t){return e[t]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(t){r[t]=t})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(t){return!1}}()?Object.assign:function(t,e){for(var n,l,u=o(t),s=1;s=0||(i[n]=t[n]);return i}},function(t,e,n){"use strict";var r=n(71),i={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},o={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function u(t){return r.isMemo(t)?o:l[t.$$typeof]||i}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0};var s=Object.defineProperty,c=Object.getOwnPropertyNames,f=Object.getOwnPropertySymbols,h=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,d=Object.prototype;t.exports=function t(e,n,r){if("string"!=typeof n){if(d){var i=p(n);i&&i!==d&&t(e,i,r)}var o=c(n);f&&(o=o.concat(f(n)));for(var l=u(e),m=u(n),y=0;yL.length&&L.push(t)}function z(t,e,n){return null==t?0:function t(e,n,r,i){var l=typeof e;"undefined"!==l&&"boolean"!==l||(e=null);var u=!1;if(null===e)u=!0;else switch(l){case"string":case"number":u=!0;break;case"object":switch(e.$$typeof){case a:case o:u=!0}}if(u)return r(i,e,""===n?"."+I(e,0):n),1;if(u=0,n=""===n?".":n+":",Array.isArray(e))for(var s=0;s