Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / symbology / fmap / mapcontext / rendering / symbol / impl / MultiShapeSymbol.java @ 40560

History | View | Annotate | Download (18 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.symbology.fmap.mapcontext.rendering.symbol.impl;
25

    
26
import java.awt.Color;
27
import java.awt.Graphics2D;
28
import java.awt.Rectangle;
29
import java.awt.geom.AffineTransform;
30
import java.awt.geom.Point2D;
31

    
32
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34

    
35
import org.gvsig.compat.print.PrintAttributes;
36
import org.gvsig.fmap.dal.feature.Feature;
37
import org.gvsig.fmap.geom.Geometry;
38
import org.gvsig.fmap.geom.aggregate.Aggregate;
39
import org.gvsig.fmap.geom.type.GeometryType;
40
import org.gvsig.fmap.mapcontext.MapContextLocator;
41
import org.gvsig.fmap.mapcontext.ViewPort;
42
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
43
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolDrawingException;
44
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
45
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.IMultiShapeSymbol;
46
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.fill.IFillSymbol;
47
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.line.ILineSymbol;
48
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.marker.IMarkerSymbol;
49
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.ILineStyle;
50
import org.gvsig.symbology.fmap.mapcontext.rendering.symbol.style.IMask;
51
import org.gvsig.tools.ToolsLocator;
52
import org.gvsig.tools.dynobject.DynStruct;
53
import org.gvsig.tools.persistence.PersistenceManager;
54
import org.gvsig.tools.persistence.PersistentState;
55
import org.gvsig.tools.persistence.exception.PersistenceException;
56
import org.gvsig.tools.task.Cancellable;
57
import org.gvsig.tools.util.Callable;
58

    
59
/**
60
 * MultiShapeSymbol class allows to create a composition of several symbols with
61
 * different shapes and be treated as a single symbol.These shapes can be
62
 * marker,line or fill.
63
 * 
64
 * @author 2005-2008 jaume dominguez faus - jaume.dominguez@iver.es
65
 * @author 2009- <a href="cordinyana@gvsig.org">C?sar Ordi?ana</a> - gvSIG team
66
 */
67
public class MultiShapeSymbol implements ILineSymbol, IMarkerSymbol, IFillSymbol, IMultiShapeSymbol {
68

    
69
        private static final Logger LOG = LoggerFactory.getLogger(MultiShapeSymbol.class); 
70

    
71
        public static final String MULTI_SHAPE_SYMBOL_PERSISTENCE_DEFINITION_NAME = "MultiShapeSymbol";
72
        
73
        private static final String FIELD_MARKER = "marker";
74
        private static final String FIELD_LINE = "line";
75
        private static final String FIELD_FILL = "fill";
76
        private static final String FIELD_DESCRIPTION = "description";
77

    
78
        public static final String SYMBOL_NAME = "multiShape";
79
        
80
        private SymbolManager manager = MapContextLocator.getSymbolManager();
81
        
82
        private IMarkerSymbol marker;
83
        private ILineSymbol line;
84
        private IFillSymbol fill;
85
        private IMask mask;
86
        private String desc;
87
        private int referenceSystem;
88
        private MultiShapeSymbol symSelect;
89
        
90
        public MultiShapeSymbol() {
91
                super();
92
                marker = (IMarkerSymbol) createSymbol(IMarkerSymbol.SYMBOL_NAME);
93
                line = (ILineSymbol) createSymbol(ILineSymbol.SYMBOL_NAME);
94
                fill = (IFillSymbol) createSymbol(IFillSymbol.SYMBOL_NAME);
95
        }
96
        
97
        private ISymbol createSymbol(String symbolName) {
98
                return manager.createSymbol(symbolName);
99
        }
100

    
101
        public Color getLineColor() {
102
                return line.getColor();
103
        }
104

    
105
        public void setLineColor(Color color) {
106
                line.setLineColor(color);
107
        }
108

    
109
        public ILineStyle getLineStyle() {
110
                return line.getLineStyle();
111
        }
112

    
113
        public void setLineStyle(ILineStyle lineStyle) {
114
                line.setLineStyle(lineStyle);
115
        }
116

    
117
        public void setLineWidth(double width) {
118
                line.setLineWidth(width);
119
        }
120

    
121
        public double getLineWidth() {
122
                return line.getLineWidth();
123
        }
124

    
125
        public int getAlpha() {
126
                return line.getAlpha();
127
        }
128

    
129
        public void setAlpha(int outlineAlpha) {
130
                line.setAlpha(outlineAlpha);
131
        }
132

    
133
        public ISymbol getSymbolForSelection() {
134
                if (symSelect == null) {
135
                        symSelect = new MultiShapeSymbol();
136
                }
137

    
138
                if (marker!=null){
139
                        symSelect.setMarkerSymbol((IMarkerSymbol) marker.getSymbolForSelection());
140
                }
141

    
142
                if (line!=null){
143
                        symSelect.setLineSymbol((ILineSymbol) line.getSymbolForSelection());
144
                }
145

    
146
                if (fill!=null ){
147
                        symSelect.setFillSymbol((IFillSymbol) fill.getSymbolForSelection());
148
                }
149

    
150
                return symSelect;
151

    
152
        }
153

    
154
        public void draw(Graphics2D g, AffineTransform affineTransform,
155
                        Geometry geom, Feature feature, Cancellable cancel) {
156
            GeometryType geometryType = geom.getGeometryType();
157
            if (geometryType.isTypeOf(Geometry.TYPES.POINT)){
158
                if (marker != null) {
159
                    marker.draw(g, affineTransform, geom, feature, cancel);
160
                }
161
            }else if (geometryType.isTypeOf(Geometry.TYPES.CURVE)){
162
                if (line != null) {
163
                    line.draw(g, affineTransform, geom, feature, cancel);
164
                }
165
            }else if (geometryType.isTypeOf(Geometry.TYPES.SURFACE)){
166
                if (fill != null) {
167
                    fill.draw(g, affineTransform, geom, feature, cancel);
168
                }                        
169
            }else if (geometryType.isTypeOf(Geometry.TYPES.AGGREGATE)){
170
                Aggregate aggregate = (Aggregate)geom;
171
                for (int i=0 ; i<aggregate.getPrimitivesNumber() ; i++){
172
                    draw(g, affineTransform, aggregate.getPrimitiveAt(i), feature, cancel);
173
                }
174
            }
175
        }
176
        
177
        public boolean isOneDotOrPixel(Geometry geom,
178
                        double[] positionOfDotOrPixel, ViewPort viewPort, int dpi) {
179
                switch (geom.getType()) {
180
                case Geometry.TYPES.POINT: //Tipo punto
181
                   if (marker != null) {
182
                                return marker.isOneDotOrPixel(geom, positionOfDotOrPixel, viewPort, dpi);
183
                        }
184
                        break;
185
                case Geometry.TYPES.CURVE:
186
                case Geometry.TYPES.ARC:
187
                case Geometry.TYPES.SPLINE:
188
                if (line != null) {
189
                                return line.isOneDotOrPixel(geom, positionOfDotOrPixel, viewPort, dpi);
190
                        }
191
                        break;
192

    
193
                case Geometry.TYPES.SURFACE:
194
        case Geometry.TYPES.ELLIPSE:
195
                case Geometry.TYPES.CIRCLE:
196
                        if (fill != null) {
197
                                return fill.isOneDotOrPixel(geom, positionOfDotOrPixel, viewPort, dpi);
198
                        }
199
                        break;
200
                }
201
                if (!geom.isSimple()){
202
                        Aggregate aggregate = (Aggregate)geom;                        
203
                        for (int i=0 ; i<aggregate.getPrimitivesNumber() ; i++){
204
                                if (!isOneDotOrPixel(aggregate.getPrimitiveAt(i), positionOfDotOrPixel, viewPort, dpi)){
205
                                        return false;
206
                                }
207
                        }
208
                        return true;
209
                }
210
                return true;
211
        }
212

    
213
        public void getPixExtentPlus(Geometry geom, float[] distances,
214
                        ViewPort viewPort, int dpi) {
215
                // TODO Implement it
216
                throw new Error("Not yet implemented!");
217

    
218
        }
219

    
220
        public int getOnePointRgb() {
221
                // will return a mixture of all symbol's getOnePointRgb() value
222

    
223
                int rMarker = 0;
224
                int gMarker = 0;
225
                int bMarker = 0;
226
                int aMarker = 0;
227

    
228
                if (marker!=null && marker.getColor() != null) {
229
                        rMarker = marker.getColor().getRed();
230
                        gMarker = marker.getColor().getGreen();
231
                        bMarker = marker.getColor().getBlue();
232
                        aMarker = marker.getColor().getAlpha();
233
                }
234

    
235
                int rLine = 0;
236
                int gLine = 0;
237
                int bLine = 0;
238
                int aLine = 0;
239

    
240
                if (line != null  && line.getColor() != null) {
241
                        rLine = line.getColor().getRed();
242
                        gLine = line.getColor().getGreen();
243
                        bLine = line.getColor().getBlue();
244
                        aLine = line.getColor().getAlpha();
245
                }
246

    
247
                int rFill = 0;
248
                int gFill = 0;
249
                int bFill = 0;
250
                int aFill = 0;
251

    
252
                if (fill != null ) {
253
                        Color colorOfFill = null;
254
                        if (fill.getOutline()!=null) {
255
                                colorOfFill = fill.getOutline().getColor();
256
                        } else if (fill.getFillColor()!=null) {
257
                                colorOfFill = fill.getFillColor();
258
                        }
259
                        if (colorOfFill != null) {
260
                                rFill = colorOfFill.getRed();
261
                                gFill = colorOfFill.getGreen();
262
                                bFill = colorOfFill.getBlue();
263
                                aFill = colorOfFill.getAlpha();
264

    
265
                        }
266
                }
267

    
268
                int red = (rMarker + rLine + rFill) / 3;
269
                int green = (gMarker + gLine + gFill) / 3;
270
                int blue = (bMarker + bLine + bFill) / 3;
271
                int alpha = (aMarker + aLine + aFill) / 3;
272

    
273
                return (alpha) << 24 + (red << 16) + (green << 8) + blue;
274
        }
275

    
276
        public String getDescription() {
277
                return desc;
278
        }
279

    
280
        public boolean isShapeVisible() {
281
                if (marker!=null) {
282
                        return marker.isShapeVisible();
283
                }
284

    
285
                if (line != null) {
286
                        return line.isShapeVisible();
287
                }
288

    
289
                if (fill != null) {
290
                        fill.isShapeVisible();
291
                }
292

    
293
                return false;
294
        }
295

    
296
        public void setDescription(String desc) {
297
                this.desc = desc ;
298
        }
299

    
300
        public int getSymbolType() {
301
                return Geometry.TYPES.GEOMETRY;
302
        }
303

    
304
        public boolean isSuitableFor(Geometry geom) {
305
                // suitable for everything (why else does it exist?)
306
                return true;
307
        }
308

    
309
        public void drawInsideRectangle(Graphics2D g,
310
                        AffineTransform scaleInstance, Rectangle r, PrintAttributes properties) throws SymbolDrawingException {
311
                double myWidth =  (r.getWidth()/3);
312

    
313
                Rectangle rect = new Rectangle(0, 0, (int) myWidth, r.height);
314

    
315
                if (marker != null) {
316
                        g.translate(r.x, r.y);
317
                        marker.drawInsideRectangle(g, scaleInstance, rect, properties);
318
                        g.translate(-(r.x), -(r.y));
319
                }
320

    
321
                if (line != null) {
322
                        g.translate(r.x+myWidth, r.y);
323
                        line.drawInsideRectangle(g, scaleInstance, rect, properties);
324
                        g.translate(-(r.x+myWidth), -(r.y));
325
                }
326

    
327
                if (fill != null) {
328
                        g.translate(r.x+myWidth+myWidth, r.y);
329
                        fill.drawInsideRectangle(g, scaleInstance, rect, properties);
330
                        g.translate(-(r.x+myWidth+myWidth), -(r.y));
331

    
332
                }
333
        }
334

    
335
//        public String getClassName() {
336
//                return getClass().getName();
337
//        }
338

    
339
        public void print(Graphics2D g, AffineTransform at, Geometry geom, PrintAttributes properties) {
340
                switch (geom.getType()) {
341
                case Geometry.TYPES.POINT: //Tipo punto
342
                   if (marker != null) {
343
                                marker.print(g, at, geom, properties);
344
                        }
345
                        break;
346
                case Geometry.TYPES.CURVE:
347
                case Geometry.TYPES.ARC:
348
                        if (line != null) {
349
                                line.print(g, at, geom, properties);
350
                        }
351
                        break;
352

    
353
                case Geometry.TYPES.SURFACE:
354
                case Geometry.TYPES.ELLIPSE:
355
        case Geometry.TYPES.CIRCLE:
356
                        if (fill != null) {
357
                                fill.print(g, at, geom, properties);
358
                        }
359
                        break;
360
                }
361
        }
362

    
363
        public double getRotation() {
364
                if (marker != null) {
365
                        return marker.getRotation();
366
                }
367
                return 0;
368
        }
369

    
370
        public void setRotation(double rotation) {
371
                if (marker != null) {
372
                        marker.setRotation(rotation);
373
                }
374
        }
375

    
376
        public Point2D getOffset() {
377
                if (marker != null) {
378
                        return marker.getOffset();
379
                }
380
                return new Point2D.Double();
381
        }
382

    
383
        public void setOffset(Point2D offset) {
384
                if (marker != null) {
385
                        marker.setOffset(offset);
386
                }
387
        }
388

    
389
        public double getSize() {
390
                if (marker != null) {
391
                        return marker.getSize();
392
                }
393
                return 0;
394
        }
395

    
396
        public void setSize(double size) {
397
                if (marker != null) {
398
                        marker.setSize(size);
399
                }
400

    
401
        }
402

    
403
        public Color getColor() {
404
                if (marker != null) {
405
                        return marker.getColor();
406
                }
407
                return null;
408
        }
409

    
410
        public void setColor(Color color) {
411
                if (marker != null) {
412
                        marker.setColor(color);
413
                }
414
        }
415

    
416
        public void setFillColor(Color color) {
417
                if (fill != null) {
418
                        fill.setFillColor(color);
419
                }
420
        }
421

    
422
        public void setOutline(ILineSymbol outline) {
423
                if (fill != null) {
424
                        fill.setOutline(outline);
425
                }
426
        }
427

    
428
        public Color getFillColor() {
429
                if (fill != null) {
430
                        return fill.getFillColor();
431
                }
432
                return null;
433
        }
434

    
435
        public ILineSymbol getOutline() {
436
                if (fill != null) {
437
                        return fill.getOutline();
438
                }
439
                return null;
440
        }
441

    
442
        public int getFillAlpha() {
443
                if (fill != null) {
444
                        return fill.getFillAlpha();
445
                }
446
                return 255;
447
        }
448

    
449
        public IMask getMask() {
450
                return mask;
451
        }
452

    
453
        public void setUnit(int unitIndex) {
454
                if (marker != null) {
455
                        marker.setUnit(unitIndex);
456
                }
457
                if (line != null) {
458
                        line.setUnit(unitIndex);
459
                }
460
        }
461

    
462
        public int getUnit() {
463
                if (marker != null) {
464
                        return marker.getUnit();
465
                }
466
                if (line != null) {
467
                        return line.getUnit();
468
                }
469
                return -1;
470
        }
471

    
472
        public void setMask(IMask mask) {
473
                // TODO Implement it
474
                throw new Error("Not yet implemented!");
475

    
476
        }
477

    
478
        public int getReferenceSystem() {
479
                return this.referenceSystem;
480
        }
481

    
482
        public void setReferenceSystem(int system) {
483
                this.referenceSystem = system;
484

    
485
        }
486

    
487
        public double toCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
488
                switch (geom.getType()) {
489
                case Geometry.TYPES.POINT: //Tipo punto
490
                if (marker != null) {
491
                                return marker.toCartographicSize(viewPort, dpi, geom);
492
                        }
493
                case Geometry.TYPES.CURVE:
494
                case Geometry.TYPES.ARC:
495
                        if (line != null) {
496
                                return line.toCartographicSize(viewPort, dpi, geom);
497
                        }
498
                case Geometry.TYPES.SURFACE:
499
                case Geometry.TYPES.ELLIPSE:
500
                case Geometry.TYPES.CIRCLE:
501
                        LOG.warn("Cartographic size does not have any sense for fill symbols");
502

    
503
                }
504
                return -1;
505
        }
506

    
507
        public void setCartographicSize(double cartographicSize, Geometry geom) {
508
                switch (geom.getType()) {
509
                case Geometry.TYPES.POINT: //Tipo punto
510
                if (marker != null) {
511
                                marker.setCartographicSize(cartographicSize, null);
512
                        }
513
                break;
514
                case Geometry.TYPES.CURVE:
515
                case Geometry.TYPES.ARC:
516
                        if (line != null) {
517
                                line.setCartographicSize(cartographicSize, null);
518
                        }
519
                break;
520
                case Geometry.TYPES.SURFACE:
521
                case Geometry.TYPES.ELLIPSE:
522
            case Geometry.TYPES.CIRCLE:
523
                    LOG.warn("Cartographic size does not have any sense for fill symbols");
524
                }
525
        }
526

    
527

    
528
        public double getCartographicSize(ViewPort viewPort, double dpi, Geometry geom) {
529
                switch (geom.getType()) {
530
                case Geometry.TYPES.POINT: //Tipo punto
531
                return CartographicSupportToolkit.
532
                        getCartographicLength(marker,
533
                                                                  getSize(),
534
                                                                  viewPort,
535
                                                                  dpi);
536
                case Geometry.TYPES.CURVE:
537
                case Geometry.TYPES.ARC:
538
                        return CartographicSupportToolkit.
539
                        getCartographicLength(line,
540
                                                                  getSize(),
541
                                                                  viewPort,
542
                                                                  dpi);
543
                case Geometry.TYPES.SURFACE:
544
             case Geometry.TYPES.ELLIPSE:
545
            case Geometry.TYPES.CIRCLE:
546
                    LOG.warn("Cartographic size does not have any sense for fill symbols");
547
                }
548
                return -1;
549
        }
550

    
551
        public IMarkerSymbol getMarkerSymbol() {
552
                return marker;
553
        }
554

    
555
        public ILineSymbol getLineSymbol() {
556
                return line;
557
        }
558

    
559
        public IFillSymbol getFillSymbol() {
560
                return fill;
561
        }
562

    
563
        public void setMarkerSymbol(IMarkerSymbol markerSymbol) {
564
                this.marker = markerSymbol;
565
        }
566

    
567
        public void setLineSymbol(ILineSymbol lineSymbol) {
568
                this.line = lineSymbol;
569
        }
570

    
571
        public void setFillSymbol(IFillSymbol fillFillSymbol) {
572
                this.fill = fillFillSymbol;
573
        }
574

    
575
        public boolean hasFill() {
576
        if (fill == null) {
577
                return false;
578
        }
579
        return fill.hasFill();
580
        }
581

    
582
        public void setHasFill(boolean hasFill) {
583
                if (fill != null) {
584
                        fill.setHasFill(hasFill);
585
//                        this.hasFill = hasFill;
586
                }
587
        }
588

    
589
        public boolean hasOutline() {
590
                // TODO Auto-generated method stub
591
                return false;
592
        }
593

    
594
        public void setHasOutline(boolean hasOutline) {
595
                // TODO Auto-generated method stub
596

    
597
        }
598

    
599
        public Object clone() throws CloneNotSupportedException {
600
                MultiShapeSymbol copy = (MultiShapeSymbol) super.clone();
601

    
602
                // Clone inner symbols
603
                if (marker != null) {
604
                        copy.marker = (IMarkerSymbol) marker.clone();
605
                }
606
                if (line != null) {
607
                        copy.line = (ILineSymbol) line.clone();
608
                }
609
                if (fill != null) {
610
                        copy.fill = (IFillSymbol) fill.clone();
611
                }
612
                
613
                if (mask != null) {
614
                        copy.mask = (IMask) mask.clone();
615
                }
616
                
617
                // Clone selection symbol
618
                if (symSelect != null) {
619
                        copy.symSelect = (MultiShapeSymbol) symSelect.clone();
620
                }
621
                
622
                return copy;
623
        }
624

    
625
        public void loadFromState(PersistentState state)
626
                        throws PersistenceException {
627
                setDescription(state.getString(FIELD_DESCRIPTION));
628
                setFillSymbol((IFillSymbol) state.get(FIELD_FILL));
629
                setMarkerSymbol((IMarkerSymbol) state.get(FIELD_MARKER));
630
                setLineSymbol((ILineSymbol) state.get(FIELD_LINE));
631
        }
632

    
633
        public void saveToState(PersistentState state) throws PersistenceException {
634
                state.set(FIELD_DESCRIPTION, getDescription());
635
                state.set(FIELD_FILL, getFillSymbol());
636
                state.set(FIELD_MARKER, getMarkerSymbol());
637
                state.set(FIELD_LINE, getLineSymbol());
638
        }
639

    
640
        public static class RegisterPersistence implements Callable {
641

    
642
                public Object call() throws Exception {
643
                        PersistenceManager manager = ToolsLocator.getPersistenceManager();
644
                        if( manager.getDefinition(MULTI_SHAPE_SYMBOL_PERSISTENCE_DEFINITION_NAME)==null ) {
645
                                DynStruct definition = manager.addDefinition(
646
                                                MultiShapeSymbol.class,
647
                                                MULTI_SHAPE_SYMBOL_PERSISTENCE_DEFINITION_NAME,
648
                                                MULTI_SHAPE_SYMBOL_PERSISTENCE_DEFINITION_NAME+" Persistence definition",
649
                                                null, 
650
                                                null
651
                                );
652
                                // Description
653
                                definition.addDynFieldString(FIELD_DESCRIPTION).setMandatory(false);
654
                                // Fill symbol
655
                                definition.addDynFieldObject(FIELD_FILL).setClassOfValue(IFillSymbol.class).setMandatory(true);
656
                                // Line symbol
657
                                definition.addDynFieldObject(FIELD_LINE).setClassOfValue(ILineSymbol.class).setMandatory(true);
658
                                // Marker symbol
659
                                definition.addDynFieldObject(FIELD_MARKER).setClassOfValue(IMarkerSymbol.class).setMandatory(true);
660
                        }
661
                        return Boolean.TRUE;
662
                }
663
                
664
        }
665

    
666
        public static class RegisterSymbol implements Callable {
667

    
668
                public Object call() throws Exception {
669
                int[] shapeTypes;
670
                SymbolManager manager = MapContextLocator.getSymbolManager();
671
                
672
                shapeTypes = new int[] { Geometry.TYPES.GEOMETRY };
673
                manager.registerSymbol(MultiShapeSymbol.SYMBOL_NAME,
674
                    shapeTypes,
675
                    MultiShapeSymbol.class
676
                );
677
                        return Boolean.TRUE;
678
                }
679
                
680
        }
681
        
682
}