root / drupal7 / sites / all / libraries / fpdi-1.5.4 / fpdf_tpl.php @ 4b706e38
1 | 60370e04 | Assos Assos | <?php
|
---|---|---|---|
2 | //
|
||
3 | // FPDI - Version 1.5.4
|
||
4 | //
|
||
5 | // Copyright 2004-2015 Setasign - Jan Slabon
|
||
6 | //
|
||
7 | // Licensed under the Apache License, Version 2.0 (the "License");
|
||
8 | // you may not use this file except in compliance with the License.
|
||
9 | // You may obtain a copy of the License at
|
||
10 | //
|
||
11 | // http://www.apache.org/licenses/LICENSE-2.0
|
||
12 | //
|
||
13 | // Unless required by applicable law or agreed to in writing, software
|
||
14 | // distributed under the License is distributed on an "AS IS" BASIS,
|
||
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
16 | // See the License for the specific language governing permissions and
|
||
17 | // limitations under the License.
|
||
18 | //
|
||
19 | |||
20 | if (!class_exists('fpdi_bridge')) { |
||
21 | require_once('fpdi_bridge.php'); |
||
22 | } |
||
23 | |||
24 | /**
|
||
25 | * Class FPDF_TPL
|
||
26 | */
|
||
27 | class FPDF_TPL extends fpdi_bridge |
||
28 | { |
||
29 | /**
|
||
30 | * Array of template data
|
||
31 | *
|
||
32 | * @var array
|
||
33 | */
|
||
34 | protected $_tpls = array(); |
||
35 | |||
36 | /**
|
||
37 | * Current Template-Id
|
||
38 | *
|
||
39 | * @var int
|
||
40 | */
|
||
41 | public $tpl = 0; |
||
42 | |||
43 | /**
|
||
44 | * "In Template"-Flag
|
||
45 | *
|
||
46 | * @var boolean
|
||
47 | */
|
||
48 | protected $_inTpl = false; |
||
49 | |||
50 | /**
|
||
51 | * Name prefix of templates used in Resources dictionary
|
||
52 | *
|
||
53 | * @var string A String defining the Prefix used as Template-Object-Names. Have to begin with an /
|
||
54 | */
|
||
55 | public $tplPrefix = "/TPL"; |
||
56 | |||
57 | /**
|
||
58 | * Resources used by templates and pages
|
||
59 | *
|
||
60 | * @var array
|
||
61 | */
|
||
62 | protected $_res = array(); |
||
63 | |||
64 | /**
|
||
65 | * Last used template data
|
||
66 | *
|
||
67 | * @var array
|
||
68 | */
|
||
69 | public $lastUsedTemplateData = array(); |
||
70 | |||
71 | /**
|
||
72 | * Start a template.
|
||
73 | *
|
||
74 | * This method starts a template. You can give own coordinates to build an own sized
|
||
75 | * template. Pay attention, that the margins are adapted to the new template size.
|
||
76 | * If you want to write outside the template, for example to build a clipped template,
|
||
77 | * you have to set the margins and "cursor"-position manual after beginTemplate()-call.
|
||
78 | *
|
||
79 | * If no parameter is given, the template uses the current page-size.
|
||
80 | * The method returns an id of the current template. This id is used later for using this template.
|
||
81 | * Warning: A created template is saved in the resulting PDF at all events. Also if you don't use it after creation!
|
||
82 | *
|
||
83 | * @param int $x The x-coordinate given in user-unit
|
||
84 | * @param int $y The y-coordinate given in user-unit
|
||
85 | * @param int $w The width given in user-unit
|
||
86 | * @param int $h The height given in user-unit
|
||
87 | * @return int The id of new created template
|
||
88 | * @throws LogicException
|
||
89 | */
|
||
90 | public function beginTemplate($x = null, $y = null, $w = null, $h = null) |
||
91 | { |
||
92 | if (is_subclass_of($this, 'TCPDF')) { |
||
93 | throw new LogicException('This method is only usable with FPDF. Use TCPDF methods startTemplate() instead.'); |
||
94 | } |
||
95 | |||
96 | if ($this->page <= 0) { |
||
97 | throw new LogicException("You have to add at least a page first!"); |
||
98 | } |
||
99 | |||
100 | if ($x == null) |
||
101 | $x = 0; |
||
102 | if ($y == null) |
||
103 | $y = 0; |
||
104 | if ($w == null) |
||
105 | $w = $this->w; |
||
106 | if ($h == null) |
||
107 | $h = $this->h; |
||
108 | |||
109 | // Save settings
|
||
110 | $this->tpl++;
|
||
111 | $tpl =& $this->_tpls[$this->tpl]; |
||
112 | $tpl = array( |
||
113 | 'o_x' => $this->x, |
||
114 | 'o_y' => $this->y, |
||
115 | 'o_AutoPageBreak' => $this->AutoPageBreak, |
||
116 | 'o_bMargin' => $this->bMargin, |
||
117 | 'o_tMargin' => $this->tMargin, |
||
118 | 'o_lMargin' => $this->lMargin, |
||
119 | 'o_rMargin' => $this->rMargin, |
||
120 | 'o_h' => $this->h, |
||
121 | 'o_w' => $this->w, |
||
122 | 'o_FontFamily' => $this->FontFamily, |
||
123 | 'o_FontStyle' => $this->FontStyle, |
||
124 | 'o_FontSizePt' => $this->FontSizePt, |
||
125 | 'o_FontSize' => $this->FontSize, |
||
126 | 'buffer' => '', |
||
127 | 'x' => $x, |
||
128 | 'y' => $y, |
||
129 | 'w' => $w, |
||
130 | 'h' => $h |
||
131 | ); |
||
132 | |||
133 | $this->SetAutoPageBreak(false); |
||
134 | |||
135 | // Define own high and width to calculate correct positions
|
||
136 | $this->h = $h; |
||
137 | $this->w = $w; |
||
138 | |||
139 | $this->_inTpl = true; |
||
140 | $this->SetXY($x + $this->lMargin, $y + $this->tMargin); |
||
141 | $this->SetRightMargin($this->w - $w + $this->rMargin); |
||
142 | |||
143 | if ($this->CurrentFont) { |
||
144 | $fontKey = $this->FontFamily . $this->FontStyle; |
||
145 | if ($fontKey) { |
||
146 | $this->_res['tpl'][$this->tpl]['fonts'][$fontKey] =& $this->fonts[$fontKey]; |
||
147 | $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); |
||
148 | } |
||
149 | } |
||
150 | |||
151 | return $this->tpl; |
||
152 | } |
||
153 | |||
154 | /**
|
||
155 | * End template.
|
||
156 | *
|
||
157 | * This method ends a template and reset initiated variables collected in {@link beginTemplate()}.
|
||
158 | *
|
||
159 | * @return int|boolean If a template is opened, the id is returned. If not a false is returned.
|
||
160 | */
|
||
161 | public function endTemplate() |
||
162 | { |
||
163 | if (is_subclass_of($this, 'TCPDF')) { |
||
164 | $args = func_get_args(); |
||
165 | return call_user_func_array(array($this, 'TCPDF::endTemplate'), $args); |
||
166 | } |
||
167 | |||
168 | if ($this->_inTpl) { |
||
169 | $this->_inTpl = false; |
||
170 | $tpl = $this->_tpls[$this->tpl]; |
||
171 | $this->SetXY($tpl['o_x'], $tpl['o_y']); |
||
172 | $this->tMargin = $tpl['o_tMargin']; |
||
173 | $this->lMargin = $tpl['o_lMargin']; |
||
174 | $this->rMargin = $tpl['o_rMargin']; |
||
175 | $this->h = $tpl['o_h']; |
||
176 | $this->w = $tpl['o_w']; |
||
177 | $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']); |
||
178 | |||
179 | $this->FontFamily = $tpl['o_FontFamily']; |
||
180 | $this->FontStyle = $tpl['o_FontStyle']; |
||
181 | $this->FontSizePt = $tpl['o_FontSizePt']; |
||
182 | $this->FontSize = $tpl['o_FontSize']; |
||
183 | |||
184 | $fontKey = $this->FontFamily . $this->FontStyle; |
||
185 | if ($fontKey) |
||
186 | $this->CurrentFont =& $this->fonts[$fontKey]; |
||
187 | |||
188 | return $this->tpl; |
||
189 | } else {
|
||
190 | return false; |
||
191 | } |
||
192 | } |
||
193 | |||
194 | /**
|
||
195 | * Use a template in current page or other template.
|
||
196 | *
|
||
197 | * You can use a template in a page or in another template.
|
||
198 | * You can give the used template a new size.
|
||
199 | * All parameters are optional. The width or height is calculated automatically
|
||
200 | * if one is given. If no parameter is given the origin size as defined in
|
||
201 | * {@link beginTemplate()} method is used.
|
||
202 | *
|
||
203 | * The calculated or used width and height are returned as an array.
|
||
204 | *
|
||
205 | * @param int $tplIdx A valid template-id
|
||
206 | * @param int $x The x-position
|
||
207 | * @param int $y The y-position
|
||
208 | * @param int $w The new width of the template
|
||
209 | * @param int $h The new height of the template
|
||
210 | * @return array The height and width of the template (array('w' => ..., 'h' => ...))
|
||
211 | * @throws LogicException|InvalidArgumentException
|
||
212 | */
|
||
213 | public function useTemplate($tplIdx, $x = null, $y = null, $w = 0, $h = 0) |
||
214 | { |
||
215 | if ($this->page <= 0) { |
||
216 | throw new LogicException('You have to add at least a page first!'); |
||
217 | } |
||
218 | |||
219 | if (!isset($this->_tpls[$tplIdx])) { |
||
220 | throw new InvalidArgumentException('Template does not exist!'); |
||
221 | } |
||
222 | |||
223 | if ($this->_inTpl) { |
||
224 | $this->_res['tpl'][$this->tpl]['tpls'][$tplIdx] =& $this->_tpls[$tplIdx]; |
||
225 | } |
||
226 | |||
227 | $tpl = $this->_tpls[$tplIdx]; |
||
228 | $_w = $tpl['w']; |
||
229 | $_h = $tpl['h']; |
||
230 | |||
231 | if ($x == null) { |
||
232 | $x = 0; |
||
233 | } |
||
234 | |||
235 | if ($y == null) { |
||
236 | $y = 0; |
||
237 | } |
||
238 | |||
239 | $x += $tpl['x']; |
||
240 | $y += $tpl['y']; |
||
241 | |||
242 | $wh = $this->getTemplateSize($tplIdx, $w, $h); |
||
243 | $w = $wh['w']; |
||
244 | $h = $wh['h']; |
||
245 | |||
246 | $tplData = array( |
||
247 | 'x' => $this->x, |
||
248 | 'y' => $this->y, |
||
249 | 'w' => $w, |
||
250 | 'h' => $h, |
||
251 | 'scaleX' => ($w / $_w), |
||
252 | 'scaleY' => ($h / $_h), |
||
253 | 'tx' => $x, |
||
254 | 'ty' => ($this->h - $y - $h), |
||
255 | 'lty' => ($this->h - $y - $h) - ($this->h - $_h) * ($h / $_h) |
||
256 | ); |
||
257 | |||
258 | $this->_out(sprintf('q %.4F 0 0 %.4F %.4F %.4F cm', |
||
259 | $tplData['scaleX'], $tplData['scaleY'], $tplData['tx'] * $this->k, $tplData['ty'] * $this->k) |
||
260 | ); // Translate
|
||
261 | $this->_out(sprintf('%s%d Do Q', $this->tplPrefix, $tplIdx)); |
||
262 | |||
263 | $this->lastUsedTemplateData = $tplData; |
||
264 | |||
265 | return array('w' => $w, 'h' => $h); |
||
266 | } |
||
267 | |||
268 | /**
|
||
269 | * Get the calculated size of a template.
|
||
270 | *
|
||
271 | * If one size is given, this method calculates the other one.
|
||
272 | *
|
||
273 | * @param int $tplIdx A valid template-id
|
||
274 | * @param int $w The width of the template
|
||
275 | * @param int $h The height of the template
|
||
276 | * @return array The height and width of the template (array('w' => ..., 'h' => ...))
|
||
277 | */
|
||
278 | public function getTemplateSize($tplIdx, $w = 0, $h = 0) |
||
279 | { |
||
280 | if (!isset($this->_tpls[$tplIdx])) |
||
281 | return false; |
||
282 | |||
283 | $tpl = $this->_tpls[$tplIdx]; |
||
284 | $_w = $tpl['w']; |
||
285 | $_h = $tpl['h']; |
||
286 | |||
287 | if ($w == 0 && $h == 0) { |
||
288 | $w = $_w; |
||
289 | $h = $_h; |
||
290 | } |
||
291 | |||
292 | if ($w == 0) |
||
293 | $w = $h * $_w / $_h; |
||
294 | if($h == 0) |
||
295 | $h = $w * $_h / $_w; |
||
296 | |||
297 | return array("w" => $w, "h" => $h); |
||
298 | } |
||
299 | |||
300 | /**
|
||
301 | * Sets the font used to print character strings.
|
||
302 | *
|
||
303 | * See FPDF/TCPDF documentation.
|
||
304 | *
|
||
305 | * @see http://fpdf.org/en/doc/setfont.htm
|
||
306 | * @see http://www.tcpdf.org/doc/code/classTCPDF.html#afd56e360c43553830d543323e81bc045
|
||
307 | */
|
||
308 | public function SetFont($family, $style = '', $size = null, $fontfile = '', $subset = 'default', $out = true) |
||
309 | { |
||
310 | if (is_subclass_of($this, 'TCPDF')) { |
||
311 | $args = func_get_args(); |
||
312 | return call_user_func_array(array($this, 'TCPDF::SetFont'), $args); |
||
313 | } |
||
314 | |||
315 | parent::SetFont($family, $style, $size); |
||
316 | |||
317 | $fontkey = $this->FontFamily . $this->FontStyle; |
||
318 | |||
319 | if ($this->_inTpl) { |
||
320 | $this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey]; |
||
321 | } else {
|
||
322 | $this->_res['page'][$this->page]['fonts'][$fontkey] =& $this->fonts[$fontkey]; |
||
323 | } |
||
324 | } |
||
325 | |||
326 | /**
|
||
327 | * Puts an image.
|
||
328 | *
|
||
329 | * See FPDF/TCPDF documentation.
|
||
330 | *
|
||
331 | * @see http://fpdf.org/en/doc/image.htm
|
||
332 | * @see http://www.tcpdf.org/doc/code/classTCPDF.html#a714c2bee7d6b39d4d6d304540c761352
|
||
333 | */
|
||
334 | public function Image( |
||
335 | $file, $x = '', $y = '', $w = 0, $h = 0, $type = '', $link = '', $align = '', $resize = false, |
||
336 | $dpi = 300, $palign = '', $ismask = false, $imgmask = false, $border = 0, $fitbox = false, |
||
337 | $hidden = false, $fitonpage = false, $alt = false, $altimgs = array() |
||
338 | ) |
||
339 | { |
||
340 | if (is_subclass_of($this, 'TCPDF')) { |
||
341 | $args = func_get_args(); |
||
342 | return call_user_func_array(array($this, 'TCPDF::Image'), $args); |
||
343 | } |
||
344 | |||
345 | $ret = parent::Image($file, $x, $y, $w, $h, $type, $link); |
||
346 | if ($this->_inTpl) { |
||
347 | $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file]; |
||
348 | } else {
|
||
349 | $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file]; |
||
350 | } |
||
351 | |||
352 | return $ret; |
||
353 | } |
||
354 | |||
355 | /**
|
||
356 | * Adds a new page to the document.
|
||
357 | *
|
||
358 | * See FPDF/TCPDF documentation.
|
||
359 | *
|
||
360 | * This method cannot be used if you'd started a template.
|
||
361 | *
|
||
362 | * @see http://fpdf.org/en/doc/addpage.htm
|
||
363 | * @see http://www.tcpdf.org/doc/code/classTCPDF.html#a5171e20b366b74523709d84c349c1ced
|
||
364 | */
|
||
365 | public function AddPage($orientation = '', $format = '', $keepmargins = false, $tocpage = false) |
||
366 | { |
||
367 | if (is_subclass_of($this, 'TCPDF')) { |
||
368 | $args = func_get_args(); |
||
369 | return call_user_func_array(array($this, 'TCPDF::AddPage'), $args); |
||
370 | } |
||
371 | |||
372 | if ($this->_inTpl) { |
||
373 | throw new LogicException('Adding pages in templates is not possible!'); |
||
374 | } |
||
375 | |||
376 | parent::AddPage($orientation, $format); |
||
377 | } |
||
378 | |||
379 | /**
|
||
380 | * Puts a link on a rectangular area of the page.
|
||
381 | *
|
||
382 | * Overwritten because adding links in a template will not work.
|
||
383 | *
|
||
384 | * @see http://fpdf.org/en/doc/link.htm
|
||
385 | * @see http://www.tcpdf.org/doc/code/classTCPDF.html#ab87bf1826384fbfe30eb499d42f1d994
|
||
386 | */
|
||
387 | public function Link($x, $y, $w, $h, $link, $spaces = 0) |
||
388 | { |
||
389 | if (is_subclass_of($this, 'TCPDF')) { |
||
390 | $args = func_get_args(); |
||
391 | return call_user_func_array(array($this, 'TCPDF::Link'), $args); |
||
392 | } |
||
393 | |||
394 | if ($this->_inTpl) { |
||
395 | throw new LogicException('Using links in templates is not posible!'); |
||
396 | } |
||
397 | |||
398 | parent::Link($x, $y, $w, $h, $link); |
||
399 | } |
||
400 | |||
401 | /**
|
||
402 | * Creates a new internal link and returns its identifier.
|
||
403 | *
|
||
404 | * Overwritten because adding links in a template will not work.
|
||
405 | *
|
||
406 | * @see http://fpdf.org/en/doc/addlink.htm
|
||
407 | * @see http://www.tcpdf.org/doc/code/classTCPDF.html#a749522038ed7786c3e1701435dcb891e
|
||
408 | */
|
||
409 | public function AddLink() |
||
410 | { |
||
411 | if (is_subclass_of($this, 'TCPDF')) { |
||
412 | $args = func_get_args(); |
||
413 | return call_user_func_array(array($this, 'TCPDF::AddLink'), $args); |
||
414 | } |
||
415 | |||
416 | if ($this->_inTpl) { |
||
417 | throw new LogicException('Adding links in templates is not possible!'); |
||
418 | } |
||
419 | |||
420 | return parent::AddLink(); |
||
421 | } |
||
422 | |||
423 | /**
|
||
424 | * Defines the page and position a link points to.
|
||
425 | *
|
||
426 | * Overwritten because adding links in a template will not work.
|
||
427 | *
|
||
428 | * @see http://fpdf.org/en/doc/setlink.htm
|
||
429 | * @see http://www.tcpdf.org/doc/code/classTCPDF.html#ace5be60e7857953ea5e2b89cb90df0ae
|
||
430 | */
|
||
431 | public function SetLink($link, $y = 0, $page = -1) |
||
432 | { |
||
433 | if (is_subclass_of($this, 'TCPDF')) { |
||
434 | $args = func_get_args(); |
||
435 | return call_user_func_array(array($this, 'TCPDF::SetLink'), $args); |
||
436 | } |
||
437 | |||
438 | if ($this->_inTpl) { |
||
439 | throw new LogicException('Setting links in templates is not possible!'); |
||
440 | } |
||
441 | |||
442 | parent::SetLink($link, $y, $page); |
||
443 | } |
||
444 | |||
445 | /**
|
||
446 | * Writes the form XObjects to the PDF document.
|
||
447 | */
|
||
448 | protected function _putformxobjects() |
||
449 | { |
||
450 | $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; |
||
451 | reset($this->_tpls); |
||
452 | |||
453 | foreach($this->_tpls AS $tplIdx => $tpl) { |
||
454 | $this->_newobj();
|
||
455 | $this->_tpls[$tplIdx]['n'] = $this->n; |
||
456 | $this->_out('<<'.$filter.'/Type /XObject'); |
||
457 | $this->_out('/Subtype /Form'); |
||
458 | $this->_out('/FormType 1'); |
||
459 | $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', |
||
460 | // llx
|
||
461 | $tpl['x'] * $this->k, |
||
462 | // lly
|
||
463 | -$tpl['y'] * $this->k, |
||
464 | // urx
|
||
465 | ($tpl['w'] + $tpl['x']) * $this->k, |
||
466 | // ury
|
||
467 | ($tpl['h'] - $tpl['y']) * $this->k |
||
468 | )); |
||
469 | |||
470 | if ($tpl['x'] != 0 || $tpl['y'] != 0) { |
||
471 | $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]', |
||
472 | -$tpl['x'] * $this->k * 2, $tpl['y'] * $this->k * 2 |
||
473 | )); |
||
474 | } |
||
475 | |||
476 | $this->_out('/Resources '); |
||
477 | $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); |
||
478 | |||
479 | if (isset($this->_res['tpl'][$tplIdx])) { |
||
480 | $res = $this->_res['tpl'][$tplIdx]; |
||
481 | if (isset($res['fonts']) && count($res['fonts'])) { |
||
482 | $this->_out('/Font <<'); |
||
483 | |||
484 | foreach($res['fonts'] as $font) { |
||
485 | $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); |
||
486 | } |
||
487 | |||
488 | $this->_out('>>'); |
||
489 | } |
||
490 | |||
491 | if(isset($res['images']) || isset($res['tpls'])) { |
||
492 | $this->_out('/XObject <<'); |
||
493 | |||
494 | if (isset($res['images'])) { |
||
495 | foreach($res['images'] as $image) |
||
496 | $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); |
||
497 | } |
||
498 | |||
499 | if (isset($res['tpls'])) { |
||
500 | foreach($res['tpls'] as $i => $_tpl) |
||
501 | $this->_out($this->tplPrefix . $i . ' ' . $_tpl['n'] . ' 0 R'); |
||
502 | } |
||
503 | |||
504 | $this->_out('>>'); |
||
505 | } |
||
506 | } |
||
507 | |||
508 | $this->_out('>>'); |
||
509 | |||
510 | $buffer = ($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; |
||
511 | $this->_out('/Length ' . strlen($buffer) . ' >>'); |
||
512 | $this->_putstream($buffer); |
||
513 | $this->_out('endobj'); |
||
514 | } |
||
515 | } |
||
516 | |||
517 | /**
|
||
518 | * Output images.
|
||
519 | *
|
||
520 | * Overwritten to add {@link _putformxobjects()} after _putimages().
|
||
521 | */
|
||
522 | public function _putimages() |
||
523 | { |
||
524 | parent::_putimages();
|
||
525 | $this->_putformxobjects();
|
||
526 | } |
||
527 | |||
528 | /**
|
||
529 | * Writes the references of XObject resources to the document.
|
||
530 | *
|
||
531 | * Overwritten to add the the templates to the XObject resource dictionary.
|
||
532 | */
|
||
533 | public function _putxobjectdict() |
||
534 | { |
||
535 | parent::_putxobjectdict();
|
||
536 | |||
537 | foreach($this->_tpls as $tplIdx => $tpl) { |
||
538 | $this->_out(sprintf('%s%d %d 0 R', $this->tplPrefix, $tplIdx, $tpl['n'])); |
||
539 | } |
||
540 | } |
||
541 | |||
542 | /**
|
||
543 | * Writes bytes to the resulting document.
|
||
544 | *
|
||
545 | * Overwritten to delegate the data to the template buffer.
|
||
546 | *
|
||
547 | * @param string $s
|
||
548 | */
|
||
549 | public function _out($s) |
||
550 | { |
||
551 | if ($this->state == 2 && $this->_inTpl) { |
||
552 | $this->_tpls[$this->tpl]['buffer'] .= $s . "\n"; |
||
553 | } else {
|
||
554 | parent::_out($s); |
||
555 | } |
||
556 | } |
||
557 | } |