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