001package Torello.Browser;
002
003import java.util.*;
004import javax.json.*;
005import javax.json.stream.*;
006import java.io.*;
007
008import java.lang.reflect.Method;
009import java.lang.reflect.Parameter;
010import java.util.function.Function;
011
012import Torello.Java.Additional.*;
013import Torello.Java.JSON.*;
014
015import static Torello.Java.JSON.JFlag.*;
016
017import Torello.Java.StrCmpr;
018import Torello.JavaDoc.StaticFunctional;
019import Torello.JavaDoc.JDHeaderBackgroundImg;
020import Torello.JavaDoc.Excuse;
021
022/**
023 * <SPAN CLASS=COPIEDJDK><B><CODE>[No Description Provided by Google]</CODE></B></SPAN>
024 * 
025 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
026 */
027@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
028@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
029public class LayerTree
030{
031    // ********************************************************************************************
032    // ********************************************************************************************
033    // Class Header Stuff
034    // ********************************************************************************************
035    // ********************************************************************************************
036
037
038    // No Pubic Constructors
039    private LayerTree () { }
040
041    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
042    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
043    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
044    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
045
046    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
047    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
048    // offically, two empty-vectors.  One for String's, and the other for Classes.
049
050    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
051    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
052
053    static
054    {
055        for (Method m : LayerTree.class.getMethods())
056        {
057            // This doesn't work!  The parameter names are all "arg0" ... "argN"
058            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
059            //
060            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
061
062            Vector<Class<?>> parameterTypesList = new Vector<>();
063        
064            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
065
066            parameterTypes.put(
067                m.getName(),
068                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
069            );
070        }
071    }
072
073    static
074    {
075        Vector<String> v = null;
076
077        v = new Vector<String>(1);
078        parameterNames.put("compositingReasons", v);
079        Collections.addAll(v, new String[]
080        { "layerId", });
081
082        parameterNames.put("disable", EMPTY_VEC_STR);
083
084        parameterNames.put("enable", EMPTY_VEC_STR);
085
086        v = new Vector<String>(1);
087        parameterNames.put("loadSnapshot", v);
088        Collections.addAll(v, new String[]
089        { "tiles", });
090
091        v = new Vector<String>(1);
092        parameterNames.put("makeSnapshot", v);
093        Collections.addAll(v, new String[]
094        { "layerId", });
095
096        v = new Vector<String>(4);
097        parameterNames.put("profileSnapshot", v);
098        Collections.addAll(v, new String[]
099        { "snapshotId", "minRepeatCount", "minDuration", "clipRect", });
100
101        v = new Vector<String>(1);
102        parameterNames.put("releaseSnapshot", v);
103        Collections.addAll(v, new String[]
104        { "snapshotId", });
105
106        v = new Vector<String>(4);
107        parameterNames.put("replaySnapshot", v);
108        Collections.addAll(v, new String[]
109        { "snapshotId", "fromStep", "toStep", "scale", });
110
111        v = new Vector<String>(1);
112        parameterNames.put("snapshotCommandLog", v);
113        Collections.addAll(v, new String[]
114        { "snapshotId", });
115    }
116
117
118    // ********************************************************************************************
119    // ********************************************************************************************
120    // Types - Static Inner Classes
121    // ********************************************************************************************
122    // ********************************************************************************************
123
124    // public static class LayerId => String
125    
126    // public static class SnapshotId => String
127    
128    // public static class PaintProfile => Number[]
129    
130    /** Rectangle where scrolling happens on the main thread. */
131    public static class ScrollRect
132        extends BaseType
133        implements java.io.Serializable
134    {
135        /** For Object Serialization.  java.io.Serializable */
136        protected static final long serialVersionUID = 1;
137        
138        public boolean[] optionals()
139        { return new boolean[] { false, false, }; }
140        
141        /** Rectangle itself. */
142        public final DOM.Rect rect;
143        
144        /** Reason for rectangle to force scrolling on the main thread */
145        public final String type;
146        
147        /**
148         * Constructor
149         *
150         * @param rect Rectangle itself.
151         * 
152         * @param type Reason for rectangle to force scrolling on the main thread
153         * <BR />Acceptable Values: ["RepaintsOnScroll", "TouchEventHandler", "WheelEventHandler"]
154         */
155        public ScrollRect(DOM.Rect rect, String type)
156        {
157            // Exception-Check(s) to ensure that if any parameters which are not declared as
158            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
159            
160            if (rect == null) THROWS.throwNPE("rect");
161            if (type == null) THROWS.throwNPE("type");
162            
163            // Exception-Check(s) to ensure that if any parameters which must adhere to a
164            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
165            
166            THROWS.checkIAE(
167                "type", type,
168                "RepaintsOnScroll", "TouchEventHandler", "WheelEventHandler"
169            );
170            
171            this.rect  = rect;
172            this.type  = type;
173        }
174        
175        /**
176         * JSON Object Constructor
177         * @param jo A Json-Object having data about an instance of {@code 'ScrollRect'}.
178         */
179        public ScrollRect (JsonObject jo)
180        {
181            this.rect  = ReadJSON.getObject(jo, "rect", DOM.Rect.class, false, true);
182            this.type  = ReadJSON.getString(jo, "type", false, true);
183        }
184        
185        
186        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
187        public boolean equals(Object other)
188        {
189            if (this == other)                       return true;
190            if (other == null)                       return false;
191            if (other.getClass() != this.getClass()) return false;
192        
193            ScrollRect o = (ScrollRect) other;
194        
195            return
196                    Objects.equals(this.rect, o.rect)
197                &&  Objects.equals(this.type, o.type);
198        }
199        
200        /** Generates a Hash-Code for {@code 'this'} instance */
201        public int hashCode()
202        {
203            return
204                    this.rect.hashCode()
205                +   Objects.hashCode(this.type);
206        }
207    }
208    
209    /** Sticky position constraints. */
210    public static class StickyPositionConstraint
211        extends BaseType
212        implements java.io.Serializable
213    {
214        /** For Object Serialization.  java.io.Serializable */
215        protected static final long serialVersionUID = 1;
216        
217        public boolean[] optionals()
218        { return new boolean[] { false, false, true, true, }; }
219        
220        /** Layout rectangle of the sticky element before being shifted */
221        public final DOM.Rect stickyBoxRect;
222        
223        /** Layout rectangle of the containing block of the sticky element */
224        public final DOM.Rect containingBlockRect;
225        
226        /**
227         * The nearest sticky layer that shifts the sticky box
228         * <BR />
229         * <BR /><B>OPTIONAL</B>
230         */
231        public final String nearestLayerShiftingStickyBox;
232        
233        /**
234         * The nearest sticky layer that shifts the containing block
235         * <BR />
236         * <BR /><B>OPTIONAL</B>
237         */
238        public final String nearestLayerShiftingContainingBlock;
239        
240        /**
241         * Constructor
242         *
243         * @param stickyBoxRect Layout rectangle of the sticky element before being shifted
244         * 
245         * @param containingBlockRect Layout rectangle of the containing block of the sticky element
246         * 
247         * @param nearestLayerShiftingStickyBox The nearest sticky layer that shifts the sticky box
248         * <BR /><B>OPTIONAL</B>
249         * 
250         * @param nearestLayerShiftingContainingBlock The nearest sticky layer that shifts the containing block
251         * <BR /><B>OPTIONAL</B>
252         */
253        public StickyPositionConstraint(
254                DOM.Rect stickyBoxRect, DOM.Rect containingBlockRect, 
255                String nearestLayerShiftingStickyBox, String nearestLayerShiftingContainingBlock
256            )
257        {
258            // Exception-Check(s) to ensure that if any parameters which are not declared as
259            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
260            
261            if (stickyBoxRect == null)       THROWS.throwNPE("stickyBoxRect");
262            if (containingBlockRect == null) THROWS.throwNPE("containingBlockRect");
263            
264            this.stickyBoxRect                        = stickyBoxRect;
265            this.containingBlockRect                  = containingBlockRect;
266            this.nearestLayerShiftingStickyBox        = nearestLayerShiftingStickyBox;
267            this.nearestLayerShiftingContainingBlock  = nearestLayerShiftingContainingBlock;
268        }
269        
270        /**
271         * JSON Object Constructor
272         * @param jo A Json-Object having data about an instance of {@code 'StickyPositionConstraint'}.
273         */
274        public StickyPositionConstraint (JsonObject jo)
275        {
276            this.stickyBoxRect                        = ReadJSON.getObject(jo, "stickyBoxRect", DOM.Rect.class, false, true);
277            this.containingBlockRect                  = ReadJSON.getObject(jo, "containingBlockRect", DOM.Rect.class, false, true);
278            this.nearestLayerShiftingStickyBox        = ReadJSON.getString(jo, "nearestLayerShiftingStickyBox", true, false);
279            this.nearestLayerShiftingContainingBlock  = ReadJSON.getString(jo, "nearestLayerShiftingContainingBlock", true, false);
280        }
281        
282        
283        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
284        public boolean equals(Object other)
285        {
286            if (this == other)                       return true;
287            if (other == null)                       return false;
288            if (other.getClass() != this.getClass()) return false;
289        
290            StickyPositionConstraint o = (StickyPositionConstraint) other;
291        
292            return
293                    Objects.equals(this.stickyBoxRect, o.stickyBoxRect)
294                &&  Objects.equals(this.containingBlockRect, o.containingBlockRect)
295                &&  Objects.equals(this.nearestLayerShiftingStickyBox, o.nearestLayerShiftingStickyBox)
296                &&  Objects.equals(this.nearestLayerShiftingContainingBlock, o.nearestLayerShiftingContainingBlock);
297        }
298        
299        /** Generates a Hash-Code for {@code 'this'} instance */
300        public int hashCode()
301        {
302            return
303                    this.stickyBoxRect.hashCode()
304                +   this.containingBlockRect.hashCode()
305                +   Objects.hashCode(this.nearestLayerShiftingStickyBox)
306                +   Objects.hashCode(this.nearestLayerShiftingContainingBlock);
307        }
308    }
309    
310    /** Serialized fragment of layer picture along with its offset within the layer. */
311    public static class PictureTile
312        extends BaseType
313        implements java.io.Serializable
314    {
315        /** For Object Serialization.  java.io.Serializable */
316        protected static final long serialVersionUID = 1;
317        
318        public boolean[] optionals()
319        { return new boolean[] { false, false, false, }; }
320        
321        /** Offset from owning layer left boundary */
322        public final Number x;
323        
324        /** Offset from owning layer top boundary */
325        public final Number y;
326        
327        /** Base64-encoded snapshot data. (Encoded as a base64 string when passed over JSON) */
328        public final String picture;
329        
330        /**
331         * Constructor
332         *
333         * @param x Offset from owning layer left boundary
334         * 
335         * @param y Offset from owning layer top boundary
336         * 
337         * @param picture Base64-encoded snapshot data. (Encoded as a base64 string when passed over JSON)
338         */
339        public PictureTile(Number x, Number y, String picture)
340        {
341            // Exception-Check(s) to ensure that if any parameters which are not declared as
342            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
343            
344            if (x == null)       THROWS.throwNPE("x");
345            if (y == null)       THROWS.throwNPE("y");
346            if (picture == null) THROWS.throwNPE("picture");
347            
348            this.x        = x;
349            this.y        = y;
350            this.picture  = picture;
351        }
352        
353        /**
354         * JSON Object Constructor
355         * @param jo A Json-Object having data about an instance of {@code 'PictureTile'}.
356         */
357        public PictureTile (JsonObject jo)
358        {
359            this.x        = ReadNumberJSON.get(jo, "x", false, true);
360            this.y        = ReadNumberJSON.get(jo, "y", false, true);
361            this.picture  = ReadJSON.getString(jo, "picture", false, true);
362        }
363        
364        
365        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
366        public boolean equals(Object other)
367        {
368            if (this == other)                       return true;
369            if (other == null)                       return false;
370            if (other.getClass() != this.getClass()) return false;
371        
372            PictureTile o = (PictureTile) other;
373        
374            return
375                    Objects.equals(this.x, o.x)
376                &&  Objects.equals(this.y, o.y)
377                &&  Objects.equals(this.picture, o.picture);
378        }
379        
380        /** Generates a Hash-Code for {@code 'this'} instance */
381        public int hashCode()
382        {
383            return
384                    Objects.hashCode(this.x)
385                +   Objects.hashCode(this.y)
386                +   Objects.hashCode(this.picture);
387        }
388    }
389    
390    /** Information about a compositing layer. */
391    public static class Layer
392        extends BaseType
393        implements java.io.Serializable
394    {
395        /** For Object Serialization.  java.io.Serializable */
396        protected static final long serialVersionUID = 1;
397        
398        public boolean[] optionals()
399        { return new boolean[] { false, true, true, false, false, false, false, true, true, true, true, false, false, true, true, true, }; }
400        
401        /** The unique id for this layer. */
402        public final String layerId;
403        
404        /**
405         * The id of parent (not present for root).
406         * <BR />
407         * <BR /><B>OPTIONAL</B>
408         */
409        public final String parentLayerId;
410        
411        /**
412         * The backend id for the node associated with this layer.
413         * <BR />
414         * <BR /><B>OPTIONAL</B>
415         */
416        public final Integer backendNodeId;
417        
418        /** Offset from parent layer, X coordinate. */
419        public final Number offsetX;
420        
421        /** Offset from parent layer, Y coordinate. */
422        public final Number offsetY;
423        
424        /** Layer width. */
425        public final Number width;
426        
427        /** Layer height. */
428        public final Number height;
429        
430        /**
431         * Transformation matrix for layer, default is identity matrix
432         * <BR />
433         * <BR /><B>OPTIONAL</B>
434         */
435        public final Number[] transform;
436        
437        /**
438         * Transform anchor point X, absent if no transform specified
439         * <BR />
440         * <BR /><B>OPTIONAL</B>
441         */
442        public final Number anchorX;
443        
444        /**
445         * Transform anchor point Y, absent if no transform specified
446         * <BR />
447         * <BR /><B>OPTIONAL</B>
448         */
449        public final Number anchorY;
450        
451        /**
452         * Transform anchor point Z, absent if no transform specified
453         * <BR />
454         * <BR /><B>OPTIONAL</B>
455         */
456        public final Number anchorZ;
457        
458        /** Indicates how many time this layer has painted. */
459        public final int paintCount;
460        
461        /**
462         * Indicates whether this layer hosts any content, rather than being used for
463         * transform/scrolling purposes only.
464         */
465        public final boolean drawsContent;
466        
467        /**
468         * Set if layer is not visible.
469         * <BR />
470         * <BR /><B>OPTIONAL</B>
471         */
472        public final Boolean invisible;
473        
474        /**
475         * Rectangles scrolling on main thread only.
476         * <BR />
477         * <BR /><B>OPTIONAL</B>
478         */
479        public final LayerTree.ScrollRect[] scrollRects;
480        
481        /**
482         * Sticky position constraint information
483         * <BR />
484         * <BR /><B>OPTIONAL</B>
485         */
486        public final LayerTree.StickyPositionConstraint stickyPositionConstraint;
487        
488        /**
489         * Constructor
490         *
491         * @param layerId The unique id for this layer.
492         * 
493         * @param parentLayerId The id of parent (not present for root).
494         * <BR /><B>OPTIONAL</B>
495         * 
496         * @param backendNodeId The backend id for the node associated with this layer.
497         * <BR /><B>OPTIONAL</B>
498         * 
499         * @param offsetX Offset from parent layer, X coordinate.
500         * 
501         * @param offsetY Offset from parent layer, Y coordinate.
502         * 
503         * @param width Layer width.
504         * 
505         * @param height Layer height.
506         * 
507         * @param transform Transformation matrix for layer, default is identity matrix
508         * <BR /><B>OPTIONAL</B>
509         * 
510         * @param anchorX Transform anchor point X, absent if no transform specified
511         * <BR /><B>OPTIONAL</B>
512         * 
513         * @param anchorY Transform anchor point Y, absent if no transform specified
514         * <BR /><B>OPTIONAL</B>
515         * 
516         * @param anchorZ Transform anchor point Z, absent if no transform specified
517         * <BR /><B>OPTIONAL</B>
518         * 
519         * @param paintCount Indicates how many time this layer has painted.
520         * 
521         * @param drawsContent 
522         * Indicates whether this layer hosts any content, rather than being used for
523         * transform/scrolling purposes only.
524         * 
525         * @param invisible Set if layer is not visible.
526         * <BR /><B>OPTIONAL</B>
527         * 
528         * @param scrollRects Rectangles scrolling on main thread only.
529         * <BR /><B>OPTIONAL</B>
530         * 
531         * @param stickyPositionConstraint Sticky position constraint information
532         * <BR /><B>OPTIONAL</B>
533         */
534        public Layer(
535                String layerId, String parentLayerId, Integer backendNodeId, Number offsetX, 
536                Number offsetY, Number width, Number height, Number[] transform, Number anchorX, 
537                Number anchorY, Number anchorZ, int paintCount, boolean drawsContent, 
538                Boolean invisible, LayerTree.ScrollRect[] scrollRects, 
539                LayerTree.StickyPositionConstraint stickyPositionConstraint
540            )
541        {
542            // Exception-Check(s) to ensure that if any parameters which are not declared as
543            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
544            
545            if (layerId == null) THROWS.throwNPE("layerId");
546            if (offsetX == null) THROWS.throwNPE("offsetX");
547            if (offsetY == null) THROWS.throwNPE("offsetY");
548            if (width == null)   THROWS.throwNPE("width");
549            if (height == null)  THROWS.throwNPE("height");
550            
551            this.layerId                   = layerId;
552            this.parentLayerId             = parentLayerId;
553            this.backendNodeId             = backendNodeId;
554            this.offsetX                   = offsetX;
555            this.offsetY                   = offsetY;
556            this.width                     = width;
557            this.height                    = height;
558            this.transform                 = transform;
559            this.anchorX                   = anchorX;
560            this.anchorY                   = anchorY;
561            this.anchorZ                   = anchorZ;
562            this.paintCount                = paintCount;
563            this.drawsContent              = drawsContent;
564            this.invisible                 = invisible;
565            this.scrollRects               = scrollRects;
566            this.stickyPositionConstraint  = stickyPositionConstraint;
567        }
568        
569        /**
570         * JSON Object Constructor
571         * @param jo A Json-Object having data about an instance of {@code 'Layer'}.
572         */
573        public Layer (JsonObject jo)
574        {
575            this.layerId                   = ReadJSON.getString(jo, "layerId", false, true);
576            this.parentLayerId             = ReadJSON.getString(jo, "parentLayerId", true, false);
577            this.backendNodeId             = ReadBoxedJSON.getInteger(jo, "backendNodeId", true);
578            this.offsetX                   = ReadNumberJSON.get(jo, "offsetX", false, true);
579            this.offsetY                   = ReadNumberJSON.get(jo, "offsetY", false, true);
580            this.width                     = ReadNumberJSON.get(jo, "width", false, true);
581            this.height                    = ReadNumberJSON.get(jo, "height", false, true);
582            this.transform = (jo.getJsonArray("transform") == null)
583                ? null
584                : RJArrIntoBoxedStream.numberArr(jo.getJsonArray("transform"), -1, 0, null).toArray(Number[]::new);
585        
586            this.anchorX                   = ReadNumberJSON.get(jo, "anchorX", true, false);
587            this.anchorY                   = ReadNumberJSON.get(jo, "anchorY", true, false);
588            this.anchorZ                   = ReadNumberJSON.get(jo, "anchorZ", true, false);
589            this.paintCount                = ReadPrimJSON.getInt(jo, "paintCount");
590            this.drawsContent              = ReadPrimJSON.getBoolean(jo, "drawsContent");
591            this.invisible                 = ReadBoxedJSON.getBoolean(jo, "invisible", true);
592            this.scrollRects = (jo.getJsonArray("scrollRects") == null)
593                ? null
594                : RJArrIntoStream.objArr(jo.getJsonArray("scrollRects"), null, 0, LayerTree.ScrollRect.class).toArray(LayerTree.ScrollRect[]::new);
595        
596            this.stickyPositionConstraint  = ReadJSON.getObject(jo, "stickyPositionConstraint", LayerTree.StickyPositionConstraint.class, true, false);
597        }
598        
599        
600        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
601        public boolean equals(Object other)
602        {
603            if (this == other)                       return true;
604            if (other == null)                       return false;
605            if (other.getClass() != this.getClass()) return false;
606        
607            Layer o = (Layer) other;
608        
609            return
610                    Objects.equals(this.layerId, o.layerId)
611                &&  Objects.equals(this.parentLayerId, o.parentLayerId)
612                &&  Objects.equals(this.backendNodeId, o.backendNodeId)
613                &&  Objects.equals(this.offsetX, o.offsetX)
614                &&  Objects.equals(this.offsetY, o.offsetY)
615                &&  Objects.equals(this.width, o.width)
616                &&  Objects.equals(this.height, o.height)
617                &&  Arrays.deepEquals(this.transform, o.transform)
618                &&  Objects.equals(this.anchorX, o.anchorX)
619                &&  Objects.equals(this.anchorY, o.anchorY)
620                &&  Objects.equals(this.anchorZ, o.anchorZ)
621                &&  (this.paintCount == o.paintCount)
622                &&  (this.drawsContent == o.drawsContent)
623                &&  Objects.equals(this.invisible, o.invisible)
624                &&  Arrays.deepEquals(this.scrollRects, o.scrollRects)
625                &&  Objects.equals(this.stickyPositionConstraint, o.stickyPositionConstraint);
626        }
627        
628        /** Generates a Hash-Code for {@code 'this'} instance */
629        public int hashCode()
630        {
631            return
632                    Objects.hashCode(this.layerId)
633                +   Objects.hashCode(this.parentLayerId)
634                +   Objects.hashCode(this.backendNodeId)
635                +   Objects.hashCode(this.offsetX)
636                +   Objects.hashCode(this.offsetY)
637                +   Objects.hashCode(this.width)
638                +   Objects.hashCode(this.height)
639                +   Arrays.deepHashCode(this.transform)
640                +   Objects.hashCode(this.anchorX)
641                +   Objects.hashCode(this.anchorY)
642                +   Objects.hashCode(this.anchorZ)
643                +   this.paintCount
644                +   (this.drawsContent ? 1 : 0)
645                +   Objects.hashCode(this.invisible)
646                +   Arrays.deepHashCode(this.scrollRects)
647                +   this.stickyPositionConstraint.hashCode();
648        }
649    }
650    
651    /** <CODE>[No Description Provided by Google]</CODE> */
652    public static class layerPainted
653        extends BrowserEvent
654        implements java.io.Serializable
655    {
656        /** For Object Serialization.  java.io.Serializable */
657        protected static final long serialVersionUID = 1;
658        
659        public boolean[] optionals()
660        { return new boolean[] { false, false, }; }
661        
662        /** The id of the painted layer. */
663        public final String layerId;
664        
665        /** Clip rectangle. */
666        public final DOM.Rect clip;
667        
668        /**
669         * Constructor
670         *
671         * @param layerId The id of the painted layer.
672         * 
673         * @param clip Clip rectangle.
674         */
675        public layerPainted(String layerId, DOM.Rect clip)
676        {
677            super("LayerTree", "layerPainted", 2);
678            
679            // Exception-Check(s) to ensure that if any parameters which are not declared as
680            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
681            
682            if (layerId == null) THROWS.throwNPE("layerId");
683            if (clip == null)    THROWS.throwNPE("clip");
684            
685            this.layerId  = layerId;
686            this.clip     = clip;
687        }
688        
689        /**
690         * JSON Object Constructor
691         * @param jo A Json-Object having data about an instance of {@code 'layerPainted'}.
692         */
693        public layerPainted (JsonObject jo)
694        {
695            super("LayerTree", "layerPainted", 2);
696        
697            this.layerId  = ReadJSON.getString(jo, "layerId", false, true);
698            this.clip     = ReadJSON.getObject(jo, "clip", DOM.Rect.class, false, true);
699        }
700        
701        
702        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
703        public boolean equals(Object other)
704        {
705            if (this == other)                       return true;
706            if (other == null)                       return false;
707            if (other.getClass() != this.getClass()) return false;
708        
709            layerPainted o = (layerPainted) other;
710        
711            return
712                    Objects.equals(this.layerId, o.layerId)
713                &&  Objects.equals(this.clip, o.clip);
714        }
715        
716        /** Generates a Hash-Code for {@code 'this'} instance */
717        public int hashCode()
718        {
719            return
720                    Objects.hashCode(this.layerId)
721                +   this.clip.hashCode();
722        }
723    }
724    
725    /** <CODE>[No Description Provided by Google]</CODE> */
726    public static class layerTreeDidChange
727        extends BrowserEvent
728        implements java.io.Serializable
729    {
730        /** For Object Serialization.  java.io.Serializable */
731        protected static final long serialVersionUID = 1;
732        
733        public boolean[] optionals()
734        { return new boolean[] { true, }; }
735        
736        /**
737         * Layer tree, absent if not in the comspositing mode.
738         * <BR />
739         * <BR /><B>OPTIONAL</B>
740         */
741        public final LayerTree.Layer[] layers;
742        
743        /**
744         * Constructor
745         *
746         * @param layers Layer tree, absent if not in the comspositing mode.
747         * <BR /><B>OPTIONAL</B>
748         */
749        public layerTreeDidChange(LayerTree.Layer[] layers)
750        {
751            super("LayerTree", "layerTreeDidChange", 1);
752            
753            this.layers  = layers;
754        }
755        
756        /**
757         * JSON Object Constructor
758         * @param jo A Json-Object having data about an instance of {@code 'layerTreeDidChange'}.
759         */
760        public layerTreeDidChange (JsonObject jo)
761        {
762            super("LayerTree", "layerTreeDidChange", 1);
763        
764            this.layers = (jo.getJsonArray("layers") == null)
765                ? null
766                : RJArrIntoStream.objArr(jo.getJsonArray("layers"), null, 0, LayerTree.Layer.class).toArray(LayerTree.Layer[]::new);
767        
768        }
769        
770        
771        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
772        public boolean equals(Object other)
773        {
774            if (this == other)                       return true;
775            if (other == null)                       return false;
776            if (other.getClass() != this.getClass()) return false;
777        
778            layerTreeDidChange o = (layerTreeDidChange) other;
779        
780            return
781                    Arrays.deepEquals(this.layers, o.layers);
782        }
783        
784        /** Generates a Hash-Code for {@code 'this'} instance */
785        public int hashCode()
786        {
787            return
788                    Arrays.deepHashCode(this.layers);
789        }
790    }
791    
792    
793    // Counter for keeping the WebSocket Request ID's distinct.
794    private static int counter = 1;
795    
796    /**
797     * Provides the reasons why the given layer was composited.
798     * 
799     * @param layerId The id of the layer for which we want to get the reasons it was composited.
800     * 
801     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
802     * {@link Ret2}&gt;</CODE>
803     *
804     * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 
805     * {@link Script#exec()}), and a {@link Promise} returned.
806     *
807     * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B>
808     * (using {@link Promise#await()}), the {@code Ret2} will subsequently
809     * be returned from that call.
810     * 
811     * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated
812     * in an instance of <B>{@link Ret2}</B>
813     *
814     * <BR /><BR /><UL CLASS=JDUL>
815     * <LI><CODE><B>Ret2.a:</B> String[] (<B>compositingReasons</B>)</CODE>
816     *     <BR />A list of strings specifying reasons for the given layer to become composited.
817     *     <BR /><BR /></LI>
818     * <LI><CODE><B>Ret2.b:</B> String[] (<B>compositingReasonIds</B>)</CODE>
819     *     <BR />A list of strings specifying reason IDs for the given layer to become composited.
820     *     </LI>
821     * </UL>
822     */
823    public static Script<String, JsonObject, Ret2<String[], String[]>> compositingReasons
824        (String layerId)
825    {
826        // Exception-Check(s) to ensure that if any parameters which are not declared as
827        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
828        
829        if (layerId == null) THROWS.throwNPE("layerId");
830        
831        final int       webSocketID = 27000000 + counter++;
832        final boolean[] optionals   = { false, };
833        
834        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
835        String requestJSON = WriteJSON.get(
836            parameterTypes.get("compositingReasons"),
837            parameterNames.get("compositingReasons"),
838            optionals, webSocketID,
839            "LayerTree.compositingReasons",
840            layerId
841        );
842        
843        // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret2'
844        Function<JsonObject, Ret2<String[], String[]>> 
845            responseProcessor = (JsonObject jo) -> new Ret2<>(
846                (jo.getJsonArray("compositingReasons") == null)
847                    ? null
848                    : RJArrIntoStream.strArr(jo.getJsonArray("compositingReasons"), null, 0).toArray(String[]::new),
849                (jo.getJsonArray("compositingReasonIds") == null)
850                    ? null
851                    : RJArrIntoStream.strArr(jo.getJsonArray("compositingReasonIds"), null, 0).toArray(String[]::new)
852            );
853        
854        return new Script<>(webSocketID, requestJSON, responseProcessor);
855    }
856    
857    /**
858     * Disables compositing tree inspection.
859     * 
860     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
861     * {@link Ret0}&gt;</CODE>
862     *
863     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
864     * browser receives the invocation-request.
865     *
866     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
867     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
868     * {@code >} to ensure the Browser Function has run to completion.
869     */
870    public static Script<String, JsonObject, Ret0> disable()
871    {
872        final int          webSocketID = 27001000 + counter++;
873        final boolean[]    optionals   = new boolean[0];
874        
875        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
876        String requestJSON = WriteJSON.get(
877            parameterTypes.get("disable"),
878            parameterNames.get("disable"),
879            optionals, webSocketID,
880            "LayerTree.disable"
881        );
882        
883        // This Remote Command does not have a Return-Value.
884        return new Script<>
885            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
886    }
887    
888    /**
889     * Enables compositing tree inspection.
890     * 
891     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
892     * {@link Ret0}&gt;</CODE>
893     *
894     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
895     * browser receives the invocation-request.
896     *
897     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
898     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
899     * {@code >} to ensure the Browser Function has run to completion.
900     */
901    public static Script<String, JsonObject, Ret0> enable()
902    {
903        final int          webSocketID = 27002000 + counter++;
904        final boolean[]    optionals   = new boolean[0];
905        
906        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
907        String requestJSON = WriteJSON.get(
908            parameterTypes.get("enable"),
909            parameterNames.get("enable"),
910            optionals, webSocketID,
911            "LayerTree.enable"
912        );
913        
914        // This Remote Command does not have a Return-Value.
915        return new Script<>
916            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
917    }
918    
919    /**
920     * Returns the snapshot identifier.
921     * 
922     * @param tiles An array of tiles composing the snapshot.
923     * 
924     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
925     * String&gt;</CODE>
926     * 
927     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
928     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
929     * String&gt;</CODE> will be returned.
930     *
931     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
932     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
933      * may be retrieved.</I>
934     *
935     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
936     * <BR /><BR /><UL CLASS=JDUL>
937     * <LI><CODE>String (<B>snapshotId</B></CODE>)
938     *     <BR />The id of the snapshot.
939     * </LI>
940     * </UL> */
941    public static Script<String, JsonObject, String> loadSnapshot(LayerTree.PictureTile[] tiles)
942    {
943        // Exception-Check(s) to ensure that if any parameters which are not declared as
944        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
945        
946        if (tiles == null) THROWS.throwNPE("tiles");
947        
948        final int       webSocketID = 27003000 + counter++;
949        final boolean[] optionals   = { false, };
950        
951        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
952        String requestJSON = WriteJSON.get(
953            parameterTypes.get("loadSnapshot"),
954            parameterNames.get("loadSnapshot"),
955            optionals, webSocketID,
956            "LayerTree.loadSnapshot",
957            (Object) tiles
958        );
959        
960        // 'JSON Binding' ... Converts Browser Response-JSON to 'String'
961        Function<JsonObject, String> responseProcessor = (JsonObject jo) ->
962            ReadJSON.getString(jo, "snapshotId", false, true);
963        
964        return new Script<>(webSocketID, requestJSON, responseProcessor);
965    }
966    
967    /**
968     * Returns the layer snapshot identifier.
969     * 
970     * @param layerId The id of the layer.
971     * 
972     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
973     * String&gt;</CODE>
974     * 
975     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
976     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
977     * String&gt;</CODE> will be returned.
978     *
979     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
980     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
981      * may be retrieved.</I>
982     *
983     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
984     * <BR /><BR /><UL CLASS=JDUL>
985     * <LI><CODE>String (<B>snapshotId</B></CODE>)
986     *     <BR />The id of the layer snapshot.
987     * </LI>
988     * </UL> */
989    public static Script<String, JsonObject, String> makeSnapshot(String layerId)
990    {
991        // Exception-Check(s) to ensure that if any parameters which are not declared as
992        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
993        
994        if (layerId == null) THROWS.throwNPE("layerId");
995        
996        final int       webSocketID = 27004000 + counter++;
997        final boolean[] optionals   = { false, };
998        
999        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1000        String requestJSON = WriteJSON.get(
1001            parameterTypes.get("makeSnapshot"),
1002            parameterNames.get("makeSnapshot"),
1003            optionals, webSocketID,
1004            "LayerTree.makeSnapshot",
1005            layerId
1006        );
1007        
1008        // 'JSON Binding' ... Converts Browser Response-JSON to 'String'
1009        Function<JsonObject, String> responseProcessor = (JsonObject jo) ->
1010            ReadJSON.getString(jo, "snapshotId", false, true);
1011        
1012        return new Script<>(webSocketID, requestJSON, responseProcessor);
1013    }
1014    
1015    /**
1016     * <CODE>[No Description Provided by Google]</CODE>
1017     * 
1018     * @param snapshotId The id of the layer snapshot.
1019     * 
1020     * @param minRepeatCount The maximum number of times to replay the snapshot (1, if not specified).
1021     * <BR /><B>OPTIONAL</B>
1022     * 
1023     * @param minDuration The minimum duration (in seconds) to replay the snapshot.
1024     * <BR /><B>OPTIONAL</B>
1025     * 
1026     * @param clipRect The clip rectangle to apply when replaying the snapshot.
1027     * <BR /><B>OPTIONAL</B>
1028     * 
1029     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1030     * Number[][]&gt;</CODE>
1031     * 
1032     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
1033     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
1034     * Number[][]&gt;</CODE> will be returned.
1035     *
1036     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
1037     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
1038      * may be retrieved.</I>
1039     *
1040     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
1041     * <BR /><BR /><UL CLASS=JDUL>
1042     * <LI><CODE>Number[][] (<B>timings</B></CODE>)
1043     *     <BR />The array of paint profiles, one per run.
1044     * </LI>
1045     * </UL> */
1046    public static Script<String, JsonObject, Number[][]> profileSnapshot
1047        (String snapshotId, Integer minRepeatCount, Number minDuration, DOM.Rect clipRect)
1048    {
1049        // Exception-Check(s) to ensure that if any parameters which are not declared as
1050        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1051        
1052        if (snapshotId == null) THROWS.throwNPE("snapshotId");
1053        
1054        final int       webSocketID = 27005000 + counter++;
1055        final boolean[] optionals   = { false, true, true, true, };
1056        
1057        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1058        String requestJSON = WriteJSON.get(
1059            parameterTypes.get("profileSnapshot"),
1060            parameterNames.get("profileSnapshot"),
1061            optionals, webSocketID,
1062            "LayerTree.profileSnapshot",
1063            snapshotId, minRepeatCount, minDuration, clipRect
1064        );
1065        
1066        // 'JSON Binding' ... Converts Browser Response-JSON to 'Number[][]'
1067        Function<JsonObject, Number[][]> responseProcessor = (JsonObject jo) ->
1068            (jo.getJsonArray("timings") == null)
1069                ? null
1070                : RJArrDimN.arrNumber(jo.getJsonArray("timings"), -1, 0, null, Number[][].class);
1071        
1072        return new Script<>(webSocketID, requestJSON, responseProcessor);
1073    }
1074    
1075    /**
1076     * Releases layer snapshot captured by the back-end.
1077     * 
1078     * @param snapshotId The id of the layer snapshot.
1079     * 
1080     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1081     * {@link Ret0}&gt;</CODE>
1082     *
1083     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
1084     * browser receives the invocation-request.
1085     *
1086     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
1087     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
1088     * {@code >} to ensure the Browser Function has run to completion.
1089     */
1090    public static Script<String, JsonObject, Ret0> releaseSnapshot(String snapshotId)
1091    {
1092        // Exception-Check(s) to ensure that if any parameters which are not declared as
1093        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1094        
1095        if (snapshotId == null) THROWS.throwNPE("snapshotId");
1096        
1097        final int       webSocketID = 27006000 + counter++;
1098        final boolean[] optionals   = { false, };
1099        
1100        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1101        String requestJSON = WriteJSON.get(
1102            parameterTypes.get("releaseSnapshot"),
1103            parameterNames.get("releaseSnapshot"),
1104            optionals, webSocketID,
1105            "LayerTree.releaseSnapshot",
1106            snapshotId
1107        );
1108        
1109        // This Remote Command does not have a Return-Value.
1110        return new Script<>
1111            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
1112    }
1113    
1114    /**
1115     * Replays the layer snapshot and returns the resulting bitmap.
1116     * 
1117     * @param snapshotId The id of the layer snapshot.
1118     * 
1119     * @param fromStep The first step to replay from (replay from the very start if not specified).
1120     * <BR /><B>OPTIONAL</B>
1121     * 
1122     * @param toStep The last step to replay to (replay till the end if not specified).
1123     * <BR /><B>OPTIONAL</B>
1124     * 
1125     * @param scale The scale to apply while replaying (defaults to 1).
1126     * <BR /><B>OPTIONAL</B>
1127     * 
1128     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1129     * String&gt;</CODE>
1130     * 
1131     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
1132     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
1133     * String&gt;</CODE> will be returned.
1134     *
1135     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
1136     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
1137      * may be retrieved.</I>
1138     *
1139     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
1140     * <BR /><BR /><UL CLASS=JDUL>
1141     * <LI><CODE>String (<B>dataURL</B></CODE>)
1142     *     <BR />A data: URL for resulting image.
1143     * </LI>
1144     * </UL> */
1145    public static Script<String, JsonObject, String> replaySnapshot
1146        (String snapshotId, Integer fromStep, Integer toStep, Number scale)
1147    {
1148        // Exception-Check(s) to ensure that if any parameters which are not declared as
1149        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1150        
1151        if (snapshotId == null) THROWS.throwNPE("snapshotId");
1152        
1153        final int       webSocketID = 27007000 + counter++;
1154        final boolean[] optionals   = { false, true, true, true, };
1155        
1156        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1157        String requestJSON = WriteJSON.get(
1158            parameterTypes.get("replaySnapshot"),
1159            parameterNames.get("replaySnapshot"),
1160            optionals, webSocketID,
1161            "LayerTree.replaySnapshot",
1162            snapshotId, fromStep, toStep, scale
1163        );
1164        
1165        // 'JSON Binding' ... Converts Browser Response-JSON to 'String'
1166        Function<JsonObject, String> responseProcessor = (JsonObject jo) ->
1167            ReadJSON.getString(jo, "dataURL", false, true);
1168        
1169        return new Script<>(webSocketID, requestJSON, responseProcessor);
1170    }
1171    
1172    /**
1173     * Replays the layer snapshot and returns canvas log.
1174     * 
1175     * @param snapshotId The id of the layer snapshot.
1176     * 
1177     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
1178     * JsonArray&gt;</CODE>
1179     * 
1180     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
1181     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
1182     * JsonArray&gt;</CODE> will be returned.
1183     *
1184     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
1185     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
1186      * may be retrieved.</I>
1187     *
1188     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
1189     * <BR /><BR /><UL CLASS=JDUL>
1190     * <LI><CODE>JsonArray (<B>commandLog</B></CODE>)
1191     *     <BR />The array of canvas function calls.
1192     * </LI>
1193     * </UL> */
1194    public static Script<String, JsonObject, JsonArray> snapshotCommandLog(String snapshotId)
1195    {
1196        // Exception-Check(s) to ensure that if any parameters which are not declared as
1197        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1198        
1199        if (snapshotId == null) THROWS.throwNPE("snapshotId");
1200        
1201        final int       webSocketID = 27008000 + counter++;
1202        final boolean[] optionals   = { false, };
1203        
1204        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
1205        String requestJSON = WriteJSON.get(
1206            parameterTypes.get("snapshotCommandLog"),
1207            parameterNames.get("snapshotCommandLog"),
1208            optionals, webSocketID,
1209            "LayerTree.snapshotCommandLog",
1210            snapshotId
1211        );
1212        
1213        // 'JSON Binding' ... Converts Browser Response-JSON to 'JsonArray'
1214        Function<JsonObject, JsonArray> responseProcessor = (JsonObject jo) ->
1215            jo.getJsonArray("commandLog");
1216        
1217        return new Script<>(webSocketID, requestJSON, responseProcessor);
1218    }
1219    
1220}