laser-cutter 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 32ce72abddaaccd285d8dbcbf03b9a7644bf0a91
4
- data.tar.gz: df1bfc141e15b055e054dd70cbf921460f663ce2
3
+ metadata.gz: d78af71d854c6d20420b751eab1db6f8ab0052dc
4
+ data.tar.gz: 36373b9a7e2858dc489aa2c7ba4489f7db044b0e
5
5
  SHA512:
6
- metadata.gz: 14f27fcf968d47af5505d7430022c02b6b69c33aec68102822ad5b80bb6915e44783509e94e4e169b8ee5af840fdc1173116138b239ac184cb52521d99e5ab13
7
- data.tar.gz: 90c95f1f44c2ae2f0f15ae978faf130e2a3a62316bf405a719ef70fd26354695f0e905eedf9f440d2d3d591a5ec48ad8cf839c4302ee4fca1c449c217516498a
6
+ metadata.gz: 9e7ad6c1861371edf9e00856c68f79e9ccc0833918d442f42270b57afd4751fa0a462701ce280ec2e781d2a178a3236c5b3e518da9c5699930f2103af0ff63ec
7
+ data.tar.gz: 3bade22e2009f8ac1d1dbd2efb9c195323e6a66d094ff5e742b56a1457dee2e28f79b5d111cda64942ec66e7e1f4571dfa0dbcbdc3a27321ffed8732c7aa1717
data/README.md CHANGED
@@ -45,22 +45,25 @@ Usage: laser-cutter [options] -o filename.pdf
45
45
  eg: laser-cutter -i -s 1x1.5x2/0.125/0.125 -O -o box.pdf
46
46
 
47
47
  Specific Options:
48
- -w, --width WIDTH Internal width of the box
48
+ --width WIDTH Internal width of the box
49
49
  -h, --height HEIGHT Internal height of the box
50
50
  -d, --depth DEPTH Internal depth of the box
51
- -t, --thickness THICKNESS Thickness of the box material
51
+ --thickness THICKNESS Thickness of the box material
52
52
  -n, --notch NOTCH Preferred notch length (used only as a guide)
53
53
 
54
54
  -m, --margin MARGIN Margins from the edge of the document
55
55
  -p, --padding PADDING Space between the boxes on the page
56
- -S, --stroke WIDTH Numeric stroke width of the line
57
- -P, --page_size LETTER Page size, see --list-all-page-sizes for more info.
58
- -L, --page_layout portrait Page layout, other option is 'landscape'
56
+ -t, --stroke WIDTH Numeric stroke width of the line
57
+ -z, --page_size LETTER Page size, see --list-all-page-sizes for more info.
58
+ -y, --page_layout portrait Page layout, other option is 'landscape'
59
59
 
60
60
  -O, --open Open generated file with system viewer before exiting
61
+ -w, --write FILE Save current configuration to a file, use '-' for STDOUT
62
+ -r, --read FILE Read configuration from a file, use '-' for STDIN
61
63
  -u, --units UNITS Either 'mm' (default) or 'in'
62
64
 
63
- -A, --list-all-page-sizes Print all available page sizes with dimensions and exit
65
+ -l, --list-all-page-sizes Print all available page sizes with dimensions and exit
66
+ -M, --no-metadata Do not print box metadata on the PDF
64
67
  -v, --[no-]verbose Run verbosely
65
68
 
66
69
  --examples Show detailed usage examples
data/bin/laser-cutter CHANGED
@@ -19,7 +19,7 @@ module Laser
19
19
 
20
20
  Usage: laser-cutter [options] -o filename.pdf
21
21
  eg: laser-cutter -i -s 1x1.5x2/0.125/0.125 -O -o box.pdf
22
- EOF
22
+ EOF
23
23
 
24
24
  examples = <<-EOF
25
25
 
@@ -37,7 +37,7 @@ Examples:
37
37
 
38
38
  laser-cutter --list-all-page-sizes
39
39
  laser-cutter --list-all-page-sizes --inches
40
- EOF
40
+ EOF
41
41
  options = Hashie::Mash.new
42
42
  options.verbose = false
43
43
  options.units = 'mm'
@@ -45,40 +45,46 @@ EOF
45
45
  opt_parser = OptionParser.new do |opts|
46
46
  opts.banner = banner_text.blue
47
47
  opts.separator "Specific Options:"
48
- opts.on("-w", "--width WIDTH", "Internal width of the box") { |value| options.width = value }
49
- opts.on("-h", "--height HEIGHT", "Internal height of the box") { |value| options.height = value }
50
- opts.on("-d", "--depth DEPTH", "Internal depth of the box") { |value| options.depth= value }
51
- opts.on("-t", "--thickness THICKNESS", "Thickness of the box material") { |value| options.thickness = value }
52
- opts.on("-n", "--notch NOTCH", "Preferred notch length (used only as a guide)") { |value| options.notch = value }
48
+ opts.on("-w", "--width WIDTH", "Internal width of the box") { |value| options.width = value }
49
+ opts.on("-h", "--height HEIGHT", "Internal height of the box") { |value| options.height = value }
50
+ opts.on("-d", "--depth DEPTH", "Internal depth of the box") { |value| options.depth= value }
51
+ opts.on("-t", "--thickness THICKNESS", "Thickness of the box material") { |value| options.thickness = value }
52
+ opts.on("-n", "--notch NOTCH", "Preferred notch length (used only as a guide)") { |value| options.notch = value }
53
53
  opts.separator ""
54
- opts.on("-m", "--margin MARGIN", "Margins from the edge of the document") { |value| options.margin = value }
55
- opts.on("-p", "--padding PADDING", "Space between the boxes on the page") { |value| options.padding = value }
56
- opts.on("-S", "--stroke WIDTH", "Numeric stroke width of the line") { |value| options.stroke = value }
57
- opts.on("-P", "--page_size LETTER", "Page size, see --list-all-page-sizes for more info.") { |value| options.page_size = value }
58
- opts.on("-L", "--page_layout portrait", "Page layout, other option is 'landscape' ") { |value| options.page_layout = value }
54
+ opts.on("-m", "--margin MARGIN", "Margins from the edge of the document") { |value| options.margin = value }
55
+ opts.on("-p", "--padding PADDING", "Space between the boxes on the page") { |value| options.padding = value }
56
+ opts.on("-t", "--stroke WIDTH", "Numeric stroke width of the line") { |value| options.stroke = value }
57
+ opts.on("-z", "--page_size LETTER", "Page size, see --list-all-page-sizes for more info.") { |value| options.page_size = value }
58
+ opts.on("-y", "--page_layout portrait", "Page layout, other option is 'landscape' ") { |value| options.page_layout = value }
59
59
  opts.separator ""
60
60
  opts.on("-O", "--open", "Open generated file with system viewer before exiting") { |v| options.open = v }
61
- opts.on("-u", "--units UNITS", "Either 'mm' (default) or 'in'") { |value| options.units = value }
61
+ opts.on("-w", "--write FILE", "Save current configuration to a file, use '-' for STDOUT") { |v| options.write_file = v }
62
+ opts.on("-r", "--read FILE", "Read configuration from a file, use '-' for STDIN") { |v| options.read_file = v }
63
+ opts.on("-u", "--units UNITS", "Either 'mm' (default) or 'in'") { |value| options.units = value }
62
64
  opts.separator ""
63
- opts.on("-A", "--list-all-page-sizes", "Print all available page sizes with dimensions and exit") { |v| options.list_all_page_sizes = true }
65
+ opts.on("-l", "--list-all-page-sizes", "Print all available page sizes with dimensions and exit") { |v| options.list_all_page_sizes = true }
66
+ opts.on("-M", "--no-metadata", "Do not print box metadata on the PDF") { |value| options.metadata = value }
64
67
  opts.on("-v", "--[no-]verbose", "Run verbosely") { |v| options.verbose = v }
65
- opts.on("-m", "--[no-]metadata", "Print to the PDF metadata") { |value| options.metadata = value }
66
68
  opts.separator ""
67
- opts.on("--examples", "Show detailed usage examples") { puts opts; puts examples.yellow; exit }
69
+ opts.on("--examples", "Show detailed usage examples") { puts opts; puts examples.yellow; exit }
68
70
  opts.on("--help", "Show this message") { puts opts; exit }
69
- opts.on("--version", "Show version") { puts Laser::Cutter::VERSION; exit }
71
+ opts.on("--version", "Show version") { puts Laser::Cutter::VERSION; exit }
70
72
  opts.separator ""
71
73
  opts.separator "Common Options:"
72
- opts.on_tail("-o", "--file FILE", "Required output filename of the PDF") { |value| options.file = value }
74
+ opts.on_tail("-o", "--file FILE", "Required output filename of the PDF") { |value| options.file = value }
73
75
  opts.on_tail("-s", "--size WxHxD/T/N",
74
76
  "Combined internal dimensions: W = width, H = height,\n#{" " * 37}D = depth, T = thickness, N = notch length\n\n") do |size|
75
77
  options.size = size
76
78
  end
77
- opts.on_tail("-i", "--inches", "Switch measurements to inches instead of millimeters") { |value| options.units = 'in' }
79
+ opts.on_tail("-i", "--inches", "Switch measurements to inches instead of millimeters") { |value| options.units = 'in' }
78
80
  end
79
81
 
80
82
  opt_parser.parse!(args)
81
83
 
84
+ if options.read_file
85
+ read_options_from_file(options)
86
+ end
87
+
82
88
  config = Laser::Cutter::Configuration.new(options.to_hash)
83
89
  if config.list_all_page_sizes
84
90
  puts config.all_page_sizes
@@ -91,12 +97,52 @@ EOF
91
97
  end
92
98
 
93
99
  config.validate!
100
+
101
+ if config.write_file
102
+ write_options_to_file(config)
103
+ end
104
+
94
105
  config
95
106
  rescue OptionParser::InvalidOption, OptionParser::MissingArgument, Laser::Cutter::MissingOption => e
96
107
  puts opt_parser.banner.blue
97
108
  puts_error(e)
98
109
  exit 1
99
- end # end parse()
110
+ end
111
+
112
+ def self.read_options_from_file(options)
113
+ string = if options.read_file.eql?('-')
114
+ $stdin.read
115
+ elsif File.exist?(options.read_file)
116
+ File.read(options.read_file)
117
+ end
118
+ if string
119
+ options.replace(JSON.load(string))
120
+ end
121
+ rescue Exception => e
122
+ STDERR.puts "Error reading options from file #{options.read_file}, #{e.message}".red
123
+ if options.verbose
124
+ STDERR.puts e.backtrace.join("\n").red
125
+ end
126
+ exit 1
127
+ end
128
+
129
+ def self.write_options_to_file(options)
130
+ output = if options.write_file.eql?('-')
131
+ $stdout
132
+ elsif options.write_file
133
+ File.open(options.write_file, 'w')
134
+ else
135
+ nil
136
+ end
137
+ output.puts(JSON.pretty_generate(options))
138
+ output.close if output != $stdout
139
+ rescue Exception => e
140
+ STDERR.puts "Error writing options to file #{options.write_file}, #{e.message}".red
141
+ if options.verbose
142
+ STDERR.puts e.backtrace.join("\n").red
143
+ end
144
+ exit 1
145
+ end
100
146
  end
101
147
  end
102
148
  end # class OptParse
@@ -10,6 +10,7 @@ module Laser
10
10
 
11
11
  attr_accessor :front, :back, :top, :bottom, :left, :right
12
12
  attr_accessor :faces, :bounds, :conf, :corner_face
13
+ attr_accessor :metadata
13
14
 
14
15
  def initialize(config = {})
15
16
  self.dim = Geometry::Dimensions.new(config['width'], config['height'], config['depth'])
@@ -19,11 +20,11 @@ module Laser
19
20
  self.padding = config['padding']
20
21
  self.units = config['units']
21
22
 
23
+ self.metadata = Geometry::Point[config['metadata_width'] || 0, config['metadata_height'] || 0]
24
+
22
25
  create_faces! # generates dimensions for each side
23
26
  self.faces = [top, front, bottom, back, left, right]
24
27
 
25
- position_faces!
26
-
27
28
  self.conf = {
28
29
  valign: [ :out, :out, :out, :out, :in, :in],
29
30
  halign: [ :in, :out, :in, :out, :in, :in],
@@ -39,6 +40,8 @@ module Laser
39
40
  # Returns an flattened array of lines representing notched
40
41
  # rectangle.
41
42
  def notches
43
+ position_faces!
44
+
42
45
  corner_face = pick_corners_face
43
46
 
44
47
  notches = []
@@ -93,7 +96,7 @@ module Laser
93
96
  # | | | | | |
94
97
  # | left | | front: W x H | | right |
95
98
  # | D x H | | | | D x H |
96
- # +--------+ +-----------------+ +--------+
99
+ # +--------+ X-----------------+ +--------+
97
100
  # +-----------------+
98
101
  # | top : W x D |
99
102
  # +-----------------+
@@ -102,22 +105,23 @@ module Laser
102
105
  #___________________________________________________________________
103
106
 
104
107
  def position_faces!
105
- offset = padding + d + 3 * thickness
106
- left.x = top.y = thickness
107
- [bottom, front, top, back].each do |s|
108
- s.x = offset
109
- end
108
+ offset_x = [padding + d + 3 * thickness, metadata.x + 2 * thickness + padding].max
109
+ offset_y = [padding + d + 3 * thickness, metadata.y + 2 * thickness + padding].max
110
110
 
111
- right.x = 2 * padding + w + d + 5 * thickness
112
- [left, front, right].each do |s|
113
- s.y = offset
114
- end
111
+ # X Coordinate
112
+ left.x = offset_x - d - 2 * thickness - padding
113
+ right.x = offset_x + w + 2 * thickness + padding
115
114
 
116
- bottom.y = d + 2 * padding + h + 5 * thickness
117
- back.y = 3 * padding + 2 * d + h + 7*thickness
115
+ [bottom, front, top, back].each { |s| s.x = offset_x }
118
116
 
119
- faces.each(&:relocate!)
117
+ # Y Coordinate
118
+ top.y = offset_y - d - 2 * thickness - padding
119
+ bottom.y = offset_y + h + 2 * thickness + padding
120
+ back.y = bottom.y + d + 2 * thickness + padding
120
121
 
122
+ [left, front, right].each { |s| s.y = offset_y }
123
+
124
+ faces.each(&:relocate!)
121
125
  end
122
126
 
123
127
  def create_faces!
@@ -29,6 +29,7 @@ module Laser
29
29
  }
30
30
  }
31
31
 
32
+
32
33
  SIZE_REGEXP = /[\d\.]+x[\d\.]+x[\d\.]+\/[\d\.]+\/[\d\.]+/
33
34
 
34
35
  FLOATS = %w(width height depth thickness notch margin padding stroke)
@@ -64,18 +65,33 @@ module Laser
64
65
  end
65
66
 
66
67
  def page_size_values
67
- unit = 1.0 / 72.0 # PDF units per inch
68
- multiplier = (self.units == 'in') ? 1.0 : 25.4
69
68
  h = PDF::Core::PageGeometry::SIZES
70
69
  array = []
71
70
  h.keys.sort.each do |k|
72
- array << [ k,
73
- multiplier * h[k][0].to_f * unit,
74
- multiplier * h[k][1].to_f * unit ]
71
+ array << [k, value_from_units(h[k][0].to_f), value_from_units(h[k][1].to_f)]
75
72
  end
76
73
  array
77
74
  end
78
75
 
76
+ # if from_units is nil, we expect it to be in dots per inch (default
77
+ # measurements for Prawn
78
+ def value_from_units value, from_units = nil
79
+ multiplier = if from_units.nil?
80
+ if units.eql?('in')
81
+ 1.0 / 72.0 # PDF units per inch
82
+ else
83
+ 25.4 * 1.0 / 72.0
84
+ end
85
+ elsif self.units.eql?(from_units)
86
+ 1.0
87
+ elsif self.units.eql?('in') && from_units.eql?('mm')
88
+ (1.0 / 25.4)
89
+ else
90
+ 25.4
91
+ end
92
+ value.to_f * multiplier
93
+ end
94
+
79
95
  def all_page_sizes
80
96
  output = ""
81
97
  page_size_values.each do |k|
@@ -11,10 +11,16 @@ module Laser
11
11
  def x= value
12
12
  position.x = value
13
13
  end
14
+ def x
15
+ position.x
16
+ end
14
17
 
15
18
  def y= value
16
19
  position.y = value
17
20
  end
21
+ def y
22
+ position.y
23
+ end
18
24
 
19
25
  def move_to new_point
20
26
  self.position = new_point
@@ -6,6 +6,8 @@ module Laser
6
6
  class BoxRenderer < AbstractRenderer
7
7
  alias_method :box, :subject
8
8
 
9
+ META_RECT = Geometry::Rect.create(Geometry::Point[0, 0], 140, 150)
10
+
9
11
  def initialize(options = {})
10
12
  self.options = options
11
13
  self.subject = Laser::Cutter::Box.new(options)
@@ -27,15 +29,19 @@ module Laser
27
29
 
28
30
  renderer = self
29
31
 
30
- meta_color = "406080"
31
- meta_top = 150
32
+ meta_color = "4090E0"
33
+ meta_top_height = 50
32
34
  metadata = renderer.options.to_hash
33
- metadata.delete_if { |k| %w(verbose metadata open).include?(k) }
35
+ metadata.delete_if { |k| %w(verbose metadata open file).include?(k) }
36
+ if options.metadata
37
+ coords = [ META_RECT.p2.x, META_RECT.p2.y ].map{|a| options.value_from_units(a)}
38
+ box.metadata = Geometry::Point.new(coords)
39
+ end
34
40
  pdf.instance_eval do
35
41
  self.line_width = renderer.options.stroke.send(renderer.options.units.to_sym)
36
42
  if renderer.options.metadata
37
43
  float do
38
- bounding_box([0, meta_top], :width => 140, :height => 150) do
44
+ bounding_box([0, META_RECT.h], :width => META_RECT.w, :height => META_RECT.h) do
39
45
  stroke_color meta_color
40
46
  stroke_bounds
41
47
  indent 10 do
@@ -44,11 +50,13 @@ module Laser
44
50
  end
45
51
  end
46
52
  float do
47
- bounding_box([0, 100], :width => 140, :height => 100) do
53
+ bounding_box([0, META_RECT.h - meta_top_height],
54
+ :width => META_RECT.w,
55
+ :height => META_RECT.h - meta_top_height) do
48
56
  stroke_color meta_color
49
57
  stroke_bounds
50
58
  float do
51
- bounding_box([0, 100], :width => 70, :height => 100) do
59
+ bounding_box([0, META_RECT.h - meta_top_height], :width => 70, :height => META_RECT.h - meta_top_height) do
52
60
  indent 10 do
53
61
  font('Helvetica', :size => 6) do
54
62
  out = JSON.pretty_generate(metadata).gsub(/[\{\}",]/, '').gsub(/:.*\n/x, "\n")
@@ -58,7 +66,7 @@ module Laser
58
66
  end
59
67
  end
60
68
  float do
61
- bounding_box([60, 100], :width => 70, :height => 100) do
69
+ bounding_box([60, META_RECT.h - meta_top_height], :width => 70, :height => META_RECT.h - meta_top_height) do
62
70
  indent 10 do
63
71
  font('Helvetica', :size => 6) do
64
72
  out = JSON.pretty_generate(metadata).gsub(/[\{\}",]/, '').gsub(/\n?.*:/x, "\n:")
@@ -1,5 +1,5 @@
1
1
  module Laser
2
2
  module Cutter
3
- VERSION = "0.4.3"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -17,18 +17,18 @@ module Laser
17
17
  end
18
18
  context '#validate' do
19
19
  context 'missing options' do
20
- let(:opts) { {"height" => "23"} }
21
- it 'should be able to validate missing options' do
22
- expect(config.height).to eql(23.0)
23
- expect { config.validate! }.to raise_error(Laser::Cutter::MissingOption)
24
- end
20
+ let(:opts) { {"height" => "23"} }
21
+ it 'should be able to validate missing options' do
22
+ expect(config.height).to eql(23.0)
23
+ expect { config.validate! }.to raise_error(Laser::Cutter::MissingOption)
24
+ end
25
25
  end
26
26
  context 'zero options' do
27
- let(:opts) { {"size" => "2.0x0.0x2/0.125/0.5", "inches" => true, 'file' => '/tmp/a'} }
28
- it 'should be able to validate missing options' do
29
- expect(config.height).to eql(0.0)
30
- expect { config.validate! }.to raise_error(Laser::Cutter::ZeroValueNotAllowed)
31
- end
27
+ let(:opts) { {"size" => "2.0x0.0x2/0.125/0.5", "inches" => true, 'file' => '/tmp/a'} }
28
+ it 'should be able to validate missing options' do
29
+ expect(config.height).to eql(0.0)
30
+ expect { config.validate! }.to raise_error(Laser::Cutter::ZeroValueNotAllowed)
31
+ end
32
32
  end
33
33
  end
34
34
  context '#list_page_sizes' do
@@ -48,36 +48,56 @@ module Laser
48
48
  end
49
49
  end
50
50
 
51
- context "#default to mm for incorrect units" do
51
+ context 'when invalid units are provided' do
52
52
  let(:opts) { {"size" => "2x3x2/0.125/0.5", "units" => 'xx'} }
53
53
  it 'should default to millimeters' do
54
54
  expect(config.units).to eql('mm')
55
55
  end
56
56
  end
57
57
 
58
- context "#change_units" do
59
- context "from inches" do
60
- let(:opts) { {"size" => "2.0x3x2/0.125/0.5", 'padding' => '4.2', "units" => 'in'} }
61
- it "should convert to mm" do
62
- expect(config.width).to eql(2.0)
63
- config.change_units('in')
64
- expect(config.width).to eql(2.0)
65
- config.change_units('mm')
66
- expect(config.width).to eql(50.8)
67
- expect(config.padding).to eql(106.68)
68
- expect(config.units).to eql('mm')
58
+ context 'when converting between units' do
59
+ context 'a single value' do
60
+ context 'to inches' do
61
+ let(:opts) { {'units' => 'in'} }
62
+ it 'should be correct' do
63
+ expect(config.value_from_units(150)).to be_within(0.0001).of(150.0/72.0)
64
+ expect(config.value_from_units(150, 'mm')).to be_within(0.0001).of(150.0/25.4)
65
+ expect(config.value_from_units(150, 'in')).to be_within(0.0001).of(150.0)
66
+ end
67
+ end
68
+ context 'to mm' do
69
+ let(:opts) { {'units' => 'mm'} }
70
+ it 'should be correct' do
71
+ expect(config.value_from_units(150)).to be_within(0.0001).of(25.4 * 150.0 / 72.0)
72
+ expect(config.value_from_units(150, 'in')).to be_within(0.0001).of(150.0 * 25.4)
73
+ expect(config.value_from_units(150, 'mm')).to be_within(0.0001).of(150.0)
74
+ end
69
75
  end
70
76
  end
71
- context "from mm" do
72
- let(:opts) { {"size" => "20.0x30.0x40.0/5/5", 'margin' => '10.0', "units" => 'mm'} }
73
- it "should convert to inches" do
74
- expect(config.width).to eql(20.0)
75
- config.change_units('mm')
76
- expect(config.width).to eql(20.0)
77
- config.change_units('in')
78
- expect(config.width).to be_within(0.00001).of(0.787401575)
79
- expect(config.margin).to be_within(0.00001).of(0.393700787)
80
- expect(config.units).to eql('in')
77
+ context 'all config values' do
78
+ context "to mm" do
79
+ let(:opts) { {'size' => "2.0x3x2/0.125/0.5", 'padding' => '4.2', "units" => 'in'} }
80
+ it 'should be correct' do
81
+ expect(config.width).to eql(2.0)
82
+ config.change_units('in')
83
+ expect(config.width).to eql(2.0)
84
+ config.change_units('mm')
85
+ expect(config.width).to eql(50.8)
86
+ expect(config.padding).to eql(106.68)
87
+ expect(config.units).to eql('mm')
88
+ end
89
+ end
90
+ context 'to inches' do
91
+ let(:opts) { {'size' => "20.0x30.0x40.0/5/5", 'margin' => '10.0', "units" => 'mm'} }
92
+ it 'should be correct' do
93
+ expect(config.width).to eql(20.0)
94
+ config.change_units('mm')
95
+ expect(config.width).to eql(20.0)
96
+ config.change_units('in')
97
+ expect(config.width).to be_within(0.00001).of(0.787401575)
98
+ expect(config.margin).to be_within(0.00001).of(0.393700787)
99
+ expect(config.units).to eql('in')
100
+ end
81
101
  end
82
102
  end
83
103
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: laser-cutter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Gredeskoul
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-28 00:00:00.000000000 Z
11
+ date: 2014-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: prawn