prawn 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +2 -1
- data/Rakefile +12 -0
- data/lib/prawn.rb +9 -21
- data/lib/prawn/document.rb +95 -68
- data/lib/prawn/document/bounding_box.rb +22 -4
- data/lib/prawn/document/column_box.rb +2 -0
- data/lib/prawn/document/graphics_state.rb +1 -1
- data/lib/prawn/document/internals.rb +2 -2
- data/lib/prawn/document/snapshot.rb +2 -1
- data/lib/prawn/document/span.rb +2 -0
- data/lib/prawn/encoding.rb +1 -1
- data/lib/prawn/font.rb +89 -75
- data/lib/prawn/font/afm.rb +3 -0
- data/lib/prawn/font/dfont.rb +1 -0
- data/lib/prawn/font/ttf.rb +2 -0
- data/lib/prawn/font_metric_cache.rb +3 -1
- data/lib/prawn/graphics.rb +2 -14
- data/lib/prawn/graphics/cap_style.rb +1 -0
- data/lib/prawn/graphics/color.rb +1 -0
- data/lib/prawn/graphics/dash.rb +3 -2
- data/lib/prawn/graphics/join_style.rb +2 -0
- data/lib/prawn/graphics/patterns.rb +1 -0
- data/lib/prawn/graphics/transformation.rb +1 -0
- data/lib/prawn/graphics/transparency.rb +2 -0
- data/lib/prawn/image_handler.rb +2 -0
- data/lib/prawn/images.rb +5 -0
- data/lib/prawn/images/image.rb +1 -0
- data/lib/prawn/images/jpg.rb +3 -0
- data/lib/prawn/images/png.rb +2 -0
- data/lib/prawn/layout.rb +8 -13
- data/lib/prawn/layout/grid.rb +15 -3
- data/lib/prawn/measurement_extensions.rb +4 -0
- data/lib/prawn/measurements.rb +2 -0
- data/lib/prawn/outline.rb +3 -1
- data/lib/prawn/repeater.rb +3 -1
- data/lib/prawn/security.rb +15 -7
- data/lib/prawn/security/arcfour.rb +52 -0
- data/lib/prawn/soft_mask.rb +3 -1
- data/lib/prawn/stamp.rb +2 -0
- data/lib/prawn/table.rb +2 -0
- data/lib/prawn/table/cell.rb +4 -1
- data/lib/prawn/table/cell/image.rb +1 -2
- data/lib/prawn/table/cell/in_table.rb +2 -0
- data/lib/prawn/table/cell/span_dummy.rb +1 -0
- data/lib/prawn/table/cells.rb +7 -2
- data/lib/prawn/table/column_width_calculator.rb +8 -2
- data/lib/prawn/text.rb +4 -2
- data/lib/prawn/text/box.rb +3 -0
- data/lib/prawn/text/formatted/arranger.rb +2 -0
- data/lib/prawn/text/formatted/box.rb +55 -50
- data/lib/prawn/text/formatted/fragment.rb +2 -0
- data/lib/prawn/text/formatted/line_wrap.rb +1 -0
- data/lib/prawn/text/formatted/parser.rb +2 -0
- data/lib/prawn/text/formatted/wrap.rb +2 -0
- data/lib/prawn/utilities.rb +5 -3
- data/manual/graphics/common_lines.rb +2 -0
- data/manual/text/group.rb +2 -0
- data/manual/text/text.rb +1 -1
- data/prawn.gemspec +4 -3
- data/spec/grid_spec.rb +11 -0
- data/spec/object_store_spec.rb +1 -96
- data/spec/reference_spec.rb +0 -57
- data/spec/spec_helper.rb +7 -0
- data/spec/table_spec.rb +26 -0
- metadata +172 -185
- data/lib/pdf/core.rb +0 -35
- data/lib/pdf/core/annotations.rb +0 -60
- data/lib/pdf/core/byte_string.rb +0 -9
- data/lib/pdf/core/destinations.rb +0 -90
- data/lib/pdf/core/document_state.rb +0 -79
- data/lib/pdf/core/filter_list.rb +0 -51
- data/lib/pdf/core/filters.rb +0 -36
- data/lib/pdf/core/graphics_state.rb +0 -89
- data/lib/pdf/core/literal_string.rb +0 -16
- data/lib/pdf/core/name_tree.rb +0 -177
- data/lib/pdf/core/object_store.rb +0 -311
- data/lib/pdf/core/outline.rb +0 -315
- data/lib/pdf/core/page.rb +0 -212
- data/lib/pdf/core/page_geometry.rb +0 -126
- data/lib/pdf/core/pdf_object.rb +0 -99
- data/lib/pdf/core/reference.rb +0 -103
- data/lib/pdf/core/stream.rb +0 -98
- data/lib/pdf/core/text.rb +0 -275
- data/lib/prawn/templates.rb +0 -75
- data/spec/filters_spec.rb +0 -34
- data/spec/name_tree_spec.rb +0 -112
- data/spec/pdf_object_spec.rb +0 -172
- data/spec/stream_spec.rb +0 -58
- data/spec/template_spec_obsolete.rb +0 -352
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97e70822529ce4c7edb736c4c57f2c6a015ddb02
|
4
|
+
data.tar.gz: 685b8386302414f80c7ac7a7c714987e0a8d2ff9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dad2cab43e9fdda28fa1a4c364507fd7ecff16d2120a65b3c8ab9a07130d8c6fd73a6a9ae44a98be6faad680b20e894e9d6d1d8b88a870b824f08b9a5a28e527
|
7
|
+
data.tar.gz: 3c61667b13c7ed6aa815728ec777e8d12b04f7219184682d8b2b37d9fe046c942529c957f35597c3ccfe2a48131c701834d209a5cd77a454be9395e695450be3
|
data/.yardopts
CHANGED
data/Rakefile
CHANGED
@@ -40,3 +40,15 @@ Gem::PackageTask.new(spec) do |pkg|
|
|
40
40
|
pkg.need_zip = true
|
41
41
|
pkg.need_tar = true
|
42
42
|
end
|
43
|
+
|
44
|
+
desc "Run a console with Prawn loaded"
|
45
|
+
task :console do
|
46
|
+
require 'irb'
|
47
|
+
require 'irb/completion'
|
48
|
+
require_relative 'lib/prawn'
|
49
|
+
Prawn.debug = true
|
50
|
+
|
51
|
+
ARGV.clear
|
52
|
+
IRB.start
|
53
|
+
end
|
54
|
+
|
data/lib/prawn.rb
CHANGED
@@ -1,26 +1,13 @@
|
|
1
1
|
# Welcome to Prawn, the best PDF Generation library ever.
|
2
2
|
# This documentation covers user level functionality.
|
3
3
|
#
|
4
|
-
# Those looking to contribute code or write extensions should look
|
5
|
-
# into the lib/prawn/core/* source tree.
|
6
|
-
#
|
7
|
-
%w[ttfunk/lib].each do |dep|
|
8
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__) + "/../../vendor/#{dep}")
|
9
|
-
end
|
10
|
-
|
11
|
-
begin
|
12
|
-
require 'ttfunk'
|
13
|
-
rescue LoadError
|
14
|
-
puts "Failed to load ttfunk. If you are running Prawn from git:"
|
15
|
-
puts " git submodule init"
|
16
|
-
puts " git submodule update"
|
17
|
-
exit
|
18
|
-
end
|
19
|
-
|
20
4
|
require "set"
|
21
5
|
|
6
|
+
require 'ttfunk'
|
7
|
+
require "pdf/core"
|
8
|
+
|
22
9
|
module Prawn
|
23
|
-
VERSION = "0.
|
10
|
+
VERSION = "0.15.0"
|
24
11
|
|
25
12
|
extend self
|
26
13
|
|
@@ -33,6 +20,8 @@ module Prawn
|
|
33
20
|
#
|
34
21
|
BASEDIR = File.expand_path(File.join(dir, '..'))
|
35
22
|
DATADIR = File.expand_path(File.join(dir, '..', 'data'))
|
23
|
+
|
24
|
+
FLOAT_PRECISION = 1.0e-9
|
36
25
|
|
37
26
|
# Whe set to true, Prawn will verify hash options to ensure only valid keys
|
38
27
|
# are used. Off by default.
|
@@ -43,9 +32,9 @@ module Prawn
|
|
43
32
|
# Detected unknown option(s): [:tomato]
|
44
33
|
# Accepted options are: [:page_size, :page_layout, :left_margin, ...]
|
45
34
|
#
|
46
|
-
attr_accessor :debug
|
35
|
+
attr_accessor :debug # @private
|
47
36
|
|
48
|
-
def verify_options(accepted, actual)
|
37
|
+
def verify_options(accepted, actual) # @private
|
49
38
|
return unless debug || $DEBUG
|
50
39
|
unless (act=Set[*actual.keys]).subset?(acc=Set[*accepted])
|
51
40
|
raise Prawn::Errors::UnknownOption,
|
@@ -55,7 +44,7 @@ module Prawn
|
|
55
44
|
yield if block_given?
|
56
45
|
end
|
57
46
|
|
58
|
-
module Configurable
|
47
|
+
module Configurable # @private
|
59
48
|
def configuration(*args)
|
60
49
|
@config ||= Marshal.load(Marshal.dump(default_configuration))
|
61
50
|
if Hash === args[0]
|
@@ -75,7 +64,6 @@ end
|
|
75
64
|
|
76
65
|
require_relative "prawn/errors"
|
77
66
|
|
78
|
-
require_relative "pdf/core"
|
79
67
|
|
80
68
|
require_relative "prawn/utilities"
|
81
69
|
require_relative "prawn/text"
|
data/lib/prawn/document.rb
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
8
|
|
9
9
|
require "stringio"
|
10
|
+
|
10
11
|
require_relative "document/bounding_box"
|
11
12
|
require_relative "document/column_box"
|
12
13
|
require_relative "document/internals"
|
@@ -62,6 +63,8 @@ module Prawn
|
|
62
63
|
include Prawn::Stamp
|
63
64
|
include Prawn::SoftMask
|
64
65
|
|
66
|
+
# @group Extension API
|
67
|
+
|
65
68
|
# NOTE: We probably need to rethink the options validation system, but this
|
66
69
|
# constant temporarily allows for extensions to modify the list.
|
67
70
|
|
@@ -90,14 +93,28 @@ module Prawn
|
|
90
93
|
# party!
|
91
94
|
# end
|
92
95
|
#
|
96
|
+
#
|
93
97
|
def self.extensions
|
94
98
|
@extensions ||= []
|
95
99
|
end
|
96
100
|
|
97
|
-
|
101
|
+
# @private
|
102
|
+
def self.inherited(base)
|
98
103
|
extensions.each { |e| base.extensions << e }
|
99
104
|
end
|
100
105
|
|
106
|
+
# @group Stable Attributes
|
107
|
+
|
108
|
+
attr_accessor :margin_box
|
109
|
+
attr_reader :margins, :y
|
110
|
+
attr_accessor :page_number
|
111
|
+
|
112
|
+
# @group Extension Attributes
|
113
|
+
|
114
|
+
attr_accessor :text_formatter
|
115
|
+
|
116
|
+
# @group Stable API
|
117
|
+
|
101
118
|
# Creates and renders a PDF document.
|
102
119
|
#
|
103
120
|
# When using the implicit block form, Prawn will evaluate the block
|
@@ -215,27 +232,7 @@ module Prawn
|
|
215
232
|
end
|
216
233
|
end
|
217
234
|
|
218
|
-
|
219
|
-
attr_reader :margins, :y
|
220
|
-
attr_writer :font_size
|
221
|
-
attr_accessor :page_number
|
222
|
-
attr_accessor :text_formatter
|
223
|
-
|
224
|
-
def state
|
225
|
-
@internal_state
|
226
|
-
end
|
227
|
-
|
228
|
-
def page
|
229
|
-
state.page
|
230
|
-
end
|
231
|
-
|
232
|
-
def initialize_first_page(options)
|
233
|
-
if options[:skip_page_creation]
|
234
|
-
start_new_page(options.merge(:orphan => true))
|
235
|
-
else
|
236
|
-
start_new_page(options)
|
237
|
-
end
|
238
|
-
end
|
235
|
+
# @group Stable API
|
239
236
|
|
240
237
|
# Creates and advances to a new page in the document.
|
241
238
|
#
|
@@ -356,6 +353,9 @@ module Prawn
|
|
356
353
|
# Pass an open file descriptor to render to file.
|
357
354
|
#
|
358
355
|
def render(output = StringIO.new)
|
356
|
+
if output.instance_of?(StringIO)
|
357
|
+
output.set_encoding(::Encoding::ASCII_8BIT)
|
358
|
+
end
|
359
359
|
finalize_all_page_contents
|
360
360
|
|
361
361
|
render_header(output)
|
@@ -412,6 +412,7 @@ module Prawn
|
|
412
412
|
|
413
413
|
# Returns the innermost non-stretchy bounding box.
|
414
414
|
#
|
415
|
+
# @private
|
415
416
|
def reference_bounds
|
416
417
|
@bounding_box.reference_bounds
|
417
418
|
end
|
@@ -497,47 +498,6 @@ module Prawn
|
|
497
498
|
bounds.indent(left, right, &block)
|
498
499
|
end
|
499
500
|
|
500
|
-
|
501
|
-
def mask(*fields) # :nodoc:
|
502
|
-
# Stores the current state of the named attributes, executes the block, and
|
503
|
-
# then restores the original values after the block has executed.
|
504
|
-
# -- I will remove the nodoc if/when this feature is a little less hacky
|
505
|
-
stored = {}
|
506
|
-
fields.each { |f| stored[f] = send(f) }
|
507
|
-
yield
|
508
|
-
fields.each { |f| send("#{f}=", stored[f]) }
|
509
|
-
end
|
510
|
-
|
511
|
-
# Attempts to group the given block vertically within the current context.
|
512
|
-
# First attempts to render it in the current position on the current page.
|
513
|
-
# If that attempt overflows, it is tried anew after starting a new context
|
514
|
-
# (page or column). Returns a logically true value if the content fits in
|
515
|
-
# one page/column, false if a new page or column was needed.
|
516
|
-
#
|
517
|
-
# Raises CannotGroup if the provided content is too large to fit alone in
|
518
|
-
# the current page or column.
|
519
|
-
#
|
520
|
-
def group(second_attempt=false)
|
521
|
-
old_bounding_box = @bounding_box
|
522
|
-
@bounding_box = SimpleDelegator.new(@bounding_box)
|
523
|
-
|
524
|
-
def @bounding_box.move_past_bottom
|
525
|
-
raise RollbackTransaction
|
526
|
-
end
|
527
|
-
|
528
|
-
success = transaction { yield }
|
529
|
-
|
530
|
-
@bounding_box = old_bounding_box
|
531
|
-
|
532
|
-
unless success
|
533
|
-
raise Prawn::Errors::CannotGroup if second_attempt
|
534
|
-
old_bounding_box.move_past_bottom
|
535
|
-
group(second_attempt=true) { yield }
|
536
|
-
end
|
537
|
-
|
538
|
-
success
|
539
|
-
end
|
540
|
-
|
541
501
|
# Places a text box on specified pages for page numbering. This should be called
|
542
502
|
# towards the end of document creation, after all your content is already in
|
543
503
|
# place. In your template string, <page> refers to the current page, and
|
@@ -610,6 +570,46 @@ module Prawn
|
|
610
570
|
end
|
611
571
|
end
|
612
572
|
|
573
|
+
# Returns true if content streams will be compressed before rendering,
|
574
|
+
# false otherwise
|
575
|
+
#
|
576
|
+
def compression_enabled?
|
577
|
+
!!state.compress
|
578
|
+
end
|
579
|
+
|
580
|
+
# @group Experimental API
|
581
|
+
|
582
|
+
# Attempts to group the given block vertically within the current context.
|
583
|
+
# First attempts to render it in the current position on the current page.
|
584
|
+
# If that attempt overflows, it is tried anew after starting a new context
|
585
|
+
# (page or column). Returns a logically true value if the content fits in
|
586
|
+
# one page/column, false if a new page or column was needed.
|
587
|
+
#
|
588
|
+
# Raises CannotGroup if the provided content is too large to fit alone in
|
589
|
+
# the current page or column.
|
590
|
+
#
|
591
|
+
def group(second_attempt=false)
|
592
|
+
old_bounding_box = @bounding_box
|
593
|
+
@bounding_box = SimpleDelegator.new(@bounding_box)
|
594
|
+
|
595
|
+
# @private
|
596
|
+
def @bounding_box.move_past_bottom
|
597
|
+
raise RollbackTransaction
|
598
|
+
end
|
599
|
+
|
600
|
+
success = transaction { yield }
|
601
|
+
|
602
|
+
@bounding_box = old_bounding_box
|
603
|
+
|
604
|
+
unless success
|
605
|
+
raise Prawn::Errors::CannotGroup if second_attempt
|
606
|
+
old_bounding_box.move_past_bottom
|
607
|
+
group(second_attempt=true) { yield }
|
608
|
+
end
|
609
|
+
|
610
|
+
success
|
611
|
+
end
|
612
|
+
|
613
613
|
# Provides a way to execute a block of code repeatedly based on a
|
614
614
|
# page_filter.
|
615
615
|
#
|
@@ -635,16 +635,43 @@ module Prawn
|
|
635
635
|
end
|
636
636
|
end
|
637
637
|
|
638
|
+
# @private
|
639
|
+
|
640
|
+
def mask(*fields)
|
641
|
+
# Stores the current state of the named attributes, executes the block, and
|
642
|
+
# then restores the original values after the block has executed.
|
643
|
+
# -- I will remove the nodoc if/when this feature is a little less hacky
|
644
|
+
stored = {}
|
645
|
+
fields.each { |f| stored[f] = send(f) }
|
646
|
+
yield
|
647
|
+
fields.each { |f| send("#{f}=", stored[f]) }
|
648
|
+
end
|
638
649
|
|
639
|
-
#
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
650
|
+
# @group Extension API
|
651
|
+
|
652
|
+
def initialize_first_page(options)
|
653
|
+
if options[:skip_page_creation]
|
654
|
+
start_new_page(options.merge(:orphan => true))
|
655
|
+
else
|
656
|
+
start_new_page(options)
|
657
|
+
end
|
658
|
+
end
|
659
|
+
|
660
|
+
## Internals. Don't depend on them!
|
661
|
+
|
662
|
+
# @private
|
663
|
+
def state
|
664
|
+
@internal_state
|
665
|
+
end
|
666
|
+
|
667
|
+
# @private
|
668
|
+
def page
|
669
|
+
state.page
|
644
670
|
end
|
645
671
|
|
646
672
|
private
|
647
673
|
|
674
|
+
|
648
675
|
# setting override_settings to true ensures that a new graphic state does not end up using
|
649
676
|
# previous settings.
|
650
677
|
def use_graphic_settings(override_settings = false)
|
@@ -8,6 +8,7 @@
|
|
8
8
|
|
9
9
|
module Prawn
|
10
10
|
class Document
|
11
|
+
# @group Stable API
|
11
12
|
|
12
13
|
# :call-seq:
|
13
14
|
# bounding_box(point, options={}, &block)
|
@@ -219,7 +220,7 @@ module Prawn
|
|
219
220
|
#
|
220
221
|
class BoundingBox
|
221
222
|
|
222
|
-
def initialize(document, parent, point, options={})
|
223
|
+
def initialize(document, parent, point, options={}) # @private
|
223
224
|
unless options[:width]
|
224
225
|
raise ArgumentError, "BoundingBox needs the :width option to be set"
|
225
226
|
end
|
@@ -233,15 +234,22 @@ module Prawn
|
|
233
234
|
@stretched_height = nil
|
234
235
|
end
|
235
236
|
|
237
|
+
# @private
|
238
|
+
|
236
239
|
attr_reader :document, :parent
|
240
|
+
|
241
|
+
# @private
|
237
242
|
# The current indentation of the left side of the bounding box.
|
238
243
|
attr_reader :total_left_padding
|
244
|
+
|
245
|
+
# @private
|
239
246
|
# The current indentation of the right side of the bounding box.
|
240
247
|
attr_reader :total_right_padding
|
241
248
|
|
242
249
|
# The translated origin (x,y-height) which describes the location
|
243
250
|
# of the bottom left corner of the bounding box
|
244
251
|
#
|
252
|
+
# @private
|
245
253
|
def anchor
|
246
254
|
[@x, @y - height]
|
247
255
|
end
|
@@ -272,6 +280,7 @@ module Prawn
|
|
272
280
|
# text "indented on both sides"
|
273
281
|
# end
|
274
282
|
#
|
283
|
+
# @private
|
275
284
|
def indent(left_padding, right_padding = 0, &block)
|
276
285
|
add_left_padding(left_padding)
|
277
286
|
add_right_padding(right_padding)
|
@@ -282,6 +291,7 @@ module Prawn
|
|
282
291
|
end
|
283
292
|
|
284
293
|
# Increase the left padding of the bounding box.
|
294
|
+
# @private
|
285
295
|
def add_left_padding(left_padding)
|
286
296
|
@total_left_padding += left_padding
|
287
297
|
@x += left_padding
|
@@ -289,6 +299,7 @@ module Prawn
|
|
289
299
|
end
|
290
300
|
|
291
301
|
# Decrease the left padding of the bounding box.
|
302
|
+
# @private
|
292
303
|
def subtract_left_padding(left_padding)
|
293
304
|
@total_left_padding -= left_padding
|
294
305
|
@x -= left_padding
|
@@ -296,12 +307,14 @@ module Prawn
|
|
296
307
|
end
|
297
308
|
|
298
309
|
# Increase the right padding of the bounding box.
|
310
|
+
# @private
|
299
311
|
def add_right_padding(right_padding)
|
300
312
|
@total_right_padding += right_padding
|
301
313
|
@width -= right_padding
|
302
314
|
end
|
303
315
|
|
304
316
|
# Decrease the right padding of the bounding box.
|
317
|
+
# @private
|
305
318
|
def subtract_right_padding(right_padding)
|
306
319
|
@total_right_padding -= right_padding
|
307
320
|
@width += right_padding
|
@@ -452,15 +465,19 @@ module Prawn
|
|
452
465
|
end
|
453
466
|
|
454
467
|
# an alias for absolute_left
|
468
|
+
# @private
|
455
469
|
def left_side
|
456
470
|
absolute_left
|
457
471
|
end
|
458
472
|
|
459
473
|
# an alias for absolute_right
|
474
|
+
# @private
|
460
475
|
def right_side
|
461
476
|
absolute_right
|
462
477
|
end
|
463
478
|
|
479
|
+
# @group Extension API
|
480
|
+
|
464
481
|
# Moves to the top of the next page of the document, starting a new page
|
465
482
|
# if necessary.
|
466
483
|
#
|
@@ -472,9 +489,6 @@ module Prawn
|
|
472
489
|
end
|
473
490
|
end
|
474
491
|
|
475
|
-
|
476
|
-
alias_method :update_height, :height
|
477
|
-
|
478
492
|
# Returns +false+ when the box has a defined height, +true+ when the height
|
479
493
|
# is being calculated on the fly based on the current vertical position.
|
480
494
|
#
|
@@ -493,9 +507,12 @@ module Prawn
|
|
493
507
|
end
|
494
508
|
end
|
495
509
|
|
510
|
+
alias_method :update_height, :height
|
511
|
+
|
496
512
|
# Returns a deep copy of these bounds (including all parent bounds but
|
497
513
|
# not copying the reference to the Document).
|
498
514
|
#
|
515
|
+
# @private
|
499
516
|
def deep_copy
|
500
517
|
copy = dup
|
501
518
|
# Deep-copy the parent bounds
|
@@ -510,6 +527,7 @@ module Prawn
|
|
510
527
|
# context of the given +document+. Does *not* set the bounds of the
|
511
528
|
# document to the resulting BoundingBox, only returns it.
|
512
529
|
#
|
530
|
+
# @private
|
513
531
|
def self.restore_deep_copy(bounds, document)
|
514
532
|
bounds.instance_variable_set("@document", document)
|
515
533
|
bounds
|