wco_models 3.1.0.325 → 3.4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/production_theme.scss +4 -1
  3. data/app/assets/stylesheets/wco/main.scss +4 -0
  4. data/app/assets/stylesheets/wco/studio.scss +12 -4
  5. data/app/controllers/wco/api/newspartials_controller.rb +1 -1
  6. data/app/controllers/wco/api/newsproducer_controller.rb +5 -0
  7. data/app/controllers/wco/newspartials_controller.rb +1 -0
  8. data/app/models/iro/datapoint.rb +1 -1
  9. data/app/models/iro/option.rb +16 -2
  10. data/app/models/iro/position.rb +4 -6
  11. data/app/models/iro/priceitem.rb +42 -4
  12. data/app/models/iro/purse.rb +2 -0
  13. data/app/models/iro/stock.rb +1 -2
  14. data/app/models/tda/option.rb +4 -9
  15. data/app/models/wco/newspartial.rb +12 -4
  16. data/app/views/wco/api/newsproducer/README_newsproducer.txt +12 -0
  17. data/app/views/wco/api/newsproducer/_scenes.js-bk +20 -0
  18. data/app/views/wco/api/newsproducer/_scenes.js.erb +15 -0
  19. data/app/views/wco/api/newsproducer/{_studio_blue.js → _studio_blue1.js} +4 -1
  20. data/app/views/wco/api/newsproducer/_studio_blue2.js +912 -0
  21. data/app/views/wco/api/newsproducer/_studio_coc.js +769 -0
  22. data/app/views/wco/api/newsproducer/_studio_coc.js-bk +389 -0
  23. data/app/views/wco/api/newsproducer/_studio_coc.js-cannon +677 -0
  24. data/app/views/wco/api/newsproducer/_studio_fps.js +1018 -0
  25. data/app/views/wco/api/newsproducer/_studio_ra2.js +255 -0
  26. data/app/views/wco/api/newsproducer/_touch_controls.js +708 -0
  27. data/app/views/wco/api/newsproducer/_touch_pad.css +200 -0
  28. data/app/views/wco/api/newsproducer/games_fps.html +504 -0
  29. data/app/views/wco/api/newsproducer/{studio_green.html.erb → studio_blue0.html.erb} +1 -1
  30. data/app/views/wco/api/newsproducer/{studio_blue.html.erb → studio_blue1.html.erb} +3 -3
  31. data/app/views/wco/api/newsproducer/studio_blue2.html.erb +146 -0
  32. data/app/views/wco/api/newsproducer/studio_coc.html.erb +95 -0
  33. data/app/views/wco/api/newsproducer/studio_fps.html.erb +199 -0
  34. data/app/views/wco/api/newsproducer/studio_ra2.html.erb +95 -0
  35. data/app/views/wco/newspartials/_show_in_newsvideo.haml +6 -7
  36. data/app/views/wco/newspartials/index.haml-trash +6 -0
  37. data/config/initializers/08_integrations.rb +14 -1
  38. data/config/initializers/08_integrations.rb-example +0 -2
  39. data/config/routes.rb +3 -0
  40. data/lib/shortcuts.rb +1 -1
  41. metadata +23 -7
  42. data/app/views/wco/api/newsproducer/README.txt +0 -2
  43. /data/app/views/wco/api/newsproducer/{_studio_green.js → _studio_blue0.js} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d95eea4a598e5389d573c28d57e23e740eee706e16d49f11caa94cc4da9aff2a
4
- data.tar.gz: 207e4184c9e47dcf4b5453cea12f912980295be59119c5ee2a010278591d7591
3
+ metadata.gz: '0274939884ef534ba5826efd3adcbbd3fa0605a03b93d95333c2251432098f7c'
4
+ data.tar.gz: bc0e8ed07d318199cfb9c7fbaff36d35c42900bfb93377ce99ea32162751b2f8
5
5
  SHA512:
6
- metadata.gz: caa0ef2c0ee957e1d1d64cdd46ea4e1d4a85156e95af185cf8dd0fc5e38159aeda7aa39f8456fceae8383cfd1663a56a93f1ace6b7451c703702ed2bdc1fd40d
7
- data.tar.gz: 8b2149ea65ba1d0ee33d163b73c89ff73f2e702d5c45d8b6cbd5d6218f85f9449e9fa3e39621c7a8548a956c2afb7f29ff12093421a613d344168ef414b9958e
6
+ metadata.gz: 61f84d2f853ca2b8a8b88ae421045245770c2ce183da46ea19ab15212927cad4110ea2b6ecff6316c10482ff8f9b48c70e0f7a83c2d2e2ddf47d05babe2fb35f
7
+ data.tar.gz: 27f0896d5d76acfd21f00946f91ddd4b7c8bc95e073d75292ac1ed3601ab95d250c01d3d52773082f0cfc0b351b402763be0515a53c387ea2e6e749a26ef4204
@@ -1,6 +1,9 @@
1
+ /*
2
+ *= require wco/main
3
+ **/
1
4
 
2
5
  /**
3
- * production theme
6
+ * news production theme
4
7
  **/
5
8
 
6
9
  body {
@@ -44,6 +44,9 @@ textarea {
44
44
  .border-right {
45
45
  border-right: 1px solid red !important;
46
46
  }
47
+ .border-yellow {
48
+ border: 1px solid yellow;
49
+ }
47
50
 
48
51
  .bordered {
49
52
  border: 1px solid gray;
@@ -214,6 +217,7 @@ input[type=file] {
214
217
 
215
218
  /* M */
216
219
 
220
+ .fixed-container, /* _TODO: take the definition from drupal */
217
221
  .maxwidth {
218
222
  width: 1200px;
219
223
  max-width: 1200px; /* @TODO: this would be responsive by-breakpoint _vp_ 2024-04-23 */
@@ -5,11 +5,18 @@ body {
5
5
 
6
6
 
7
7
  .ctrl-row {
8
- label {
8
+ display: flex;
9
+ flex-wrap: wrap;
10
+
11
+ > * {
9
12
  margin-right: 2em;
10
13
  }
11
14
  }
12
15
 
16
+ .rotatingW {
17
+ display: flex;
18
+ justify-content: center;
19
+ }
13
20
 
14
21
  .StudioW1 {
15
22
  border: 1px solid red;
@@ -23,9 +30,10 @@ body {
23
30
  border: 1px solid blue;
24
31
  background: #bbb;
25
32
 
26
- display: flex;
27
- flex-direction: column;
28
- justify-content: center;
33
+ display: block;
34
+ // display: flex;
35
+ // flex-direction: column;
36
+ // justify-content: center;
29
37
 
30
38
  z-index: 5;
31
39
  }
@@ -47,7 +47,7 @@ class Wco::Api::NewspartialsController < Wco::ApiController
47
47
  ## syncronous, everyone waits.
48
48
  def generate_speech
49
49
  @newspartial = Wco::Newspartial.unscoped.find params[:id]
50
- @newspartial.generate_speech
50
+ @newspartial.generate_speech( voice: params[:voice] )
51
51
  render json: { status: :ok }
52
52
  end
53
53
 
@@ -25,6 +25,11 @@ class Wco::Api::NewsproducerController < Wco::ApiController
25
25
  def studio_blue
26
26
  authorize! :home, Wco
27
27
  @newspartial = Wco::Newspartial.find params[:newspartial_id] rescue nil
28
+ render 'studio_blue2'
29
+ end
30
+
31
+ def studio_fps
32
+ authorize! :home, Wco
28
33
  end
29
34
 
30
35
  def studio_green
@@ -36,6 +36,7 @@ class Wco::NewspartialsController < Wco::ApplicationController
36
36
  def generate_speech
37
37
  @newspartial = Wco::Newspartial.unscoped.find params[:id]
38
38
  authorize! :show, @newspartial
39
+ @newspartial.update_attributes( voice: params[:voice] )
39
40
  @newspartial.generate_speech
40
41
  redirect_to controller: 'newsvideos', id: @newspartial.newsvideo_id, action: 'show'
41
42
  end
@@ -18,7 +18,7 @@ class Iro::Datapoint
18
18
  KIND_CURRENCY = 'CURRENCY'
19
19
  KIND_TREASURY = 'TREASURY'
20
20
 
21
- field :symbol ## ticker, but use 'symbol' here
21
+ field :symbol ## ticker or option symbol, etc
22
22
  ## crypto
23
23
  SYMBOL_BTC = 'BTC'
24
24
  SYMBOL_ETH = 'ETH'
@@ -49,13 +49,24 @@ class Iro::Option
49
49
  field :end_price, type: :float
50
50
  field :end_delta, type: :float
51
51
 
52
- has_one :pos_of_outer, class_name: 'Iro::Position', inverse_of: :outer
53
- has_one :pos_of_inner, class_name: 'Iro::Position', inverse_of: :inner
52
+ has_one :pos_of_outer, class_name: 'Iro::Position', inverse_of: :outer
53
+ has_one :pos_of_inner, class_name: 'Iro::Position', inverse_of: :inner
54
54
  belongs_to :poss_of_inner, class_name: 'Iro::Position', inverse_of: :inners, optional: true
55
55
  belongs_to :poss_of_outer, class_name: 'Iro::Position', inverse_of: :outers, optional: true
56
56
 
57
+ has_many :priceitems, inverse_of: :option
58
+
57
59
  field :last, type: :float
58
60
 
61
+ def self.active
62
+ options = []
63
+ Iro::Position.active.each do |pos|
64
+ options.push pos.inner
65
+ options.push pos.outer if pos.outer
66
+ end
67
+ return options
68
+ end
69
+
59
70
  ## for schwab, eg:
60
71
  ## "COST 260306C01030000"
61
72
  def symbol
@@ -81,6 +92,9 @@ class Iro::Option
81
92
  expires_on: expires_on,
82
93
  }
83
94
  end
95
+ def to_h
96
+ self.class.symbol_to_h symbol
97
+ end
84
98
 
85
99
  def matches_h h
86
100
  if h[:put_call] == put_call &&
@@ -271,8 +271,7 @@ class Iro::Position
271
271
  expiration_dates = @positions.map { |p| p.expires_on.to_s }.sort
272
272
  # puts! expiration_dates, 'expiration_dates'
273
273
 
274
- count = 1
275
- @positions.each do |pos|
274
+ @positions.each_with_index do |pos, idx|
276
275
  # puts! pos.id.to_s, '#sync_all.pos'
277
276
 
278
277
  quotes_h = Tda::Option.get_quotes_h({
@@ -284,7 +283,7 @@ class Iro::Position
284
283
 
285
284
  pos.inner.end_price = quotes_h[pos.expires_on.to_date.to_s][pos.put_call][pos.inner.strike][:price]
286
285
  pos.inner.end_delta = quotes_h[pos.expires_on.to_date.to_s][pos.put_call][pos.inner.strike][:delta]
287
- pos.inner.save ? print("#{count}^") : print("#{count}X")
286
+ pos.inner.save ? print("#{idx}^") : print("#{idx}Error")
288
287
 
289
288
  # if [ Iro::Strategy::KIND_LONG_CREDIT_PUT_SPREAD,
290
289
  # Iro::Strategy::KIND_SHORT_CREDIT_CALL_SPREAD,
@@ -293,12 +292,11 @@ class Iro::Position
293
292
  if pos.outer
294
293
  pos.outer.end_price = quotes_h[pos.expires_on.to_date.to_s][pos.put_call][pos.outer.strike][:price]
295
294
  pos.outer.end_delta = quotes_h[pos.expires_on.to_date.to_s][pos.put_call][pos.outer.strike][:delta]
296
- pos.outer.save ? print('^') : print('X')
295
+ pos.outer.save ? print('^') : print('Error')
297
296
  end
298
- count = count+1
299
297
  end
300
298
 
301
- print 'synced-all.'
299
+ puts 'synced-all.'
302
300
  end
303
301
 
304
302
 
@@ -13,22 +13,24 @@ class Iro::Priceitem
13
13
  field :symbol, type: String
14
14
  field :description, type: String
15
15
  field :ticker, type: String
16
- # belongs_to :stock, inverse_of: :priceitems
16
+
17
+ belongs_to :stock, inverse_of: :priceitems, optional: true
18
+ belongs_to :option, inverse_of: :priceitems, optional: true
17
19
 
18
20
  field :bid, type: Float
19
21
  field :bidSize, type: Integer
20
22
  field :ask, type: Float
21
23
  field :askSize, type: Integer
22
- field :last, type: Float
24
+ field :last, type: Float ## this is important
23
25
 
24
26
  field :openPrice, type: Float
25
27
  field :lowPrice, type: Float
26
28
  field :highPrice, type: Float
27
29
  field :closePrice, type: Float
28
30
 
29
- field :quote_at, type: DateTime
31
+ field :quote_at, type: DateTime ## this is important, the timestamp mostly used for analysis
30
32
  field :quoteTimeInLong, type: Integer
31
- field :timestamp, type: Integer
33
+ field :timestamp, type: Integer ## do not use?!
32
34
  field :totalVolume, type: Integer
33
35
  field :mark, type: Float
34
36
  field :exchangeName, type: String
@@ -90,4 +92,40 @@ class Iro::Priceitem
90
92
  # puts! outs.to_a, 'result'
91
93
  end
92
94
 
95
+ ## interval: bucket length (ActiveSupport::Duration or seconds), e.g. 1.minute
96
+ def self.to_chart(interval = 5.minutes)
97
+ bucket_ms = interval.to_i * 1000
98
+
99
+ pipeline = [
100
+ { '$match' => all.selector },
101
+ { '$match' => { 'quote_at' => { '$ne' => nil }, 'last' => { '$ne' => nil } } },
102
+ { '$sort' => { 'quote_at' => 1 } },
103
+ { '$group' => {
104
+ '_id' => {
105
+ '$toDate' => {
106
+ '$subtract' => [
107
+ { '$toLong' => '$quote_at' },
108
+ { '$mod' => [ { '$toLong' => '$quote_at' }, bucket_ms ] },
109
+ ],
110
+ },
111
+ },
112
+ 'open' => { '$first' => '$last' },
113
+ 'high' => { '$max' => '$last' },
114
+ 'low' => { '$min' => '$last' },
115
+ 'close' => { '$last' => '$last' },
116
+ } },
117
+ { '$sort' => { '_id' => 1 } },
118
+ { '$project' => {
119
+ '_id' => 0,
120
+ 'time' => { '$toLong' => '$_id' },
121
+ 'open' => 1,
122
+ 'high' => 1,
123
+ 'low' => 1,
124
+ 'close' => 1,
125
+ } },
126
+ ]
127
+
128
+ collection.aggregate(pipeline).to_a
129
+ end
130
+
93
131
  end
@@ -31,6 +31,8 @@ class Iro::Purse
31
31
  field :available_amount, type: :float
32
32
  # validates :available_amount, presence: true
33
33
 
34
+ field :status ## active or disabled
35
+
34
36
  def to_s
35
37
  slug
36
38
  end
@@ -53,7 +53,6 @@ class ::Iro::Stock
53
53
 
54
54
  has_many :positions, class_name: '::Iro::Position', inverse_of: :stock
55
55
  has_many :strategies, class_name: '::Iro::Strategy', inverse_of: :stock
56
- # has_many :purses, class_name: '::Iro::Purse', inverse_of: :stock
57
56
  has_many :options, class_name: '::Iro::Option', inverse_of: :stock
58
57
  has_many :priceitems, inverse_of: :stock
59
58
 
@@ -197,7 +196,7 @@ class ::Iro::Stock
197
196
  date_from = date_from.strftime('%Y-%m-%d')
198
197
  date_to = date_to.strftime('%Y-%m-%d')
199
198
  puts! [ticker, date_from, date_to], "ticker,date_from,date_to"
200
- outs = HTTParty.get("https://api.stockdata.org/v1/data/eod?symbols=#{ticker}&date_from=#{date_from}&date_to=#{date_to}&api_token=#{STOCKDATA_ORG_KEY}")
199
+ outs = HTTParty.get("https://api.stockdata.org/v1/data/eod?symbols=#{ticker}&date_from=#{date_from}&date_to=#{date_to}&api_token=#{::STOCKDATA_ORG_KEY}")
201
200
  outs['data'].each do |datum|
202
201
  existing = ::Iro::Datapoint.find_by({ symbol: ticker, date: datum['date'].to_date.strftime('%Y-%m-%d') }) rescue nil
203
202
  if existing
@@ -29,13 +29,12 @@ class Tda::Option
29
29
  return JSON.parse File.read filename
30
30
 
31
31
  else
32
- profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
33
32
  query = { symbol: params[:ticker] } ## use 'GME' as symbol here even though a symbol is eg 'GME_021023P2.5'
34
33
  # puts! query, 'query'
35
34
 
36
35
  headers = {
37
36
  accept: 'application/json',
38
- Authorization: "Bearer #{profile[:schwab_access_token]}",
37
+ Authorization: "Bearer #{Iro::Iro.schwab_data_token}",
39
38
  }
40
39
  path = "/chains"
41
40
  out = self.get path, {
@@ -110,8 +109,6 @@ class Tda::Option
110
109
  ##
111
110
  def self.get_quotes params
112
111
  # puts! params, 'core Tda::Option#get_quotes...'
113
-
114
- profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
115
112
  opts = {}
116
113
 
117
114
  #
@@ -150,11 +147,11 @@ class Tda::Option
150
147
  out = self.get( "/chains", {
151
148
  headers: {
152
149
  accept: 'application/json',
153
- Authorization: "Bearer #{profile[:schwab_access_token]}",
150
+ Authorization: "Bearer #{Iro::Iro.schwab_data_token}",
154
151
  },
155
152
  query: query,
156
153
  })
157
- # puts! out, '/chains --'
154
+ puts! out, '/chains --'
158
155
  timestamp = DateTime.parse out.headers['date']
159
156
  out = out.parsed_response.deep_symbolize_keys
160
157
 
@@ -179,8 +176,6 @@ class Tda::Option
179
176
  ## 2026-02-23 use this instead.
180
177
  def self.get_quotes_h params
181
178
  # puts! params, 'Tda::Option#get_quotes_h params ...'
182
-
183
- profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
184
179
  opts = {}
185
180
 
186
181
  #
@@ -219,7 +214,7 @@ class Tda::Option
219
214
  results = self.get( "/chains", {
220
215
  headers: {
221
216
  accept: 'application/json',
222
- Authorization: "Bearer #{profile[:schwab_access_token]}",
217
+ Authorization: "Bearer #{Iro::Iro.schwab_data_token}",
223
218
  },
224
219
  query: query,
225
220
  })
@@ -16,6 +16,8 @@ class Wco::Newspartial
16
16
  field :config_json, type: :string, default: '{}'
17
17
  field :speech_json, type: :string, default: '{}' # the smaller config, excludes audio wav
18
18
 
19
+ field :voice, type: :string ## 'af_jessica', 'am_fenrir'
20
+
19
21
  belongs_to :newsvideo
20
22
 
21
23
  has_one :video
@@ -63,6 +65,12 @@ class Wco::Newspartial
63
65
  duration = config['vtimes'].last.to_i + config['vdurations'].last.to_i rescue 0
64
66
  end
65
67
 
68
+ ##
69
+ ## "am_fenrir", ## bad
70
+ ## am_michael good
71
+ ## "af_bella" ## bad
72
+ ## "af_jessica", ## good
73
+ ##
66
74
  def generate_speech
67
75
  out = HTTParty.post( "#{Wco::Setting.get('HEAD_TTS_ORIGIN')}/v1/synthesize",
68
76
  headers: {
@@ -70,15 +78,15 @@ class Wco::Newspartial
70
78
  'Accept' => 'application/json',
71
79
  }, body: {
72
80
  input: body,
73
- # voice: "am_fenrir", # good?
74
- # "af_bella" # bad
75
- voice: "af_jessica", # good
81
+
82
+ voice: voice,
83
+
76
84
  language: "en-us",
77
85
  audioEncoding: "wav",
78
86
  }.to_json
79
87
  );
80
88
  out = out.body
81
- puts! out, 'out'
89
+ # puts! out, 'out'
82
90
 
83
91
  self[:config_json] = out
84
92
  tmp = JSON.parse( out )
@@ -0,0 +1,12 @@
1
+
2
+
3
+ const scene_url = 'https://cdn.jsdelivr.net/gh/wasya-co/ishlib3js@0.3.0/public/vendor/models/scenes/000mb%20collision-world/collision-world.glb'
4
+
5
+ const vehicle_url = 'https://cdn.jsdelivr.net/gh/wasya-co/ishlib3js@0.3.0/public/vendor/models/vehicles/000mb car-mazda-miata/model.glb'
6
+ const vehicle_config = {
7
+ height: 1.235,
8
+ length: 3.970,
9
+ width: 1.675,
10
+ }
11
+
12
+ // const vehicle_url = 'https://cdn.jsdelivr.net/gh/wasya-co/ishlib3js@0.3.0/public/vendor/models/vehicles/001mb truck-drifter-lowpoly/model.glb'
@@ -0,0 +1,20 @@
1
+
2
+ const MODELS_ROOT = '/vendor/models'
3
+ let scenes = {
4
+ collision_world: `${MODELS_ROOT}/scenes/000mb collision-world/collision-world.glb`,
5
+ skybox_1: { height: 30, url: `${MODELS_ROOT}/scenes/000mb skybox_1/scene.glb` },
6
+ room_1: { height: 6, url: `${MODELS_ROOT}/scenes/000mb room-1/scene.glb` },
7
+ mountain_1: { height: 30, url: `${MODELS_ROOT}/scenes/000mb lowpoly-mountain/scene.glb` },
8
+ meshy_3: { height: 30, url: `${MODELS_ROOT}/scenes/004mb meshy-scene-3/scene.glb` },
9
+ newsroom_green: { height: 3.3, url: `${MODELS_ROOT}/scenes/001mb newsroom_green/scene.glb` },
10
+ rick_and_morty_garage: `${MODELS_ROOT}/scenes/003mb rick-and-morty-garage/scene.glb`,
11
+ white_park: { height: 10, name: '003mb h100cm white_park' },
12
+ }
13
+
14
+ <% Dir.glob(Rails.root.join('public/vendor/models/scenes/00*')).each do |file| %>
15
+ <%- basename = File.basename(file) -%>
16
+ <%= basename.split.last -%>: {
17
+ <%= "height: #{$1.to_i / 10.0}," if basename =~ /h(\d{3})cm/ -%>
18
+ name: "<%= File.basename(file) -%>",
19
+ },
20
+ <% end %>
@@ -0,0 +1,15 @@
1
+
2
+ let MODELS_ROOT = '/vendor/models'
3
+ let scenes = {
4
+
5
+ <% Dir.glob(Rails.root.join('public/vendor/models/scenes/00*')).each do |file| %>
6
+ <%- basename = File.basename(file) -%>
7
+ "<%= basename.split.last -%>": {
8
+ <%= "height: #{$1.to_i / 10.0}," if basename =~ / h(\d+)cm / -%>
9
+ <%= "height: #{$1}," if basename =~ / h(\d+) / -%>
10
+ name: "<%= basename -%>",
11
+ },
12
+ <% end %>
13
+
14
+ }
15
+ window.scenes = scenes
@@ -12,8 +12,11 @@ const logg = (a, b="", c=null) => {
12
12
 
13
13
  let avatar_brunette_url = 'https://cdn.jsdelivr.net/gh/wasya-co/ishlib3js@0.2.0/public/vendor/models/avatars/brunette/model.glb'
14
14
  let avatar_avaturn_url = 'https://cdn.jsdelivr.net/gh/wasya-co/ishlib3js@0.2.0/public/vendor/models/avatars/avaturn/model.glb'
15
+ // cute short-haired girl
15
16
  let avatar_45_url = 'https://cdn.jsdelivr.net/gh/wasya-co/ishlib3js@0.2.0/public/vendor/models/avatars/extra/45.glb'
16
17
  let avatar_mula_url = 'https://cdn.jsdelivr.net/gh/wasya-co/ishlib3js@0.2.0/public/vendor/models/avatars/mula/model.glb'
18
+ // works! male-x, buddy-y. Yes, it took me like 3 days to find a single good male avatar.
19
+ let avatar_male_url = 'https://cdn.jsdelivr.net/gh/wasya-co/ishlib3js@0.2.0/public/vendor/models/avatars/buddy-y/model.glb'
17
20
 
18
21
 
19
22
  let scene_url = 'https://cdn.jsdelivr.net/gh/wasya-co/ishlib3js@0.2.0/public/vendor/models/scenes/001mb newsroom_green/scene.glb'
@@ -25,7 +28,7 @@ let wave_url = 'https://wco-drupal-prod.s3.amazonaws.com/public/2026-08/F_Talkin
25
28
 
26
29
 
27
30
  let avatar_1_url = avatar_brunette_url
28
- let avatar_2_url = avatar_45_url
31
+ let avatar_2_url = avatar_male_url
29
32
  // let avatar_3_url = avatar_mula_url
30
33
 
31
34