Giter Site home page Giter Site logo

ruby-processing / jrubyart Goto Github PK

View Code? Open in Web Editor NEW
89.0 9.0 9.0 7.19 MB

JRubyArt a ruby implementation of processing

Home Page: https://ruby-processing.github.io/JRubyArt/

License: GNU General Public License v3.0

Ruby 2.85% Java 95.81% GLSL 1.35%
processing ruby jruby graphics video sound art jrubyart generative-art creative-coding

jrubyart's People

Contributors

monkstone avatar tyfkda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jrubyart's Issues

Errors on run : Unhandled Java exception

I feel this is an installation or compatability issue, please confirm.

Error Message on run:

tstuder:contributed tstuder$ k9 --run fire.rb 
Unhandled Java exception: java.lang.NoClassDefFoundError: com/apple/eawt/QuitHandler
java.lang.NoClassDefFoundError: com/apple/eawt/QuitHandler
                getDeclaredMethods0 at java/lang/Class.java:-2
          privateGetDeclaredMethods at java/lang/Class.java:3119
                getMethodsRecursive at java/lang/Class.java:3260
                         getMethod0 at java/lang/Class.java:3246
                          getMethod at java/lang/Class.java:2065
                          runSketch at processing/core/PApplet.java:10751
                          runSketch at processing/core/PApplet.java:10989
                          runSketch at processing/core/PApplet.java:10995
                            invoke0 at jdk/internal/reflect/NativeMethodAccessorImpl.java:-2
                             invoke at jdk/internal/reflect/NativeMethodAccessorImpl.java:62
                             invoke at jdk/internal/reflect/DelegatingMethodAccessorImpl.java:43
                             invoke at java/lang/reflect/Method.java:564
  invokeDirectWithExceptionHandling at org/jruby/javasupport/JavaMethod.java:440
                 tryProxyInvocation at org/jruby/javasupport/JavaMethod.java:625
                       invokeDirect at org/jruby/javasupport/JavaMethod.java:301
                         initialize at /Users/tstuder/.rvm/gems/ruby-2.5.1/gems/jruby_art-1.5.2/lib/jruby_art/app.rb:116
                        newInstance at org/jruby/RubyClass.java:997
                               call at org/jruby/RubyClass$INVOKER$i$newInstance.gen:-1
                load_and_run_sketch at /Users/tstuder/.rvm/gems/ruby-2.5.1/gems/jruby_art-1.5.2/lib/jruby_art/runners/base.rb:46
   invokeOther2:load_and_run_sketch at Users/tstuder/$_dot_rvm/gems/ruby_minus_2_dot_5_dot_1/gems/jruby_art_minus_1_dot_5_dot_2/lib/jruby_art/runners//Users/tstuder/.rvm/gems/ruby-2.5.1/gems/jruby_art-1.5.2/lib/jruby_art/runners/run.rb:4
                             <main> at Users/tstuder/$_dot_rvm/gems/ruby_minus_2_dot_5_dot_1/gems/jruby_art_minus_1_dot_5_dot_2/lib/jruby_art/runners//Users/tstuder/.rvm/gems/ruby-2.5.1/gems/jruby_art-1.5.2/lib/jruby_art/runners/run.rb:4
                invokeWithArguments at java/lang/invoke/MethodHandle.java:707
                          runScript at org/jruby/Ruby.java:852
                        runNormally at org/jruby/Ruby.java:771
                        runNormally at org/jruby/Ruby.java:789
                        runFromMain at org/jruby/Ruby.java:601
                      doRunFromMain at org/jruby/Main.java:415
                        internalRun at org/jruby/Main.java:307
                                run at org/jruby/Main.java:234
                               main at org/jruby/Main.java:206

Caused by:
java.lang.ClassNotFoundException: com.apple.eawt.QuitHandler
                          findClass at java/net/URLClassLoader.java:466
                          loadClass at java/lang/ClassLoader.java:566
                          loadClass at java/lang/ClassLoader.java:499
                getDeclaredMethods0 at java/lang/Class.java:-2
          privateGetDeclaredMethods at java/lang/Class.java:3119
                getMethodsRecursive at java/lang/Class.java:3260
                         getMethod0 at java/lang/Class.java:3246
                          getMethod at java/lang/Class.java:2065
                          runSketch at processing/core/PApplet.java:10751
                          runSketch at processing/core/PApplet.java:10989
                          runSketch at processing/core/PApplet.java:10995
                            invoke0 at jdk/internal/reflect/NativeMethodAccessorImpl.java:-2
                             invoke at jdk/internal/reflect/NativeMethodAccessorImpl.java:62
                             invoke at jdk/internal/reflect/DelegatingMethodAccessorImpl.java:43
                             invoke at java/lang/reflect/Method.java:564
  invokeDirectWithExceptionHandling at org/jruby/javasupport/JavaMethod.java:440
                 tryProxyInvocation at org/jruby/javasupport/JavaMethod.java:625
                       invokeDirect at org/jruby/javasupport/JavaMethod.java:301
                               call at org/jruby/java/invokers/InstanceMethodInvoker.java:36
                       cacheAndCall at org/jruby/runtime/callsite/CachingCallSite.java:323
                               call at org/jruby/runtime/callsite/CachingCallSite.java:139
                        processCall at org/jruby/ir/interpreter/InterpreterEngine.java:344
                          interpret at org/jruby/ir/interpreter/StartupInterpreterEngine.java:72
                          interpret at org/jruby/ir/interpreter/InterpreterEngine.java:78
                   INTERPRET_METHOD at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:136
                               call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:123
                       cacheAndCall at org/jruby/runtime/callsite/CachingCallSite.java:334
                               call at org/jruby/runtime/callsite/CachingCallSite.java:149
                        newInstance at org/jruby/RubyClass.java:997
                               call at org/jruby/RubyClass$INVOKER$i$newInstance.gen:-1
                               call at org/jruby/internal/runtime/methods/DynamicMethod.java:194
                               call at org/jruby/java/proxies/ConcreteJavaProxy.java:151
                       cacheAndCall at org/jruby/runtime/callsite/CachingCallSite.java:323
                               call at org/jruby/runtime/callsite/CachingCallSite.java:139
                        processCall at org/jruby/ir/interpreter/InterpreterEngine.java:344
                          interpret at org/jruby/ir/interpreter/StartupInterpreterEngine.java:72
                          interpret at org/jruby/ir/interpreter/InterpreterEngine.java:78
                   INTERPRET_METHOD at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:136
                               call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:123
                               call at org/jruby/internal/runtime/methods/DynamicMethod.java:194
                       cacheAndCall at org/jruby/runtime/callsite/CachingCallSite.java:323
                               call at org/jruby/runtime/callsite/CachingCallSite.java:139
   invokeOther2:load_and_run_sketch at Users/tstuder/$_dot_rvm/gems/ruby_minus_2_dot_5_dot_1/gems/jruby_art_minus_1_dot_5_dot_2/lib/jruby_art/runners//Users/tstuder/.rvm/gems/ruby-2.5.1/gems/jruby_art-1.5.2/lib/jruby_art/runners/run.rb:4
                             <main> at /Users/tstuder/.rvm/gems/ruby-2.5.1/gems/jruby_art-1.5.2/lib/jruby_art/runners/run.rb:4
                invokeWithArguments at java/lang/invoke/MethodHandle.java:707
                               load at org/jruby/ir/Compiler.java:94
                          runScript at org/jruby/Ruby.java:852
                        runNormally at org/jruby/Ruby.java:771
                        runNormally at org/jruby/Ruby.java:789
                        runFromMain at org/jruby/Ruby.java:601
                      doRunFromMain at org/jruby/Main.java:415
                        internalRun at org/jruby/Main.java:307
                                run at org/jruby/Main.java:234
                               main at org/jruby/Main.java:206

JRuby yml

---
PROCESSING_ROOT: "/Applications/Processing.app/Contents/Java"
JRUBY: false
sketchbook_path: "/Users/tstuder/Documents/Processing"
template: bare
MAX_WATCH: 32
sketch_title: JRubyArt Static Sketch
width: 600
height: 600

Environment

**java --version**
java 10.0.2 2018-07-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.2+13)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode)

**ruby --version**
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin16]

**Processing**
Processing 3.4

Actual Behavior

It appears the file attempts to launch, and then quits.

Need to implement a library loader

An alternative library loader is required, if we no-longer assume we have a sketchbook (or similar mac/windows) to install libraries. A central location (and vanilla processing compatible path is required).
It is thus proposed that libraries such as video and sound should live in eponymous folders in a libraries folder in the ~/.jruby_art folder. See fb3fe74 for first hack, works on linux with video library.

require 'jruby_art'

#Dir[File.join('library/video', '*.jar')].each do |jar|
#  require_relative jar
#end

class AsciiVideoCapture < Processing::App
  load_library :video
  attr_reader :bright, :char, :cheat_screen, :font, :font_size, :letters, :video
  # All ASCII characters, sorted according to their visual density
  LETTER_STRING = %q{ .`-_':,;^=+/\"|)\\<>)iv%xclrs{*}I?!][1taeo7zjLunT#JCwfy325Fp6mqSghVd4EgXPGZbYkOA&8U$@KHDBWNMR0Q}
  LETTER_ORDER = LETTER_STRING.scan(/./)

  def setup
    size(640, 480)
    init_video
    @font_size = 1.5
    @font = load_font(data_path('UniversLTStd-Light-48.vlw'))
    # for the 256 levels of brightness, distribute the letters across
    # the an array of 256 elements to use for the lookup
    @letters = (0...256).map do |i|
      LETTER_ORDER[map1d(i, (0...256), (0...LETTER_ORDER.length))]
    end
    # current brightness for each point
    @bright = Array.new(video.width * video.height, 128)
  end

  def init_video
    # This the default video input, see the test_capture
    # example if it creates an error
    @video = Java::ProcessingVideo::Capture.new(self, 160, 120)
    # Start capturing the images from the camera
    video.start
    @cheat_screen = false
  end

  def capture_event(c)
    c.read
    background 0
  end

  def draw
    return unless (video.available == true)
    capture_event(video)
    push_matrix
    hgap = width / video.width
    vgap = height / video.height
    scale([hgap, vgap].max * font_size)
    text_font(font, font_size)
    index = 0
    video.load_pixels
    (0...video.height).each do
      # Move down for next line
      translate(0,  1.0 / font_size)
      push_matrix
      (0...video.width).each do
        pixel_color = video.pixels[index]
        # Faster method of calculating r, g, b than red(), green(), blue()
        r = pixel_color >> 16 & 0xff
        g = pixel_color >> 8 & 0xff
        b = pixel_color & 0xff
        # Another option would be to properly calculate brightness as luminance:
        # luminance = 0.3*red + 0.59*green + 0.11*blue
        # Or you could instead red + green + blue, and make the the values[] array
        #256*3 elements long instead of just 256.
        pixel_bright = [r, g, b].max
        # The 0.1 value is used to damp the changes so that letters flicker less
        diff = pixel_bright - bright[index]
        bright[index] += diff * 0.1
        fill(pixel_color)
        text(letters[bright[index]], 0, 0)
        # Move to the next pixel
        index += 1
        # Move over for next character
        translate(1.0 / font_size, 0)
      end
      pop_matrix
    end
    pop_matrix
    # image(video, 0, height - video.height)
    # set() is faster than image() when drawing untransformed images
    set(0, height - video.height, video) if cheat_screen
  end

  MESSAGE = <<-EOS
  Controls are:
  g to save_frame, f & F to set font size
  c to toggle cheat screen display
  EOS

  #
  # Handle key presses:
  # 'c' toggles the cheat screen that shows the original image in the corner
  # 'g' grabs an image and saves the frame to a tiff image
  # 'f' and 'F' increase and decrease the font size
  #
  def key_pressed
    case key
    when 'g' then save_frame
    when 'c' then @cheat_screen = !cheat_screen
    when 'f' then @font_size *= 1.1
    when 'F' then @font_size *= 0.9
    else
      warn MESSAGE
    end
  end
end

AsciiVideoCapture.new(title: 'Video Capture Sketch')

issue with draw

Hi ,
for some reason when i excute my code i cant see the (@Head and @food as in the code ) but if i replace (height/2 and width/2 and rend(height) and rand(width)) with numbers it will work

def settings
  size 400, 400
end

def setup
  sketch_title 'snake'
  background 0
  stroke 255
  strokeWeight 2
  grid
  @head = Snake.new(width/2, height/2) # if i replace width/2 and height/2 with numbers like (..new(5,5)) it will work 
  @food = Food.new(rand(width), rand(height)) # if i replace rand(width) and rand(height) with numbers like (..new(5,5)) it will work 
  @up = false
  @down = false
  @lef = true
  @right = false
end

def draw
  @head.show
  @food.show
end

def grid
  (0..width).each do |x|
    line(x*20,0,x*20,height)
  end
  (0..height).each do |x|
    line(0,x*20,width,x*20)
  end
end
class Snake
  include Processing::Proxy
  attr_accessor :x,:y
  def initialize(x,y)
    @x=x
    @y=y
  end
  def show
    fill 255
    rect(@x*20,@y*20,20,20)
  end
end
class Food
  include Processing::Proxy
  attr_accessor :x,:y
  def initialize(x,y)
    @x = x
    @y = y
  end
  def show
    fill (color(255,160,14))
    rect(@x*20,@y*20,20,20)
  end
end
def key_pressed
  if key == CODED
    if keyCode == UP && !@down
      @up = true
      @left = false
      @down = false
      @right = false
    end
    if keyCode == DOWN && !@up
      @down = true
      @up = false
      @right = false
      @left = false
    end
    if keyCode == RIGHT && !@left
      @right  = true
      @up = false
      @down = false
      @left = false
    end
    if keyCode == LEFT && !@right
      @left  = true
      @right = false
      @up = false
      @down = false
    end
  end
end

Installation Issue: Problem running sketches

Other

eg installation issue (just use this header and explain the problem as best you can)

I just recently installed jruby_art following the macOS instructions. However when I try and run an example I get an error message:

Running ./raining.rb...quit to run next sample
LoadError: load error: /usr/local/lib/ruby/gems/2.4.0/gems/jruby_art-1.2.9/lib/jruby_art/app -- java.lang.NoClassDefFoundError: processing/core/PApplet
           require at org/jruby/RubyKernel.java:961
  require_relative at uri:classloader:/jruby/kernel/kernel.rb:13
            <main> at /usr/local/lib/ruby/gems/2.4.0/gems/jruby_art-1.2.9/lib/jruby_art/runners/base.rb:6
           require at org/jruby/RubyKernel.java:961
            (root) at uri:classloader:/jruby/kernel/kernel.rb:1
            <main> at /usr/local/lib/ruby/gems/2.4.0/gems/jruby_art-1.2.9/lib/jruby_art/runners/run.rb:2

Any idea what is causing the issue?

Processing Methods not found on Windows

I made simple test sketch.

def settings
  size 400, 400
  c = color rand 255
  red c
end

def setup
  sketch_title 'Test'
end

And when I ran it, um...

Unhandled Java exception: java.lang.NullPointerException
java.lang.NullPointerException: null
                                red at processing/core/PApplet.java:15154
                             invoke at java/lang/reflect/Method:-1
  invokeDirectWithExceptionHandling at org/jruby/javasupport/JavaMethod.java:455
                       invokeDirect at org/jruby/javasupport/JavaMethod.java:316
                           settings at test.rb:3
                         invokeRuby at org/jruby/javasupport/proxy/JavaProxyConstructor.java:255
                             invoke at org/jruby/javasupport/proxy/JavaProxyConstructor.java:238
                           settings at org/jruby/proxy/processing/core/PApplet$Proxy1:-1
                     handleSettings at processing/core/PApplet.java:951
                          runSketch at processing/core/PApplet.java:10742
                          runSketch at processing/core/PApplet.java:10945
                          runSketch at processing/core/PApplet.java:10951
                             invoke at java/lang/reflect/Method:-1
  invokeDirectWithExceptionHandling at org/jruby/javasupport/JavaMethod.java:440
                 tryProxyInvocation at org/jruby/javasupport/JavaMethod.java:625
                       invokeDirect at org/jruby/javasupport/JavaMethod.java:301
                         initialize at C:/JRuby92-x64/lib/ruby/gems/shared/gems/jruby_art-1.5.0/lib/jruby_art/app.rb:116
                        newInstance at org/jruby/RubyClass.java:997
                               call at org/jruby/RubyClass$INVOKER$i$newInstance.gen:-1
                load_and_run_sketch at C:/JRuby92-x64/lib/ruby/gems/shared/gems/jruby_art-1.5.0/lib/jruby_art/runners/base.rb:46
   invokeOther2:load_and_run_sketch at C_3a_/JRuby92_minus_x64/lib/ruby/gems/shared/gems/jruby_art_minus_1_dot_5_dot_0/lib/jruby_art/runners/C:/JRuby92-x64/lib/ruby/gems/shared/gems/jruby_art-1.5.0/lib/jruby_art/runners/run.rb:4
                             <main> at C_3a_/JRuby92_minus_x64/lib/ruby/gems/shared/gems/jruby_art_minus_1_dot_5_dot_0/lib/jruby_art/runners/C:/JRuby92-x64/lib/ruby/gems/shared/gems/jruby_art-1.5.0/lib/jruby_art/runners/run.rb:4
                invokeWithArguments at java/lang/invoke/MethodHandle:-1
                          runScript at org/jruby/Ruby.java:852
                        runNormally at org/jruby/Ruby.java:771
                        runNormally at org/jruby/Ruby.java:789
                        runFromMain at org/jruby/Ruby.java:601
                      doRunFromMain at org/jruby/Main.java:415
                        internalRun at org/jruby/Main.java:307
                                run at org/jruby/Main.java:234
                               main at org/jruby/Main.java:206

Which I assume means that the gem, or JRuby itself, couldn't find the red method? This also happens for a few other methods such as green, blue, colorMode, etc.

It's listed when I call find_method 'red' and I can run a sketch that doesn't call red such as loading an image or some such. And k9 --check returns fine for me. I don't quite know what's going on.

Error with loading data

Environment

k9 setup check:
RubyArt version 1.0.7 PROCESSING_ROOT = /Applications/Processing.app/Contents/Java JRUBY = false jruby-complete installed = true

jruby -v
jruby 9.1.0.0 (2.3.0) 2016-05-02 a633c63 Java HotSpot(TM) 64-Bit Server VM 25.92-b14 on 1.8.0_92-b14 +jit [darwin-x86_64]

java -version
java version "1.8.0_92" Java(TM) SE Runtime Environment (build 1.8.0_92-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)

k9 --version:
JRubyArt version 1.0.7

Expected Behavior

The sketch should show the image with the histogram:
k9_samples/processing_app/topics/image_processing/histogram.rb

(But it happens with any sketch that requires depends on archives inside a data folder).

Actual Behavior

Every time I try to run any sketch file with stuff loading from the data folder a get this kind of error:

CompilerOracle: dontinline org/jruby/runtime/invokedynamic/InvokeDynamicSupport.invocationFallback The file "frontier.jpg" is missing or inaccessible, make sure the URL is valid or that the file has been added to your sketch and is readable. Java::JavaLang::NullPointerException processing.core.PGraphics.image(processing/core/PGraphics.java:3765) processing.core.PApplet.image(processing/core/PApplet.java:12116) java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:498) org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(org/jruby/javasupport/JavaMethod.java:423) org.jruby.javasupport.JavaMethod.tryProxyInvocation(org/jruby/javasupport/JavaMethod.java:613) org.jruby.javasupport.JavaMethod.invokeDirect(org/jruby/javasupport/JavaMethod.java:287) RUBY.setup(samples/processing_app/topics/image_processing/histogram.rb:17) org.jruby.javasupport.proxy.JavaProxyConstructor$MethodInvocationHandler.invokeRuby(org/jruby/javasupport/proxy/JavaProxyConstructor.java:229) org.jruby.javasupport.proxy.JavaProxyConstructor$MethodInvocationHandler.invoke(org/jruby/javasupport/proxy/JavaProxyConstructor.java:212) processing.core.PApplet.handleDraw(processing/core/PApplet.java:2378) processing.awt.PSurfaceAWT$12.callDraw(processing/awt/PSurfaceAWT.java:1527) processing.core.PSurfaceNone$AnimationThread.run(processing/core/PSurfaceNone.java:316)

Wrong Ruby Version

Environment

processing 3.3.6
jruby 9.1.13
java oracle-java8-installer
jrubyart 1.4.5
ubuntu

Expected Behavior

k9 --run jwishy.rb

Actual Behavior

/home/u/.rvm/gems/ruby-2.4.1@global/gems/rubygems-bundler-1.4.4/lib/rubygems-bundler/noexec.rb:5:in pwd': No such file or directory - getcwd (Errno::ENOENT) from /home/u/.rvm/gems/ruby-2.4.1@global/gems/rubygems-bundler-1.4.4/lib/rubygems-bundler/noexec.rb:5:in class:Noexec'
from /home/u/.rvm/gems/ruby-2.4.1@global/gems/rubygems-bundler-1.4.4/lib/rubygems-bundler/noexec.rb:3:in <top (required)>' from /home/u/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:133:in require'
from /home/u/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:133:in rescue in require' from /home/u/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:40:in require'
from /home/u/.rvm/gems/ruby-2.4.1@global/gems/rubygems-bundler-1.4.4/lib/rubygems_executable_plugin.rb:4:in block in <top (required)>' from /home/u/.rvm/gems/ruby-2.4.1@global/gems/executable-hooks-1.3.2/lib/executable-hooks/hooks.rb:50:in block in run'
from /home/u/.rvm/gems/ruby-2.4.1@global/gems/executable-hooks-1.3.2/lib/executable-hooks/hooks.rb:49:in each' from /home/u/.rvm/gems/ruby-2.4.1@global/gems/executable-hooks-1.3.2/lib/executable-hooks/hooks.rb:49:in run'
from /home/u/.rvm/gems/ruby-2.4.1/bin/ruby_executable_hooks:10:in `

'

Other

This has been giving me a headache for over 4 hours... I can't figure out what I'm doing wrong. I've goen through every guide at least 5 times and followed every instruction exactly...

Error loading data on macosx

@b-jufre has reported that the data path is not correctly interpreted on macosx. Until we find a more elegant fix for this problem you can get round it by providing an absolute path to the data folder in the sketch:-

# replace
loadImage('pic.png')
# with
loadImage('/path_to_sketch_folder/data/pic.png')

Or more elegantly and less volatile, use ruby to do it for us:-

loadImage(File.absolute_path('data/pic.png'))

This problem is expected to exist with shader sketches and basically any other sketch where data gets loaded from a local folder (using processing methods) does not affect sketches where we use ruby for io.

A possibly intermediate solution might be to override the processing dataPath method that is designed to to provide the absolute data path using java (seems to work OK on linux) but the processing/java form does not work on the mac (whereas the following does).

def data_path(pic)
   File.absolute_path("data/#{pic}")
end

But then you would need to use the data_path wrapper in your sketches.

loadImage(data_path('pic.png'))

Apart form the extra typing the advantage is there would be a mac specific fix, but such sketches should still work cross-platform. Furthermore it might obviate the need for the --nojruby flag (all-platforms?), proven to work in sketch on linux, with both shader and image sketches @tyfkda @poqudrof

JRubyART reflective access warnings (JRuby modules and jogamp)

Running JRubyArt with a PixelFlow shader sketch jruby_art-2.2.0 (jruby-9.2.8.0) and the --illegal-access=warn flag in data/java_args.txt

WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Object.finalize()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Object.clone()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to field java.io.FileDescriptor.fd
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.enumConstantDirectory()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.typeVarBounds(java.lang.reflect.TypeVariable)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.getClassLoader0()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.setSigners(java.lang.Object[])
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.getDeclaredPublicMethods(java.lang.String,java.lang.Class[])
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.getPrimitiveClass(java.lang.String)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.getRawAnnotations()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.getRawTypeAnnotations()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.getExecutableTypeAnnotationBytes(java.lang.reflect.Executable)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.getConstantPool()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.getEnumConstantsShared()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.casAnnotationType(sun.reflect.annotation.AnnotationType,sun.reflect.annotation.AnnotationType)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.getAnnotationType()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Class.getDeclaredAnnotationMap()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Enum.finalize()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Enum.clone()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.System$LoggerFinder.accessProvider()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.io.File.isInvalid()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.io.File.getPrefixLength()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.base()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.checkIndex(int,int)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.checkIndex(int)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.createSameBufferException()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.createCapacityException(int)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.nextGetIndex()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.nextGetIndex(int)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.nextPutIndex()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.nextPutIndex(int)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.markValue()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.discardMark()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.Buffer.checkBounds(int,int,int)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.ByteBuffer.base()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.nio.ByteBuffer.slice(int,int)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Thread.clone()
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Thread.blockedOn(sun.nio.ch.Interruptible)
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method java.lang.Thread.processQueue(java.lang.ref.ReferenceQueue,java.util.concurrent.ConcurrentMap)
WARNING: Illegal reflective access by com.jogamp.common.os.NativeLibrary$3 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/gluegen-rt.jar) to method java.lang.ClassLoader.findLibrary(java.lang.String)
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$2 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to field sun.java2d.opengl.OGLUtilities.UNDEFINED
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$2 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to field sun.java2d.opengl.OGLUtilities.WINDOW
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$2 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to field sun.java2d.opengl.OGLUtilities.TEXTURE
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$2 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to field sun.java2d.opengl.OGLUtilities.FLIP_BACKBUFFER
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$2 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to field sun.java2d.opengl.OGLUtilities.FBOBJECT
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.java2d.opengl.OGLUtilities.invokeWithOGLContextCurrent(java.awt.Graphics,java.lang.Runnable)
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.java2d.opengl.OGLUtilities.isQueueFlusherThread()
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.java2d.opengl.OGLUtilities.getOGLViewport(java.awt.Graphics,int,int)
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.java2d.opengl.OGLUtilities.getOGLScissorBox(java.awt.Graphics)
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.java2d.opengl.OGLUtilities.getOGLSurfaceIdentifier(java.awt.Graphics)
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.java2d.opengl.OGLUtilities.invokeWithOGLSharedContextCurrent(java.awt.GraphicsConfiguration,java.lang.Runnable)
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.java2d.opengl.OGLUtilities.getOGLSurfaceType(java.awt.Graphics)
WARNING: Illegal reflective access by jogamp.opengl.awt.Java2D$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.java2d.opengl.OGLUtilities.getOGLTextureType(java.awt.Graphics)
WARNING: Illegal reflective access by jogamp.nativewindow.jawt.JAWTUtil$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.awt.SunToolkit.awtLock()
WARNING: Illegal reflective access by jogamp.nativewindow.jawt.JAWTUtil$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.awt.SunToolkit.awtUnlock()
WARNING: Illegal reflective access by jogamp.nativewindow.jawt.JAWTUtil$1 (file:/home/tux/.gem/ruby/2.5.0/gems/jruby_art-2.2.0/lib/jogl-all.jar) to method sun.awt.X11GraphicsDevice.getScaleFactor()

wget over https

At least under windows one has to add --no-check-certificate to the wget commands in the Rakefile. to circumvent 'Unable to locally verify the issuer's authority`.

I have a probleme with the k9

Hi, I have this probleme
´´´
/lib/jruby_art/app -- java.lang.NoClassDefFoundError: processing/core/PApplet
require at org/jruby/RubyKernel.java:956
require_relative at uri:classloader:/jruby/kernel/kernel.rb:13

at /home/moirouhs/.gem/ruby/2.5.0/gems/jruby_art-1.4.9/lib/jruby_art/runners/base.rb:6
require at org/jruby/RubyKernel.java:956
(root) at uri:classloader:/jruby/kernel/kernel.rb:1
at /home/moirouhs/.gem/ruby/2.5.0/gems/jruby_art-1.4.9/lib/jruby_art/runners/run.rb:2
k9 -r tree.rb 14,21s user 2,36s system 158% cpu 10,427 total
´´´
This is my config.yaml

PROCESSING_ROOT: "/usr/bin/processing"
JRUBY: false
sketchbook_path: "/home/moirouhs/sketchbook"
template: bare
MAX_WATCH: 32
sketch_title: JRubyArt Static Sketch
width: 600
height: 600

I have java 8, ruby 2.5.0 and jruby 9.1.17.0 (2.3.3) 2018-04-20 d8b1ff9 OpenJDK 64-Bit Server VM 25.172-b11 on 1.8.0_172-b11 +jit [linux-x86_64]

for windows JRubyArt

Windows 7
java version 1.8.0_91
JRubyArt version 1.4.6
jruby version 9.1.15.0(2.3.3)

Actual Behavior

By doing "k9 --run test.rb"

LoadError: load error: C:/jruby-9.1.15.0/lib/ruby/gems/shared/gems/jruby_art-1.4.6/lib/jruby_art/app --java.lang.NoClassDefFoundError: processing/core/PApplet

require at org/jruby/RubyKernel.java:955

require_relative at uri:classloader:/jruby/kernel/kernel.rb:13

at C:/jruby-9.1.15.0/lib/ruby/gems/shared/gems/jruby_art-1.4.6/lib/jruby_art/runners/base.rb:6

Other

Video and PDF libraries not working.

Environment

This is my result of k9 setup check:

JRubyArt version 1.0.5
  PROCESSING_ROOT = E:\processing-3.0.2 Windows
  JRUBY = true
  jruby-complete installed = true

jruby -v:

jruby 9.0.5.0 (2.2.3) 2016-01-26 7bee00d Java HotSpot(TM) Client VM 25.77-b03 on
 1.8.0_77-b03 +jit [Windows 7-x86]

java -version:

java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)

Expected Behavior

Basically, many sketches won't run. All of those that use video libraries (I do have them installed in processing, and I've made copies of them in the sketch directory); and also others that use the processing libraries, like PDF. Examples:

Ascii_capture:
https://github.com/ruby-processing/samples4ruby-processing3/blob/master/processing_app/library/video/capture/ascii_capture.rb

PDF large_page
https://github.com/ruby-processing/samples4ruby-processing3/blob/master/processing_app/library/pdf/large_page.rb

Actual Behavior

>k9 --nojruby run ascii_capture.rb

LoadError: no such file to load -- /ascii_capture
                  require at org/jruby/RubyKernel.java:937
                  require at uri:classloader:/META-INF/jruby.home/lib/ruby/stdli
b/rubygems/core_ext/kernel_require.rb:54
        load_ruby_library at C:/jruby-9.0.5.0/lib/ruby/gems/shared/gems/jruby_ar
t-1.0.5/lib/jruby_art/library_loader.rb:44
  block in load_libraries at C:/jruby-9.0.5.0/lib/ruby/gems/shared/gems/jruby_ar
t-1.0.5/lib/jruby_art/library_loader.rb:30
                     each at org/jruby/RubyArray.java:1560
           load_libraries at C:/jruby-9.0.5.0/lib/ruby/gems/shared/gems/jruby_ar
t-1.0.5/lib/jruby_art/library_loader.rb:29
           load_libraries at C:/jruby-9.0.5.0/lib/ruby/gems/shared/gems/jruby_ar
t-1.0.5/lib/jruby_art/app.rb:65
           <class:Sketch> at ascii_capture.rb:9
                   <eval> at ascii_capture.rb:1
              module_eval at org/jruby/RubyModule.java:2711
      load_and_run_sketch at C:/jruby-9.0.5.0/lib/ruby/gems/shared/gems/jruby_ar
t-1.0.5/lib/jruby_art/runners/base.rb:43
                    <top> at C:/jruby-9.0.5.0/lib/ruby/gems/shared/gems/jruby_ar
t-1.0.5/lib/jruby_art/runners/run.rb:5

Other

I've tried copying the libraries to the sketch folder with the appropiate folder structure. It makes no difference. Help?

issues with jdk12.02 on archlinux

The latest version of JRubyArt seems to work OK on linux mint, but not on Archlinux. Seems to be related to this issue:-
https://stackoverflow.com/questions/55847497/how-do-i-troubleshoot-inconsistency-detected-dl-lookup-c-111-java-result-12

Inconsistency detected by ld.so: dl-lookup.c: 111: check_match: Assertion `version->filename == NULL || ! _dl_name_match_p (version->filename, map)' failed!

I do not pretend to know what it means, but seems possibly a jogl issue or more likely glibc issue on Archlinux?

Issues with jdk9 with using inherited protected method

The most immediate problem is that JRuby can't access inherited protected methods (specifically runSketch) jruby/jruby#4851. Java 9 is much more restrictive concerning reflective access to non-public fields/methods, and @headius can't see a way of fixing it without making non-inherited java protected methods available. However there probably more issues to come and hit jruby before it hits us. For one example of offending code see line 67 library_loader.rb

 field = java.lang.Class.for_name('java.lang.ClassLoader').get_declared_field('sys_paths')
        if field
          field.accessible = true
          field.set(java.lang.Class.for_name('java.lang.System').get_class_loader, nil)
        end

Here is link to slated possible workaround http://mail.openjdk.java.net/pipermail/jigsaw-dev/2017-March/011763.html that will be banished by jdk10 (by then parrot will have fallen off perch or worse).

Sketch creator error

Hello,

I have some trouble with the sketch creators. I have two kind of errors, here is the first kind :

[jiii@jeremy-alienware contributed]$ k9 create fred 200 200     
ArgumentError: wrong number of arguments (0 for 1)
   create! at /home/jiii/.rvm/gems/jruby-9.0.1.0/gems/jruby_art-1.1.2/lib/jruby_art/creators/creator.rb:198
    create at /home/jiii/.rvm/gems/jruby-9.0.1.0/gems/jruby_art-1.1.2/lib/jruby_art/runner.rb:101
  execute! at /home/jiii/.rvm/gems/jruby-9.0.1.0/gems/jruby_art-1.1.2/lib/jruby_art/runner.rb:72
   execute at /home/jiii/.rvm/gems/jruby-9.0.1.0/gems/jruby_art-1.1.2/lib/jruby_art/runner.rb:63
     <top> at /home/jiii/.rvm/gems/jruby-9.0.1.0/gems/jruby_art-1.1.2/bin/k9:10
      load at org/jruby/RubyKernel.java:957
    <eval> at /home/jiii/.rvm/gems/jruby-9.0.1.0/bin/k9:1
      eval at org/jruby/RubyKernel.java:978
     <top> at /home/jiii/.rvm/gems/jruby-9.0.1.0/bin/jruby_executable_hooks:15

I also had this other error, which was before I did the k9 setup install :

NameError: undefined local variable or method `underscore' for "fred":String
  titleize at /home/jiii/.rvm/gems/jruby-9.1.2.0/gems/jruby_art-1.1.2/lib/jruby_art/helpers/string_extra.rb:6
   create! at /home/jiii/.rvm/gems/jruby-9.1.2.0/gems/jruby_art-1.1.2/lib/jruby_art/creators/creator.rb:200
    create at /home/jiii/.rvm/gems/jruby-9.1.2.0/gems/jruby_art-1.1.2/lib/jruby_art/runner.rb:101
  execute! at /home/jiii/.rvm/gems/jruby-9.1.2.0/gems/jruby_art-1.1.2/lib/jruby_art/runner.rb:72
   execute at /home/jiii/.rvm/gems/jruby-9.1.2.0/gems/jruby_art-1.1.2/lib/jruby_art/runner.rb:63
     <top> at /home/jiii/.rvm/gems/jruby-9.1.2.0/gems/jruby_art-1.1.2/bin/k9:10
      load at org/jruby/RubyKernel.java:962
    <eval> at /home/jiii/.rvm/gems/jruby-9.1.2.0/bin/k9:1
      eval at org/jruby/RubyKernel.java:983
     <top> at /home/jiii/.rvm/gems/jruby-9.1.2.0/bin/jruby_executable_hooks:15

Environment

The other elements work well.

JRubyArt version 1.1.2
java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)

Sketches not starting with Processing b3

Hello,

I recently moved to Processing 3, and it seems that JRubyArt is not working on my machine.

Here is the message : 

k9 run jwishy.rb 
LoadError: load error: /home/jiii/.rvm/gems/jruby-9.0.0.0.pre1/gems/jruby_art-0.4.2/lib/jruby_art/app -- java.lang.NoClassDefFoundError: processing/core/PApplet
           require at org/jruby/RubyKernel.java:954
           require at /home/jiii/.rvm/rubies/jruby-9.0.0.0.pre1/lib/ruby/stdlib/rubygems/core_ext/kernel_require.rb:54
  require_relative at file:/home/jiii/.rvm/rubies/jruby-9.0.0.0.pre1/lib/jruby.jar!/jruby/kernel/kernel.rb:24
            (root) at /home/jiii/.rvm/gems/jruby-9.0.0.0.pre1/gems/jruby_art-0.4.2/lib/jruby_art/runners/base.rb:7
           require at org/jruby/RubyKernel.java:954
            (root) at /home/jiii/.rvm/rubies/jruby-9.0.0.0.pre1/lib/ruby/stdlib/rubygems/core_ext/kernel_require.rb:1
           require at /home/jiii/.rvm/rubies/jruby-9.0.0.0.pre1/lib/ruby/stdlib/rubygems/core_ext/kernel_require.rb:54
        __script__ at /home/jiii/.rvm/gems/jruby-9.0.0.0.pre1/gems/jruby_art-0.4.2/lib/jruby_art/runners/run.rb:1


jruby -v
jruby 9.0.0.0.pre1 (2.2.0p0) 2015-01-20 d537cab Java HotSpot(TM) 64-Bit Server VM 25.51-b03 on 1.8.0_51-b16 +jit [linux-amd64]

I have Processing 3.0b3, I tried with the one distributed on the website, and a custom build. Same error.
My version of JRuby is this from RVM :

jruby-9.0.0.0.pre1 [ x86_64 ]

Cheers,

Jeremy.

The binaries for the video library for MacOS are in macosx64 folder

No one complained about this, but I'm not sure how or if native binaries got picked up because we'd falsely assumed all mac binaries were in the macosx folder. I'm in process of major refactor of library loader, however I'm looking at quick fix first see video branch.

Detect OS Error on Windows

Environment

K9_VERSION: JRubyArt version 1.5.0
OS: MINGW64_NT-10.0 DESKTOP-22BGKLK 2.8.0(0.309/5/3) 2017-05-19 13:17 x86_64 Msys

Expected Behavior

I'd like k9 to work.

Actual Behavior

RuntimeError: unsupported os: "mswin"
RuntimeError: unsupported os: "mswin32"
RuntimeError: unsupported os: "mswin64"

Problem

The person who wrote this didn't know how Regexp#match? works.

# Snippet from lib/jruby_art/config.rb
  class HostOS
    def self.os
      detect_os = RbConfig::CONFIG['host_os']
      case detect_os
      when /mac|darwin/ then :mac
      when /gnueabihf/ then :arm 
      when /linux/ then :linux
      when /solaris|bsd/ then :unix
      else
        WIN_PATTERNS.find { |reg| reg.match?(detect_os) } # <- issue here
        raise "unsupported os: #{detect_os.inspect}" if Regexp.last_match.nil? # <- this will never be true
        :windows
      end
    end
  end

In the Regexp documentation it says, Regexp#match? specifically checks for a match without updating relevant variables such as Regexp#last_match and $~. Therefore, you will always raise on windows unless you've use a match somewhere else in your codebase.

Solution

# Explicitly check for a match. Set to explicit false if none found.
windows = WIN_PATTERNS.detect(false) { |reg| reg.match?(detect_os) }
# Raise unless a match was found.
raise "unsupported os: #{detect_os.inspect}" unless windows
:windows

Does it Work?

I actually had to patch that myself to even get k9 -v to work in order to report my environment for this issue so, yeah. I didn't think something this small needed a PR, but I can do one if needed.

Cheers!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.