jruby_art 0.2.0.pre
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 +7 -0
- data/LICENSE.md +39 -0
- data/README.md +88 -0
- data/Rakefile +93 -0
- data/bin/k9 +10 -0
- data/lib/core.jar +0 -0
- data/lib/export.txt +10 -0
- data/lib/gluegen-rt-natives-linux-amd64.jar +0 -0
- data/lib/gluegen-rt-natives-linux-armv6hf.jar +0 -0
- data/lib/gluegen-rt-natives-linux-i586.jar +0 -0
- data/lib/gluegen-rt-natives-macosx-universal.jar +0 -0
- data/lib/gluegen-rt-natives-windows-amd64.jar +0 -0
- data/lib/gluegen-rt-natives-windows-i586.jar +0 -0
- data/lib/gluegen-rt.jar +0 -0
- data/lib/jogl-all-natives-linux-amd64.jar +0 -0
- data/lib/jogl-all-natives-linux-armv6hf.jar +0 -0
- data/lib/jogl-all-natives-linux-i586.jar +0 -0
- data/lib/jogl-all-natives-macosx-universal.jar +0 -0
- data/lib/jogl-all-natives-windows-amd64.jar +0 -0
- data/lib/jogl-all-natives-windows-i586.jar +0 -0
- data/lib/jogl-all.jar +0 -0
- data/lib/jruby_art.rb +27 -0
- data/lib/jruby_art/app.rb +153 -0
- data/lib/jruby_art/config.rb +18 -0
- data/lib/jruby_art/creator.rb +100 -0
- data/lib/jruby_art/helper_methods.rb +220 -0
- data/lib/jruby_art/helpers/camel_string.rb +18 -0
- data/lib/jruby_art/helpers/numeric.rb +9 -0
- data/lib/jruby_art/helpers/range.rb +11 -0
- data/lib/jruby_art/helpers/string_extra.rb +33 -0
- data/lib/jruby_art/parse.rb +60 -0
- data/lib/jruby_art/runner.rb +142 -0
- data/lib/jruby_art/version.rb +3 -0
- data/lib/jruby_art/writer.rb +40 -0
- data/lib/rpextras.jar +0 -0
- data/spec/app_spec.rb +208 -0
- data/spec/deglut_spec.rb +25 -0
- data/spec/spec_helper.rb +96 -0
- data/spec/vecmath_spec.rb +277 -0
- data/vendors/Rakefile +95 -0
- metadata +116 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a3828fdddac86cd22f16778671b86ca7177b73aa
|
4
|
+
data.tar.gz: 0cc177cf9d0e4d9027694777439ffd4330ed4ad2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9493554519ee7744117ebfb307c0f9c48e78f0e447f3bc0dd98bd5ad1921605bd43debd6173d0ed46582bfae4c39670d1fd2e3674c9d5306c6857cc457ab7dc1
|
7
|
+
data.tar.gz: 2813e9daadee89de3bd19ca20f6a8d4252bb7a9f2e1c3171efde53ca5cfb0df720100c5ef65ca7cc0e55a5e1ba4cd2648e81ba4132e11b61f0122fa44fd4154e
|
data/LICENSE.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
JRubyArt is released under the MIT License.
|
2
|
+
You can do pretty much whatever you'd like with it.
|
3
|
+
|
4
|
+
___
|
5
|
+
|
6
|
+
Copyright (c) 2013 Martin Prout
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge,
|
9
|
+
to any person obtaining a copy of this software
|
10
|
+
and associated documentation files (the "Software"),
|
11
|
+
to deal in the Software without restriction,
|
12
|
+
including without limitation the rights to use,
|
13
|
+
copy, modify, merge, publish, distribute, sublicense,
|
14
|
+
and/or sell copies of the Software, and to permit
|
15
|
+
persons to whom the Software is furnished to do so,
|
16
|
+
subject to the following conditions:
|
17
|
+
|
18
|
+
The above copyright notice and this permission
|
19
|
+
notice shall be included in all copies or substantial
|
20
|
+
portions of the Software.
|
21
|
+
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY
|
23
|
+
OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24
|
+
LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
26
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
27
|
+
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
28
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
29
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
30
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
31
|
+
|
32
|
+
___
|
33
|
+
|
34
|
+
JRubyArt depends on core components
|
35
|
+
of both [JRuby][] and [Processing][] both of which are
|
36
|
+
licensed under the GNU lesser public license
|
37
|
+
|
38
|
+
[jruby]: http://www.jruby.org/
|
39
|
+
[processing]: http://www.processing.org/
|
data/README.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
## JRubyArt
|
2
|
+
|
3
|
+
|
4
|
+
Is a development fork of [ruby-processing][] that may soon have a somewhat independent existence, see [processing-core][] at least in the short term. Plan was that JRubyArt releases (pre-releases) would use jruby-9.0.0.0 from the start, but now I think it might be more sane to start with jruby-1.7.19. However until that time:-
|
5
|
+
|
6
|
+
|
7
|
+
You should (like ruby-processing) install [processing-2.2.1][]
|
8
|
+
|
9
|
+
Then create a `~/.jruby_art/config.yml` config file, here is
|
10
|
+
what mine looks like on arch-linux
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
---
|
14
|
+
PROCESSING_ROOT: /usr/share/processing
|
15
|
+
|
16
|
+
```
|
17
|
+
However unlike ruby-processing, the core jars become part of the gem and PROCESSING_ROOT is not used at runtime.
|
18
|
+
|
19
|
+
The following config should work on macosx
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
---
|
23
|
+
PROCESSING_ROOT: /Applications/Processing.app/Contents/Java
|
24
|
+
```
|
25
|
+
|
26
|
+
To copy processing jars `rake processing_jars`
|
27
|
+
|
28
|
+
To compile extensions `jruby -S rake compile` _requires rake-compiler gem_
|
29
|
+
|
30
|
+
To build gem `jruby -S rake package`
|
31
|
+
|
32
|
+
To install `gem install pkg/jruby_art-0.2.pre.gem`
|
33
|
+
|
34
|
+
To create a new blank sketch
|
35
|
+
|
36
|
+
```bash
|
37
|
+
k9 create my_app 200 200
|
38
|
+
```
|
39
|
+
|
40
|
+
or for 3D opengl sketch
|
41
|
+
|
42
|
+
```bash
|
43
|
+
k9 create my_app 200 200 p3d
|
44
|
+
```
|
45
|
+
|
46
|
+
To run most sketches, all you need is an installed jruby:-
|
47
|
+
|
48
|
+
```bash
|
49
|
+
jruby my_app.rb
|
50
|
+
```
|
51
|
+
|
52
|
+
To run certain sketches, eg those with load_image (or shaders), either use [netbeans][] as your development ide or use the vendored jruby-complete (beyond our control something to do with jruby permissions?). To install jruby-complete:-
|
53
|
+
|
54
|
+
```bash
|
55
|
+
k9 setup install # requires wget (Now also downloads examples to users home)
|
56
|
+
```
|
57
|
+
To run sketches with jruby-complete (rather than installed jruby)
|
58
|
+
|
59
|
+
```bash
|
60
|
+
k9 run my_app.rb # NB: k9 setup install, is a one-time install to gem procedure
|
61
|
+
```
|
62
|
+
|
63
|
+
[Contributing][]
|
64
|
+
|
65
|
+
[License][]
|
66
|
+
|
67
|
+
[Acknowledgements][]
|
68
|
+
|
69
|
+
[Examples][]
|
70
|
+
|
71
|
+
[CHANGELOG][]
|
72
|
+
|
73
|
+
###Ruby Versions
|
74
|
+
|
75
|
+
jruby-9.0.0.0.pre1+ (when sketches run with jruby command)
|
76
|
+
|
77
|
+
ruby-2.1.2+ (when sketches are run using k9 command, ie using jruby-complete)
|
78
|
+
|
79
|
+
[Acknowledgements]:ACKNOWLEDGEMENTS.md
|
80
|
+
[CHANGELOG]:CHANGELOG.md
|
81
|
+
[Contributing]:CONTRIBUTING.md
|
82
|
+
[Examples]:https://github.com/ruby-processing/JRubyArt-examples
|
83
|
+
[License]:LICENSE.md
|
84
|
+
[processing]:https://github.com/processing/processing
|
85
|
+
[ruby-processing]:https://github.com/jashkenas/ruby-processing
|
86
|
+
[netbeans]:http://learning-ruby-processing.blogspot.co.uk/2014/10/alternative-ruby-processing-implentation.html
|
87
|
+
[processing-2.2.1]:https://processing.org/download/
|
88
|
+
[processing-core]:https://github.com/ruby-processing/processing-core/blob/master/README.md
|
data/Rakefile
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rubygems/package_task'
|
5
|
+
require 'rdoc/task'
|
6
|
+
require 'rake/testtask'
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
require_relative 'lib/jruby_art/version'
|
9
|
+
|
10
|
+
spec = Gem::Specification.new do |s|
|
11
|
+
s.name = 'jruby_art'
|
12
|
+
s.version = JRubyArt::VERSION
|
13
|
+
s.has_rdoc = true
|
14
|
+
s.extra_rdoc_files = ['README.md', 'LICENSE.md']
|
15
|
+
s.summary = 'Ruby processing development branch'
|
16
|
+
s.description = 'A jruby wrapper for processing'
|
17
|
+
s.license = 'MIT'
|
18
|
+
s.author = 'Martin Prout'
|
19
|
+
s.email = 'martin_p@lineone.net'
|
20
|
+
s.homepage = 'https://github.com/ruby-processing/JRubyArt'
|
21
|
+
s.executables << 'k9'
|
22
|
+
s.files = %w(LICENSE.md README.md Rakefile) + Dir.glob("{bin,lib,spec,vendors}/**/*")
|
23
|
+
s.require_path = 'lib'
|
24
|
+
s.add_development_dependency "rake", "~> 10.3"
|
25
|
+
s.add_development_dependency "rake-compiler", "~> 0.9"
|
26
|
+
s.requirements << 'A decent graphics card'
|
27
|
+
s.requirements << 'java runtime >= 1.7+'
|
28
|
+
s.requirements << 'processing = 2.2.1+'
|
29
|
+
end
|
30
|
+
|
31
|
+
# -*- ruby -*-
|
32
|
+
|
33
|
+
require 'java'
|
34
|
+
require 'rake/javaextensiontask'
|
35
|
+
|
36
|
+
# -*- encoding: utf-8 -*-
|
37
|
+
require 'psych'
|
38
|
+
|
39
|
+
def copy_jars(name, dest)
|
40
|
+
conf = '~/.jruby_art/config.yml'
|
41
|
+
begin
|
42
|
+
path = File.expand_path(conf)
|
43
|
+
rp_config = (Psych.load_file(path))
|
44
|
+
source= "#{rp_config["PROCESSING_ROOT"]}/core/library/"
|
45
|
+
rescue
|
46
|
+
raise "WARNING: you must set PROCESSING_ROOT in #{conf} compile"
|
47
|
+
end
|
48
|
+
body = proc {
|
49
|
+
Dir["#{source}/*.jar"].each do |f|
|
50
|
+
puts "Copying #{f} To #{dest}"
|
51
|
+
FileUtils.cp f, dest
|
52
|
+
end
|
53
|
+
}
|
54
|
+
Rake::Task.define_task(name, &body)
|
55
|
+
end
|
56
|
+
|
57
|
+
copy_jars(:processing_jars, 'lib')
|
58
|
+
|
59
|
+
Rake::JavaExtensionTask.new('processing') do |ext|
|
60
|
+
jars = FileList['lib/*.jar']
|
61
|
+
ext.classpath = jars.map { |x| File.expand_path x}.join ':'
|
62
|
+
ext.name = 'rpextras'
|
63
|
+
ext.debug = true
|
64
|
+
ext.lib_dir = 'lib'
|
65
|
+
ext.source_version='1.7'
|
66
|
+
ext.target_version='1.7'
|
67
|
+
end
|
68
|
+
|
69
|
+
Gem::PackageTask.new(spec) do |p|
|
70
|
+
p.gem_spec = spec
|
71
|
+
p.need_tar = true
|
72
|
+
p.need_zip = true
|
73
|
+
end
|
74
|
+
|
75
|
+
Rake::RDocTask.new do |rdoc|
|
76
|
+
files =['README.md', 'LICENSE.md', 'lib/**/*.rb']
|
77
|
+
rdoc.rdoc_files.add(files)
|
78
|
+
rdoc.main = "README.md" # page to start on
|
79
|
+
rdoc.title = "JRubyArt Docs"
|
80
|
+
rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
|
81
|
+
rdoc.options << '--line-numbers'
|
82
|
+
end
|
83
|
+
|
84
|
+
Rake::TestTask.new do |t|
|
85
|
+
t.test_files = FileList['test/**/*.rb']
|
86
|
+
end
|
87
|
+
|
88
|
+
RSpec::Core::RakeTask.new do |spec|
|
89
|
+
spec.pattern = 'spec/*_spec.rb'
|
90
|
+
spec.rspec_opts = [Dir["lib"].to_a.join(':')]
|
91
|
+
end
|
92
|
+
|
93
|
+
|
data/bin/k9
ADDED
data/lib/core.jar
ADDED
Binary file
|
data/lib/export.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# If you want to support more platforms, visit jogamp.org to get the
|
2
|
+
# natives libraries for the platform in question (i.e. Solaris).
|
3
|
+
|
4
|
+
name = OpenGL
|
5
|
+
|
6
|
+
application.macosx=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-macosx-universal.jar,gluegen-rt-natives-macosx-universal.jar
|
7
|
+
application.windows32=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-windows-i586.jar,gluegen-rt-natives-windows-i586.jar
|
8
|
+
application.windows64=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-windows-amd64.jar,gluegen-rt-natives-windows-amd64.jar
|
9
|
+
application.linux32=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-linux-i586.jar,gluegen-rt-natives-linux-i586.jar
|
10
|
+
application.linux64=core.jar,jogl-all.jar,gluegen-rt.jar,jogl-all-natives-linux-amd64.jar,gluegen-rt-natives-linux-amd64.jar
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/gluegen-rt.jar
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/jogl-all.jar
ADDED
Binary file
|
data/lib/jruby_art.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
VERBOSE = true
|
2
|
+
|
3
|
+
unless defined? K9_ROOT
|
4
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
|
5
|
+
K9_ROOT = File.expand_path(File.dirname(__FILE__) + '/../')
|
6
|
+
end
|
7
|
+
|
8
|
+
# guard prevents issues with mri ruby when using creator
|
9
|
+
if RUBY_PLATFORM == 'java'
|
10
|
+
working_directory = File.join(File.dirname(__FILE__))
|
11
|
+
$LOAD_PATH << working_directory unless $LOAD_PATH.include?(working_directory)
|
12
|
+
Dir[File.join(working_directory, '*.jar')].each do |jar|
|
13
|
+
require jar
|
14
|
+
end
|
15
|
+
Java::ProcessingFastmath::DeglutLibrary.new.load(JRuby.runtime, false)
|
16
|
+
Java::ProcessingVecmathVec2::Vec2Library.new.load(JRuby.runtime, false)
|
17
|
+
Java::ProcessingVecmathVec3::Vec3Library.new.load(JRuby.runtime, false)
|
18
|
+
AppRender = Java::ProcessingVecmath::AppRender
|
19
|
+
ShapeRender = Java::ProcessingVecmath::ShapeRender
|
20
|
+
require 'jruby_art/app'
|
21
|
+
require 'jruby_art/helper_methods'
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'jruby_art/version'
|
25
|
+
require 'jruby_art/helpers/numeric'
|
26
|
+
require 'jruby_art/helpers/range'
|
27
|
+
require 'jruby_art/runner'
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require_relative 'helper_methods'
|
2
|
+
|
3
|
+
# The Processing module is a wrapper for JRubyArt
|
4
|
+
# Author:: Martin Prout (extends / re-implements ruby-processing)
|
5
|
+
module Processing
|
6
|
+
include_package 'processing.core' # imports the processing.core package.
|
7
|
+
include_package 'processing.event'
|
8
|
+
# This class is the base class the user should inherit from when making
|
9
|
+
# their own sketch.
|
10
|
+
#
|
11
|
+
# i.e.
|
12
|
+
#
|
13
|
+
# class MySketch < Processing::App
|
14
|
+
#
|
15
|
+
# def draw
|
16
|
+
# background rand(255)
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
module Common
|
22
|
+
# This method provides the possibility of adding and using
|
23
|
+
# new runtime options in sketches no need to re-define initialize
|
24
|
+
#
|
25
|
+
def post_initialize(_opts = {})
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
# This method configures the sketch title and and presentation mode.
|
30
|
+
#
|
31
|
+
def configure_sketch
|
32
|
+
presentation_mode
|
33
|
+
sketch_title
|
34
|
+
end
|
35
|
+
|
36
|
+
# This method sets the sketch presentation mode.
|
37
|
+
#
|
38
|
+
def presentation_mode
|
39
|
+
return unless opts[:fullscreen]
|
40
|
+
args << '--full-screen'
|
41
|
+
args << "--bgcolor=#{opts[:bgcolor]}" if opts[:bgcolor]
|
42
|
+
end
|
43
|
+
|
44
|
+
# This method is the main draw loop of the sketch. This is usually
|
45
|
+
# overridden by the user.
|
46
|
+
#
|
47
|
+
def draw
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
# This method runs the processing sketch.
|
52
|
+
#
|
53
|
+
def run_sketch
|
54
|
+
PApplet.run_sketch(args.to_java(:string), self)
|
55
|
+
end
|
56
|
+
|
57
|
+
# This method sets the sketch title.
|
58
|
+
#
|
59
|
+
def sketch_title
|
60
|
+
args << opts.fetch(:title, 'Sketch')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
# Watch the definition of these methods, to make sure
|
64
|
+
# that Processing is able to call them during events.
|
65
|
+
METHODS_TO_ALIAS = {
|
66
|
+
mouse_pressed: :mousePressed,
|
67
|
+
mouse_dragged: :mouseDragged,
|
68
|
+
mouse_clicked: :mouseClicked,
|
69
|
+
mouse_moved: :mouseMoved,
|
70
|
+
mouse_released: :mouseReleased,
|
71
|
+
key_pressed: :keyPressed,
|
72
|
+
key_released: :keyReleased,
|
73
|
+
key_typed: :keyTyped
|
74
|
+
}
|
75
|
+
|
76
|
+
# This class is for default (Java2D) sketches only
|
77
|
+
class App < PApplet
|
78
|
+
include Common, HelperMethods
|
79
|
+
Java::ProcessingVecmathArcball::ArcballLibrary.new.load(JRuby.runtime, false)
|
80
|
+
attr_reader :title, :args, :opts
|
81
|
+
|
82
|
+
# App should be instantiated with an optional list of opts
|
83
|
+
# and array of args.
|
84
|
+
#
|
85
|
+
# App.new(title: 'My Simple App', fullscreen: true)
|
86
|
+
#
|
87
|
+
def initialize(opts = {}, args = [])
|
88
|
+
super()
|
89
|
+
proxy_java_fields
|
90
|
+
post_initialize(opts)
|
91
|
+
@args = args
|
92
|
+
@opts = opts
|
93
|
+
configure_sketch
|
94
|
+
run_sketch
|
95
|
+
end
|
96
|
+
|
97
|
+
# This method provides the default setup for the sketch. It can
|
98
|
+
# be overridden by the user for finer grained control.
|
99
|
+
#
|
100
|
+
def setup
|
101
|
+
size(width, height)
|
102
|
+
end
|
103
|
+
|
104
|
+
# When certain special methods get added to the sketch, we need to let
|
105
|
+
# Processing call them by their expected Java names.
|
106
|
+
def self.method_added(method_name) # :nodoc:
|
107
|
+
# Watch the definition of these methods, to make sure
|
108
|
+
# that Processing is able to call them during events.
|
109
|
+
if METHODS_TO_ALIAS.key?(method_name)
|
110
|
+
alias_method METHODS_TO_ALIAS[method_name], method_name
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# This class is for opengl sketches (P2D and P3D)
|
116
|
+
class AppGL < PApplet
|
117
|
+
include Processing, Common
|
118
|
+
include_package 'processing.opengl' # imports the processing.opengl package.
|
119
|
+
include HelperMethods
|
120
|
+
attr_reader :title, :args, :opts
|
121
|
+
|
122
|
+
# App should be instantiated with an optional list of opts
|
123
|
+
# and array of args.
|
124
|
+
#
|
125
|
+
# App.new(title: 'My Simple App', fullscreen: true)
|
126
|
+
#
|
127
|
+
def initialize(opts = {}, args = [])
|
128
|
+
super()
|
129
|
+
proxy_java_fields
|
130
|
+
post_initialize(opts)
|
131
|
+
@args = args
|
132
|
+
@opts = opts
|
133
|
+
configure_sketch
|
134
|
+
run_sketch
|
135
|
+
end
|
136
|
+
|
137
|
+
# This method provides the default setup for the sketch. It can
|
138
|
+
# be overridden by the user for finer grained control.
|
139
|
+
#
|
140
|
+
def setup
|
141
|
+
size(width, height, mode = P3D)
|
142
|
+
fail unless /opengl/ =~ mode
|
143
|
+
end
|
144
|
+
|
145
|
+
# When certain special methods get added to the sketch, we need to let
|
146
|
+
# Processing call them by their expected Java names.
|
147
|
+
def self.method_added(method_name) #:nodoc:
|
148
|
+
if METHODS_TO_ALIAS.key?(method_name)
|
149
|
+
alias_method METHODS_TO_ALIAS[method_name], method_name
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|