pennyworth 10.0.1 → 11.0.0
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.adoc +209 -30
- data/bin/pennyworth +1 -3
- data/lib/pennyworth.rb +11 -2
- data/lib/pennyworth/cli/actions/config.rb +35 -0
- data/lib/pennyworth/cli/actions/encodings.rb +23 -0
- data/lib/pennyworth/cli/actions/git_hub.rb +27 -0
- data/lib/pennyworth/cli/actions/http_statuses.rb +23 -0
- data/lib/pennyworth/cli/actions/ruby_gems.rb +27 -0
- data/lib/pennyworth/cli/actions/system/errors.rb +25 -0
- data/lib/pennyworth/cli/actions/system/signals.rb +25 -0
- data/lib/pennyworth/cli/actions/text.rb +23 -0
- data/lib/pennyworth/cli/configuration/content.rb +28 -0
- data/lib/pennyworth/cli/configuration/defaults.yml +25 -0
- data/lib/pennyworth/cli/configuration/loader.rb +37 -0
- data/lib/pennyworth/cli/parsers.rb +11 -0
- data/lib/pennyworth/cli/parsers/assembler.rb +32 -0
- data/lib/pennyworth/cli/parsers/core.rb +100 -0
- data/lib/pennyworth/cli/parsers/git_hub.rb +51 -0
- data/lib/pennyworth/cli/parsers/ruby_gems.rb +35 -0
- data/lib/pennyworth/cli/shell.rb +82 -0
- data/lib/pennyworth/container.rb +40 -0
- data/lib/pennyworth/identity.rb +2 -1
- data/lib/pennyworth/inflector.rb +18 -0
- data/lib/pennyworth/integrations/git_hub/client.rb +59 -0
- data/lib/pennyworth/integrations/git_hub/response.rb +33 -0
- data/lib/pennyworth/integrations/ruby_gems/client.rb +29 -0
- data/lib/pennyworth/loaders/encodings.rb +31 -0
- data/lib/pennyworth/loaders/http_statuses.rb +28 -0
- data/lib/pennyworth/loaders/projects.rb +22 -0
- data/lib/pennyworth/loaders/system/errors.rb +33 -0
- data/lib/pennyworth/loaders/system/signals.rb +21 -0
- data/lib/pennyworth/loaders/text.rb +27 -0
- data/lib/pennyworth/models/encoding.rb +8 -0
- data/lib/pennyworth/models/http_status.rb +8 -0
- data/lib/pennyworth/models/system/error.rb +10 -0
- data/lib/pennyworth/models/system/signal.rb +10 -0
- data/lib/pennyworth/models/text.rb +8 -0
- data/lib/pennyworth/presenters/encoding.rb +22 -0
- data/lib/pennyworth/presenters/gem.rb +48 -0
- data/lib/pennyworth/presenters/http_status.rb +41 -0
- data/lib/pennyworth/presenters/repository.rb +35 -0
- data/lib/pennyworth/presenters/system/error.rb +28 -0
- data/lib/pennyworth/presenters/system/signal.rb +22 -0
- data/lib/pennyworth/presenters/text.rb +25 -0
- data/lib/pennyworth/processor.rb +68 -0
- data/lib/pennyworth/serializers/encoding.rb +33 -0
- data/lib/pennyworth/serializers/http_status.rb +41 -0
- data/lib/pennyworth/serializers/project.rb +52 -0
- data/lib/pennyworth/serializers/system/error.rb +46 -0
- data/lib/pennyworth/serializers/system/signal.rb +40 -0
- data/lib/pennyworth/serializers/text.rb +31 -0
- metadata +110 -19
- metadata.gz.sig +2 -2
- data/lib/pennyworth/cli.rb +0 -140
- data/lib/pennyworth/templates/workflows/user.workflow.B59B22A2-1880-4765-9358-412791BE9202/icon.png +0 -0
- data/lib/pennyworth/templates/workflows/user.workflow.B59B22A2-1880-4765-9358-412791BE9202/info.plist +0 -159
- data/lib/pennyworth/templates/workflows/user.workflow.C431E56A-0EC2-47EE-94D5-D67D9FE323BE/icon.png +0 -0
- data/lib/pennyworth/templates/workflows/user.workflow.C431E56A-0EC2-47EE-94D5-D67D9FE323BE/info.plist +0 -272
- data/lib/pennyworth/templates/workflows/user.workflow.C431E56A-0EC2-47EE-94D5-D67D9FE323BE/string-camelcase.png +0 -0
- data/lib/pennyworth/templates/workflows/user.workflow.C431E56A-0EC2-47EE-94D5-D67D9FE323BE/string-capitalize.png +0 -0
- data/lib/pennyworth/templates/workflows/user.workflow.C431E56A-0EC2-47EE-94D5-D67D9FE323BE/string-lowercase.png +0 -0
- data/lib/pennyworth/templates/workflows/user.workflow.C431E56A-0EC2-47EE-94D5-D67D9FE323BE/string-size.png +0 -0
- data/lib/pennyworth/templates/workflows/user.workflow.C431E56A-0EC2-47EE-94D5-D67D9FE323BE/string-snakecase.png +0 -0
- data/lib/pennyworth/templates/workflows/user.workflow.C431E56A-0EC2-47EE-94D5-D67D9FE323BE/string-titleize.png +0 -0
- data/lib/pennyworth/templates/workflows/user.workflow.C431E56A-0EC2-47EE-94D5-D67D9FE323BE/string-uppercase.png +0 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pennyworth
|
4
|
+
module CLI
|
5
|
+
module Actions
|
6
|
+
module System
|
7
|
+
# Handles the system errors action.
|
8
|
+
class Errors
|
9
|
+
def initialize processor: Processor.for_system_errors, container: Container
|
10
|
+
@processor = processor
|
11
|
+
@container = container
|
12
|
+
end
|
13
|
+
|
14
|
+
def call = processor.call.to_json.then { |json| logger.info json }
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :processor, :container
|
19
|
+
|
20
|
+
def logger = container[__method__]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pennyworth
|
4
|
+
module CLI
|
5
|
+
module Actions
|
6
|
+
module System
|
7
|
+
# Handles the signal action.
|
8
|
+
class Signals
|
9
|
+
def initialize processor: Processor.for_system_signals, container: Container
|
10
|
+
@processor = processor
|
11
|
+
@container = container
|
12
|
+
end
|
13
|
+
|
14
|
+
def call = processor.call.to_json.then { |json| logger.info json }
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :processor, :container
|
19
|
+
|
20
|
+
def logger = container[__method__]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pennyworth
|
4
|
+
module CLI
|
5
|
+
module Actions
|
6
|
+
# Handles the text action.
|
7
|
+
class Text
|
8
|
+
def initialize processor: Processor.for_text, container: Container
|
9
|
+
@processor = processor
|
10
|
+
@container = container
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(content) = processor.call(content).to_json.then { |json| logger.info json }
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
attr_reader :processor, :container
|
18
|
+
|
19
|
+
def logger = container[__method__]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pennyworth
|
4
|
+
module CLI
|
5
|
+
module Configuration
|
6
|
+
# Defines configuration content as the primary source of truth for use throughout the gem.
|
7
|
+
Content = Struct.new :action_encodings,
|
8
|
+
:action_git_hub,
|
9
|
+
:action_http_statuses,
|
10
|
+
:action_ruby_gems,
|
11
|
+
:action_system_errors,
|
12
|
+
:action_system_signals,
|
13
|
+
:action_text,
|
14
|
+
:action_config,
|
15
|
+
:action_version,
|
16
|
+
:action_help,
|
17
|
+
:alfred_preferences,
|
18
|
+
:inflections,
|
19
|
+
:git_hub_api_url,
|
20
|
+
:git_hub_organization,
|
21
|
+
:git_hub_user,
|
22
|
+
:http_statuses_url,
|
23
|
+
:ruby_gems_api_url,
|
24
|
+
:ruby_gems_owner,
|
25
|
+
keyword_init: true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
:alfred:
|
2
|
+
:preferences:
|
3
|
+
:inflections:
|
4
|
+
- "Bkuhlmann": "bkuhlmann"
|
5
|
+
- "Dry Auto Inject": "Dry AutoInject"
|
6
|
+
- "Dry Cli": "Dry CLI"
|
7
|
+
- "Flacsmith": "FLACsmith"
|
8
|
+
- "Git Plus": "Git+"
|
9
|
+
- "Mac Os Config": "macOS Configuration"
|
10
|
+
- "Mac Os": "MacOS"
|
11
|
+
- "Prawn Plus": "Prawn+"
|
12
|
+
- "Rubocop Ast": "Rubocop AST"
|
13
|
+
- "Rubocop Md": "Rubocop Markdown"
|
14
|
+
- "Rubocop Rspec": "Rubocop RSpec"
|
15
|
+
- "Xdg": "XDG"
|
16
|
+
:git_hub:
|
17
|
+
:api_url: "https://api.github.com"
|
18
|
+
:organization:
|
19
|
+
:user:
|
20
|
+
:http:
|
21
|
+
:statuses:
|
22
|
+
:url: "https://httpstatuses.com"
|
23
|
+
:ruby_gems:
|
24
|
+
:api_url: "https://rubygems.org/api/v1"
|
25
|
+
:owner:
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "refinements/hashes"
|
5
|
+
require "refinements/structs"
|
6
|
+
require "runcom"
|
7
|
+
require "yaml"
|
8
|
+
|
9
|
+
module Pennyworth
|
10
|
+
module CLI
|
11
|
+
module Configuration
|
12
|
+
# Represents the fully assembled Command Line Interface (CLI) configuration.
|
13
|
+
class Loader
|
14
|
+
using Refinements::Hashes
|
15
|
+
using Refinements::Structs
|
16
|
+
|
17
|
+
DEFAULTS = YAML.load_file(Pathname(__dir__).join("defaults.yml")).freeze
|
18
|
+
HANDLER = Runcom::Config.new "#{Identity::NAME}/configuration.yml", defaults: DEFAULTS
|
19
|
+
|
20
|
+
def self.call = new.call
|
21
|
+
|
22
|
+
def self.with_defaults = new(handler: DEFAULTS)
|
23
|
+
|
24
|
+
def initialize content: Content.new, handler: HANDLER
|
25
|
+
@content = content
|
26
|
+
@handler = handler
|
27
|
+
end
|
28
|
+
|
29
|
+
def call = content.merge(**handler.to_h.flatten_keys)
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :content, :handler
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pennyworth
|
4
|
+
module CLI
|
5
|
+
module Parsers
|
6
|
+
SECTIONS = [Core, GitHub, RubyGems].freeze # Order is important.
|
7
|
+
|
8
|
+
# Assembles and parses all Command Line Interface (CLI) options.
|
9
|
+
class Assembler
|
10
|
+
def initialize configuration = CLI::Configuration::Loader.call,
|
11
|
+
sections: SECTIONS,
|
12
|
+
client: CLIENT
|
13
|
+
@configuration = configuration
|
14
|
+
@sections = sections
|
15
|
+
@client = client
|
16
|
+
end
|
17
|
+
|
18
|
+
def call arguments = []
|
19
|
+
sections.each { |parser| parser.call configuration, client: client }
|
20
|
+
client.parse! arguments
|
21
|
+
configuration
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s = client.to_s
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :configuration, :client, :sections
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "refinements/structs"
|
4
|
+
|
5
|
+
module Pennyworth
|
6
|
+
module CLI
|
7
|
+
# Handles parsing of Command Line Interface (CLI) primary options.
|
8
|
+
module Parsers
|
9
|
+
using Refinements::Structs
|
10
|
+
|
11
|
+
# Handles parsing of Command Line Interface (CLI) core options.
|
12
|
+
class Core
|
13
|
+
def self.call(...) = new(...).call
|
14
|
+
|
15
|
+
def initialize configuration = Configuration::Loader.call, client: CLIENT
|
16
|
+
@configuration = configuration
|
17
|
+
@client = client
|
18
|
+
end
|
19
|
+
|
20
|
+
def call arguments = []
|
21
|
+
client.banner = "#{Identity::LABEL} - #{Identity::SUMMARY}"
|
22
|
+
client.separator "\nUSAGE:\n"
|
23
|
+
collate
|
24
|
+
arguments.empty? ? arguments : client.parse!(arguments)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :configuration, :client
|
30
|
+
|
31
|
+
def collate = private_methods.sort.grep(/add_/).each { |method| __send__ method }
|
32
|
+
|
33
|
+
def add_config
|
34
|
+
client.on(
|
35
|
+
"-c",
|
36
|
+
"--config ACTION",
|
37
|
+
%i[edit view],
|
38
|
+
"Manage gem configuration. Actions: edit || view."
|
39
|
+
) do |action|
|
40
|
+
configuration.action_config = action
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_encodings
|
45
|
+
client.on "--encodings", "Render Alfred encodings script filter." do
|
46
|
+
configuration.action_encodings = true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_git_hub
|
51
|
+
client.on "--git_hub", "Render Alfred GitHub repositories script filter." do
|
52
|
+
configuration.action_git_hub = true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def add_http_statuses
|
57
|
+
client.on "--http_statuses", "Render Alfred HTTP statuses script filter." do
|
58
|
+
configuration.action_http_statuses = true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_ruby_gems
|
63
|
+
client.on "--ruby_gems", "Render Alfred RubyGems script filter." do
|
64
|
+
configuration.action_ruby_gems = true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_system_errors
|
69
|
+
client.on "--system_errors", "Render Alfred system errors script filter." do
|
70
|
+
configuration.action_system_errors = true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_system_signals
|
75
|
+
client.on "--system_signals", "Render Alfred system signals script filter." do
|
76
|
+
configuration.action_system_signals = true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def add_text
|
81
|
+
client.on "--text CONTENT", "Render Alfred text script filter." do |content|
|
82
|
+
configuration.action_text = content
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def add_version
|
87
|
+
client.on "-v", "--version", "Show gem version." do
|
88
|
+
configuration.action_version = Identity::VERSION_LABEL
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def add_help
|
93
|
+
client.on "-h", "--help", "Show this message." do
|
94
|
+
configuration.action_help = true
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "refinements/structs"
|
4
|
+
|
5
|
+
module Pennyworth
|
6
|
+
module CLI
|
7
|
+
module Parsers
|
8
|
+
# Handles parsing of Command Line Interface (CLI) GitHub options.
|
9
|
+
class GitHub
|
10
|
+
using Refinements::Structs
|
11
|
+
|
12
|
+
def self.call(...) = new(...).call
|
13
|
+
|
14
|
+
def initialize configuration = Configuration::Loader.call, client: CLIENT
|
15
|
+
@configuration = configuration
|
16
|
+
@client = client
|
17
|
+
end
|
18
|
+
|
19
|
+
def call arguments = []
|
20
|
+
client.separator "\nGITHUB OPTIONS:\n"
|
21
|
+
private_methods.sort.grep(/add_/).each { |method| __send__ method }
|
22
|
+
arguments.empty? ? arguments : client.parse!(arguments)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :configuration, :client
|
28
|
+
|
29
|
+
def add_organization
|
30
|
+
client.on(
|
31
|
+
"--organization [HANDLE]",
|
32
|
+
%(Set organization. Default: "#{organization}".)
|
33
|
+
) do |handle|
|
34
|
+
configuration.merge! action_git_hub: :organization,
|
35
|
+
git_hub_organization: handle || organization
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_user
|
40
|
+
client.on "--user [HANDLE]", %(Set user. Default: "#{user}".) do |handle|
|
41
|
+
configuration.merge! action_git_hub: :user, git_hub_user: handle || user
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def organization = configuration.git_hub_organization
|
46
|
+
|
47
|
+
def user = configuration.git_hub_user
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pennyworth
|
4
|
+
module CLI
|
5
|
+
module Parsers
|
6
|
+
# Handles parsing of Command Line Interface (CLI) RubyGems options.
|
7
|
+
class RubyGems
|
8
|
+
def self.call(...) = new(...).call
|
9
|
+
|
10
|
+
def initialize configuration = Configuration::Loader.call, client: CLIENT
|
11
|
+
@configuration = configuration
|
12
|
+
@client = client
|
13
|
+
end
|
14
|
+
|
15
|
+
def call arguments = []
|
16
|
+
client.separator "\nRUBYGEMS OPTIONS:\n"
|
17
|
+
add_owner
|
18
|
+
arguments.empty? ? arguments : client.parse!(arguments)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :configuration, :client
|
24
|
+
|
25
|
+
def add_owner
|
26
|
+
client.on "--owner [HANDLE]", %(Set owner. Default: "#{owner}".) do |handle|
|
27
|
+
configuration.ruby_gems_owner = handle || owner
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def owner = configuration.ruby_gems_owner
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pennyworth
|
4
|
+
module CLI
|
5
|
+
# The main Command Line Interface (CLI) object.
|
6
|
+
class Shell
|
7
|
+
ACTIONS = {
|
8
|
+
config: Actions::Config.new,
|
9
|
+
encodings: Actions::Encodings.new,
|
10
|
+
git_hub: Actions::GitHub.new,
|
11
|
+
http_statuses: Actions::HTTPStatuses.new,
|
12
|
+
ruby_gems: Actions::RubyGems.new,
|
13
|
+
system_errors: Actions::System::Errors.new,
|
14
|
+
system_signals: Actions::System::Signals.new,
|
15
|
+
text: Actions::Text.new
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
def initialize parser: Parsers::Assembler.new, actions: ACTIONS, container: Container
|
19
|
+
@parser = parser
|
20
|
+
@actions = actions
|
21
|
+
@container = container
|
22
|
+
end
|
23
|
+
|
24
|
+
def call arguments = []
|
25
|
+
perform parser.call(arguments)
|
26
|
+
rescue OptionParser::ParseError, KeyError => error
|
27
|
+
logger.error error.message
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :parser, :actions, :container
|
33
|
+
|
34
|
+
# rubocop:disable Metrics/MethodLength
|
35
|
+
def perform configuration
|
36
|
+
case configuration
|
37
|
+
in action_config: Symbol => action then config action
|
38
|
+
in action_encodings: true then encodings
|
39
|
+
in action_git_hub: :organization then git_hub_organization configuration
|
40
|
+
in action_git_hub: :user then git_hub_user configuration
|
41
|
+
in action_http_statuses: true then http_statuses
|
42
|
+
in action_ruby_gems: true then ruby_gems configuration
|
43
|
+
in action_system_signals: true then system_signals
|
44
|
+
in action_system_errors: true then system_errors
|
45
|
+
in action_text: String => content then text content
|
46
|
+
in action_version: String => version then logger.info version
|
47
|
+
in action_help: then usage
|
48
|
+
else usage
|
49
|
+
end
|
50
|
+
end
|
51
|
+
# rubocop:enable Metrics/MethodLength
|
52
|
+
|
53
|
+
def config(action) = actions.fetch(__method__).call(action)
|
54
|
+
|
55
|
+
def encodings = actions.fetch(__method__).call
|
56
|
+
|
57
|
+
def git_hub_organization configuration
|
58
|
+
actions.fetch(:git_hub).call("orgs/#{configuration.git_hub_organization}/repos")
|
59
|
+
end
|
60
|
+
|
61
|
+
def git_hub_user configuration
|
62
|
+
actions.fetch(:git_hub).call("users/#{configuration.git_hub_user}/repos")
|
63
|
+
end
|
64
|
+
|
65
|
+
def http_statuses = actions.fetch(__method__).call
|
66
|
+
|
67
|
+
def ruby_gems configuration
|
68
|
+
actions.fetch(__method__).call("owners/#{configuration.ruby_gems_owner}/gems.json")
|
69
|
+
end
|
70
|
+
|
71
|
+
def system_errors = actions.fetch(__method__).call
|
72
|
+
|
73
|
+
def system_signals = actions.fetch(__method__).call
|
74
|
+
|
75
|
+
def text(content) = actions.fetch(__method__).call(content)
|
76
|
+
|
77
|
+
def usage = logger.unknown { parser.to_s }
|
78
|
+
|
79
|
+
def logger = container[__method__]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|