laser-cutter 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/LICENSE.txt +22 -0
- data/README.md +67 -0
- data/Rakefile +2 -0
- data/bin/laser-cutter +110 -0
- data/laser-cutter.gemspec +29 -0
- data/lib/laser-cutter.rb +12 -0
- data/lib/laser-cutter/box.rb +136 -0
- data/lib/laser-cutter/configuration.rb +56 -0
- data/lib/laser-cutter/geometry.rb +14 -0
- data/lib/laser-cutter/geometry/dimensions.rb +30 -0
- data/lib/laser-cutter/geometry/edge.rb +33 -0
- data/lib/laser-cutter/geometry/notched_path.rb +46 -0
- data/lib/laser-cutter/geometry/path_generator.rb +132 -0
- data/lib/laser-cutter/geometry/point.rb +57 -0
- data/lib/laser-cutter/geometry/shape.rb +36 -0
- data/lib/laser-cutter/geometry/shape/line.rb +66 -0
- data/lib/laser-cutter/geometry/shape/rect.rb +59 -0
- data/lib/laser-cutter/geometry/tuple.rb +89 -0
- data/lib/laser-cutter/renderer.rb +19 -0
- data/lib/laser-cutter/renderer/box_renderer.rb +69 -0
- data/lib/laser-cutter/renderer/line_renderer.rb +16 -0
- data/lib/laser-cutter/renderer/rect_renderer.rb +17 -0
- data/lib/laser-cutter/version.rb +5 -0
- data/spec/box_spec.rb +31 -0
- data/spec/configuration_spec.rb +28 -0
- data/spec/dimensions_spec.rb +28 -0
- data/spec/line_spec.rb +79 -0
- data/spec/path_generator_spec.rb +94 -0
- data/spec/point_spec.rb +74 -0
- data/spec/rect_spec.rb +53 -0
- data/spec/renderer_spec.rb +60 -0
- data/spec/spec_helper.rb +26 -0
- metadata +177 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
module Laser
|
4
|
+
module Cutter
|
5
|
+
module Geometry
|
6
|
+
describe PathGenerator do
|
7
|
+
let(:notch) { 2 }
|
8
|
+
let(:thickness) { 1 }
|
9
|
+
let(:center_out) { true }
|
10
|
+
let(:fill_edge) { true }
|
11
|
+
let(:outside) { Line.new(from: [0, 0], to: [10, 0]) }
|
12
|
+
let(:inside) { Line.new(from: [1, 1], to: [9, 1]) }
|
13
|
+
let(:edge) { Edge.new(outside, inside, notch) }
|
14
|
+
let(:generator) { PathGenerator.new(notch_width: notch,
|
15
|
+
thickness: thickness,
|
16
|
+
center_out: center_out,
|
17
|
+
fill_edge: fill_edge) }
|
18
|
+
context 'edge' do
|
19
|
+
it 'should properly calculate notch size' do
|
20
|
+
expect(edge.notch_width).to be_within(0.001).of(1.6)
|
21
|
+
end
|
22
|
+
context 'edge cases with the edge :)' do
|
23
|
+
let(:notch) { 15 } # too big
|
24
|
+
it 'should properly handle edge cases' do
|
25
|
+
# 3 is the minimum number of notches we support per side
|
26
|
+
expect(edge.notch_width).to be_within(0.001).of(8.0/3.0)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'alternating iterator' do
|
32
|
+
let(:iterator) { InfiniteIterator.new([:a, :b, :c]) }
|
33
|
+
it 'returns things in alternating order' do
|
34
|
+
expect(iterator.next).to eq(:a)
|
35
|
+
expect(iterator.next).to eq(:b)
|
36
|
+
expect(iterator.next).to eq(:c)
|
37
|
+
expect(iterator.next).to eq(:a)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'shift definition' do
|
42
|
+
|
43
|
+
it 'correctly defines shifts' do
|
44
|
+
shifts = generator.send(:define_shifts, edge)
|
45
|
+
expect(edge.outside.length).to eql(10.0)
|
46
|
+
expect(edge.inside.length).to eql(8.0)
|
47
|
+
expect(edge.notch_width).to be_within(0.001).of(1.6)
|
48
|
+
expect(edge.notch_count).to eql(5)
|
49
|
+
expect(shifts.size).to eql(11)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
context 'path generation' do
|
55
|
+
# let(:outside) { Line.new(
|
56
|
+
# from: inside.p1.move_by(-thickness, -thickness),
|
57
|
+
# to: inside.p2.move_by(thickness, -thickness)) }
|
58
|
+
|
59
|
+
context 'center out' do
|
60
|
+
it 'generates correct path vertices' do
|
61
|
+
inside.freeze
|
62
|
+
expect(inside.p1).to_not eql(inside.p2)
|
63
|
+
path = generator.path(edge)
|
64
|
+
expect(path).to be_a_kind_of(NotchedPath)
|
65
|
+
expect(path.size).to be > 5
|
66
|
+
|
67
|
+
expect(Line.new(path.vertices.first, inside.p1).length).to be_within(0.001).of(0)
|
68
|
+
expect(Line.new(path.vertices.last, inside.p2).length).to be_within(0.001).of(0)
|
69
|
+
|
70
|
+
# Sanity Check
|
71
|
+
expect(Point.new(1, 1)).to eql(inside.p1)
|
72
|
+
expect(Point.new(9, 1)).to eql(inside.p2)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'generates correct lines' do
|
76
|
+
path = generator.path(edge)
|
77
|
+
lines = path.create_lines
|
78
|
+
expect(path.size).to eq(12)
|
79
|
+
expect(lines.size).to be > 1
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'remove dupes' do
|
85
|
+
let(:a) { [1,5,3,1,2,2,2,2 ] }
|
86
|
+
it 'should remove dups' do
|
87
|
+
expect(PathGenerator.deduplicate(a)).to eql([3,5])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/spec/point_spec.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
module Laser
|
4
|
+
module Cutter
|
5
|
+
module Geometry
|
6
|
+
describe Point do
|
7
|
+
let(:p1) { Point.new(1, 2) }
|
8
|
+
context 'creation' do
|
9
|
+
context 'from string' do
|
10
|
+
it 'should instantiate correctly' do
|
11
|
+
expect(Point.new "1,2").to eql(p1)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'from a point' do
|
16
|
+
it 'should instantiate correctly' do
|
17
|
+
expect(Point.new(Point.new("1,2"))).to eql(p1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'from an array' do
|
22
|
+
it 'should properly duplicate underlying coordinates and not bug out' do
|
23
|
+
a = [1, 2]
|
24
|
+
p2 = Point.new(a)
|
25
|
+
expect(p2).to eql(p1)
|
26
|
+
a.shift # modify original array
|
27
|
+
# should not affect our point
|
28
|
+
expect(p2).to eql(p1)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should create point from class method' do
|
32
|
+
expect(Point[1,2]).to eql(p1)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'from a hash' do
|
37
|
+
it 'should instantiate correctly' do
|
38
|
+
expect(Point.new(x: 1, y: 2)).to eql(p1)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'move by' do
|
44
|
+
it 'should move properly' do
|
45
|
+
p = p1.move_by(10, -2)
|
46
|
+
expect(p.x).to be_within(0.001).of(11)
|
47
|
+
expect(p.y).to be_within(0.001).of(0)
|
48
|
+
end
|
49
|
+
it 'should move cloned version properly' do
|
50
|
+
p2 = p1.clone.move_by(10, -2)
|
51
|
+
expect(p2.x).to be_within(0.001).of(11)
|
52
|
+
expect(p2.y).to be_within(0.001).of(0)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'ordering and equality' do
|
57
|
+
let(:p1) { Point[0,0]}
|
58
|
+
let(:p2) { Point[10,0]}
|
59
|
+
let(:p3) { Point[0,10]}
|
60
|
+
let(:p4) { Point[10,10]}
|
61
|
+
let(:p5) { Point[-1,-1]}
|
62
|
+
it 'should propertly sort' do
|
63
|
+
expect([p3,p2,p1,p4,p5].sort).to eql([p5,p1,p3,p2,p4])
|
64
|
+
end
|
65
|
+
it 'should detect equality' do
|
66
|
+
expect(p1).to_not eql(p2)
|
67
|
+
expect(p2).to eql(Point[10,0])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/spec/rect_spec.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
module Laser
|
4
|
+
module Cutter
|
5
|
+
module Geometry
|
6
|
+
describe Rect do
|
7
|
+
let(:p1) { Point[ 1.0, 3.0] }
|
8
|
+
let(:p2) { Point[11.0, 23.0] }
|
9
|
+
|
10
|
+
let(:rect1) { Rect.new(p1, p2) }
|
11
|
+
|
12
|
+
context 'creating' do
|
13
|
+
it 'creates from a class method' do
|
14
|
+
expect(Rect[p1, p2]).to eql(rect1)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'sides' do
|
19
|
+
it 'sets correctly all attributes' do
|
20
|
+
expect(rect1.w).to eql(10.0)
|
21
|
+
expect(rect1.h).to eql(20.0)
|
22
|
+
expect(rect1.position).to eql(rect1.vertices[0])
|
23
|
+
expect(rect1.p2).to eql(rect1.vertices[2])
|
24
|
+
end
|
25
|
+
it 'it generates four side lines' do
|
26
|
+
expect(rect1.sides.size).to eql(4)
|
27
|
+
expect(rect1.sides.first).to be_kind_of(Line)
|
28
|
+
expect(rect1.sides.first.p1).to eql(p1)
|
29
|
+
expect(rect1.sides[0].p1.to_s).to eql("{1.00000,3.00000}")
|
30
|
+
expect(rect1.sides[1].p1.to_s).to eql("{11.00000,3.00000}")
|
31
|
+
expect(rect1.sides[2].p1).to eql(p1.move_by(10, 20))
|
32
|
+
end
|
33
|
+
it 'can be moved' do
|
34
|
+
expect(rect1.sides[0].p1.to_s).to eql("{1.00000,3.00000}")
|
35
|
+
rect1.x = 1000
|
36
|
+
rect1.y = 100
|
37
|
+
rect1.relocate!
|
38
|
+
|
39
|
+
expect(rect1.sides[0].p1.to_s).to eql("{1000.00000,100.00000}")
|
40
|
+
expect(rect1.sides[1].p1.to_s).to eql("{1010.00000,100.00000}")
|
41
|
+
expect(rect1.sides[2].p1.to_s).to eql("{1010.00000,120.00000}")
|
42
|
+
expect(rect1.sides[3].p1.to_s).to eql("{1000.00000,120.00000}")
|
43
|
+
|
44
|
+
expect(rect1.sides[0].p2.to_s).to eql("{1010.00000,100.00000}")
|
45
|
+
expect(rect1.sides[1].p2.to_s).to eql("{1010.00000,120.00000}")
|
46
|
+
expect(rect1.sides[2].p2.to_s).to eql("{1000.00000,120.00000}")
|
47
|
+
expect(rect1.sides[3].p2.to_s).to eql("{1000.00000,100.00000}")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
module Laser
|
4
|
+
module Cutter
|
5
|
+
module Renderer
|
6
|
+
describe 'BoxRenderer' do
|
7
|
+
context '#render' do
|
8
|
+
let(:box) { Laser::Cutter::Box.new(config) }
|
9
|
+
let(:renderer) { BoxRenderer.new(box, config) }
|
10
|
+
let(:file) { File.expand_path("../../laser-cutter-pdf-test.#{$$}.pdf", __FILE__) }
|
11
|
+
|
12
|
+
def render_file filename
|
13
|
+
expect(!File.exists?(filename))
|
14
|
+
renderer.render
|
15
|
+
expect(File.exist?(filename))
|
16
|
+
expect(File.size(filename) > 0)
|
17
|
+
ensure
|
18
|
+
File.delete(filename)
|
19
|
+
expect(!File.exists?(filename))
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'metric' do
|
23
|
+
let(:config) { Laser::Cutter::Configuration.new(
|
24
|
+
'width' => 50, 'height' => 60, 'depth' => 20, 'thickness' => 6,
|
25
|
+
'margin' => 5, 'padding' => 3, 'notch' => 10, 'file' => file) }
|
26
|
+
|
27
|
+
it 'should be able to generate a PDF file' do
|
28
|
+
render_file file
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'imperial' do
|
33
|
+
context 'margins and padding provided' do
|
34
|
+
let(:config) { Laser::Cutter::Configuration.new(
|
35
|
+
'width' => 2.5, 'height' => 3.5, 'depth' => 2.0, 'thickness' => 0.125,
|
36
|
+
'margin' => 0, 'padding' => 0.125, 'notch' => 0.25, 'file' => file,
|
37
|
+
'units' => 'in') }
|
38
|
+
|
39
|
+
it 'should be able to generate a PDF file' do
|
40
|
+
render_file file
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'margins and padding are defaults' do
|
45
|
+
let(:config) { Laser::Cutter::Configuration.new(
|
46
|
+
'width' => 2.5, 'height' => 2, 'depth' => 2.0, 'thickness' => 0.125,
|
47
|
+
'notch' => 0.25, 'file' => file, 'units' => 'in') }
|
48
|
+
|
49
|
+
it 'should be able to generate a PDF file' do
|
50
|
+
render_file file
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __FILE__)
|
9
|
+
require 'rubygems'
|
10
|
+
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
|
11
|
+
require 'laser-cutter'
|
12
|
+
|
13
|
+
#Dir['spec/support/**/*.rb'].each { |filename| require_relative "../#{filename}" }
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
17
|
+
config.run_all_when_everything_filtered = true
|
18
|
+
config.filter_run :focus
|
19
|
+
|
20
|
+
# Run specs in random order to surface order dependencies. If you find an
|
21
|
+
# order dependency and want to debug it, you can fix the order by providing
|
22
|
+
# the seed, which is printed after each run.
|
23
|
+
# --seed 1234
|
24
|
+
config.order = 'random'
|
25
|
+
end
|
26
|
+
|
metadata
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: laser-cutter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Konstantin Gredeskoul
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: prawn
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: hashie
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: colored
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.6'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.6'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: ''
|
98
|
+
email:
|
99
|
+
- kigster@gmail.com
|
100
|
+
executables:
|
101
|
+
- laser-cutter
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".rspec"
|
107
|
+
- ".ruby-version"
|
108
|
+
- ".travis.yml"
|
109
|
+
- Gemfile
|
110
|
+
- LICENSE
|
111
|
+
- LICENSE.txt
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- bin/laser-cutter
|
115
|
+
- laser-cutter.gemspec
|
116
|
+
- lib/laser-cutter.rb
|
117
|
+
- lib/laser-cutter/box.rb
|
118
|
+
- lib/laser-cutter/configuration.rb
|
119
|
+
- lib/laser-cutter/geometry.rb
|
120
|
+
- lib/laser-cutter/geometry/dimensions.rb
|
121
|
+
- lib/laser-cutter/geometry/edge.rb
|
122
|
+
- lib/laser-cutter/geometry/notched_path.rb
|
123
|
+
- lib/laser-cutter/geometry/path_generator.rb
|
124
|
+
- lib/laser-cutter/geometry/point.rb
|
125
|
+
- lib/laser-cutter/geometry/shape.rb
|
126
|
+
- lib/laser-cutter/geometry/shape/line.rb
|
127
|
+
- lib/laser-cutter/geometry/shape/rect.rb
|
128
|
+
- lib/laser-cutter/geometry/tuple.rb
|
129
|
+
- lib/laser-cutter/renderer.rb
|
130
|
+
- lib/laser-cutter/renderer/box_renderer.rb
|
131
|
+
- lib/laser-cutter/renderer/line_renderer.rb
|
132
|
+
- lib/laser-cutter/renderer/rect_renderer.rb
|
133
|
+
- lib/laser-cutter/version.rb
|
134
|
+
- spec/box_spec.rb
|
135
|
+
- spec/configuration_spec.rb
|
136
|
+
- spec/dimensions_spec.rb
|
137
|
+
- spec/line_spec.rb
|
138
|
+
- spec/path_generator_spec.rb
|
139
|
+
- spec/point_spec.rb
|
140
|
+
- spec/rect_spec.rb
|
141
|
+
- spec/renderer_spec.rb
|
142
|
+
- spec/spec_helper.rb
|
143
|
+
homepage: ''
|
144
|
+
licenses:
|
145
|
+
- MIT
|
146
|
+
metadata: {}
|
147
|
+
post_install_message:
|
148
|
+
rdoc_options: []
|
149
|
+
require_paths:
|
150
|
+
- lib
|
151
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
requirements: []
|
162
|
+
rubyforge_project:
|
163
|
+
rubygems_version: 2.2.2
|
164
|
+
signing_key:
|
165
|
+
specification_version: 4
|
166
|
+
summary: Creates box outlines for laser-cut boxes.
|
167
|
+
test_files:
|
168
|
+
- spec/box_spec.rb
|
169
|
+
- spec/configuration_spec.rb
|
170
|
+
- spec/dimensions_spec.rb
|
171
|
+
- spec/line_spec.rb
|
172
|
+
- spec/path_generator_spec.rb
|
173
|
+
- spec/point_spec.rb
|
174
|
+
- spec/rect_spec.rb
|
175
|
+
- spec/renderer_spec.rb
|
176
|
+
- spec/spec_helper.rb
|
177
|
+
has_rdoc:
|