musa-dsl 0.24.0 → 0.26.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/gem-test-and-push.yml +62 -0
- data/Gemfile +1 -21
- data/lib/musa-dsl/core-ext/dynamic-proxy.rb +12 -6
- data/lib/musa-dsl/core-ext/with.rb +2 -1
- data/lib/musa-dsl/midi/midi-recorder.rb +5 -5
- data/lib/musa-dsl/midi/midi-voices.rb +7 -7
- data/lib/musa-dsl/sequencer/base-sequencer-implementation-every.rb +2 -1
- data/lib/musa-dsl/transport/input-midi-clock.rb +9 -9
- data/lib/musa-dsl.rb +1 -1
- data/musa-dsl.gemspec +10 -5
- metadata +63 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2baccb6e4a0d7c120cd44154229080d001861570f09a6c955acd2b8831d95b65
|
4
|
+
data.tar.gz: a191b5e72d8ee8086224d8e950a731854bd7ba8e01cfacf11e6d9295ad626439
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e11bb0c2cdd2bcb8086cac5c1c67c70a98e70a16ad7af1ee022cd31eff7947c6f7050ac2c4c8786c41624221fe54a7b5642863edc10cf82c4e50f4d4500bf523
|
7
|
+
data.tar.gz: 11824a54cd89809d1879396544a697060a31ec8884c7a70481962a1c341b10065fd9d404ef6d7811987d5a62f7ec082fdb722085c72b4d4f1dd07533a699b42d
|
@@ -0,0 +1,62 @@
|
|
1
|
+
name: Generate gem and push to rubygems repository
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby-version: ['2.7']
|
15
|
+
|
16
|
+
steps:
|
17
|
+
- uses: actions/checkout@v2
|
18
|
+
- name: Set up Ruby
|
19
|
+
uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby-version }}
|
22
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
23
|
+
- name: Run tests
|
24
|
+
run: bundle exec rspec -t \~slow
|
25
|
+
|
26
|
+
build:
|
27
|
+
name: Build + Publish
|
28
|
+
runs-on: ubuntu-latest
|
29
|
+
needs: test
|
30
|
+
permissions:
|
31
|
+
contents: read
|
32
|
+
packages: write
|
33
|
+
|
34
|
+
steps:
|
35
|
+
- uses: actions/checkout@v2
|
36
|
+
- name: Set up Ruby 2.7
|
37
|
+
uses: actions/setup-ruby@v1
|
38
|
+
with:
|
39
|
+
ruby-version: 2.7.x
|
40
|
+
|
41
|
+
# - name: Publish to GPR
|
42
|
+
# run: |
|
43
|
+
# mkdir -p $HOME/.gem
|
44
|
+
# touch $HOME/.gem/credentials
|
45
|
+
# chmod 0600 $HOME/.gem/credentials
|
46
|
+
# printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
47
|
+
# gem build *.gemspec
|
48
|
+
# gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
|
49
|
+
# env:
|
50
|
+
# GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
|
51
|
+
# OWNER: ${{ github.repository_owner }}
|
52
|
+
|
53
|
+
- name: Publish to RubyGems
|
54
|
+
run: |
|
55
|
+
mkdir -p $HOME/.gem
|
56
|
+
touch $HOME/.gem/credentials
|
57
|
+
chmod 0600 $HOME/.gem/credentials
|
58
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
59
|
+
gem build *.gemspec
|
60
|
+
gem push *.gem
|
61
|
+
env:
|
62
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/Gemfile
CHANGED
@@ -1,23 +1,3 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
gem 'logger', '~> 1.4', '>= 1.4.3'
|
6
|
-
|
7
|
-
group :neuma do
|
8
|
-
gem 'citrus', '~> 3.0.0'
|
9
|
-
end
|
10
|
-
|
11
|
-
group :transport do
|
12
|
-
gem 'midi-message', '~> 0.4', '>= 0.4.9'
|
13
|
-
gem 'midi-nibbler', '~> 0.2', '>= 0.2.4'
|
14
|
-
end
|
15
|
-
|
16
|
-
group :test do
|
17
|
-
gem 'descriptive-statistics'
|
18
|
-
gem 'rspec', '~> 3.0'
|
19
|
-
end
|
20
|
-
|
21
|
-
group :documentation do
|
22
|
-
gem 'rdoc'
|
23
|
-
end
|
3
|
+
gemspec
|
@@ -3,6 +3,8 @@ module Musa
|
|
3
3
|
module DynamicProxy
|
4
4
|
module DynamicProxyModule
|
5
5
|
def method_missing(method_name, *args, **key_args, &block)
|
6
|
+
raise NoMethodError, "Method '#{method_name}' is unknown because self is a DynamicProxy with undefined receiver" unless @receiver
|
7
|
+
|
6
8
|
if @receiver.respond_to? method_name
|
7
9
|
@receiver.send method_name, *args, **key_args, &block
|
8
10
|
else
|
@@ -11,37 +13,41 @@ module Musa
|
|
11
13
|
end
|
12
14
|
|
13
15
|
def respond_to_missing?(method_name, include_private)
|
14
|
-
@receiver
|
16
|
+
@receiver&.respond_to?(method_name, include_private) || super
|
17
|
+
end
|
18
|
+
|
19
|
+
def has_receiver?
|
20
|
+
!@receiver.nil?
|
15
21
|
end
|
16
22
|
|
17
23
|
alias _is_a? is_a?
|
18
24
|
|
19
25
|
def is_a?(klass)
|
20
|
-
_is_a?(klass) || @receiver
|
26
|
+
_is_a?(klass) || @receiver&.is_a?(klass)
|
21
27
|
end
|
22
28
|
|
23
29
|
alias _kind_of? kind_of?
|
24
30
|
|
25
31
|
def kind_of?(klass)
|
26
|
-
_kind_of?(klass) || @receiver
|
32
|
+
_kind_of?(klass) || @receiver&.is_a?(klass)
|
27
33
|
end
|
28
34
|
|
29
35
|
alias _instance_of? instance_of?
|
30
36
|
|
31
37
|
def instance_of?(klass)
|
32
|
-
_instance_of?(klass) || @receiver
|
38
|
+
_instance_of?(klass) || @receiver&.instance_of?(klass)
|
33
39
|
end
|
34
40
|
|
35
41
|
alias _equalequal ==
|
36
42
|
|
37
43
|
def ==(object)
|
38
|
-
_equalequal(object) || @receiver
|
44
|
+
_equalequal(object) || @receiver&.==(object)
|
39
45
|
end
|
40
46
|
|
41
47
|
alias _eql? eql?
|
42
48
|
|
43
49
|
def eql?(object)
|
44
|
-
_eql?(object) || @receiver
|
50
|
+
_eql?(object) || @receiver&.eql?(object)
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
@@ -6,8 +6,9 @@ module Musa
|
|
6
6
|
def with(*value_parameters, **key_parameters, &block)
|
7
7
|
binder = Musa::Extension::SmartProcBinder::SmartProcBinder.new(block)
|
8
8
|
|
9
|
-
keep_proc_context = @keep_proc_context_on_with
|
10
9
|
send_self_as_underscore_parameter = binder.parameters[0][1] == :_ unless binder.parameters.empty?
|
10
|
+
|
11
|
+
keep_proc_context = @keep_proc_context_on_with
|
11
12
|
keep_proc_context ||= send_self_as_underscore_parameter
|
12
13
|
keep_proc_context ||= false
|
13
14
|
|
@@ -1,11 +1,11 @@
|
|
1
|
-
require '
|
1
|
+
require 'midi-parser'
|
2
2
|
|
3
3
|
module Musa
|
4
4
|
module MIDIRecorder
|
5
5
|
class MIDIRecorder
|
6
6
|
def initialize(sequencer)
|
7
7
|
@sequencer = sequencer
|
8
|
-
@
|
8
|
+
@midi_parser = MIDIParser.new
|
9
9
|
|
10
10
|
clear
|
11
11
|
end
|
@@ -15,7 +15,7 @@ module Musa
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def record(midi_bytes)
|
18
|
-
m = @
|
18
|
+
m = @midi_parser.parse midi_bytes
|
19
19
|
m = [m] unless m.is_a? Array
|
20
20
|
|
21
21
|
m.each do |mm|
|
@@ -37,7 +37,7 @@ module Musa
|
|
37
37
|
mm = m.message
|
38
38
|
|
39
39
|
case mm
|
40
|
-
when
|
40
|
+
when MIDIEvents::NoteOn
|
41
41
|
if last_note[mm.channel]
|
42
42
|
notes << { position: last_note[mm.channel], channel: mm.channel, pitch: :silence, duration: m.position - last_note[mm.channel] }
|
43
43
|
last_note.delete mm.channel
|
@@ -50,7 +50,7 @@ module Musa
|
|
50
50
|
|
51
51
|
notes << note
|
52
52
|
|
53
|
-
when
|
53
|
+
when MIDIEvents::NoteOff
|
54
54
|
note_on[mm.channel] ||= {}
|
55
55
|
|
56
56
|
note = note_on[mm.channel][mm.note]
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'set'
|
2
|
-
require 'midi-
|
2
|
+
require 'midi-events'
|
3
3
|
|
4
4
|
require_relative '../core-ext/arrayfy'
|
5
5
|
require_relative '../core-ext/array-explode-ranges'
|
@@ -38,7 +38,7 @@ module Musa
|
|
38
38
|
|
39
39
|
@voices.each(&:all_notes_off)
|
40
40
|
|
41
|
-
@output.puts
|
41
|
+
@output.puts MIDIEvents::SystemRealtime.new(0xff) if reset
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -72,7 +72,7 @@ module Musa
|
|
72
72
|
def fast_forward=(enabled)
|
73
73
|
if @fast_forward && !enabled
|
74
74
|
(0..127).each do |pitch|
|
75
|
-
@output.puts
|
75
|
+
@output.puts MIDIEvents::NoteOn.new(@channel, pitch, @active_pitches[pitch][:velocity]) unless @active_pitches[pitch][:note_controls].empty?
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -114,7 +114,7 @@ module Musa
|
|
114
114
|
@active_pitches.clear
|
115
115
|
fill_active_pitches @active_pitches
|
116
116
|
|
117
|
-
@output.puts
|
117
|
+
@output.puts MIDIEvents::ChannelMessage.new(0xb, @channel, 0x7b, 0)
|
118
118
|
end
|
119
119
|
|
120
120
|
def log(msg)
|
@@ -147,7 +147,7 @@ module Musa
|
|
147
147
|
value ||= 0
|
148
148
|
|
149
149
|
@controller[number] = [[0, value].max, 0xff].min
|
150
|
-
@output.puts
|
150
|
+
@output.puts MIDIEvents::ChannelMessage.new(0xb, @channel, number, @controller[number])
|
151
151
|
end
|
152
152
|
|
153
153
|
def [](controller_number_or_symbol)
|
@@ -202,7 +202,7 @@ module Musa
|
|
202
202
|
@voice.active_pitches[pitch][:note_controls] << self
|
203
203
|
@voice.active_pitches[pitch][:velocity] = velocity
|
204
204
|
|
205
|
-
msg =
|
205
|
+
msg = MIDIEvents::NoteOn.new(@voice.channel, pitch, velocity)
|
206
206
|
@voice.log "#{msg.verbose_name} velocity: #{velocity} duration: #{@duration}"
|
207
207
|
@voice.output.puts msg if @voice.output && !@voice.fast_forward?
|
208
208
|
else
|
@@ -235,7 +235,7 @@ module Musa
|
|
235
235
|
|
236
236
|
next unless @voice.active_pitches[pitch][:note_controls].empty?
|
237
237
|
|
238
|
-
msg =
|
238
|
+
msg = MIDIEvents::NoteOff.new(@voice.channel, pitch, velocity_off)
|
239
239
|
@voice.log msg.verbose_name.to_s
|
240
240
|
@voice.output.puts msg if @voice.output && !@voice.fast_forward?
|
241
241
|
end
|
@@ -28,7 +28,8 @@ module Musa::Sequencer
|
|
28
28
|
control.do_on_stop.each(&:call)
|
29
29
|
|
30
30
|
control.do_after.each do |do_after|
|
31
|
-
_numeric_at position + (interval || 0) + do_after[:bars], control, &do_after[:block]
|
31
|
+
# _numeric_at position + (interval || 0) + do_after[:bars], control, &do_after[:block]
|
32
|
+
_numeric_at position + do_after[:bars], control, &do_after[:block]
|
32
33
|
end
|
33
34
|
else
|
34
35
|
_numeric_at control._start_position + control._execution_counter * interval, control do
|
@@ -1,5 +1,6 @@
|
|
1
|
+
require 'midi-parser'
|
2
|
+
|
1
3
|
require_relative 'clock'
|
2
|
-
require 'nibbler'
|
3
4
|
|
4
5
|
module Musa
|
5
6
|
module Clock
|
@@ -20,7 +21,7 @@ module Musa
|
|
20
21
|
@logger.debug! if do_log
|
21
22
|
end
|
22
23
|
|
23
|
-
@
|
24
|
+
@midi_parser = MIDIParser.new
|
24
25
|
end
|
25
26
|
|
26
27
|
attr_reader :input
|
@@ -36,7 +37,6 @@ module Musa
|
|
36
37
|
while @run
|
37
38
|
if @input
|
38
39
|
raw_messages = @input.gets
|
39
|
-
@input.buffer.clear
|
40
40
|
else
|
41
41
|
@logger.warn('InputMidiClock') { 'Waiting for clock input MIDI port' }
|
42
42
|
|
@@ -44,14 +44,18 @@ module Musa
|
|
44
44
|
sleep
|
45
45
|
@waiting_for_input = nil
|
46
46
|
|
47
|
-
|
47
|
+
if @input
|
48
|
+
@logger.info('InputMidiClock') { "Assigned clock input MIDI port '#{@input.name}'" }
|
49
|
+
else
|
50
|
+
@logger.warn('InputMidiClock') { 'Clock input MIDI port not found' }
|
51
|
+
end
|
48
52
|
end
|
49
53
|
|
50
54
|
messages = []
|
51
55
|
stop_index = nil
|
52
56
|
|
53
57
|
raw_messages&.each do |message|
|
54
|
-
mm = @
|
58
|
+
mm = @midi_parser.parse message[:data]
|
55
59
|
|
56
60
|
if mm
|
57
61
|
if mm.is_a? Array
|
@@ -66,10 +70,6 @@ module Musa
|
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
69
|
-
@nibbler.processed.clear
|
70
|
-
@nibbler.rejected.clear
|
71
|
-
@nibbler.messages.clear
|
72
|
-
|
73
73
|
size = messages.size
|
74
74
|
index = 0
|
75
75
|
while index < size
|
data/lib/musa-dsl.rb
CHANGED
data/musa-dsl.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'musa-dsl'
|
3
|
-
s.version = '0.
|
4
|
-
s.date = '2021-11-
|
3
|
+
s.version = '0.26.0'
|
4
|
+
s.date = '2021-11-19'
|
5
5
|
s.summary = 'A simple Ruby DSL for making complex music'
|
6
6
|
s.description = 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical thinking and composition'
|
7
7
|
s.authors = ['Javier Sánchez Yeste']
|
@@ -20,8 +20,13 @@ Gem::Specification.new do |s|
|
|
20
20
|
# "changelog_uri" => ""
|
21
21
|
#}
|
22
22
|
|
23
|
-
s.add_runtime_dependency '
|
23
|
+
s.add_runtime_dependency 'logger', '~> 1.4', '>= 1.4.3'
|
24
24
|
|
25
|
-
s.add_runtime_dependency '
|
26
|
-
|
25
|
+
s.add_runtime_dependency 'citrus', '~> 3.0', '>= 3.0.0'
|
26
|
+
|
27
|
+
s.add_runtime_dependency 'midi-events', '~> 0.5', '>= 0.5.0'
|
28
|
+
s.add_runtime_dependency 'midi-parser', '~> 0.3', '>= 0.3.0'
|
29
|
+
|
30
|
+
s.add_development_dependency 'descriptive-statistics', '~> 2.2'
|
31
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
27
32
|
end
|
metadata
CHANGED
@@ -1,22 +1,42 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: musa-dsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Javier Sánchez Yeste
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-11-
|
11
|
+
date: 2021-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: logger
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.4.3
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.4'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.4.3
|
13
33
|
- !ruby/object:Gem::Dependency
|
14
34
|
name: citrus
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
16
36
|
requirements:
|
17
37
|
- - "~>"
|
18
38
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.0
|
39
|
+
version: '3.0'
|
20
40
|
- - ">="
|
21
41
|
- !ruby/object:Gem::Version
|
22
42
|
version: 3.0.0
|
@@ -26,50 +46,78 @@ dependencies:
|
|
26
46
|
requirements:
|
27
47
|
- - "~>"
|
28
48
|
- !ruby/object:Gem::Version
|
29
|
-
version: 3.0
|
49
|
+
version: '3.0'
|
30
50
|
- - ">="
|
31
51
|
- !ruby/object:Gem::Version
|
32
52
|
version: 3.0.0
|
33
53
|
- !ruby/object:Gem::Dependency
|
34
|
-
name: midi-
|
54
|
+
name: midi-events
|
35
55
|
requirement: !ruby/object:Gem::Requirement
|
36
56
|
requirements:
|
37
57
|
- - "~>"
|
38
58
|
- !ruby/object:Gem::Version
|
39
|
-
version: '0.
|
59
|
+
version: '0.5'
|
40
60
|
- - ">="
|
41
61
|
- !ruby/object:Gem::Version
|
42
|
-
version: 0.
|
62
|
+
version: 0.5.0
|
43
63
|
type: :runtime
|
44
64
|
prerelease: false
|
45
65
|
version_requirements: !ruby/object:Gem::Requirement
|
46
66
|
requirements:
|
47
67
|
- - "~>"
|
48
68
|
- !ruby/object:Gem::Version
|
49
|
-
version: '0.
|
69
|
+
version: '0.5'
|
50
70
|
- - ">="
|
51
71
|
- !ruby/object:Gem::Version
|
52
|
-
version: 0.
|
72
|
+
version: 0.5.0
|
53
73
|
- !ruby/object:Gem::Dependency
|
54
|
-
name: midi-
|
74
|
+
name: midi-parser
|
55
75
|
requirement: !ruby/object:Gem::Requirement
|
56
76
|
requirements:
|
57
77
|
- - "~>"
|
58
78
|
- !ruby/object:Gem::Version
|
59
|
-
version: '0.
|
79
|
+
version: '0.3'
|
60
80
|
- - ">="
|
61
81
|
- !ruby/object:Gem::Version
|
62
|
-
version: 0.
|
82
|
+
version: 0.3.0
|
63
83
|
type: :runtime
|
64
84
|
prerelease: false
|
65
85
|
version_requirements: !ruby/object:Gem::Requirement
|
66
86
|
requirements:
|
67
87
|
- - "~>"
|
68
88
|
- !ruby/object:Gem::Version
|
69
|
-
version: '0.
|
89
|
+
version: '0.3'
|
70
90
|
- - ">="
|
71
91
|
- !ruby/object:Gem::Version
|
72
|
-
version: 0.
|
92
|
+
version: 0.3.0
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: descriptive-statistics
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '2.2'
|
100
|
+
type: :development
|
101
|
+
prerelease: false
|
102
|
+
version_requirements: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - "~>"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '2.2'
|
107
|
+
- !ruby/object:Gem::Dependency
|
108
|
+
name: rspec
|
109
|
+
requirement: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '3.0'
|
114
|
+
type: :development
|
115
|
+
prerelease: false
|
116
|
+
version_requirements: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - "~>"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '3.0'
|
73
121
|
description: 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical
|
74
122
|
thinking and composition'
|
75
123
|
email: javier.sy@gmail.com
|
@@ -77,6 +125,7 @@ executables: []
|
|
77
125
|
extensions: []
|
78
126
|
extra_rdoc_files: []
|
79
127
|
files:
|
128
|
+
- ".github/workflows/gem-test-and-push.yml"
|
80
129
|
- ".gitignore"
|
81
130
|
- Gemfile
|
82
131
|
- LICENSE.md
|