atome 0.5.7.1.2 → 0.5.7.1.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a382b0c451af7a259820a14e61aadbf779d0ddba6a67a603ec3940a28d6f252
4
- data.tar.gz: a44e9004e18b867645ca3be9681d295997cce04fd7b4c13b8107b546b76e0e2e
3
+ metadata.gz: f381b9c8d4123904b8ee97d71b0c6e1f78dc8143eb34b953670a273bd29fad10
4
+ data.tar.gz: d517e9cf6a13592fda0352bd5aa55c64ff30ffd4a0daab3776ce420c3ec0b970
5
5
  SHA512:
6
- metadata.gz: 956973bed7a67e04f0ec7c2921602b1751afc5281f9869587596be81621eb4cf323f870183ae9dabc5fa9a476f7e67926f8255a65adc6c9daeacdf433dc7c494
7
- data.tar.gz: bf54e93e8ab7a82854f6da1a185c2926f7bef89222da5a80b28fedb24a052ec083b2cd6341754116e72f4fb5e10f55d9f67d24df45081d055606b04787a7f7c7
6
+ metadata.gz: bd812f2209652f5f4e8b24a7d16214cedfc1e8ae5be2149d7f106393cef7f810908f61fbeb33a7854f0bbaab607e63b7d5c46c72c908e27a9cf799e27dd5380e
7
+ data.tar.gz: 77b884af5e674424861d278dcbd803f094d37600d2bf990cfbd14f041c9103e5cfbd392b772b2065485a5e54b2e146741f7f1654ae96272087d9ab9528eaeff5
data/Gemfile CHANGED
@@ -12,3 +12,4 @@ gem 'faye-websocket'
12
12
  gem "minitest", "~> 5.0"
13
13
 
14
14
  gem 'rubocop', group: 'development', require: false
15
+ gem 'rubocop', group: 'development', require: false
@@ -13,7 +13,7 @@ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
13
13
  brew install openssl
14
14
  cargo install tauri-cli --force
15
15
 
16
- Install Homebew
16
+ Install Homebrew
17
17
 
18
18
  /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
19
19
 
@@ -614,11 +614,6 @@ class Object
614
614
  end
615
615
 
616
616
 
617
- JS.eval(<<~JS)
618
- window.preventDefaultAction = function(e) {
619
- e.preventDefault();
620
- }
621
- JS
622
617
 
623
618
  def touch_allow(allow)
624
619
  if allow
@@ -633,26 +628,21 @@ JS
633
628
 
634
629
  def allow_copy(allow)
635
630
  if allow
636
- # Rétablir la sélection et la copie de texte
631
+ # allow selection and text copy
637
632
  JS.eval(<<~JS)
638
- document.body.style.userSelect = 'auto'; // Permet la sélection de texte
639
- document.removeEventListener('copy', preventDefaultAction); // Permet la copie
640
- JS
633
+ document.body.style.userSelect = 'auto'; // allow text slectiion
634
+ document.removeEventListener('copy', preventDefaultAction); // allow copy
635
+ JS
641
636
  else
642
- # Bloquer la sélection et la copie de texte
637
+ # lock selection and text copy
643
638
  JS.eval(<<~JS)
644
- document.body.style.userSelect = 'none'; // Bloque la sélection de texte
645
- document.addEventListener('copy', preventDefaultAction); // Bloque la copie
646
- JS
639
+ document.body.style.userSelect = 'none'; // prevent text selection
640
+ document.addEventListener('copy', preventDefaultAction); // prevent copy
641
+ JS
647
642
  end
648
643
  end
649
644
 
650
- # Définit la fonction preventDefaultAction dans un contexte global pour être utilisée par allow_copy
651
- JS.eval(<<~JS)
652
- window.preventDefaultAction = function(e) {
653
- e.preventDefault();
654
- }
655
- JS
645
+
656
646
 
657
647
 
658
648
  end
@@ -63,6 +63,17 @@ new({ atome: :raw })
63
63
  new({ atome: :shape })
64
64
  new({ atome: :code })
65
65
  new({ atome: :audio })
66
+ new({ sanitizer: :audio }) do |params|
67
+ unless params.instance_of? Hash
68
+ # TODO : we have to convert all image to png or maintain a database with extension
69
+ # FIXME : temporary patch that add .mp4 to the string if no extension is found
70
+ params = "#{params}.mp4" if params.to_s.split('.').length == 1
71
+
72
+ params = { path: "./medias/audios/#{params}" }
73
+ end
74
+ # TODO : the line below should get the value from default params Essentials
75
+ params
76
+ end
66
77
  new({ atome: :element })
67
78
  new({ sanitizer: :element }) do |params|
68
79
  default_params = { data: '' }
@@ -154,7 +154,8 @@ def atome_genesis
154
154
  end
155
155
  end
156
156
 
157
- def init_database # this method is call from JS (atome/communication) at WS connection
157
+ # this method is call from JS (atome/communication) at WS connection
158
+ def init_database
158
159
  # we init the db file eDen
159
160
  A.sync({ action: :init_db, data: { database: :eDen } }) do |data|
160
161
  Universe.database_ready = data[:data][:message] == 'database_ready'
@@ -16,13 +16,15 @@ class Atome
16
16
  # preset_params = {preset: atome_preset}
17
17
  basic_params[:type] = preset_params[:type] || :element
18
18
  # basic_params[:aid] = identity_generator(:a)
19
- basic_params[:id] = params[:id]|| identity_generator
19
+ # alert "common => #{params[:id]}"
20
+ # alert "basic_params #{basic_params[:id].class}"
21
+ basic_params[:id] = params[:id] || identity_generator
20
22
  basic_params[:renderers] = @renderers || preset_params[:renderers]
21
23
  essential_params = basic_params.merge(preset_params)
22
24
  #
23
25
  reordered_params = essential_params.reject { |key, _| params.has_key?(key) }
24
26
  params = reordered_params.merge(params)
25
- params[:id]=params[:id].to_sym
27
+ params[:id] = params[:id].to_sym
26
28
  # condition to handle color/shadow/paint atomes that shouldn't be attach to view
27
29
  if Universe.applicable_atomes.include?(atome_preset)
28
30
  unless params[:affect]
@@ -36,24 +38,13 @@ class Atome
36
38
  params[:attach] = params[:attach] || @id || :view
37
39
  end
38
40
  # we reorder the hash
39
- reorder_particles(params)
41
+ reorder_particles(params)
40
42
  end
41
43
 
42
44
  def preset_common(params, &bloc)
43
-
44
- ## if an atome with current id exist we update the ID in the params
45
- # params[:id] = "#{params[:id]}_#{Universe.atomes.length}" if grab(params[:id])
46
- # if Universe.atomes[params[:id]]
47
- # alert "atome found : #{ grab(params[:id])}"
48
- # grab(params[:id])
49
- # else
50
-
51
45
  Atome.new(params, &bloc)
52
- # end
53
46
  end
54
47
 
55
-
56
-
57
48
  # def box(params = {}, &bloc)
58
49
  # atome_preset = :box
59
50
  # params = atome_common(atome_preset, params)
data/lib/atome/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  # return atome version
4
4
  class Atome
5
- VERSION = '0.5.7.1.2'
5
+ VERSION = '0.5.7.1.4'
6
6
  end
@@ -4,9 +4,10 @@ new({ renderer: :html, method: :attach, type: :string }) do |parent_found, _user
4
4
  html.append_to(parent_found)
5
5
  end
6
6
 
7
+
7
8
  new({ renderer: :html, method: :apply, type: :string }) do |parent_found, _user_proc|
8
9
 
9
- # TODO : factorise code below between text and shape, especially shadow as code is written twice and identical
10
+ # TODO : factorise code below between text and shape, especially shadow as code is written twice and identical
10
11
  case parent_found.type
11
12
  when :shadow
12
13
  shadows_to_apply = { filter: [], boxShadow: [] }
@@ -32,7 +33,6 @@ new({ renderer: :html, method: :apply, type: :string }) do |parent_found, _user_
32
33
  html.style("boxShadow", box_shadow)
33
34
  html.style("filter", drop_shadow)
34
35
  when :color
35
-
36
36
  red = parent_found.red * 255
37
37
  green = parent_found.green * 255
38
38
  blue = parent_found.blue * 255
@@ -4,8 +4,6 @@
4
4
 
5
5
  class HTML
6
6
 
7
-
8
-
9
7
  # def id
10
8
  # :poil
11
9
  # end
@@ -221,7 +219,6 @@ STRDELIM
221
219
  particles_from_style[key.to_sym] = value if key && value
222
220
  end
223
221
 
224
- # alert "hyperedit"
225
222
 
226
223
  particles_found = particles_found.merge(particles_from_style)
227
224
  current_atome = grab(@id)
@@ -378,6 +375,18 @@ STRDELIM
378
375
  self
379
376
  end
380
377
 
378
+ def audio(id)
379
+ # we remove any element if the id already exist
380
+ check_double(id)
381
+ markup_found = @original_atome.markup || :audio
382
+ @element_type = markup_found.to_s
383
+ @element = JS.global[:document].createElement(@element_type)
384
+ JS.global[:document][:body].appendChild(@element)
385
+ add_class('atome')
386
+ self.id(id)
387
+ self
388
+ end
389
+
381
390
  def www(id)
382
391
  # we remove any element if the id already exist
383
392
  check_double(id)
@@ -505,7 +514,6 @@ STRDELIM
505
514
  end
506
515
  end
507
516
 
508
-
509
517
  def transform(property, value = nil)
510
518
  transform_needed = "#{property}(#{value}deg)"
511
519
  @element[:style][:transform] = transform_needed.to_s
@@ -578,8 +586,6 @@ STRDELIM
578
586
  @element[:style][:"-webkit-backdrop-filter"] = filter_needed
579
587
  end
580
588
 
581
-
582
-
583
589
  def currentTime(time)
584
590
  @element[:currentTime] = time
585
591
  end
@@ -598,7 +604,6 @@ STRDELIM
598
604
 
599
605
  def action(_particle, action_found, option = nil)
600
606
 
601
- # alert option
602
607
  if action_found == :stop
603
608
  currentTime(option)
604
609
  @element.pause
@@ -1146,13 +1151,11 @@ STRDELIM
1146
1151
  end
1147
1152
 
1148
1153
  def touch_tap(_option)
1149
- # alert :touch_tap
1150
1154
  @element[:style][:cursor] = 'pointer'
1151
1155
  interact = JS.eval("return interact('##{@id}')")
1152
1156
  touch_tap = @original_atome.instance_variable_get('@touch_code')[:tap]
1153
1157
  # unless @touch_removed[:tap]
1154
1158
  interact.on('tap') do |native_event|
1155
- # alert 'touchy'
1156
1159
  event = Native(native_event)
1157
1160
  # we use .call instead of instance_eval because instance_eval bring the current object as context
1158
1161
  # and it's lead to a problem of context and force the use of grab(:view) when using atome method such as shape ,
@@ -1359,7 +1362,6 @@ STRDELIM
1359
1362
 
1360
1363
  table_html.appendChild(thead)
1361
1364
  tbody = JS.global[:document].createElement('tbody')
1362
- # alert data
1363
1365
  data.each_with_index do |row, row_index|
1364
1366
  tr = JS.global[:document].createElement('tr')
1365
1367
 
@@ -1389,8 +1391,6 @@ STRDELIM
1389
1391
  JS.global[:document].querySelector("##{@id}").appendChild(table_html)
1390
1392
  end
1391
1393
 
1392
-
1393
-
1394
1394
  # Helper function to handle Atome objects
1395
1395
  def handle_atome(atome, td_element)
1396
1396
  atome.fit(cell_height)
@@ -1402,7 +1402,6 @@ STRDELIM
1402
1402
  atome.left(0)
1403
1403
  end
1404
1404
 
1405
-
1406
1405
  def refresh_table(_params)
1407
1406
  # first we need to extact all atome from the table or they will be deleted by the table refres
1408
1407
  data = @original_atome.data
@@ -1442,9 +1441,21 @@ STRDELIM
1442
1441
  def set_td_style(td)
1443
1442
  cell_height = @original_atome.component[:height]
1444
1443
  cell_width = @original_atome.component[:width]
1445
- td[:style][:border] = '1px solid black'
1444
+ # shadow_found = @original_atome.component[:shadow]
1445
+ # if shadow_found
1446
+ # red = shadow_found[:red] * 255
1447
+ # green = shadow_found[:green] * 255
1448
+ # blue = shadow_found[:blue] * 255
1449
+ # alpha = shadow_found[:alpha]
1450
+ # left = shadow_found[:left]
1451
+ # top = shadow_found[:top]
1452
+ # blur = shadow_found[:blur] # new correct behavior all atome's value should now be get using :value,here to resolve conflict with blur and back blur
1453
+ # inset = :inset if shadow_found[:invert]
1454
+ # shadow_created = "#{left}px #{top}px #{blur}px rgba(#{red}, #{green}, #{blue}, #{alpha}) #{inset}"
1455
+ # end
1456
+ # td[:style][:border] = '1px solid black'
1446
1457
  td[:style][:backgroundColor] = 'white'
1447
- td[:style][:boxShadow] = '10px 10px 5px #888888'
1458
+ # td[:style][:boxShadow] = shadow_created
1448
1459
  td[:style][:width] = "#{cell_width}px"
1449
1460
  td[:style]['min-width'] = "#{cell_width}px"
1450
1461
  td[:style]['max-width'] = "#{cell_height}px"
@@ -1641,7 +1652,7 @@ STRDELIM
1641
1652
 
1642
1653
  # atomisation!
1643
1654
  def atomized(html_object)
1644
- html_object = html_object[0] if html_object.instance_of? Array
1655
+ # html_object = html_object[0] if html_object.instance_of? Array
1645
1656
  @element = html_object
1646
1657
  end
1647
1658
 
@@ -17,6 +17,9 @@ end
17
17
  new({ method: :type, type: :string, renderer: :html, specific: :video }) do |_value, _user_proc|
18
18
  html.video(@id)
19
19
  end
20
+ new({ method: :type, type: :string, renderer: :html, specific: :audio }) do |_value, _user_proc|
21
+ html.audio(@id)
22
+ end
20
23
 
21
24
  new({ method: :type, type: :string, renderer: :html, specific: :www }) do |_value, _user_proc|
22
25
  html.www(@id)
@@ -95,7 +98,7 @@ new({ method: :data, type: :string, specific: :table, renderer: :html }) do |val
95
98
  end
96
99
 
97
100
  new({ method: :type, type: :hash, specific: :atomized, renderer: :html }) do |value, _user_proc|
98
- html.atomized(value)
101
+ html.atomized(alien)
99
102
  end
100
103
 
101
104
 
@@ -167,4 +167,4 @@ new({ renderer: :html, method: :record }) do |params, user_proc|
167
167
  end
168
168
  end
169
169
 
170
- end
170
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # # audio tag
4
+ a = audio({ path: 'medias/audios/clap.wav', id: :audioElement })
5
+ b=box({id: :playButton})
6
+ b.text(:audio_tag)
7
+ a.left(333)
8
+ b.touch(:down) do
9
+ a.play(true)
10
+ end
11
+
12
+
13
+ #
14
+ #
15
+ ### Web Audio
16
+ # Initialisation des variables globales
17
+ @audio_context = JS.eval('return new AudioContext()')
18
+ @audio_element = JS.global[:document].getElementById('audioElement')
19
+ @track = @audio_context.createMediaElementSource(@audio_element)
20
+
21
+ # Ajout d'un nœud de gain (volume)
22
+ @gain_node = @audio_context.createGain()
23
+ @gain_node[:gain][:value] = 0.5 # Réduit le volume à 50%
24
+ #
25
+ # # Connexion de la chaîne
26
+ @track.connect(@gain_node) # Connecte la source au nœud de gain
27
+ @gain_node.connect(@audio_context[:destination]) # Connecte le nœud de gain à la sortie
28
+
29
+ def play_audio
30
+ # Réactive l'AudioContext s'il est suspendu
31
+ @audio_context[:resume].to_s if @audio_context[:state].to_s == 'suspended'
32
+ # Joue l'audio
33
+ @audio_element.play
34
+ end
35
+ b2=box({left: 166})
36
+ b2.text(:web_audio)
37
+ b2.touch(:down) do
38
+ play_audio
39
+ end
40
+
41
+
42
+ # ######### wadjs
43
+ bb=box({left: 333})
44
+ bb.text(:wadjs)
45
+ init_code = "window.snare = new Wad({source : 'medias/audios/clap.wav'});"
46
+ JS.eval(init_code)
47
+
48
+ # Code JavaScript pour jouer le son et l'arrêter après 300 ms, dans un bloc indépendant
49
+ play_code = <<~STRDEL
50
+ window.snare.play();
51
+ setTimeout(function() {
52
+ window.snare.stop();
53
+ }, 300);
54
+ STRDEL
55
+
56
+ # Exécution du bloc indépendant pour jouer et arrêter le son
57
+ # JS.eval(play_code)
58
+ # snare=JS.eval("return new Wad({source : 'medias/audios/clap.wav'})")
59
+ # js_code=<<STRDEL
60
+ # snare = #{snare};
61
+ # snare =new Wad({source : 'medias/audios/clap.wav'})
62
+ # snare.play();
63
+ # setTimeout(() => {
64
+ # snare.stop();
65
+ # }, "300");
66
+ # STRDEL
67
+ bb.touch(:down) do
68
+ JS.eval(play_code)
69
+ end
70
+
@@ -58,7 +58,7 @@ html_desc = <<STR
58
58
  </nav>
59
59
  </header>
60
60
 
61
- <section id='title' class="section my_class" style='left: 333px;color: yellow'>
61
+ <section id='div_id' class="section my_class" style='left: 333px;color: yellow'>
62
62
  <h2>PRODUCTIONS AUDIOVISUELLES</h2>
63
63
  <!-- Contenu de la section -->
64
64
  </section>
@@ -105,8 +105,29 @@ b.hypertext(html_desc)
105
105
  # get tag content convert to data
106
106
  # get style and class convert to particle
107
107
  # end
108
- b.hyperedit(:title) do |tag_desc|
109
- puts tag_desc
108
+ b.hyperedit(:div_id) do |tag_desc|
109
+ puts tag_desc.class
110
+ end
111
+
112
+ wait 2 do
113
+ div_result = HTML.locate(id: 'div_id') # find by ID
114
+
115
+ atomized_el= atomizer({ target: div_result, id: :my_second_html_obj })
116
+ atomized_el.rotate(55)
117
+ atomized_el.color(:purple)
118
+ atomized_el.position(:absolute)
119
+ atomized_el.left(255)
120
+ atomized_el.top(255)
121
+ end
122
+
123
+
124
+ wait 3 do
125
+ # or handle the objet in pure ruby js style
126
+ div_result = HTML.locate(id: 'div_id') # find by ID
127
+ div_result[:style][:left]= "66px"
128
+ puts "the div is : #{div_result[:style][:left]}"
129
+
130
+
110
131
  end
111
132
 
112
133
  # TODO : create an html to atome converter
@@ -1,57 +1,158 @@
1
- m = table({ renderers: [:html], attach: :view, id: :my_test_box, type: :table, apply: [:shape_color],
2
- left: 333, top: 0, width: 300, smooth: 15, height: 900, overflow: :scroll, option: { header: false },
3
- component: {
4
- border: { thickness: 5, color: :blue, pattern: :dotted },
5
- overflow: :auto,
6
- color: "white",
7
- shadow: {
8
- id: :s4,
9
- left: 20, top: 0, blur: 9,
10
- option: :natural,
11
- red: 0, green: 1, blue: 0, alpha: 1
12
- },
13
- # height: 80,
14
- # width: 12,
15
- component: { size: 12, color: :black }
16
- },
17
- data: [
18
- { remove_me: :nonono },
19
- { dfgdf: 1, name: 'Alice', age: 30, no: 'oko', t: 123, r: 654, f: 123, g: 654, w: 123, x: 654, c: 123, v: 654 },
20
- ]
21
- })
1
+ # # frozen_string_literal: true
2
+ #
3
+ # # m = table({ renderers: [:html], attach: :view, id: :my_test_box, type: :table, apply: [:shape_color],
4
+ # # left: 333, top: 0, width: 900, smooth: 15, height: 900, overflow: :scroll, option: { header: false },
5
+ # # component: {
6
+ # # # border: { thickness: 5, color: :blue, pattern: :dotted },
7
+ # # # overflow: :auto,
8
+ # # # color: "red",
9
+ # # shadow: {
10
+ # # id: :s4,
11
+ # # left: 20, top: 0, blur: 9,
12
+ # # option: :natural,
13
+ # # red: 0, green: 0, blue: 0, alpha: 1
14
+ # # },
15
+ # # height: 5,
16
+ # # width: 12,
17
+ # # component: { size: 12, color: :black }
18
+ # # },
19
+ # # # data: [
20
+ # # # { titi: :toto },
21
+ # # # { dfgdf: 1, name: 'Alice', age: 30, no: 'oko', t: 123, r: 654 },
22
+ # # # { id: 2, name: 'Bob', age: 22 },
23
+ # # # { dfg: 4, name: 'Vincent', age: 33, no: grab(:my_circle) },
24
+ # # # { dfgd: 3, name: 'Roger', age: 18, no: image(:red_planet), now: :nothing }
25
+ # # #
26
+ # # # ]
27
+ # # })
28
+ # b=box({top: 120})
29
+ # box({top: 190, id: :the_box})
30
+ #
31
+ # b.touch(true) do
32
+ # a=JS.eval("return performance.now()")
33
+ # z=Time.now
34
+ # circle
35
+ # columns = []
36
+ #
37
+ # 96.times do
38
+ # line = {}
39
+ # 128.times do |index|
40
+ # line[:"vel#{index}"] = nil
41
+ # end
42
+ # columns << line
43
+ # end
44
+ # columns.each_with_index do |a, index|
45
+ # b= box({left: index*30, width: 12})
46
+ # # b.touch(true) do
47
+ # # alert b.id
48
+ # # end
49
+ # end
50
+ # z2=Time.now
51
+ # x=JS.eval("return performance.now();")
52
+ # alert "#{x.to_f-a.to_f} : #{(z2-z)*1000}"
53
+ #
54
+ # end
55
+ #
56
+ #
57
+ # # m.data(columns)
58
+ # # # tests
59
+ # # m.color(:orange)
60
+ # # m.border({ thickness: 5, color: :blue, pattern: :dotted })
61
+ # #
62
+ # # m.get({ cell: [1, 2]}).class
63
+ # # wait 2 do
64
+ # # m.insert({ cell: [2, 2], content: 999 })
65
+ # # m.insert({ row: 1 })
66
+ # # wait 1 do
67
+ # # m.remove({ row: 2 })
68
+ # # end
69
+ # # wait 2 do
70
+ # # m.remove({ column: 1 })
71
+ # # end
72
+ # # wait 3 do
73
+ # # m.insert({ column: 3 })
74
+ # # end
75
+ # #
76
+ # # wait 4 do
77
+ # # m.sort({ column: 1, method: :alphabetic })
78
+ # # puts 1
79
+ # # wait 1 do
80
+ # # puts 2
81
+ # # m.sort({ column: 2, method: :numeric })
82
+ # # wait 1 do
83
+ # # puts 3
84
+ # # m.sort({ column: 3, method: :numeric })
85
+ # # wait 1 do
86
+ # # puts 4
87
+ # # m.sort({ column: 1, method: :numeric })
88
+ # # end
89
+ # # end
90
+ # # end
91
+ # # end
92
+ # #
93
+ # # end
94
+ # #
95
+ # # # cell.fusion() # to be implemented later
96
+ #
97
+ #
98
+ # # b=box({width: 1200, height: 900, color: {alpha: 0},top: -50})
99
+ # # grab(:black_matter).image({id: :kb,path: 'medias/images/utils/keyboard.svg', width: 66, left: 55})
100
+ # # # grab(:black_matter).image({id: :planet,path: 'medias/images/red_planet.png', width: 66,height: 66, left: 555, top: 180})
101
+ # # b.fill([atome: :kb, repeat: {x: 8, y: 1}])
102
+ # # b.drag(true)
103
+ # #
104
+ # #
105
+ # # b2=box({width: 1200, height: 298, top: -100})
106
+ # # grab(:black_matter).image({id: :notes,path: 'medias/images/utils/notes.svg', width: 166, left: 55})
107
+ # # # grab(:black_matter).image({id: :planet,path: 'medias/images/red_planet.png', width: 66,height: 66, left: 555, top: 180})
108
+ # # b2.fill([atome: :notes, repeat: {x: 8, y: 5}])
109
+ # # b2.drag(true)
110
+ #
111
+ #
112
+ # JS.eval("
113
+ # // Fonction pour créer les divs
114
+ # function createDivs() {
115
+ # // Démarrer le chronomètre
116
+ # const startTime = performance.now();
117
+ #
118
+ # const view = document.getElementById('view');
119
+ # //view.innerHTML = ''; // Nettoyer le contenu précédent de 'view' si nécessaire
120
+ #
121
+ # // Boucle pour créer 98 divs sur l'axe X
122
+ # for (let i = 0; i < 98; i++) {
123
+ # const xDiv = document.createElement('div');
124
+ # xDiv.style.display = 'flex';
125
+ # xDiv.style.flexDirection = 'column';
126
+ # xDiv.style.margin = '2px'; // Marge entre les divs de l'axe X
127
+ #
128
+ # // Boucle pour créer 128 divs sur l'axe Y
129
+ # for (let j = 0; j < 128; j++) {
130
+ # const yDiv = document.createElement('div');
131
+ # yDiv.style.width = '10px'; // Largeur de chaque div sur l'axe Y
132
+ # yDiv.style.height = '10px'; // Hauteur de chaque div sur l'axe Y
133
+ # yDiv.style.border = '1px solid black'; // Bordure pour rendre les divs visibles
134
+ # yDiv.style.boxSizing = 'border-box'; // Inclure la bordure dans les dimensions
135
+ # xDiv.appendChild(yDiv);
136
+ # }
137
+ #
138
+ # view.appendChild(xDiv);
139
+ # }
140
+ #
141
+ # // Arrêter le chronomètre
142
+ # const endTime = performance.now();
143
+ # const timeTaken = endTime - startTime;
144
+ #
145
+ # // Afficher le temps écoulé en console
146
+ # alert(`Temps écoulé pour créer les divs : ${timeTaken.toFixed(2)} ms`);
147
+ # }
148
+ #
149
+ # // Ajouter un écouteur d'événements au div 'the_box'
150
+ # document.getElementById('the_box').addEventListener('click', createDivs);
151
+ # ``
152
+ #
153
+ # ")
22
154
 
23
-
24
-
25
- m.data( [
26
- {header_title: nil },
27
- { dfgdf:nil, name: nil, age: nil, no: nil, t: nil, r: nil, f: nil, g: nil, w: nil, x: nil, c: nil, v: nil },
28
- { id: nil, name: nil, age: nil },
29
- { dfg: nil, name: nil, age: nil, no: nil },
30
- { dfgd: nil, name: nil, age: nil, no: nil },
31
- {header_title: nil },
32
- { dfgdf:nil, name: nil, age: nil, no: nil, t: nil, r: nil, f: nil, g: nil, w: nil, x: nil, c: nil, v: nil },
33
- { id: nil, name: nil, age: nil },
34
- { dfg: nil, name: nil, age: nil, no: nil },
35
- { dfgd: nil, name: nil, age: nil, no: nil },
36
- {header_title: nil },
37
- { dfgdf:nil, name: nil, age: nil, no: nil, t: nil, r: nil, f: nil, g: nil, w: nil, x: nil, c: nil, v: nil },
38
- { id: nil, name: nil, age: nil },
39
- { dfg: nil, name: nil, age: nil, no: nil },
40
- { dfgd: nil, name: nil, age: nil, no: nil },
41
- {header_title: nil },
42
- { dfgdf:nil, name: nil, age: nil, no: nil, t: nil, r: nil, f: nil, g: nil, w: nil, x: nil, c: nil, v: nil },
43
- { id: nil, name: nil, age: nil },
44
- { dfg: nil, name: nil, age: nil, no: nil },
45
- { dfgd: nil, name: nil, age: nil, no: nil },
46
- {header_title: nil },
47
- { dfgdf:nil, name: nil, age: nil, no: nil, t: nil, r: nil, f: nil, g: nil, w: nil, x: nil, c: nil, v: nil },
48
- { id: nil, name: nil, age: nil },
49
- { dfg: nil, name: nil, age: nil, no: nil },
50
- { dfgd: nil, name: nil, age: nil, no: nil },
51
- {header_title: nil },
52
- { dfgdf:nil, name: nil, age: nil, no: nil, t: nil, r: nil, f: nil, g: nil, w: nil, x: nil, c: nil, v: nil },
53
- { id: nil, name: nil, age: nil },
54
- { dfg: nil, name: nil, age: nil, no: nil },
55
- { dfgd: nil, name: nil, age: nil, no: nil },
56
-
57
- ])
155
+ new({particle: :merge})
156
+ a=box
157
+ c=box
158
+ d=a.merge(c)
@@ -15,6 +15,7 @@
15
15
  <script type="text/javascript" src="js/third_parties/sortable.min.js" defer></script>
16
16
  <script type="text/javascript" src="js/third_parties/wad.min.js" defer></script>
17
17
  <script type="text/javascript" src="js/third_parties/wavesurfer.min.js" defer></script>
18
+ <script type="text/javascript" src="js/third_parties/webaudio-pianoroll.min.js" defer></script>
18
19
  <script type="text/javascript" src="js/third_parties/sha256.min.js" defer></script>
19
20
  <script type="text/javascript" src="js/third_parties/ping.min.js" defer></script>
20
21
  <script type="text/javascript" src="js/third_parties/fabric.min.js" defer></script>
@@ -43,16 +44,22 @@
43
44
  const NativeMode = true; // used by atome.js to load code on the fly
44
45
  </script>
45
46
  <script defer src="js/atome/atome.js" type="text/javascript"></script>
47
+ <script>
48
+ // to prevent right click
49
+ document.addEventListener("contextmenu", function (e) {
50
+ e.preventDefault();
51
+ });
52
+ </script>
46
53
  <script defer>
47
- document.addEventListener('touchstart', function(event) {
54
+ document.addEventListener('touchstart', function (event) {
48
55
  if (event.touches.length > 1) {
49
56
  event.preventDefault();
50
57
  }
51
- }, { passive: false });
52
- document.addEventListener('wheel', function(event) {
58
+ }, {passive: false});
59
+ document.addEventListener('wheel', function (event) {
53
60
  if (event.ctrlKey === true) {
54
- event.preventDefault(); // Empêche le zoom quand Ctrl est pressé et que l'utilisateur scroll avec le trackpad
61
+ event.preventDefault(); // prevent zoom
55
62
  }
56
- }, { passive: false });
57
- </script >
63
+ }, {passive: false});
64
+ </script>
58
65
  </html>
@@ -3,7 +3,8 @@
3
3
  <head>
4
4
  <link rel="icon" type="image/x-icon"
5
5
  href="https://github.com/atomecorp/atome/blob/master/vendor/assets/src/favicon.ico">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, viewport-fit=cover,user-scalable=no">
6
+ <meta name="viewport"
7
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, viewport-fit=cover,user-scalable=no">
7
8
  <meta charset='UTF-8'/>
8
9
  <meta name="format-detection" content="telephone=no">
9
10
  <meta name="msapplication-tap-highlight" content="no">
@@ -14,6 +15,7 @@
14
15
  <script type="text/javascript" src="js/third_parties/sortable.min.js" defer></script>
15
16
  <script type="text/javascript" src="js/third_parties/wad.min.js" defer></script>
16
17
  <script type="text/javascript" src="js/third_parties/wavesurfer.min.js" defer></script>
18
+ <script type="text/javascript" src="js/third_parties/webaudio-pianoroll.min.js" defer></script>
17
19
  <script type="text/javascript" src="js/third_parties/sha256.min.js" defer></script>
18
20
  <script type="text/javascript" src="js/third_parties/ping.min.js" defer></script>
19
21
  <script defer src="js/third_parties/fabric.min.js" type="text/javascript"></script>
@@ -37,16 +39,22 @@
37
39
  </script>
38
40
  <script defer src="js/atome/atome.js" type="text/javascript"></script>
39
41
  <script src='js/application.js' defer></script>
42
+ <script>
43
+ // to prevent right click
44
+ document.addEventListener("contextmenu", function (e) {
45
+ e.preventDefault();
46
+ });
47
+ </script>
40
48
  <script defer>
41
- document.addEventListener('touchstart', function(event) {
49
+ document.addEventListener('touchstart', function (event) {
42
50
  if (event.touches.length > 1) {
43
51
  event.preventDefault();
44
52
  }
45
- }, { passive: false });
46
- document.addEventListener('wheel', function(event) {
53
+ }, {passive: false});
54
+ document.addEventListener('wheel', function (event) {
47
55
  if (event.ctrlKey === true) {
48
- event.preventDefault(); // Empêche le zoom quand Ctrl est pressé et que l'utilisateur scroll avec le trackpad
56
+ event.preventDefault(); // prevent zoom
49
57
  }
50
- }, { passive: false });
51
- </script >
58
+ }, {passive: false});
59
+ </script>
52
60
  </html>
@@ -14,6 +14,7 @@
14
14
  <script defer src="js/third_parties/sortable.min.js" type="text/javascript"></script>
15
15
  <script defer src="js/third_parties/wad.min.js" type="text/javascript"></script>
16
16
  <script defer src="js/third_parties/wavesurfer.min.js" type="text/javascript"></script>
17
+ <script type="text/javascript" src="js/third_parties/webaudio-pianoroll.min.js" defer></script>
17
18
  <script defer src="js/third_parties/sha256.min.js" type="text/javascript"></script>
18
19
  <script defer src="js/third_parties/ping.min.js" type="text/javascript"></script>
19
20
  <script defer src="js/third_parties/fabric.min.js" type="text/javascript"></script>
@@ -36,4 +37,22 @@
36
37
  const NativeMode = false; // used by atome.js to load code on the fly
37
38
  </script>
38
39
  <script defer src="js/atome/atome.js" type="text/javascript"></script>
40
+ <script>
41
+ // to prevent right click
42
+ document.addEventListener("contextmenu", function (e) {
43
+ e.preventDefault();
44
+ });
45
+ </script>
46
+ <script defer>
47
+ document.addEventListener('touchstart', function (event) {
48
+ if (event.touches.length > 1) {
49
+ event.preventDefault();
50
+ }
51
+ }, {passive: false});
52
+ document.addEventListener('wheel', function (event) {
53
+ if (event.ctrlKey === true) {
54
+ event.preventDefault(); // prevent zoom
55
+ }
56
+ }, {passive: false});
57
+ </script>
39
58
  </html>
@@ -15,6 +15,7 @@
15
15
  <script type="text/javascript" src="js/third_parties/sortable.min.js" defer></script>
16
16
  <script type="text/javascript" src="js/third_parties/wad.min.js" defer></script>
17
17
  <script type="text/javascript" src="js/third_parties/wavesurfer.min.js" defer></script>
18
+ <script type="text/javascript" src="js/third_parties/webaudio-pianoroll.min.js" defer></script>
18
19
  <script type="text/javascript" src="js/third_parties/sha256.min.js" defer></script>
19
20
  <script type="text/javascript" src="js/third_parties/ping.min.js" defer></script>
20
21
  <script type="text/javascript" src="js/third_parties/fabric.min.js" defer></script>
@@ -43,16 +44,22 @@
43
44
  const NativeMode = false; // used by atome.js to load code on the fly
44
45
  </script>
45
46
  <script defer src="js/atome/atome.js" type="text/javascript"></script>
47
+ <script>
48
+ // to prevent right click
49
+ document.addEventListener("contextmenu", function (e) {
50
+ e.preventDefault();
51
+ });
52
+ </script>
46
53
  <script defer>
47
- document.addEventListener('touchstart', function(event) {
54
+ document.addEventListener('touchstart', function (event) {
48
55
  if (event.touches.length > 1) {
49
56
  event.preventDefault();
50
57
  }
51
- }, { passive: false });
52
- document.addEventListener('wheel', function(event) {
58
+ }, {passive: false});
59
+ document.addEventListener('wheel', function (event) {
53
60
  if (event.ctrlKey === true) {
54
- event.preventDefault(); // Empêche le zoom quand Ctrl est pressé et que l'utilisateur scroll avec le trackpad
61
+ event.preventDefault(); // prevent zoom
55
62
  }
56
- }, { passive: false });
57
- </script >
63
+ }, {passive: false});
64
+ </script>
58
65
  </html>
@@ -15,18 +15,19 @@
15
15
  <script type="text/javascript" src="js/third_parties/sortable.min.js" defer></script>
16
16
  <script type="text/javascript" src="js/third_parties/wad.min.js" defer></script>
17
17
  <script type="text/javascript" src="js/third_parties/wavesurfer.min.js" defer></script>
18
+ <script type="text/javascript" src="js/third_parties/webaudio-pianoroll.min.js" defer></script>
18
19
  <script type="text/javascript" src="js/third_parties/sha256.min.js" defer></script>
19
20
  <script type="text/javascript" src="js/third_parties/ping.min.js" defer></script>
20
21
  <script type="text/javascript" src="js/third_parties/fabric.min.js" defer></script>
21
22
  <script type="text/javascript" src="js/third_parties/papaparse.min.js" defer></script>
22
23
  <script defer src="js/atome/atome_helpers/communication.js" type="text/javascript"></script>
23
24
  <script defer src="js/atome/atome_helpers/file.js" type="text/javascript"></script>
24
- <script>
25
- // to prevent right click
26
- document.addEventListener("contextmenu", function (e) {
27
- e.preventDefault();
28
- });
29
- </script>
25
+ <!-- <script>-->
26
+ <!-- // to prevent right click-->
27
+ <!-- document.addEventListener("contextmenu", function (e) {-->
28
+ <!-- e.preventDefault();-->
29
+ <!-- });-->
30
+ <!-- </script>-->
30
31
  <title>atome</title>
31
32
  </head>
32
33
  <body id='user_view' class='atome'>
@@ -48,16 +49,22 @@
48
49
  const NativeMode = false; // used by atome.js to load code on the fly
49
50
  </script>
50
51
  <script defer src="js/atome/atome.js" type="text/javascript"></script>
52
+ <script>
53
+ // to prevent right click
54
+ document.addEventListener("contextmenu", function (e) {
55
+ e.preventDefault();
56
+ });
57
+ </script>
51
58
  <script defer>
52
- document.addEventListener('touchstart', function(event) {
59
+ document.addEventListener('touchstart', function (event) {
53
60
  if (event.touches.length > 1) {
54
61
  event.preventDefault();
55
62
  }
56
- }, { passive: false });
57
- document.addEventListener('wheel', function(event) {
63
+ }, {passive: false});
64
+ document.addEventListener('wheel', function (event) {
58
65
  if (event.ctrlKey === true) {
59
- event.preventDefault(); // Empêche le zoom quand Ctrl est pressé et que l'utilisateur scroll avec le trackpad
66
+ event.preventDefault(); // prevent zoom
60
67
  }
61
- }, { passive: false });
62
- </script >
68
+ }, {passive: false});
69
+ </script>
63
70
  </html>
@@ -0,0 +1,66 @@
1
+ customElements.define("webaudio-pianoroll",class t extends HTMLElement{constructor(){super()}defineprop(){let t=this.module.properties;for(let e in t){let i=t[e];this["_"+e]=this.getAttr(e,i.value),Object.defineProperty(this,e,{get:()=>this["_"+e],set:t=>{this["_"+e]=t,"function"==typeof this[i.observer]&&this[i.observer]()}})}}connectedCallback(){let t;t=this,this.module={is:"webaudio-pianoroll",properties:{width:{type:Number,value:640,observer:"layout"},height:{type:Number,value:320,observer:"layout"},timebase:{type:Number,value:16,observer:"layout"},editmode:{type:String,value:"dragpoly"},xrange:{type:Number,value:16,observer:"layout"},yrange:{type:Number,value:16,observer:"layout"},xoffset:{type:Number,value:0,observer:"layout"},yoffset:{type:Number,value:60,observer:"layout"},grid:{type:Number,value:4},snap:{type:Number,value:1},wheelzoom:{type:Number,value:0},wheelzoomx:{type:Number,value:0},wheelzoomy:{type:Number,value:0},xscroll:{type:Number,value:0},yscroll:{type:Number,value:0},gridnoteratio:{type:Number,value:.5,observer:"updateTimer"},xruler:{type:Number,value:24,observer:"layout"},yruler:{type:Number,value:24,observer:"layout"},octadj:{type:Number,value:-1},cursor:{type:Number,value:0,observer:"redrawMarker"},markstart:{type:Number,value:0,observer:"redrawMarker"},markend:{type:Number,value:16,observer:"redrawMarker"},defvelo:{type:Number,value:100},collt:{type:String,value:"#ccc"},coldk:{type:String,value:"#aaa"},colgrid:{type:String,value:"#666"},colnote:{type:String,value:"#f22"},colnotesel:{type:String,value:"#0f0"},colnoteborder:{type:String,value:"#000"},colnoteselborder:{type:String,value:"#fff"},colrulerbg:{type:String,value:"#666"},colrulerfg:{type:String,value:"#fff"},colrulerborder:{type:String,value:"#000"},colselarea:{type:String,value:"rgba(0,0,0,0.3)"},bgsrc:{type:String,value:null,observer:"layout"},cursorsrc:{type:String,value:"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIj4NCjxwYXRoIGZpbGw9InJnYmEoMjU1LDEwMCwxMDAsMC44KSIgZD0iTTAsMSAyNCwxMiAwLDIzIHoiLz4NCjwvc3ZnPg0K"},cursoroffset:{type:Number,value:0},markstartsrc:{type:String,value:"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij4NCjxwYXRoIGZpbGw9IiMwYzAiIGQ9Ik0wLDEgMjQsMSAwLDIzIHoiLz4NCjwvc3ZnPg0K"},markstartoffset:{type:Number,value:0},markendsrc:{type:String,value:"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij4NCjxwYXRoIGZpbGw9IiMwYzAiIGQ9Ik0wLDEgMjQsMSAyNCwyMyB6Ii8+DQo8L3N2Zz4NCg=="},markendoffset:{type:Number,value:-24},kbsrc:{type:String,value:"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSI0ODAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8cGF0aCBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiIGQ9Ik0wLDAgaDI0djQ4MGgtMjR6Ii8+CjxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik0wLDQwIGgxMnY0MGgtMTJ6IE0wLDEyMCBoMTJ2NDBoLTEyeiBNMCwyMDAgaDEydjQwaC0xMnogTTAsMzIwIGgxMnY0MGgtMTJ6IE0wLDQwMCBoMTJ2NDBoLTEyeiIvPgo8cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIGQ9Ik0wLDYwIGgyNCBNMCwxNDAgaDI0IE0wLDIyMCBoMjQgTTAsMjgwIGgyNCBNMCwzNDAgaDI0IE0wLDQyMCBoMjQiLz4KPC9zdmc+Cg==",observer:"layout"},kbwidth:{type:Number,value:40},loop:{type:Number,value:0},preload:{type:Number,value:1},tempo:{type:Number,value:120,observer:"updateTimer"},enable:{type:Boolean,value:!0}}},this.defineprop(),t.innerHTML=`<style>
2
+ .pianoroll{
3
+ background:#ccc;
4
+ }
5
+ :host {
6
+ user-select: none;
7
+ display: inline-block;
8
+ font-family: sans-serif;
9
+ font-size: 11px;
10
+ padding:0;
11
+ margin:0;
12
+ }
13
+ #wac-body {
14
+ position: relative;
15
+ margin:0;
16
+ padding:0;
17
+ width: 100%;
18
+ height: 100%;
19
+ overflow: hidden;
20
+ }
21
+ #wac-pianoroll {
22
+ cursor: pointer;
23
+ margin:0;
24
+ padding:0;
25
+ width: 100%;
26
+ height: 100%;
27
+ background-size:100% calc(100%*12/16);
28
+ background-position:left bottom;
29
+ }
30
+ #wac-menu {
31
+ display:none;
32
+ position:absolute;
33
+ top:0px;
34
+ left:0px;
35
+ background:#eef;
36
+ color:#000;
37
+ padding:2px 10px;
38
+ border:1px solid #66f;
39
+ border-radius: 4px;
40
+ cursor:pointer;
41
+ }
42
+ .marker{
43
+ position: absolute;
44
+ left:0px;
45
+ top:0px;
46
+ cursor:ew-resize;
47
+ }
48
+ #wac-kb{
49
+ position:absolute;
50
+ left:0px;
51
+ top:0px;
52
+ width:100px;
53
+ height:100%;
54
+ background: repeat-y;
55
+ background-size:100% calc(100%*12/16);
56
+ background-position:left bottom;
57
+ }
58
+ </style>
59
+ <div class="wac-body" id="wac-body" touch-action="none">
60
+ <canvas id="wac-pianoroll" touch-action="none" tabindex="0"></canvas>
61
+ <div id="wac-kb"></div>
62
+ <img id="wac-markstart" class="marker" src="${this.markstartsrc}"/>
63
+ <img id="wac-markend" class="marker" src="${this.markendsrc}"/>
64
+ <img id="wac-cursor" class="marker" src="${this.cursorsrc}"/>
65
+ <div id="wac-menu">Delete</div>
66
+ </div>`,this.sortSequence=function(){this.sequence.sort((t,e)=>t.t-e.t)},this.findNextEv=function(t){for(let e=0;e<this.sequence.length;++e){let i=this.sequence[e];if(i.t>=this.markend)return{t1:t,n2:this.markend,dt:this.markend-t,i:-1};if(i.t>=t)return{t1:t,t2:i.t,dt:i.t-t,i:e}}return{t1:t,t2:this.markend,dt:this.markend-t,i:-1}},this.locate=function(t){this.cursor=t},this.updateTimer=function(){this.tick2time=240/this.tempo/this.timebase},this.play=function(t,e,i){if(void 0!==i&&this.locate(i),null!=this.timer)return;this.actx=t,this.playcallback=e,this.timestack=[],this.time0=this.time1=this.actx.currentTime+.1,this.tick0=this.tick1=this.cursor,this.tick2time=240/this.tempo/this.timebase;let s=this.findNextEv(this.cursor);this.index1=s.i,this.timestack.push([0,this.cursor,0]),this.timestack.push([this.time0,this.cursor,this.tick2time]),this.time1+=s.dt*this.tick2time,s.i<0?this.timestack.push([this.time1,this.markstart,this.tick2time]):this.timestack.push([this.time1,s.t1,this.tick2time]),this.timer=setInterval((function t(){let e=this.actx.currentTime;for(;this.timestack.length>1&&e>=this.timestack[1][0];)this.timestack.shift();for(this.cursor=this.timestack[0][1]+(e-this.timestack[0][0])/this.timestack[0][2],this.redrawMarker();e+this.preload>=this.time1;){this.time0=this.time1,this.tick0=this.tick1;let i=this.sequence[this.index1];if(!i||i.t>=this.markend){this.timestack.push([this.time1,this.markstart,this.tick2time]);let s=this.findNextEv(this.markstart);this.time1+=s.dt*this.tick2time,this.index1=s.i}else{this.tick1=i.t,this.timestack.push([this.time1,i.t,this.tick2time]);let h=Math.min(i.t+i.g,this.markend)-i.t;("gridmono"==this.editmode||"gridpoly"==this.editmode)&&(h*=this.gridnoteratio);let r={t:this.time1,g:this.time1+h*this.tick2time,n:i.n};if(this.playcallback&&this.playcallback(r),(i=this.sequence[++this.index1])&&!(i.t>=this.markend))this.time1+=(i.t-this.tick1)*this.tick2time;else{this.time1+=(this.markend-this.tick1)*this.tick2time;let n=this.findNextEv(this.markstart);this.timestack.push([this.time1,this.markstart,this.tick2time]),this.time1+=n.dt*this.tick2time,this.index1=n.i}}}}).bind(this),25)},this.stop=function(){this.timer&&clearInterval(this.timer),this.timer=null},this.setMMLString=function(t){this.sequence=[];let e,i,s,h,r,n,a,o,l={s:t,i:e,tb:this.timebase};function c(t){for(var e=0;t.s[t.i]>="0"&&t.s[t.i]<="9";)e=10*e+parseInt(t.s[t.i]),++t.i;return e}function d(t){var e=c(t);0==e&&(e=n);for(var i=e=t.tb/e;"."==t.s[t.i];)++t.i,e+=i>>=1;return e}function g(t){switch(t.s[t.i]){case"c":case"C":s=0;break;case"d":case"D":s=2;break;case"e":case"E":s=4;break;case"f":case"F":s=5;break;case"g":case"G":s=7;break;case"a":case"A":s=9;break;case"b":case"B":s=11;break;default:s=-1}if(++t.i,s<0)return -1;for(;;){switch(t.s[t.i]){case"-":--s;break;case"+":case"#":++s;break;default:return s}++t.i}}for(r=4,n=8,h=0,a=0,o=null,l.i=0;l.i<l.s.length;){switch(l.s[l.i]){case">":++l.i,++r,s=-1,i=0;break;case"<":++l.i,--r,s=-1,i=0;break;case"&":case"^":++l.i,a=1,s=-1,i=0;break;case"t":case"T":++l.i,s=-1,i=0,this.tempo=c(l);break;case"o":case"O":++l.i,s=-1,i=0,r=c(l);break;case"l":case"L":++l.i,s=-1,i=0,n=c(l);break;case"r":case"R":++l.i,s=-1,i=d(l);break;default:i=(s=g(l))>=0?d(l):0}s>=0&&(s=(r-this.octadj)*12+s,a&&o&&o.n==s?(o.g+=i,a=0):this.sequence.push(o={t:h,n:s,g:i,f:0})),h+=i}this.redraw()},this.getMMLString=function(){function t(t,e,i){console.log("*****> "+t+" : "+e+" : "+i+" : ");var s="",h=[[960,"1"],[840,"2.."],[720,"2."],[480,"2"],[420,"4.."],[360,"4."],[240,"4"],[210,"8.."],[180,"8."],[120,""],[105,"16.."],[90,"16."],[60,"16"],[45,"32."],[30,"32"],[16,"60"],[15,"64"],[8,"120"],[4,"240"],[2,"480"],[1,"960"]];for(e=960*e/i;e>0;)for(let r=0;r<h.length;++r)for(;e>=h[r][0];)e-=h[r][0],s+="&"+t+h[r][1];return s.substring(1)}var e,i="t"+this.tempo+"o4l8",s=0,h=5,r=["c","d-","d","e-","e","f","g-","g","a-","a","b-","b"];for(let n=0;n<this.sequence.length;++n){var a=this.sequence[n];if(a.t>s){var o=a.t-s;i+=t("r",o,this.timebase),s=a.t}var e=a.n;(e<12*h||e>=12*h+12)&&(i+="o"+((h=e/12|0)+this.octadj)),e=r[e%12];var o=a.g;if(n+1<this.sequence.length){var l=this.sequence[n+1];l.t<a.t+o?(o=l.t-a.t,s=l.t):s=a.t+a.g}else s=a.t+a.g;i+=t(e,o,this.timebase)}return i},this.hitTest=function(t){let e={t:0,n:0,i:-1,m:" "},i=this.sequence.length;if(t.t==this.menu)return e.m="m",e;if(e.t=this.xoffset+(t.x-this.yruler-this.kbwidth)/this.swidth*this.xrange,e.n=this.yoffset-(t.y-this.height)/this.steph,t.y>=this.height||t.x>=this.width)return e;if(t.y<this.xruler)return e.m="x",e;if(t.x<this.yruler+this.kbwidth)return e.m="y",e;for(let s=0;s<i;++s){let h=this.sequence[s];if((0|e.n)==h.n){if(h.f&&Math.abs(h.t-e.t)*this.stepw<8)return e.m="B",e.i=s,e;if(h.f&&Math.abs(h.t+h.g-e.t)*this.stepw<8)return e.m="E",e.i=s,e;if(e.t>=h.t&&e.t<h.t+h.g)return e.i=s,this.sequence[s].f?e.m="N":e.m="n",e}}return e.m="s",e},this.addNote=function(t,e,i,s,h){if(t>=0&&e>=0&&e<128){let r={t:t,c:144,n:e,g:i,v:s,f:h};return this.sequence.push(r),this.sortSequence(),this.redraw(),r}return null},this.selAreaNote=function(t,e,i,s){let h,r=0,n=this.sequence[r];for(i>s&&(h=i,i=s,s=h),t>e&&(h=t,t=e,e=h);n;)n.t>=t&&n.t<e&&n.n>=i&&n.n<=s?n.f=1:n.f=0,n=this.sequence[++r]},this.delNote=function(t){this.sequence.splice(t,1),this.redraw()},this.delAreaNote=function(t,e,i){let s=this.sequence.length;for(let h=s-1;h>=0;--h){let r=this.sequence[h];void 0!==i&&i!=h&&(t<=r.t&&t+e>=r.t+r.g?this.sequence.splice(h,1):t<=r.t&&t+e>r.t&&t+e<r.t+r.g?(r.g=r.t+r.g-(t+e),r.t=t+e):t>=r.t&&t<r.t+r.g&&t+e>=r.t+r.g?r.g=t-r.t:t>r.t&&t+e<r.t+r.g&&(this.addNote(t+e,r.n,r.t+r.g-t-e,this.defvelo),r.g=t-r.t))}},this.delSelectedNote=function(){let t=this.sequence.length;for(let e=t-1;e>=0;--e){let i=this.sequence[e];i.f&&this.sequence.splice(e,1)}},this.moveSelectedNote=function(t,e){let i=this.sequence.length;for(let s=0;s<i;++s){let h=this.sequence[s];h.f&&h.ot+t<0&&(t=-h.ot)}for(let r=0;r<i;++r){let n=this.sequence[r];n.f&&(n.t=((n.ot+t)/this.snap+.5|0)*this.snap,n.n=n.on+e)}},this.clearSel=function(){let t=this.sequence.length;for(let e=0;e<t;++e)this.sequence[e].f=0},this.selectedNotes=function(){let t=[];for(let e=this.sequence.length-1;e>=0;--e){let i=this.sequence[e];i.f&&t.push({i:e,ev:i,t:i.t,g:i.g})}return t},this.editDragDown=function(t){let e=this.hitTest(t),i;if("N"==e.m){i=this.sequence[e.i],this.dragging={o:"D",m:"N",i:e.i,t:e.t,n:i.n,dt:e.t-i.t};for(let s=0,h=this.sequence.length;s<h;++s)(i=this.sequence[s]).f&&(i.on=i.n,i.ot=i.t,i.og=i.g);this.redraw()}else if("n"==e.m)i=this.sequence[e.i],this.clearSel(),i.f=1,this.redraw();else if("E"==e.m){let r=this.sequence[e.i];this.dragging={o:"D",m:"E",i:e.i,t:r.t,g:r.g,ev:this.selectedNotes()}}else if("B"==e.m){let n=this.sequence[e.i];this.dragging={o:"D",m:"B",i:e.i,t:n.t,g:n.g,ev:this.selectedNotes()}}else if("s"==e.m&&e.t>=0){this.clearSel();var a=(e.t/this.snap|0)*this.snap;this.sequence.push({t:a,n:0|e.n,g:1,f:1}),this.dragging={o:"D",m:"E",i:this.sequence.length-1,t:a,g:1,ev:[{t:a,g:1,ev:this.sequence[this.sequence.length-1]}]},this.redraw()}},this.editDragMove=function(t){let e=this.hitTest(t),i;if("D"==this.dragging.o)switch(this.dragging.m){case"E":if(this.dragging.ev){let s=(Math.max(0,e.t)/this.snap+.9|0)*this.snap-this.dragging.t-this.dragging.g,h=this.dragging.ev;for(let r=h.length-1;r>=0;--r){let n=h[r].ev;n.g=h[r].g+s,n.g<=0&&(n.g=1),"dragmono"==this.editmove&&this.delAreaNote(n.t,n.g)}}this.redraw();break;case"B":if(this.dragging.ev){let a=(Math.max(0,e.t)/this.snap+.9|0)*this.snap-this.dragging.t,o=this.dragging.ev;for(let l=o.length-1;l>=0;--l){let c=o[l].ev;c.t=o[l].t+a,c.g=o[l].g-a,c.g<=0&&(c.g=1),"dragmono"==this.editmove&&this.delAreaNote(c.t,c.g)}}this.redraw();break;case"N":i=this.sequence[this.dragging.i],this.moveSelectedNote(e.t-this.dragging.t|0,(0|e.n)-this.dragging.n),this.redraw()}},this.editGridDown=function(t){let e=this.hitTest(t);if("n"==e.m)this.delNote(e.i),this.dragging={o:"G",m:"0"};else if("s"==e.m&&e.t>=0){let i=Math.floor(e.t);"gridmono"==this.editmode&&this.delAreaNote(i,1,e.i),this.addNote(i,0|e.n,1,this.defvelo),this.dragging={o:"G",m:"1"}}},this.editGridMove=function(t){let e=this.hitTest(t);if("G"==this.dragging.o)switch(this.dragging.m){case"1":let i=Math.floor(e.t);"s"==e.m&&("gridmono"==this.editmode&&this.delAreaNote(i,1,e.i),this.addNote(i,0|e.n,1,this.defvelo));break;case"0":"n"==e.m&&this.delNote(e.i)}},this.setListener=function(t,e){this.bindcontextmenu=this.contextmenu.bind(this),this.bindpointermove=this.pointermove.bind(this),this.bindcancel=this.cancel.bind(this),t.addEventListener("mousedown",this.pointerdown.bind(this),!0),t.addEventListener("touchstart",this.pointerdown.bind(this),!1),e&&(t.addEventListener("mouseover",this.pointerover.bind(this),!1),t.addEventListener("mouseout",this.pointerout.bind(this),!1))},this.ready=function(){this.body=t.children[1],this.elem=t.childNodes[2],this.proll=this.elem.children[0],this.canvas=this.elem.children[0],this.kb=this.elem.children[1],this.ctx=this.canvas.getContext("2d"),this.kbimg=this.elem.children[1],this.markstartimg=this.elem.children[2],this.markendimg=this.elem.children[3],this.cursorimg=this.elem.children[4],this.menu=this.elem.children[5],this.rcMenu={x:0,y:0,width:0,height:0},this.lastx=0,this.lasty=0,this.canvas.addEventListener("mousemove",this.mousemove.bind(this),!1),this.canvas.addEventListener("keydown",this.keydown.bind(this),!1),this.canvas.addEventListener("DOMMouseScroll",this.wheel.bind(this),!1),this.canvas.addEventListener("mousewheel",this.wheel.bind(this),!1),this.setListener(this.canvas,!0),this.setListener(this.markendimg,!0),this.setListener(this.markstartimg,!0),this.setListener(this.cursorimg,!0),this.setListener(this.menu,!1),this.sequence=[],this.dragging={o:null},this.kbimg.style.height=this.sheight+"px",this.kbimg.style.backgroundSize=12*this.steph+"px",this.layout(),this.initialized=1,this.redraw()},this.setupImage=function(){},this.preventScroll=function(t){t.preventDefault&&t.preventDefault()},this.getPos=function(t){let e=null;return t&&(e=t.target,this.lastx=t.clientX-this.rcTarget.left,this.lasty=t.clientY-this.rcTarget.top),this.lastx>=this.rcMenu.x&&this.lastx<this.rcMenu.x+this.rcMenu.width&&this.lasty>=this.rcMenu.y&&this.lasty<this.rcMenu.y+this.rcMenu.height&&(e=this.menu),{t:e,x:this.lastx,y:this.lasty}},this.contextmenu=function(t){return t.stopPropagation(),t.preventDefault(),window.removeEventListener("contextmenu",this.bindcontextmenu),!1},this.keydown=function(t){46===t.keyCode&&(this.delSelectedNote(),this.redraw())},this.popMenu=function(t){let e=this.menu.style;e.display="block",e.top=t.y+8+"px",e.left=t.x+8+"px",this.rcMenu=this.menu.getBoundingClientRect()},this.longtapcountup=function(){if(++this.longtapcount>=18)switch(clearInterval(this.longtaptimer),this.downht.m){case"N":case"B":case"E":this.popMenu(this.downpos),this.dragging={o:"m"}}},this.pointerdown=function(t){let e;if(this.enable){if(e=t.touches?t.touches[0]:t,this.rcTarget=this.canvas.getBoundingClientRect(),this.downpos=this.getPos(e),this.downht=this.hitTest(this.downpos),console.log("======> "+this.downht),this.longtapcount=0,this.longtaptimer=setInterval(this.longtapcountup.bind(this),100),window.addEventListener("touchmove",this.bindpointermove,!1),window.addEventListener("mousemove",this.bindpointermove,!1),window.addEventListener("touchend",this.bindcancel),window.addEventListener("mouseup",this.bindcancel),window.addEventListener("contextmenu",this.bindcontextmenu),2==e.button||e.ctrlKey){switch(this.downht.m){case"N":case"B":case"E":this.popMenu(this.downpos),this.dragging={o:"m"};break;default:("dragmono"==this.editmode||"dragpoly"==this.editmode)&&(this.dragging={o:"A",p:this.downpos,p2:this.downpos,t1:this.downht.t,n1:this.downht.n})}return t.preventDefault(),t.stopPropagation(),this.canvas.focus(),!1}switch(e.target){case this.markendimg:return this.dragging={o:"E",x:this.downpos.x,m:this.markend},t.preventDefault(),t.stopPropagation(),!1;case this.markstartimg:return this.dragging={o:"S",x:this.downpos.x,m:this.markstart},t.preventDefault(),t.stopPropagation(),!1;case this.cursorimg:return this.dragging={o:"P",x:this.downpos.x,m:this.cursor},t.preventDefault(),t.stopPropagation(),!1}switch(this.dragging={o:null,x:this.downpos.x,y:this.downpos.y,offsx:this.xoffset,offsy:this.yoffset},this.canvas.focus(),this.editmode){case"gridpoly":case"gridmono":this.editGridDown(this.downpos);break;case"dragpoly":case"dragmono":this.editDragDown(this.downpos)}return this.press=1,t.preventDefault&&t.preventDefault(),t.stopPropagation&&t.stopPropagation(),!1}},this.mousemove=function(t){if(null==this.dragging.o){this.rcTarget=this.canvas.getBoundingClientRect();let e=this.getPos(t),i=this.hitTest(e);switch(i.m){case"E":this.canvas.style.cursor="e-resize";break;case"B":this.canvas.style.cursor="w-resize";break;case"N":this.canvas.style.cursor="move";break;case"n":case"s":this.canvas.style.cursor="pointer"}}},this.pointermove=function(t){let e;this.rcTarget=this.canvas.getBoundingClientRect(),e=t.touches?t.touches[0]:t,this.longtaptimer&&clearInterval(this.longtaptimer);let i=this.getPos(e),s=this.hitTest(i);switch(this.dragging.o){case null:this.xscroll&&(this.xoffset=this.dragging.offsx+(this.dragging.x-i.x)*(this.xrange/this.width)),this.yscroll&&(this.yoffset=this.dragging.offsy+(i.y-this.dragging.y)*(this.yrange/this.height));break;case"m":"m"==s.m?this.menu.style.background="#ff6":this.menu.style.background="#eef";break;case"A":this.dragging.p2=i,this.dragging.t2=s.t,this.dragging.n2=s.n,this.redraw();break;case"E":var h=Math.max(1,this.dragging.m+(i.x-this.dragging.x)/this.stepw+.5|0);this.markstart>=h&&(this.markstart=h-1),this.markend=h;break;case"S":var h=Math.max(0,this.dragging.m+(i.x-this.dragging.x)/this.stepw+.5|0);this.markend<=h&&(this.markend=h+1),this.markstart=h;break;case"P":this.cursor=Math.max(0,this.dragging.m+(i.x-this.dragging.x)/this.stepw+.5|0)}switch(this.editmode){case"gridpoly":case"gridmono":this.editGridMove(i);break;case"dragpoly":case"dragmono":this.editDragMove(i)}return t.stopPropagation(),!1},this.cancel=function(t){let e;e=t.touches?null:t,this.longtaptimer&&clearInterval(this.longtaptimer);let i=this.getPos(e);if("m"==this.dragging.o&&(this.menu.style.display="none",this.rcMenu={x:0,y:0,width:0,height:0},i.t==this.menu&&this.delSelectedNote(),this.redraw()),"A"==this.dragging.o&&(this.selAreaNote(this.dragging.t1,this.dragging.t2,this.dragging.n1,this.dragging.n2),this.dragging={o:null},this.redraw()),"dragmono"==this.editmode)for(let s=this.sequence.length-1;s>=0;--s){let h=this.sequence[s];h&&h.f&&this.delAreaNote(h.t,h.g,s)}return this.redraw(),this.dragging={o:null},this.press&&this.sortSequence(),this.press=0,window.removeEventListener("touchstart",this.preventScroll,!1),window.removeEventListener("mousemove",this.bindpointermove,!1),window.removeEventListener("touchend",this.bindcancel,!1),window.removeEventListener("mouseup",this.bindcancel,!1),t.preventDefault(),t.stopPropagation(),!1},this.pointerover=function(t){},this.pointerout=function(t){},this.wheel=function(t){let e=0,i=this.getPos(t);t||(t=window.event),t.wheelDelta?e=t.wheelDelta/120:t.detail&&(e=-t.detail/3);let s=this.hitTest(i);(this.wheelzoomx||this.wheelzoom)&&"x"==s.m&&(e>0?(this.xoffset=s.t-(s.t-this.xoffset)/1.2,this.xrange/=1.2):(this.xoffset=s.t-(s.t-this.xoffset)*1.2,this.xrange*=1.2)),(this.wheelzoomy||this.wheelzoom)&&"y"==s.m&&(e>0?(this.yoffset=s.n-(s.n-this.yoffset)/1.2,this.yrange/=1.2):(this.yoffset=s.n-(s.n-this.yoffset)*1.2,this.yrange*=1.2)),t.preventDefault()},this.layout=function(){if(void 0===this.kbwidth)return;let t=this.proll,e=this.body.style;this.bgsrc&&(t.style.background="url('"+this.bgsrc+"')"),this.kbimg.style.background="url('"+this.kbsrc+"')",this.width&&(t.width=this.width,e.width=t.style.width=this.width+"px"),this.height&&(t.height=this.height,e.height=t.style.height=this.height+"px"),this.swidth=t.width-this.yruler,this.swidth-=this.kbwidth,this.sheight=t.height-this.xruler,this.redraw()},this.redrawMarker=function(){if(!this.initialized)return;let t=(this.cursor-this.xoffset)*this.stepw+this.yruler+this.kbwidth;this.cursorimg.style.left=t+this.cursoroffset+"px";let e=(this.markstart-this.xoffset)*this.stepw+this.yruler+this.kbwidth;this.markstartimg.style.left=e+this.markstartoffset+"px";let i=(this.markend-this.xoffset)*this.stepw+this.yruler+this.kbwidth;this.markendimg.style.left=i+this.markendoffset+"px"},this.redrawGrid=function(){for(let t=0;t<128;++t){1&this.semiflag[t%12]?this.ctx.fillStyle=this.coldk:this.ctx.fillStyle=this.collt;let e=this.height-(t-this.yoffset)*this.steph;this.ctx.fillRect(this.yruler+this.kbwidth,0|e,this.swidth,-this.steph),this.ctx.fillStyle=this.colgrid,this.ctx.fillRect(this.yruler+this.kbwidth,0|e,this.swidth,1)}for(let i=0;;i+=this.grid){let s=this.stepw*(i-this.xoffset)+this.yruler+this.kbwidth;if(this.ctx.fillRect(0|s,this.xruler,1,this.sheight),s>=this.width)break}},this.semiflag=[6,1,0,1,0,2,1,0,1,0,1,0],this.redrawXRuler=function(){if(this.xruler){this.ctx.textAlign="left",this.ctx.font=this.xruler/2+"px 'sans-serif'",this.ctx.fillStyle=this.colrulerbg,this.ctx.fillRect(0,0,this.width,this.xruler),this.ctx.fillStyle=this.colrulerborder,this.ctx.fillRect(0,0,this.width,1),this.ctx.fillRect(0,0,1,this.xruler),this.ctx.fillRect(0,this.xruler-1,this.width,1),this.ctx.fillRect(this.width-1,0,1,this.xruler),this.ctx.fillStyle=this.colrulerfg;for(let t=0;;t+=this.timebase){let e=(t-this.xoffset)*this.stepw+this.yruler+this.kbwidth;if(this.ctx.fillRect(e,0,1,this.xruler),this.ctx.fillText(t/this.timebase+1,e+4,this.xruler-8),e>=this.width)break}}},this.redrawYRuler=function(){if(this.yruler){this.ctx.textAlign="right",this.ctx.font=this.steph/2+"px 'sans-serif'",this.ctx.fillStyle=this.colrulerbg,this.ctx.fillRect(0,this.xruler,this.yruler,this.sheight),this.ctx.fillStyle=this.colrulerborder,this.ctx.fillRect(0,this.xruler,1,this.sheight),this.ctx.fillRect(this.yruler,this.xruler,1,this.sheight),this.ctx.fillRect(0,this.height-1,this.yruler,1),this.ctx.fillStyle=this.colrulerfg;for(let t=0;t<128;t+=12){let e=this.height-this.steph*(t-this.yoffset);this.ctx.fillRect(0,0|e,this.yruler,-1),this.ctx.fillText("C"+((t/12|0)+this.octadj),this.yruler-4,e-4)}}this.kbimg.style.top=this.xruler+"px",this.kbimg.style.left=this.yruler+"px",this.kbimg.style.width=this.kbwidth+"px",this.kbimg.style.backgroundSize="100% "+12*this.steph+"px",this.kbimg.style.backgroundPosition="0px "+(this.sheight+this.steph*this.yoffset)+"px"},this.redrawKeyboard=function(){if(this.yruler){for(this.ctx.textAlign="right",this.ctx.font=this.steph/2+"px 'sans-serif'",this.ctx.fillStyle=this.colortab.kbwh,this.ctx.fillRect(1,this.xruler,this.yruler,this.sheight),this.ctx.fillStyle=this.colortab.kbbk,y=0;y<128;++y){let t=this.height-this.steph*(y-this.yoffset),e=y%12,i=this.semiflag[e];1&i&&(this.ctx.fillRect(0,t,this.yruler/2,-this.steph),this.ctx.fillRect(0,t-this.steph/2|0,this.yruler,-1)),2&i&&this.ctx.fillRect(0,0|t,this.yruler,-1),4&i&&this.ctx.fillText("C"+((y/12|0)+this.octadj),this.yruler-4,t-4)}this.ctx.fillRect(this.yruler,this.xruler,1,this.sheight)}},this.redrawAreaSel=function(){this.dragging&&"A"==this.dragging.o&&(this.ctx.fillStyle=this.colselarea,this.ctx.fillRect(this.dragging.p.x,this.dragging.p.y,this.dragging.p2.x-this.dragging.p.x,this.dragging.p2.y-this.dragging.p.y))},this.redraw=function(){let t,e,i,s,h;if(!this.ctx)return;this.ctx.clearRect(0,0,this.width,this.height),this.stepw=this.swidth/this.xrange,this.steph=this.sheight/this.yrange,this.redrawGrid();let r=this.sequence.length;for(let n=0;n<r;++n){let a=this.sequence[n];a.f?this.ctx.fillStyle=this.colnotesel:this.ctx.fillStyle=this.colnote,e=a.g*this.stepw,s=(t=(a.t-this.xoffset)*this.stepw+this.yruler+this.kbwidth)+e|0,t|=0,h=(i=this.height-(a.n-this.yoffset)*this.steph)-this.steph|0,i|=0,this.ctx.fillRect(t,i,s-t,h-i),a.f?this.ctx.fillStyle=this.colnoteselborder:this.ctx.fillStyle=this.colnoteborder,this.ctx.fillRect(t,i,1,h-i),this.ctx.fillRect(s,i,1,h-i),this.ctx.fillRect(t,i,s-t,1),this.ctx.fillRect(t,h,s-t,1)}this.redrawYRuler(),this.redrawXRuler(),this.redrawMarker(),this.redrawAreaSel()},this.ready()}sendEvent(t){let e;(e=document.createEvent("HTMLEvents")).initEvent(t,!1,!0),this.dispatchEvent(e)}getAttr(t,e){let i=this.getAttribute(t);if(""==i||null==i)return e;if("number"==typeof e){if("true"==i)return 1;if(isNaN(i=+i))return 0}return i}disconnectedCallback(){}});
@@ -0,0 +1,50 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120" height="120" xml:space="preserve" id="canvas1">
4
+ <!-- Generated by PaintCode - http://www.paintcodeapp.com -->
5
+ <defs>
6
+ <filter id="canvas1-shadow-outer" filterUnits="objectBoundingBox">
7
+ <feGaussianBlur stdDeviation="1" />
8
+ <feOffset dx="0.5" dy="0.5" result="blur" />
9
+ <feFlood flood-color="rgb(0, 0, 0)" flood-opacity="1" />
10
+ <feComposite in2="blur" operator="in" result="colorShadow" />
11
+ <feComposite in="SourceGraphic" in2="colorShadow" operator="over" />
12
+ </filter>
13
+ <filter id="canvas1-shadow-outer" filterUnits="objectBoundingBox">
14
+ <feGaussianBlur stdDeviation="1" />
15
+ <feOffset dx="0.5" dy="0.5" result="blur" />
16
+ <feFlood flood-color="rgb(0, 0, 0)" flood-opacity="1" />
17
+ <feComposite in2="blur" operator="in" result="colorShadow" />
18
+ <feComposite in="SourceGraphic" in2="colorShadow" operator="over" />
19
+ </filter>
20
+ </defs>
21
+ <g id="canvas1-notes">
22
+ <rect id="canvas1-rectangle" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="0" y="42" width="15" height="75" />
23
+ <rect id="canvas1-rectangle3" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="15" y="42" width="15" height="75" />
24
+ <rect id="canvas1-rectangle4" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="30" y="42" width="15" height="75" />
25
+ <rect id="canvas1-rectangle5" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="45" y="42" width="15" height="75" />
26
+ <rect id="canvas1-rectangle6" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="60" y="42" width="15" height="75" />
27
+ <rect id="canvas1-rectangle7" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="75" y="42" width="15" height="75" />
28
+ <rect id="canvas1-rectangle8" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="90" y="42" width="15" height="75" />
29
+ <rect id="canvas1-rectangle9" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="105" y="42" width="15" height="75" />
30
+ <rect id="canvas1-rectangle2" stroke="none" fill="rgb(78, 78, 78)" filter="url(#canvas1-shadow-outer)" x="10" y="42" width="10" height="61" />
31
+ <rect id="canvas1-rectangle10" stroke="none" fill="rgb(78, 78, 78)" filter="url(#canvas1-shadow-outer)" x="30" y="42" width="10" height="61" />
32
+ <rect id="canvas1-rectangle11" stroke="none" fill="rgb(78, 78, 78)" filter="url(#canvas1-shadow-outer)" x="70" y="42" width="10" height="61" />
33
+ <rect id="canvas1-rectangle12" stroke="none" fill="rgb(78, 78, 78)" filter="url(#canvas1-shadow-outer)" x="90" y="42" width="10" height="61" />
34
+ <rect id="canvas1-rectangle13" stroke="none" fill="rgb(78, 78, 78)" filter="url(#canvas1-shadow-outer)" x="110" y="42" width="10" height="61" />
35
+ </g>
36
+ <g id="canvas1-guide" filter="url(#canvas1-shadow-outer)">
37
+ <rect id="canvas1-rectangle14" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="0" y="0" width="10" height="45" />
38
+ <rect id="canvas1-rectangle15" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(92, 92, 92)" x="10" y="0" width="10" height="45" />
39
+ <rect id="canvas1-rectangle16" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="20" y="0" width="10" height="45" />
40
+ <rect id="canvas1-rectangle17" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(92, 92, 92)" x="30" y="0" width="10" height="45" />
41
+ <rect id="canvas1-rectangle18" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="40" y="0" width="10" height="45" />
42
+ <rect id="canvas1-rectangle19" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="50" y="0" width="10" height="45" />
43
+ <rect id="canvas1-rectangle20" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="60" y="0" width="10" height="45" />
44
+ <rect id="canvas1-rectangle21" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(92, 92, 92)" x="70" y="0" width="10" height="45" />
45
+ <rect id="canvas1-rectangle22" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="80" y="0" width="10" height="45" />
46
+ <rect id="canvas1-rectangle23" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(92, 92, 92)" x="90" y="0" width="10" height="45" />
47
+ <rect id="canvas1-rectangle24" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="100" y="0" width="10" height="45" />
48
+ <rect id="canvas1-rectangle25" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(92, 92, 92)" x="110" y="0" width="10" height="45" />
49
+ </g>
50
+ </svg>
@@ -0,0 +1,29 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120" height="78" xml:space="preserve" id="canvas1">
4
+ <!-- Generated by PaintCode - http://www.paintcodeapp.com -->
5
+ <defs>
6
+ <filter id="canvas1-shadow-outer" filterUnits="objectBoundingBox">
7
+ <feGaussianBlur stdDeviation="1" />
8
+ <feOffset dx="0.5" dy="0.5" result="blur" />
9
+ <feFlood flood-color="rgb(0, 0, 0)" flood-opacity="1" />
10
+ <feComposite in2="blur" operator="in" result="colorShadow" />
11
+ <feComposite in="SourceGraphic" in2="colorShadow" operator="over" />
12
+ </filter>
13
+ </defs>
14
+ <g id="canvas1-notes">
15
+ <rect id="canvas1-rectangle" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="0" y="0" width="15" height="75" />
16
+ <rect id="canvas1-rectangle3" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="15" y="0" width="15" height="75" />
17
+ <rect id="canvas1-rectangle4" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="30" y="0" width="15" height="75" />
18
+ <rect id="canvas1-rectangle5" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="45" y="0" width="15" height="75" />
19
+ <rect id="canvas1-rectangle6" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="60" y="0" width="15" height="75" />
20
+ <rect id="canvas1-rectangle7" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="75" y="0" width="15" height="75" />
21
+ <rect id="canvas1-rectangle8" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="90" y="0" width="15" height="75" />
22
+ <rect id="canvas1-rectangle9" stroke="none" fill="rgb(187, 187, 187)" filter="url(#canvas1-shadow-outer)" x="105" y="0" width="15" height="75" />
23
+ <rect id="canvas1-rectangle2" stroke="none" fill="rgb(78, 78, 78)" filter="url(#canvas1-shadow-outer)" x="10" y="0" width="10" height="61" />
24
+ <rect id="canvas1-rectangle10" stroke="none" fill="rgb(78, 78, 78)" filter="url(#canvas1-shadow-outer)" x="30" y="0" width="10" height="61" />
25
+ <rect id="canvas1-rectangle11" stroke="none" fill="rgb(78, 78, 78)" filter="url(#canvas1-shadow-outer)" x="70" y="0" width="10" height="61" />
26
+ <rect id="canvas1-rectangle12" stroke="none" fill="rgb(78, 78, 78)" filter="url(#canvas1-shadow-outer)" x="90" y="0" width="10" height="61" />
27
+ <rect id="canvas1-rectangle13" stroke="none" fill="rgb(78, 78, 78)" filter="url(#canvas1-shadow-outer)" x="110" y="0" width="10" height="61" />
28
+ </g>
29
+ </svg>
@@ -0,0 +1,28 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="120" height="39" xml:space="preserve" id="canvas1">
4
+ <!-- Generated by PaintCode - http://www.paintcodeapp.com -->
5
+ <defs>
6
+ <filter id="canvas1-shadow-outer" filterUnits="objectBoundingBox">
7
+ <feGaussianBlur stdDeviation="1" />
8
+ <feOffset dx="0.5" dy="0.5" result="blur" />
9
+ <feFlood flood-color="rgb(0, 0, 0)" flood-opacity="1" />
10
+ <feComposite in2="blur" operator="in" result="colorShadow" />
11
+ <feComposite in="SourceGraphic" in2="colorShadow" operator="over" />
12
+ </filter>
13
+ </defs>
14
+ <g id="canvas1-guide" filter="url(#canvas1-shadow-outer)">
15
+ <rect id="canvas1-rectangle14" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="0" y="0" width="10" height="45" />
16
+ <rect id="canvas1-rectangle15" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(92, 92, 92)" x="10" y="0" width="10" height="45" />
17
+ <rect id="canvas1-rectangle16" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="20" y="0" width="10" height="45" />
18
+ <rect id="canvas1-rectangle17" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(92, 92, 92)" x="30" y="0" width="10" height="45" />
19
+ <rect id="canvas1-rectangle18" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="40" y="0" width="10" height="45" />
20
+ <rect id="canvas1-rectangle19" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="50" y="0" width="10" height="45" />
21
+ <rect id="canvas1-rectangle20" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="60" y="0" width="10" height="45" />
22
+ <rect id="canvas1-rectangle21" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(92, 92, 92)" x="70" y="0" width="10" height="45" />
23
+ <rect id="canvas1-rectangle22" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="80" y="0" width="10" height="45" />
24
+ <rect id="canvas1-rectangle23" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(92, 92, 92)" x="90" y="0" width="10" height="45" />
25
+ <rect id="canvas1-rectangle24" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(109, 108, 108)" x="100" y="0" width="10" height="45" />
26
+ <rect id="canvas1-rectangle25" stroke="rgb(0, 0, 0)" stroke-width="0.1" stroke-miterlimit="10" fill="rgb(92, 92, 92)" x="110" y="0" width="10" height="45" />
27
+ </g>
28
+ </svg>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atome
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.7.1.2
4
+ version: 0.5.7.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Eric Godard
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-07 00:00:00.000000000 Z
11
+ date: 2024-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: artoo
@@ -541,6 +541,7 @@ files:
541
541
  - vendor/assets/application/examples/atomizer.rb
542
542
  - vendor/assets/application/examples/attach.rb
543
543
  - vendor/assets/application/examples/attached.rb
544
+ - vendor/assets/application/examples/audio.rb
544
545
  - vendor/assets/application/examples/b64_to_image.rb
545
546
  - vendor/assets/application/examples/basic_understanding.rb
546
547
  - vendor/assets/application/examples/behavior.rb
@@ -727,6 +728,7 @@ files:
727
728
  - vendor/assets/src/js/third_parties/w3color.js
728
729
  - vendor/assets/src/js/third_parties/wad.min.js
729
730
  - vendor/assets/src/js/third_parties/wavesurfer.min.js
731
+ - vendor/assets/src/js/third_parties/webaudio-pianoroll.min.js
730
732
  - vendor/assets/src/js/third_parties/zim.min.js
731
733
  - vendor/assets/src/medias/audios/audio_missing.wav
732
734
  - vendor/assets/src/medias/audios/clap.wav
@@ -864,6 +866,9 @@ files:
864
866
  - vendor/assets/src/medias/images/red_planet.png
865
867
  - vendor/assets/src/medias/images/shapes/triangle.svg
866
868
  - vendor/assets/src/medias/images/tile.png
869
+ - vendor/assets/src/medias/images/utils/full_keyboard.svg
870
+ - vendor/assets/src/medias/images/utils/keyboard.svg
871
+ - vendor/assets/src/medias/images/utils/notes.svg
867
872
  - vendor/assets/src/medias/texts/lorem.txt
868
873
  - vendor/assets/src/medias/utils/infos/color.rb
869
874
  - vendor/assets/src/medias/utils/infos/width.rb
@@ -891,7 +896,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
891
896
  - !ruby/object:Gem::Version
892
897
  version: '0'
893
898
  requirements: []
894
- rubygems_version: 3.5.9
899
+ rubygems_version: 3.5.10
895
900
  signing_key:
896
901
  specification_version: 4
897
902
  summary: the creative framework