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>This domain facilitates obtaining document snapshots with DOM, layout, and style information.</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 DOMSnapshot
030{
031    // ********************************************************************************************
032    // ********************************************************************************************
033    // Class Header Stuff
034    // ********************************************************************************************
035    // ********************************************************************************************
036
037
038    // No Pubic Constructors
039    private DOMSnapshot () { }
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 : DOMSnapshot.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        parameterNames.put("disable", EMPTY_VEC_STR);
078
079        parameterNames.put("enable", EMPTY_VEC_STR);
080
081        v = new Vector<String>(4);
082        parameterNames.put("getSnapshot", v);
083        Collections.addAll(v, new String[]
084        { "computedStyleWhitelist", "includeEventListeners", "includePaintOrder", "includeUserAgentShadowTree", });
085
086        v = new Vector<String>(5);
087        parameterNames.put("captureSnapshot", v);
088        Collections.addAll(v, new String[]
089        { "computedStyles", "includePaintOrder", "includeDOMRects", "includeBlendedBackgroundColors", "includeTextColorOpacities", });
090    }
091
092
093    // ********************************************************************************************
094    // ********************************************************************************************
095    // Types - Static Inner Classes
096    // ********************************************************************************************
097    // ********************************************************************************************
098
099    // public static class StringIndex => Integer
100    
101    // public static class ArrayOfStrings => int[]
102    
103    // public static class Rectangle => Number[]
104    
105    /** A Node in the DOM tree. */
106    public static class DOMNode
107        extends BaseType
108        implements java.io.Serializable
109    {
110        /** For Object Serialization.  java.io.Serializable */
111        protected static final long serialVersionUID = 1;
112        
113        public boolean[] optionals()
114        { return new boolean[] { false, false, false, true, true, true, true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, }; }
115        
116        /** <CODE>Node</CODE>'s nodeType. */
117        public final int nodeType;
118        
119        /** <CODE>Node</CODE>'s nodeName. */
120        public final String nodeName;
121        
122        /** <CODE>Node</CODE>'s nodeValue. */
123        public final String nodeValue;
124        
125        /**
126         * Only set for textarea elements, contains the text value.
127         * <BR />
128         * <BR /><B>OPTIONAL</B>
129         */
130        public final String textValue;
131        
132        /**
133         * Only set for input elements, contains the input's associated text value.
134         * <BR />
135         * <BR /><B>OPTIONAL</B>
136         */
137        public final String inputValue;
138        
139        /**
140         * Only set for radio and checkbox input elements, indicates if the element has been checked
141         * <BR />
142         * <BR /><B>OPTIONAL</B>
143         */
144        public final Boolean inputChecked;
145        
146        /**
147         * Only set for option elements, indicates if the element has been selected
148         * <BR />
149         * <BR /><B>OPTIONAL</B>
150         */
151        public final Boolean optionSelected;
152        
153        /** <CODE>Node</CODE>'s id, corresponds to DOM.Node.backendNodeId. */
154        public final int backendNodeId;
155        
156        /**
157         * The indexes of the node's child nodes in the <CODE>domNodes</CODE> array returned by <CODE>getSnapshot</CODE>, if
158         * any.
159         * <BR />
160         * <BR /><B>OPTIONAL</B>
161         */
162        public final int[] childNodeIndexes;
163        
164        /**
165         * Attributes of an <CODE>Element</CODE> node.
166         * <BR />
167         * <BR /><B>OPTIONAL</B>
168         */
169        public final DOMSnapshot.NameValue[] attributes;
170        
171        /**
172         * Indexes of pseudo elements associated with this node in the <CODE>domNodes</CODE> array returned by
173         * <CODE>getSnapshot</CODE>, if any.
174         * <BR />
175         * <BR /><B>OPTIONAL</B>
176         */
177        public final int[] pseudoElementIndexes;
178        
179        /**
180         * The index of the node's related layout tree node in the <CODE>layoutTreeNodes</CODE> array returned by
181         * <CODE>getSnapshot</CODE>, if any.
182         * <BR />
183         * <BR /><B>OPTIONAL</B>
184         */
185        public final Integer layoutNodeIndex;
186        
187        /**
188         * Document URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node points to.
189         * <BR />
190         * <BR /><B>OPTIONAL</B>
191         */
192        public final String documentURL;
193        
194        /**
195         * Base URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node uses for URL completion.
196         * <BR />
197         * <BR /><B>OPTIONAL</B>
198         */
199        public final String baseURL;
200        
201        /**
202         * Only set for documents, contains the document's content language.
203         * <BR />
204         * <BR /><B>OPTIONAL</B>
205         */
206        public final String contentLanguage;
207        
208        /**
209         * Only set for documents, contains the document's character set encoding.
210         * <BR />
211         * <BR /><B>OPTIONAL</B>
212         */
213        public final String documentEncoding;
214        
215        /**
216         * <CODE>DocumentType</CODE> node's publicId.
217         * <BR />
218         * <BR /><B>OPTIONAL</B>
219         */
220        public final String publicId;
221        
222        /**
223         * <CODE>DocumentType</CODE> node's systemId.
224         * <BR />
225         * <BR /><B>OPTIONAL</B>
226         */
227        public final String systemId;
228        
229        /**
230         * Frame ID for frame owner elements and also for the document node.
231         * <BR />
232         * <BR /><B>OPTIONAL</B>
233         */
234        public final String frameId;
235        
236        /**
237         * The index of a frame owner element's content document in the <CODE>domNodes</CODE> array returned by
238         * <CODE>getSnapshot</CODE>, if any.
239         * <BR />
240         * <BR /><B>OPTIONAL</B>
241         */
242        public final Integer contentDocumentIndex;
243        
244        /**
245         * Type of a pseudo element node.
246         * <BR />
247         * <BR /><B>OPTIONAL</B>
248         */
249        public final String pseudoType;
250        
251        /**
252         * Shadow root type.
253         * <BR />
254         * <BR /><B>OPTIONAL</B>
255         */
256        public final String shadowRootType;
257        
258        /**
259         * Whether this DOM node responds to mouse clicks. This includes nodes that have had click
260         * event listeners attached via JavaScript as well as anchor tags that naturally navigate when
261         * clicked.
262         * <BR />
263         * <BR /><B>OPTIONAL</B>
264         */
265        public final Boolean isClickable;
266        
267        /**
268         * Details of the node's event listeners, if any.
269         * <BR />
270         * <BR /><B>OPTIONAL</B>
271         */
272        public final DOMDebugger.EventListener[] eventListeners;
273        
274        /**
275         * The selected url for nodes with a srcset attribute.
276         * <BR />
277         * <BR /><B>OPTIONAL</B>
278         */
279        public final String currentSourceURL;
280        
281        /**
282         * The url of the script (if any) that generates this node.
283         * <BR />
284         * <BR /><B>OPTIONAL</B>
285         */
286        public final String originURL;
287        
288        /**
289         * Scroll offsets, set when this node is a Document.
290         * <BR />
291         * <BR /><B>OPTIONAL</B>
292         */
293        public final Number scrollOffsetX;
294        
295        /**
296         * <CODE>[No Description Provided by Google]</CODE>
297         * <BR />
298         * <BR /><B>OPTIONAL</B>
299         */
300        public final Number scrollOffsetY;
301        
302        /**
303         * Constructor
304         *
305         * @param nodeType <CODE>Node</CODE>'s nodeType.
306         * 
307         * @param nodeName <CODE>Node</CODE>'s nodeName.
308         * 
309         * @param nodeValue <CODE>Node</CODE>'s nodeValue.
310         * 
311         * @param textValue Only set for textarea elements, contains the text value.
312         * <BR /><B>OPTIONAL</B>
313         * 
314         * @param inputValue Only set for input elements, contains the input's associated text value.
315         * <BR /><B>OPTIONAL</B>
316         * 
317         * @param inputChecked Only set for radio and checkbox input elements, indicates if the element has been checked
318         * <BR /><B>OPTIONAL</B>
319         * 
320         * @param optionSelected Only set for option elements, indicates if the element has been selected
321         * <BR /><B>OPTIONAL</B>
322         * 
323         * @param backendNodeId <CODE>Node</CODE>'s id, corresponds to DOM.Node.backendNodeId.
324         * 
325         * @param childNodeIndexes 
326         * The indexes of the node's child nodes in the <CODE>domNodes</CODE> array returned by <CODE>getSnapshot</CODE>, if
327         * any.
328         * <BR /><B>OPTIONAL</B>
329         * 
330         * @param attributes Attributes of an <CODE>Element</CODE> node.
331         * <BR /><B>OPTIONAL</B>
332         * 
333         * @param pseudoElementIndexes 
334         * Indexes of pseudo elements associated with this node in the <CODE>domNodes</CODE> array returned by
335         * <CODE>getSnapshot</CODE>, if any.
336         * <BR /><B>OPTIONAL</B>
337         * 
338         * @param layoutNodeIndex 
339         * The index of the node's related layout tree node in the <CODE>layoutTreeNodes</CODE> array returned by
340         * <CODE>getSnapshot</CODE>, if any.
341         * <BR /><B>OPTIONAL</B>
342         * 
343         * @param documentURL Document URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node points to.
344         * <BR /><B>OPTIONAL</B>
345         * 
346         * @param baseURL Base URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node uses for URL completion.
347         * <BR /><B>OPTIONAL</B>
348         * 
349         * @param contentLanguage Only set for documents, contains the document's content language.
350         * <BR /><B>OPTIONAL</B>
351         * 
352         * @param documentEncoding Only set for documents, contains the document's character set encoding.
353         * <BR /><B>OPTIONAL</B>
354         * 
355         * @param publicId <CODE>DocumentType</CODE> node's publicId.
356         * <BR /><B>OPTIONAL</B>
357         * 
358         * @param systemId <CODE>DocumentType</CODE> node's systemId.
359         * <BR /><B>OPTIONAL</B>
360         * 
361         * @param frameId Frame ID for frame owner elements and also for the document node.
362         * <BR /><B>OPTIONAL</B>
363         * 
364         * @param contentDocumentIndex 
365         * The index of a frame owner element's content document in the <CODE>domNodes</CODE> array returned by
366         * <CODE>getSnapshot</CODE>, if any.
367         * <BR /><B>OPTIONAL</B>
368         * 
369         * @param pseudoType Type of a pseudo element node.
370         * <BR /><B>OPTIONAL</B>
371         * 
372         * @param shadowRootType Shadow root type.
373         * <BR /><B>OPTIONAL</B>
374         * 
375         * @param isClickable 
376         * Whether this DOM node responds to mouse clicks. This includes nodes that have had click
377         * event listeners attached via JavaScript as well as anchor tags that naturally navigate when
378         * clicked.
379         * <BR /><B>OPTIONAL</B>
380         * 
381         * @param eventListeners Details of the node's event listeners, if any.
382         * <BR /><B>OPTIONAL</B>
383         * 
384         * @param currentSourceURL The selected url for nodes with a srcset attribute.
385         * <BR /><B>OPTIONAL</B>
386         * 
387         * @param originURL The url of the script (if any) that generates this node.
388         * <BR /><B>OPTIONAL</B>
389         * 
390         * @param scrollOffsetX Scroll offsets, set when this node is a Document.
391         * <BR /><B>OPTIONAL</B>
392         * 
393         * @param scrollOffsetY -
394         * <BR /><B>OPTIONAL</B>
395         */
396        public DOMNode(
397                int nodeType, String nodeName, String nodeValue, String textValue, 
398                String inputValue, Boolean inputChecked, Boolean optionSelected, int backendNodeId, 
399                int[] childNodeIndexes, DOMSnapshot.NameValue[] attributes, 
400                int[] pseudoElementIndexes, Integer layoutNodeIndex, String documentURL, 
401                String baseURL, String contentLanguage, String documentEncoding, String publicId, 
402                String systemId, String frameId, Integer contentDocumentIndex, String pseudoType, 
403                String shadowRootType, Boolean isClickable, 
404                DOMDebugger.EventListener[] eventListeners, String currentSourceURL, 
405                String originURL, Number scrollOffsetX, Number scrollOffsetY
406            )
407        {
408            // Exception-Check(s) to ensure that if any parameters which are not declared as
409            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
410            
411            if (nodeName == null)  BRDPC.throwNPE("nodeName");
412            if (nodeValue == null) BRDPC.throwNPE("nodeValue");
413            
414            // Exception-Check(s) to ensure that if any parameters which must adhere to a
415            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
416            
417            BRDPC.checkIAE("pseudoType", pseudoType, "DOM.PseudoType", DOM.PseudoType);
418            BRDPC.checkIAE("shadowRootType", shadowRootType, "DOM.ShadowRootType", DOM.ShadowRootType);
419            
420            this.nodeType              = nodeType;
421            this.nodeName              = nodeName;
422            this.nodeValue             = nodeValue;
423            this.textValue             = textValue;
424            this.inputValue            = inputValue;
425            this.inputChecked          = inputChecked;
426            this.optionSelected        = optionSelected;
427            this.backendNodeId         = backendNodeId;
428            this.childNodeIndexes      = childNodeIndexes;
429            this.attributes            = attributes;
430            this.pseudoElementIndexes  = pseudoElementIndexes;
431            this.layoutNodeIndex       = layoutNodeIndex;
432            this.documentURL           = documentURL;
433            this.baseURL               = baseURL;
434            this.contentLanguage       = contentLanguage;
435            this.documentEncoding      = documentEncoding;
436            this.publicId              = publicId;
437            this.systemId              = systemId;
438            this.frameId               = frameId;
439            this.contentDocumentIndex  = contentDocumentIndex;
440            this.pseudoType            = pseudoType;
441            this.shadowRootType        = shadowRootType;
442            this.isClickable           = isClickable;
443            this.eventListeners        = eventListeners;
444            this.currentSourceURL      = currentSourceURL;
445            this.originURL             = originURL;
446            this.scrollOffsetX         = scrollOffsetX;
447            this.scrollOffsetY         = scrollOffsetY;
448        }
449        
450        /**
451         * JSON Object Constructor
452         * @param jo A Json-Object having data about an instance of {@code 'DOMNode'}.
453         */
454        public DOMNode (JsonObject jo)
455        {
456            this.nodeType              = ReadPrimJSON.getInt(jo, "nodeType");
457            this.nodeName              = ReadJSON.getString(jo, "nodeName", false, true);
458            this.nodeValue             = ReadJSON.getString(jo, "nodeValue", false, true);
459            this.textValue             = ReadJSON.getString(jo, "textValue", true, false);
460            this.inputValue            = ReadJSON.getString(jo, "inputValue", true, false);
461            this.inputChecked          = ReadBoxedJSON.getBoolean(jo, "inputChecked", true);
462            this.optionSelected        = ReadBoxedJSON.getBoolean(jo, "optionSelected", true);
463            this.backendNodeId         = ReadPrimJSON.getInt(jo, "backendNodeId");
464            this.childNodeIndexes = (jo.getJsonArray("childNodeIndexes") == null)
465                ? null
466                : ReadArrJSON.DimN.intArr(jo.getJsonArray("childNodeIndexes"), -1, 0, null, int[].class);
467        
468            this.attributes = (jo.getJsonArray("attributes") == null)
469                ? null
470                : ReadArrJSON.DimN.objArr(jo.getJsonArray("attributes"), null, 0, DOMSnapshot.NameValue[].class);
471        
472            this.pseudoElementIndexes = (jo.getJsonArray("pseudoElementIndexes") == null)
473                ? null
474                : ReadArrJSON.DimN.intArr(jo.getJsonArray("pseudoElementIndexes"), -1, 0, null, int[].class);
475        
476            this.layoutNodeIndex       = ReadBoxedJSON.getInteger(jo, "layoutNodeIndex", true);
477            this.documentURL           = ReadJSON.getString(jo, "documentURL", true, false);
478            this.baseURL               = ReadJSON.getString(jo, "baseURL", true, false);
479            this.contentLanguage       = ReadJSON.getString(jo, "contentLanguage", true, false);
480            this.documentEncoding      = ReadJSON.getString(jo, "documentEncoding", true, false);
481            this.publicId              = ReadJSON.getString(jo, "publicId", true, false);
482            this.systemId              = ReadJSON.getString(jo, "systemId", true, false);
483            this.frameId               = ReadJSON.getString(jo, "frameId", true, false);
484            this.contentDocumentIndex  = ReadBoxedJSON.getInteger(jo, "contentDocumentIndex", true);
485            this.pseudoType            = ReadJSON.getString(jo, "pseudoType", true, false);
486            this.shadowRootType        = ReadJSON.getString(jo, "shadowRootType", true, false);
487            this.isClickable           = ReadBoxedJSON.getBoolean(jo, "isClickable", true);
488            this.eventListeners = (jo.getJsonArray("eventListeners") == null)
489                ? null
490                : ReadArrJSON.DimN.objArr(jo.getJsonArray("eventListeners"), null, 0, DOMDebugger.EventListener[].class);
491        
492            this.currentSourceURL      = ReadJSON.getString(jo, "currentSourceURL", true, false);
493            this.originURL             = ReadJSON.getString(jo, "originURL", true, false);
494            this.scrollOffsetX         = ReadNumberJSON.get(jo, "scrollOffsetX", true, false);
495            this.scrollOffsetY         = ReadNumberJSON.get(jo, "scrollOffsetY", true, false);
496        }
497        
498        
499        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
500        public boolean equals(Object other)
501        {
502            if (other == null)                       return false;
503            if (other.getClass() != this.getClass()) return false;
504        
505            DOMNode o = (DOMNode) other;
506        
507            return
508                    (this.nodeType == o.nodeType)
509                &&  Objects.equals(this.nodeName, o.nodeName)
510                &&  Objects.equals(this.nodeValue, o.nodeValue)
511                &&  Objects.equals(this.textValue, o.textValue)
512                &&  Objects.equals(this.inputValue, o.inputValue)
513                &&  Objects.equals(this.inputChecked, o.inputChecked)
514                &&  Objects.equals(this.optionSelected, o.optionSelected)
515                &&  Objects.equals(this.backendNodeId, o.backendNodeId)
516                &&  Arrays.equals(this.childNodeIndexes, o.childNodeIndexes)
517                &&  Arrays.deepEquals(this.attributes, o.attributes)
518                &&  Arrays.equals(this.pseudoElementIndexes, o.pseudoElementIndexes)
519                &&  Objects.equals(this.layoutNodeIndex, o.layoutNodeIndex)
520                &&  Objects.equals(this.documentURL, o.documentURL)
521                &&  Objects.equals(this.baseURL, o.baseURL)
522                &&  Objects.equals(this.contentLanguage, o.contentLanguage)
523                &&  Objects.equals(this.documentEncoding, o.documentEncoding)
524                &&  Objects.equals(this.publicId, o.publicId)
525                &&  Objects.equals(this.systemId, o.systemId)
526                &&  Objects.equals(this.frameId, o.frameId)
527                &&  Objects.equals(this.contentDocumentIndex, o.contentDocumentIndex)
528                &&  Objects.equals(this.pseudoType, o.pseudoType)
529                &&  Objects.equals(this.shadowRootType, o.shadowRootType)
530                &&  Objects.equals(this.isClickable, o.isClickable)
531                &&  Arrays.deepEquals(this.eventListeners, o.eventListeners)
532                &&  Objects.equals(this.currentSourceURL, o.currentSourceURL)
533                &&  Objects.equals(this.originURL, o.originURL)
534                &&  Objects.equals(this.scrollOffsetX, o.scrollOffsetX)
535                &&  Objects.equals(this.scrollOffsetY, o.scrollOffsetY);
536        }
537        
538        /** Generates a Hash-Code for {@code 'this'} instance */
539        public int hashCode()
540        {
541            return
542                    this.nodeType
543                +   Objects.hashCode(this.nodeName)
544                +   Objects.hashCode(this.nodeValue)
545                +   Objects.hashCode(this.textValue)
546                +   Objects.hashCode(this.inputValue)
547                +   Objects.hashCode(this.inputChecked)
548                +   Objects.hashCode(this.optionSelected)
549                +   this.backendNodeId
550                +   Arrays.hashCode(this.childNodeIndexes)
551                +   Arrays.deepHashCode(this.attributes)
552                +   Arrays.hashCode(this.pseudoElementIndexes)
553                +   Objects.hashCode(this.layoutNodeIndex)
554                +   Objects.hashCode(this.documentURL)
555                +   Objects.hashCode(this.baseURL)
556                +   Objects.hashCode(this.contentLanguage)
557                +   Objects.hashCode(this.documentEncoding)
558                +   Objects.hashCode(this.publicId)
559                +   Objects.hashCode(this.systemId)
560                +   Objects.hashCode(this.frameId)
561                +   Objects.hashCode(this.contentDocumentIndex)
562                +   Objects.hashCode(this.pseudoType)
563                +   Objects.hashCode(this.shadowRootType)
564                +   Objects.hashCode(this.isClickable)
565                +   Arrays.deepHashCode(this.eventListeners)
566                +   Objects.hashCode(this.currentSourceURL)
567                +   Objects.hashCode(this.originURL)
568                +   Objects.hashCode(this.scrollOffsetX)
569                +   Objects.hashCode(this.scrollOffsetY);
570        }
571    }
572    
573    /**
574     * Details of post layout rendered text positions. The exact layout should not be regarded as
575     * stable and may change between versions.
576     */
577    public static class InlineTextBox
578        extends BaseType
579        implements java.io.Serializable
580    {
581        /** For Object Serialization.  java.io.Serializable */
582        protected static final long serialVersionUID = 1;
583        
584        public boolean[] optionals()
585        { return new boolean[] { false, false, false, }; }
586        
587        /** The bounding box in document coordinates. Note that scroll offset of the document is ignored. */
588        public final DOM.Rect boundingBox;
589        
590        /**
591         * The starting index in characters, for this post layout textbox substring. Characters that
592         * would be represented as a surrogate pair in UTF-16 have length 2.
593         */
594        public final int startCharacterIndex;
595        
596        /**
597         * The number of characters in this post layout textbox substring. Characters that would be
598         * represented as a surrogate pair in UTF-16 have length 2.
599         */
600        public final int numCharacters;
601        
602        /**
603         * Constructor
604         *
605         * @param boundingBox The bounding box in document coordinates. Note that scroll offset of the document is ignored.
606         * 
607         * @param startCharacterIndex 
608         * The starting index in characters, for this post layout textbox substring. Characters that
609         * would be represented as a surrogate pair in UTF-16 have length 2.
610         * 
611         * @param numCharacters 
612         * The number of characters in this post layout textbox substring. Characters that would be
613         * represented as a surrogate pair in UTF-16 have length 2.
614         */
615        public InlineTextBox(DOM.Rect boundingBox, int startCharacterIndex, int numCharacters)
616        {
617            // Exception-Check(s) to ensure that if any parameters which are not declared as
618            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
619            
620            if (boundingBox == null) BRDPC.throwNPE("boundingBox");
621            
622            this.boundingBox          = boundingBox;
623            this.startCharacterIndex  = startCharacterIndex;
624            this.numCharacters        = numCharacters;
625        }
626        
627        /**
628         * JSON Object Constructor
629         * @param jo A Json-Object having data about an instance of {@code 'InlineTextBox'}.
630         */
631        public InlineTextBox (JsonObject jo)
632        {
633            this.boundingBox          = ReadJSON.getObject(jo, "boundingBox", DOM.Rect.class, false, true);
634            this.startCharacterIndex  = ReadPrimJSON.getInt(jo, "startCharacterIndex");
635            this.numCharacters        = ReadPrimJSON.getInt(jo, "numCharacters");
636        }
637        
638        
639        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
640        public boolean equals(Object other)
641        {
642            if (other == null)                       return false;
643            if (other.getClass() != this.getClass()) return false;
644        
645            InlineTextBox o = (InlineTextBox) other;
646        
647            return
648                    Objects.equals(this.boundingBox, o.boundingBox)
649                &&  (this.startCharacterIndex == o.startCharacterIndex)
650                &&  (this.numCharacters == o.numCharacters);
651        }
652        
653        /** Generates a Hash-Code for {@code 'this'} instance */
654        public int hashCode()
655        {
656            return
657                    this.boundingBox.hashCode()
658                +   this.startCharacterIndex
659                +   this.numCharacters;
660        }
661    }
662    
663    /** Details of an element in the DOM tree with a LayoutObject. */
664    public static class LayoutTreeNode
665        extends BaseType
666        implements java.io.Serializable
667    {
668        /** For Object Serialization.  java.io.Serializable */
669        protected static final long serialVersionUID = 1;
670        
671        public boolean[] optionals()
672        { return new boolean[] { false, false, true, true, true, true, true, }; }
673        
674        /** The index of the related DOM node in the <CODE>domNodes</CODE> array returned by <CODE>getSnapshot</CODE>. */
675        public final int domNodeIndex;
676        
677        /** The bounding box in document coordinates. Note that scroll offset of the document is ignored. */
678        public final DOM.Rect boundingBox;
679        
680        /**
681         * Contents of the LayoutText, if any.
682         * <BR />
683         * <BR /><B>OPTIONAL</B>
684         */
685        public final String layoutText;
686        
687        /**
688         * The post-layout inline text nodes, if any.
689         * <BR />
690         * <BR /><B>OPTIONAL</B>
691         */
692        public final DOMSnapshot.InlineTextBox[] inlineTextNodes;
693        
694        /**
695         * Index into the <CODE>computedStyles</CODE> array returned by <CODE>getSnapshot</CODE>.
696         * <BR />
697         * <BR /><B>OPTIONAL</B>
698         */
699        public final Integer styleIndex;
700        
701        /**
702         * Global paint order index, which is determined by the stacking order of the nodes. Nodes
703         * that are painted together will have the same index. Only provided if includePaintOrder in
704         * getSnapshot was true.
705         * <BR />
706         * <BR /><B>OPTIONAL</B>
707         */
708        public final Integer paintOrder;
709        
710        /**
711         * Set to true to indicate the element begins a new stacking context.
712         * <BR />
713         * <BR /><B>OPTIONAL</B>
714         */
715        public final Boolean isStackingContext;
716        
717        /**
718         * Constructor
719         *
720         * @param domNodeIndex The index of the related DOM node in the <CODE>domNodes</CODE> array returned by <CODE>getSnapshot</CODE>.
721         * 
722         * @param boundingBox The bounding box in document coordinates. Note that scroll offset of the document is ignored.
723         * 
724         * @param layoutText Contents of the LayoutText, if any.
725         * <BR /><B>OPTIONAL</B>
726         * 
727         * @param inlineTextNodes The post-layout inline text nodes, if any.
728         * <BR /><B>OPTIONAL</B>
729         * 
730         * @param styleIndex Index into the <CODE>computedStyles</CODE> array returned by <CODE>getSnapshot</CODE>.
731         * <BR /><B>OPTIONAL</B>
732         * 
733         * @param paintOrder 
734         * Global paint order index, which is determined by the stacking order of the nodes. Nodes
735         * that are painted together will have the same index. Only provided if includePaintOrder in
736         * getSnapshot was true.
737         * <BR /><B>OPTIONAL</B>
738         * 
739         * @param isStackingContext Set to true to indicate the element begins a new stacking context.
740         * <BR /><B>OPTIONAL</B>
741         */
742        public LayoutTreeNode(
743                int domNodeIndex, DOM.Rect boundingBox, String layoutText, 
744                DOMSnapshot.InlineTextBox[] inlineTextNodes, Integer styleIndex, Integer paintOrder, 
745                Boolean isStackingContext
746            )
747        {
748            // Exception-Check(s) to ensure that if any parameters which are not declared as
749            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
750            
751            if (boundingBox == null) BRDPC.throwNPE("boundingBox");
752            
753            this.domNodeIndex       = domNodeIndex;
754            this.boundingBox        = boundingBox;
755            this.layoutText         = layoutText;
756            this.inlineTextNodes    = inlineTextNodes;
757            this.styleIndex         = styleIndex;
758            this.paintOrder         = paintOrder;
759            this.isStackingContext  = isStackingContext;
760        }
761        
762        /**
763         * JSON Object Constructor
764         * @param jo A Json-Object having data about an instance of {@code 'LayoutTreeNode'}.
765         */
766        public LayoutTreeNode (JsonObject jo)
767        {
768            this.domNodeIndex       = ReadPrimJSON.getInt(jo, "domNodeIndex");
769            this.boundingBox        = ReadJSON.getObject(jo, "boundingBox", DOM.Rect.class, false, true);
770            this.layoutText         = ReadJSON.getString(jo, "layoutText", true, false);
771            this.inlineTextNodes = (jo.getJsonArray("inlineTextNodes") == null)
772                ? null
773                : ReadArrJSON.DimN.objArr(jo.getJsonArray("inlineTextNodes"), null, 0, DOMSnapshot.InlineTextBox[].class);
774        
775            this.styleIndex         = ReadBoxedJSON.getInteger(jo, "styleIndex", true);
776            this.paintOrder         = ReadBoxedJSON.getInteger(jo, "paintOrder", true);
777            this.isStackingContext  = ReadBoxedJSON.getBoolean(jo, "isStackingContext", true);
778        }
779        
780        
781        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
782        public boolean equals(Object other)
783        {
784            if (other == null)                       return false;
785            if (other.getClass() != this.getClass()) return false;
786        
787            LayoutTreeNode o = (LayoutTreeNode) other;
788        
789            return
790                    (this.domNodeIndex == o.domNodeIndex)
791                &&  Objects.equals(this.boundingBox, o.boundingBox)
792                &&  Objects.equals(this.layoutText, o.layoutText)
793                &&  Arrays.deepEquals(this.inlineTextNodes, o.inlineTextNodes)
794                &&  Objects.equals(this.styleIndex, o.styleIndex)
795                &&  Objects.equals(this.paintOrder, o.paintOrder)
796                &&  Objects.equals(this.isStackingContext, o.isStackingContext);
797        }
798        
799        /** Generates a Hash-Code for {@code 'this'} instance */
800        public int hashCode()
801        {
802            return
803                    this.domNodeIndex
804                +   this.boundingBox.hashCode()
805                +   Objects.hashCode(this.layoutText)
806                +   Arrays.deepHashCode(this.inlineTextNodes)
807                +   Objects.hashCode(this.styleIndex)
808                +   Objects.hashCode(this.paintOrder)
809                +   Objects.hashCode(this.isStackingContext);
810        }
811    }
812    
813    /** A subset of the full ComputedStyle as defined by the request whitelist. */
814    public static class ComputedStyle
815        extends BaseType
816        implements java.io.Serializable
817    {
818        /** For Object Serialization.  java.io.Serializable */
819        protected static final long serialVersionUID = 1;
820        
821        public boolean[] optionals()
822        { return new boolean[] { false, }; }
823        
824        /** Name/value pairs of computed style properties. */
825        public final DOMSnapshot.NameValue[] properties;
826        
827        /**
828         * Constructor
829         *
830         * @param properties Name/value pairs of computed style properties.
831         */
832        public ComputedStyle(DOMSnapshot.NameValue[] properties)
833        {
834            // Exception-Check(s) to ensure that if any parameters which are not declared as
835            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
836            
837            if (properties == null) BRDPC.throwNPE("properties");
838            
839            this.properties  = properties;
840        }
841        
842        /**
843         * JSON Object Constructor
844         * @param jo A Json-Object having data about an instance of {@code 'ComputedStyle'}.
845         */
846        public ComputedStyle (JsonObject jo)
847        {
848            this.properties = (jo.getJsonArray("properties") == null)
849                ? null
850                : ReadArrJSON.DimN.objArr(jo.getJsonArray("properties"), null, 0, DOMSnapshot.NameValue[].class);
851        
852        }
853        
854        
855        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
856        public boolean equals(Object other)
857        {
858            if (other == null)                       return false;
859            if (other.getClass() != this.getClass()) return false;
860        
861            ComputedStyle o = (ComputedStyle) other;
862        
863            return
864                    Arrays.deepEquals(this.properties, o.properties);
865        }
866        
867        /** Generates a Hash-Code for {@code 'this'} instance */
868        public int hashCode()
869        {
870            return
871                    Arrays.deepHashCode(this.properties);
872        }
873    }
874    
875    /** A name/value pair. */
876    public static class NameValue
877        extends BaseType
878        implements java.io.Serializable
879    {
880        /** For Object Serialization.  java.io.Serializable */
881        protected static final long serialVersionUID = 1;
882        
883        public boolean[] optionals()
884        { return new boolean[] { false, false, }; }
885        
886        /** Attribute/property name. */
887        public final String name;
888        
889        /** Attribute/property value. */
890        public final String value;
891        
892        /**
893         * Constructor
894         *
895         * @param name Attribute/property name.
896         * 
897         * @param value Attribute/property value.
898         */
899        public NameValue(String name, String value)
900        {
901            // Exception-Check(s) to ensure that if any parameters which are not declared as
902            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
903            
904            if (name == null)  BRDPC.throwNPE("name");
905            if (value == null) BRDPC.throwNPE("value");
906            
907            this.name   = name;
908            this.value  = value;
909        }
910        
911        /**
912         * JSON Object Constructor
913         * @param jo A Json-Object having data about an instance of {@code 'NameValue'}.
914         */
915        public NameValue (JsonObject jo)
916        {
917            this.name   = ReadJSON.getString(jo, "name", false, true);
918            this.value  = ReadJSON.getString(jo, "value", false, true);
919        }
920        
921        
922        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
923        public boolean equals(Object other)
924        {
925            if (other == null)                       return false;
926            if (other.getClass() != this.getClass()) return false;
927        
928            NameValue o = (NameValue) other;
929        
930            return
931                    Objects.equals(this.name, o.name)
932                &&  Objects.equals(this.value, o.value);
933        }
934        
935        /** Generates a Hash-Code for {@code 'this'} instance */
936        public int hashCode()
937        {
938            return
939                    Objects.hashCode(this.name)
940                +   Objects.hashCode(this.value);
941        }
942    }
943    
944    /** Data that is only present on rare nodes. */
945    public static class RareStringData
946        extends BaseType
947        implements java.io.Serializable
948    {
949        /** For Object Serialization.  java.io.Serializable */
950        protected static final long serialVersionUID = 1;
951        
952        public boolean[] optionals()
953        { return new boolean[] { false, false, }; }
954        
955        /** <CODE>[No Description Provided by Google]</CODE> */
956        public final int[] index;
957        
958        /** <CODE>[No Description Provided by Google]</CODE> */
959        public final int[] value;
960        
961        /**
962         * Constructor
963         *
964         * @param index -
965         * 
966         * @param value -
967         */
968        public RareStringData(int[] index, int[] value)
969        {
970            // Exception-Check(s) to ensure that if any parameters which are not declared as
971            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
972            
973            if (index == null) BRDPC.throwNPE("index");
974            if (value == null) BRDPC.throwNPE("value");
975            
976            this.index  = index;
977            this.value  = value;
978        }
979        
980        /**
981         * JSON Object Constructor
982         * @param jo A Json-Object having data about an instance of {@code 'RareStringData'}.
983         */
984        public RareStringData (JsonObject jo)
985        {
986            this.index = (jo.getJsonArray("index") == null)
987                ? null
988                : ReadArrJSON.DimN.intArr(jo.getJsonArray("index"), -1, 0, null, int[].class);
989        
990            this.value = (jo.getJsonArray("value") == null)
991                ? null
992                : ReadArrJSON.DimN.intArr(jo.getJsonArray("value"), -1, 0, null, int[].class);
993        
994        }
995        
996        
997        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
998        public boolean equals(Object other)
999        {
1000            if (other == null)                       return false;
1001            if (other.getClass() != this.getClass()) return false;
1002        
1003            RareStringData o = (RareStringData) other;
1004        
1005            return
1006                    Arrays.equals(this.index, o.index)
1007                &&  Arrays.equals(this.value, o.value);
1008        }
1009        
1010        /** Generates a Hash-Code for {@code 'this'} instance */
1011        public int hashCode()
1012        {
1013            return
1014                    Arrays.hashCode(this.index)
1015                +   Arrays.hashCode(this.value);
1016        }
1017    }
1018    
1019    /** <CODE>[No Description Provided by Google]</CODE> */
1020    public static class RareBooleanData
1021        extends BaseType
1022        implements java.io.Serializable
1023    {
1024        /** For Object Serialization.  java.io.Serializable */
1025        protected static final long serialVersionUID = 1;
1026        
1027        public boolean[] optionals()
1028        { return new boolean[] { false, }; }
1029        
1030        /** <CODE>[No Description Provided by Google]</CODE> */
1031        public final int[] index;
1032        
1033        /**
1034         * Constructor
1035         *
1036         * @param index -
1037         */
1038        public RareBooleanData(int[] index)
1039        {
1040            // Exception-Check(s) to ensure that if any parameters which are not declared as
1041            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1042            
1043            if (index == null) BRDPC.throwNPE("index");
1044            
1045            this.index  = index;
1046        }
1047        
1048        /**
1049         * JSON Object Constructor
1050         * @param jo A Json-Object having data about an instance of {@code 'RareBooleanData'}.
1051         */
1052        public RareBooleanData (JsonObject jo)
1053        {
1054            this.index = (jo.getJsonArray("index") == null)
1055                ? null
1056                : ReadArrJSON.DimN.intArr(jo.getJsonArray("index"), -1, 0, null, int[].class);
1057        
1058        }
1059        
1060        
1061        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
1062        public boolean equals(Object other)
1063        {
1064            if (other == null)                       return false;
1065            if (other.getClass() != this.getClass()) return false;
1066        
1067            RareBooleanData o = (RareBooleanData) other;
1068        
1069            return
1070                    Arrays.equals(this.index, o.index);
1071        }
1072        
1073        /** Generates a Hash-Code for {@code 'this'} instance */
1074        public int hashCode()
1075        {
1076            return
1077                    Arrays.hashCode(this.index);
1078        }
1079    }
1080    
1081    /** <CODE>[No Description Provided by Google]</CODE> */
1082    public static class RareIntegerData
1083        extends BaseType
1084        implements java.io.Serializable
1085    {
1086        /** For Object Serialization.  java.io.Serializable */
1087        protected static final long serialVersionUID = 1;
1088        
1089        public boolean[] optionals()
1090        { return new boolean[] { false, false, }; }
1091        
1092        /** <CODE>[No Description Provided by Google]</CODE> */
1093        public final int[] index;
1094        
1095        /** <CODE>[No Description Provided by Google]</CODE> */
1096        public final int[] value;
1097        
1098        /**
1099         * Constructor
1100         *
1101         * @param index -
1102         * 
1103         * @param value -
1104         */
1105        public RareIntegerData(int[] index, int[] value)
1106        {
1107            // Exception-Check(s) to ensure that if any parameters which are not declared as
1108            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1109            
1110            if (index == null) BRDPC.throwNPE("index");
1111            if (value == null) BRDPC.throwNPE("value");
1112            
1113            this.index  = index;
1114            this.value  = value;
1115        }
1116        
1117        /**
1118         * JSON Object Constructor
1119         * @param jo A Json-Object having data about an instance of {@code 'RareIntegerData'}.
1120         */
1121        public RareIntegerData (JsonObject jo)
1122        {
1123            this.index = (jo.getJsonArray("index") == null)
1124                ? null
1125                : ReadArrJSON.DimN.intArr(jo.getJsonArray("index"), -1, 0, null, int[].class);
1126        
1127            this.value = (jo.getJsonArray("value") == null)
1128                ? null
1129                : ReadArrJSON.DimN.intArr(jo.getJsonArray("value"), -1, 0, null, int[].class);
1130        
1131        }
1132        
1133        
1134        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
1135        public boolean equals(Object other)
1136        {
1137            if (other == null)                       return false;
1138            if (other.getClass() != this.getClass()) return false;
1139        
1140            RareIntegerData o = (RareIntegerData) other;
1141        
1142            return
1143                    Arrays.equals(this.index, o.index)
1144                &&  Arrays.equals(this.value, o.value);
1145        }
1146        
1147        /** Generates a Hash-Code for {@code 'this'} instance */
1148        public int hashCode()
1149        {
1150            return
1151                    Arrays.hashCode(this.index)
1152                +   Arrays.hashCode(this.value);
1153        }
1154    }
1155    
1156    /** Document snapshot. */
1157    public static class DocumentSnapshot
1158        extends BaseType
1159        implements java.io.Serializable
1160    {
1161        /** For Object Serialization.  java.io.Serializable */
1162        protected static final long serialVersionUID = 1;
1163        
1164        public boolean[] optionals()
1165        { return new boolean[] { false, false, false, false, false, false, false, false, false, false, false, true, true, true, true, }; }
1166        
1167        /** Document URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node points to. */
1168        public final int documentURL;
1169        
1170        /** Document title. */
1171        public final int title;
1172        
1173        /** Base URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node uses for URL completion. */
1174        public final int baseURL;
1175        
1176        /** Contains the document's content language. */
1177        public final int contentLanguage;
1178        
1179        /** Contains the document's character set encoding. */
1180        public final int encodingName;
1181        
1182        /** <CODE>DocumentType</CODE> node's publicId. */
1183        public final int publicId;
1184        
1185        /** <CODE>DocumentType</CODE> node's systemId. */
1186        public final int systemId;
1187        
1188        /** Frame ID for frame owner elements and also for the document node. */
1189        public final int frameId;
1190        
1191        /** A table with dom nodes. */
1192        public final DOMSnapshot.NodeTreeSnapshot nodes;
1193        
1194        /** The nodes in the layout tree. */
1195        public final DOMSnapshot.LayoutTreeSnapshot layout;
1196        
1197        /** The post-layout inline text nodes. */
1198        public final DOMSnapshot.TextBoxSnapshot textBoxes;
1199        
1200        /**
1201         * Horizontal scroll offset.
1202         * <BR />
1203         * <BR /><B>OPTIONAL</B>
1204         */
1205        public final Number scrollOffsetX;
1206        
1207        /**
1208         * Vertical scroll offset.
1209         * <BR />
1210         * <BR /><B>OPTIONAL</B>
1211         */
1212        public final Number scrollOffsetY;
1213        
1214        /**
1215         * Document content width.
1216         * <BR />
1217         * <BR /><B>OPTIONAL</B>
1218         */
1219        public final Number contentWidth;
1220        
1221        /**
1222         * Document content height.
1223         * <BR />
1224         * <BR /><B>OPTIONAL</B>
1225         */
1226        public final Number contentHeight;
1227        
1228        /**
1229         * Constructor
1230         *
1231         * @param documentURL Document URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node points to.
1232         * 
1233         * @param title Document title.
1234         * 
1235         * @param baseURL Base URL that <CODE>Document</CODE> or <CODE>FrameOwner</CODE> node uses for URL completion.
1236         * 
1237         * @param contentLanguage Contains the document's content language.
1238         * 
1239         * @param encodingName Contains the document's character set encoding.
1240         * 
1241         * @param publicId <CODE>DocumentType</CODE> node's publicId.
1242         * 
1243         * @param systemId <CODE>DocumentType</CODE> node's systemId.
1244         * 
1245         * @param frameId Frame ID for frame owner elements and also for the document node.
1246         * 
1247         * @param nodes A table with dom nodes.
1248         * 
1249         * @param layout The nodes in the layout tree.
1250         * 
1251         * @param textBoxes The post-layout inline text nodes.
1252         * 
1253         * @param scrollOffsetX Horizontal scroll offset.
1254         * <BR /><B>OPTIONAL</B>
1255         * 
1256         * @param scrollOffsetY Vertical scroll offset.
1257         * <BR /><B>OPTIONAL</B>
1258         * 
1259         * @param contentWidth Document content width.
1260         * <BR /><B>OPTIONAL</B>
1261         * 
1262         * @param contentHeight Document content height.
1263         * <BR /><B>OPTIONAL</B>
1264         */
1265        public DocumentSnapshot(
1266                int documentURL, int title, int baseURL, int contentLanguage, int encodingName, 
1267                int publicId, int systemId, int frameId, DOMSnapshot.NodeTreeSnapshot nodes, 
1268                DOMSnapshot.LayoutTreeSnapshot layout, DOMSnapshot.TextBoxSnapshot textBoxes, 
1269                Number scrollOffsetX, Number scrollOffsetY, Number contentWidth, Number contentHeight
1270            )
1271        {
1272            // Exception-Check(s) to ensure that if any parameters which are not declared as
1273            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1274            
1275            if (nodes == null)     BRDPC.throwNPE("nodes");
1276            if (layout == null)    BRDPC.throwNPE("layout");
1277            if (textBoxes == null) BRDPC.throwNPE("textBoxes");
1278            
1279            this.documentURL      = documentURL;
1280            this.title            = title;
1281            this.baseURL          = baseURL;
1282            this.contentLanguage  = contentLanguage;
1283            this.encodingName     = encodingName;
1284            this.publicId         = publicId;
1285            this.systemId         = systemId;
1286            this.frameId          = frameId;
1287            this.nodes            = nodes;
1288            this.layout           = layout;
1289            this.textBoxes        = textBoxes;
1290            this.scrollOffsetX    = scrollOffsetX;
1291            this.scrollOffsetY    = scrollOffsetY;
1292            this.contentWidth     = contentWidth;
1293            this.contentHeight    = contentHeight;
1294        }
1295        
1296        /**
1297         * JSON Object Constructor
1298         * @param jo A Json-Object having data about an instance of {@code 'DocumentSnapshot'}.
1299         */
1300        public DocumentSnapshot (JsonObject jo)
1301        {
1302            this.documentURL      = ReadPrimJSON.getInt(jo, "documentURL");
1303            this.title            = ReadPrimJSON.getInt(jo, "title");
1304            this.baseURL          = ReadPrimJSON.getInt(jo, "baseURL");
1305            this.contentLanguage  = ReadPrimJSON.getInt(jo, "contentLanguage");
1306            this.encodingName     = ReadPrimJSON.getInt(jo, "encodingName");
1307            this.publicId         = ReadPrimJSON.getInt(jo, "publicId");
1308            this.systemId         = ReadPrimJSON.getInt(jo, "systemId");
1309            this.frameId          = ReadPrimJSON.getInt(jo, "frameId");
1310            this.nodes            = ReadJSON.getObject(jo, "nodes", DOMSnapshot.NodeTreeSnapshot.class, false, true);
1311            this.layout           = ReadJSON.getObject(jo, "layout", DOMSnapshot.LayoutTreeSnapshot.class, false, true);
1312            this.textBoxes        = ReadJSON.getObject(jo, "textBoxes", DOMSnapshot.TextBoxSnapshot.class, false, true);
1313            this.scrollOffsetX    = ReadNumberJSON.get(jo, "scrollOffsetX", true, false);
1314            this.scrollOffsetY    = ReadNumberJSON.get(jo, "scrollOffsetY", true, false);
1315            this.contentWidth     = ReadNumberJSON.get(jo, "contentWidth", true, false);
1316            this.contentHeight    = ReadNumberJSON.get(jo, "contentHeight", true, false);
1317        }
1318        
1319        
1320        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
1321        public boolean equals(Object other)
1322        {
1323            if (other == null)                       return false;
1324            if (other.getClass() != this.getClass()) return false;
1325        
1326            DocumentSnapshot o = (DocumentSnapshot) other;
1327        
1328            return
1329                    Objects.equals(this.documentURL, o.documentURL)
1330                &&  Objects.equals(this.title, o.title)
1331                &&  Objects.equals(this.baseURL, o.baseURL)
1332                &&  Objects.equals(this.contentLanguage, o.contentLanguage)
1333                &&  Objects.equals(this.encodingName, o.encodingName)
1334                &&  Objects.equals(this.publicId, o.publicId)
1335                &&  Objects.equals(this.systemId, o.systemId)
1336                &&  Objects.equals(this.frameId, o.frameId)
1337                &&  Objects.equals(this.nodes, o.nodes)
1338                &&  Objects.equals(this.layout, o.layout)
1339                &&  Objects.equals(this.textBoxes, o.textBoxes)
1340                &&  Objects.equals(this.scrollOffsetX, o.scrollOffsetX)
1341                &&  Objects.equals(this.scrollOffsetY, o.scrollOffsetY)
1342                &&  Objects.equals(this.contentWidth, o.contentWidth)
1343                &&  Objects.equals(this.contentHeight, o.contentHeight);
1344        }
1345        
1346        /** Generates a Hash-Code for {@code 'this'} instance */
1347        public int hashCode()
1348        {
1349            return
1350                    this.documentURL
1351                +   this.title
1352                +   this.baseURL
1353                +   this.contentLanguage
1354                +   this.encodingName
1355                +   this.publicId
1356                +   this.systemId
1357                +   this.frameId
1358                +   this.nodes.hashCode()
1359                +   this.layout.hashCode()
1360                +   this.textBoxes.hashCode()
1361                +   Objects.hashCode(this.scrollOffsetX)
1362                +   Objects.hashCode(this.scrollOffsetY)
1363                +   Objects.hashCode(this.contentWidth)
1364                +   Objects.hashCode(this.contentHeight);
1365        }
1366    }
1367    
1368    /** Table containing nodes. */
1369    public static class NodeTreeSnapshot
1370        extends BaseType
1371        implements java.io.Serializable
1372    {
1373        /** For Object Serialization.  java.io.Serializable */
1374        protected static final long serialVersionUID = 1;
1375        
1376        public boolean[] optionals()
1377        { return new boolean[] { true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, }; }
1378        
1379        /**
1380         * Parent node index.
1381         * <BR />
1382         * <BR /><B>OPTIONAL</B>
1383         */
1384        public final int[] parentIndex;
1385        
1386        /**
1387         * <CODE>Node</CODE>'s nodeType.
1388         * <BR />
1389         * <BR /><B>OPTIONAL</B>
1390         */
1391        public final int[] nodeType;
1392        
1393        /**
1394         * Type of the shadow root the <CODE>Node</CODE> is in. String values are equal to the <CODE>ShadowRootType</CODE> enum.
1395         * <BR />
1396         * <BR /><B>OPTIONAL</B>
1397         */
1398        public final DOMSnapshot.RareStringData shadowRootType;
1399        
1400        /**
1401         * <CODE>Node</CODE>'s nodeName.
1402         * <BR />
1403         * <BR /><B>OPTIONAL</B>
1404         */
1405        public final int[] nodeName;
1406        
1407        /**
1408         * <CODE>Node</CODE>'s nodeValue.
1409         * <BR />
1410         * <BR /><B>OPTIONAL</B>
1411         */
1412        public final int[] nodeValue;
1413        
1414        /**
1415         * <CODE>Node</CODE>'s id, corresponds to DOM.Node.backendNodeId.
1416         * <BR />
1417         * <BR /><B>OPTIONAL</B>
1418         */
1419        public final int[] backendNodeId;
1420        
1421        /**
1422         * Attributes of an <CODE>Element</CODE> node. Flatten name, value pairs.
1423         * <BR />
1424         * <BR /><B>OPTIONAL</B>
1425         */
1426        public final int[][] attributes;
1427        
1428        /**
1429         * Only set for textarea elements, contains the text value.
1430         * <BR />
1431         * <BR /><B>OPTIONAL</B>
1432         */
1433        public final DOMSnapshot.RareStringData textValue;
1434        
1435        /**
1436         * Only set for input elements, contains the input's associated text value.
1437         * <BR />
1438         * <BR /><B>OPTIONAL</B>
1439         */
1440        public final DOMSnapshot.RareStringData inputValue;
1441        
1442        /**
1443         * Only set for radio and checkbox input elements, indicates if the element has been checked
1444         * <BR />
1445         * <BR /><B>OPTIONAL</B>
1446         */
1447        public final DOMSnapshot.RareBooleanData inputChecked;
1448        
1449        /**
1450         * Only set for option elements, indicates if the element has been selected
1451         * <BR />
1452         * <BR /><B>OPTIONAL</B>
1453         */
1454        public final DOMSnapshot.RareBooleanData optionSelected;
1455        
1456        /**
1457         * The index of the document in the list of the snapshot documents.
1458         * <BR />
1459         * <BR /><B>OPTIONAL</B>
1460         */
1461        public final DOMSnapshot.RareIntegerData contentDocumentIndex;
1462        
1463        /**
1464         * Type of a pseudo element node.
1465         * <BR />
1466         * <BR /><B>OPTIONAL</B>
1467         */
1468        public final DOMSnapshot.RareStringData pseudoType;
1469        
1470        /**
1471         * Whether this DOM node responds to mouse clicks. This includes nodes that have had click
1472         * event listeners attached via JavaScript as well as anchor tags that naturally navigate when
1473         * clicked.
1474         * <BR />
1475         * <BR /><B>OPTIONAL</B>
1476         */
1477        public final DOMSnapshot.RareBooleanData isClickable;
1478        
1479        /**
1480         * The selected url for nodes with a srcset attribute.
1481         * <BR />
1482         * <BR /><B>OPTIONAL</B>
1483         */
1484        public final DOMSnapshot.RareStringData currentSourceURL;
1485        
1486        /**
1487         * The url of the script (if any) that generates this node.
1488         * <BR />
1489         * <BR /><B>OPTIONAL</B>
1490         */
1491        public final DOMSnapshot.RareStringData originURL;
1492        
1493        /**
1494         * Constructor
1495         *
1496         * @param parentIndex Parent node index.
1497         * <BR /><B>OPTIONAL</B>
1498         * 
1499         * @param nodeType <CODE>Node</CODE>'s nodeType.
1500         * <BR /><B>OPTIONAL</B>
1501         * 
1502         * @param shadowRootType Type of the shadow root the <CODE>Node</CODE> is in. String values are equal to the <CODE>ShadowRootType</CODE> enum.
1503         * <BR /><B>OPTIONAL</B>
1504         * 
1505         * @param nodeName <CODE>Node</CODE>'s nodeName.
1506         * <BR /><B>OPTIONAL</B>
1507         * 
1508         * @param nodeValue <CODE>Node</CODE>'s nodeValue.
1509         * <BR /><B>OPTIONAL</B>
1510         * 
1511         * @param backendNodeId <CODE>Node</CODE>'s id, corresponds to DOM.Node.backendNodeId.
1512         * <BR /><B>OPTIONAL</B>
1513         * 
1514         * @param attributes Attributes of an <CODE>Element</CODE> node. Flatten name, value pairs.
1515         * <BR /><B>OPTIONAL</B>
1516         * 
1517         * @param textValue Only set for textarea elements, contains the text value.
1518         * <BR /><B>OPTIONAL</B>
1519         * 
1520         * @param inputValue Only set for input elements, contains the input's associated text value.
1521         * <BR /><B>OPTIONAL</B>
1522         * 
1523         * @param inputChecked Only set for radio and checkbox input elements, indicates if the element has been checked
1524         * <BR /><B>OPTIONAL</B>
1525         * 
1526         * @param optionSelected Only set for option elements, indicates if the element has been selected
1527         * <BR /><B>OPTIONAL</B>
1528         * 
1529         * @param contentDocumentIndex The index of the document in the list of the snapshot documents.
1530         * <BR /><B>OPTIONAL</B>
1531         * 
1532         * @param pseudoType Type of a pseudo element node.
1533         * <BR /><B>OPTIONAL</B>
1534         * 
1535         * @param isClickable 
1536         * Whether this DOM node responds to mouse clicks. This includes nodes that have had click
1537         * event listeners attached via JavaScript as well as anchor tags that naturally navigate when
1538         * clicked.
1539         * <BR /><B>OPTIONAL</B>
1540         * 
1541         * @param currentSourceURL The selected url for nodes with a srcset attribute.
1542         * <BR /><B>OPTIONAL</B>
1543         * 
1544         * @param originURL The url of the script (if any) that generates this node.
1545         * <BR /><B>OPTIONAL</B>
1546         */
1547        public NodeTreeSnapshot(
1548                int[] parentIndex, int[] nodeType, DOMSnapshot.RareStringData shadowRootType, 
1549                int[] nodeName, int[] nodeValue, int[] backendNodeId, int[][] attributes, 
1550                DOMSnapshot.RareStringData textValue, DOMSnapshot.RareStringData inputValue, 
1551                DOMSnapshot.RareBooleanData inputChecked, 
1552                DOMSnapshot.RareBooleanData optionSelected, 
1553                DOMSnapshot.RareIntegerData contentDocumentIndex, 
1554                DOMSnapshot.RareStringData pseudoType, DOMSnapshot.RareBooleanData isClickable, 
1555                DOMSnapshot.RareStringData currentSourceURL, DOMSnapshot.RareStringData originURL
1556            )
1557        {
1558            this.parentIndex           = parentIndex;
1559            this.nodeType              = nodeType;
1560            this.shadowRootType        = shadowRootType;
1561            this.nodeName              = nodeName;
1562            this.nodeValue             = nodeValue;
1563            this.backendNodeId         = backendNodeId;
1564            this.attributes            = attributes;
1565            this.textValue             = textValue;
1566            this.inputValue            = inputValue;
1567            this.inputChecked          = inputChecked;
1568            this.optionSelected        = optionSelected;
1569            this.contentDocumentIndex  = contentDocumentIndex;
1570            this.pseudoType            = pseudoType;
1571            this.isClickable           = isClickable;
1572            this.currentSourceURL      = currentSourceURL;
1573            this.originURL             = originURL;
1574        }
1575        
1576        /**
1577         * JSON Object Constructor
1578         * @param jo A Json-Object having data about an instance of {@code 'NodeTreeSnapshot'}.
1579         */
1580        public NodeTreeSnapshot (JsonObject jo)
1581        {
1582            this.parentIndex = (jo.getJsonArray("parentIndex") == null)
1583                ? null
1584                : ReadArrJSON.DimN.intArr(jo.getJsonArray("parentIndex"), -1, 0, null, int[].class);
1585        
1586            this.nodeType = (jo.getJsonArray("nodeType") == null)
1587                ? null
1588                : ReadArrJSON.DimN.intArr(jo.getJsonArray("nodeType"), -1, 0, null, int[].class);
1589        
1590            this.shadowRootType        = ReadJSON.getObject(jo, "shadowRootType", DOMSnapshot.RareStringData.class, true, false);
1591            this.nodeName = (jo.getJsonArray("nodeName") == null)
1592                ? null
1593                : ReadArrJSON.DimN.intArr(jo.getJsonArray("nodeName"), -1, 0, null, int[].class);
1594        
1595            this.nodeValue = (jo.getJsonArray("nodeValue") == null)
1596                ? null
1597                : ReadArrJSON.DimN.intArr(jo.getJsonArray("nodeValue"), -1, 0, null, int[].class);
1598        
1599            this.backendNodeId = (jo.getJsonArray("backendNodeId") == null)
1600                ? null
1601                : ReadArrJSON.DimN.intArr(jo.getJsonArray("backendNodeId"), -1, 0, null, int[].class);
1602        
1603            this.attributes = (jo.getJsonArray("attributes") == null)
1604                ? null
1605                : ReadArrJSON.DimN.intArr(jo.getJsonArray("attributes"), -1, 0, null, int[][].class);
1606        
1607            this.textValue             = ReadJSON.getObject(jo, "textValue", DOMSnapshot.RareStringData.class, true, false);
1608            this.inputValue            = ReadJSON.getObject(jo, "inputValue", DOMSnapshot.RareStringData.class, true, false);
1609            this.inputChecked          = ReadJSON.getObject(jo, "inputChecked", DOMSnapshot.RareBooleanData.class, true, false);
1610            this.optionSelected        = ReadJSON.getObject(jo, "optionSelected", DOMSnapshot.RareBooleanData.class, true, false);
1611            this.contentDocumentIndex  = ReadJSON.getObject(jo, "contentDocumentIndex", DOMSnapshot.RareIntegerData.class, true, false);
1612            this.pseudoType            = ReadJSON.getObject(jo, "pseudoType", DOMSnapshot.RareStringData.class, true, false);
1613            this.isClickable           = ReadJSON.getObject(jo, "isClickable", DOMSnapshot.RareBooleanData.class, true, false);
1614            this.currentSourceURL      = ReadJSON.getObject(jo, "currentSourceURL", DOMSnapshot.RareStringData.class, true, false);
1615            this.originURL             = ReadJSON.getObject(jo, "originURL", DOMSnapshot.RareStringData.class, true, false);
1616        }
1617        
1618        
1619        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
1620        public boolean equals(Object other)
1621        {
1622            if (other == null)                       return false;
1623            if (other.getClass() != this.getClass()) return false;
1624        
1625            NodeTreeSnapshot o = (NodeTreeSnapshot) other;
1626        
1627            return
1628                    Arrays.equals(this.parentIndex, o.parentIndex)
1629                &&  Arrays.equals(this.nodeType, o.nodeType)
1630                &&  Objects.equals(this.shadowRootType, o.shadowRootType)
1631                &&  Arrays.equals(this.nodeName, o.nodeName)
1632                &&  Arrays.equals(this.nodeValue, o.nodeValue)
1633                &&  Arrays.equals(this.backendNodeId, o.backendNodeId)
1634                &&  Arrays.equals(this.attributes, o.attributes)
1635                &&  Objects.equals(this.textValue, o.textValue)
1636                &&  Objects.equals(this.inputValue, o.inputValue)
1637                &&  Objects.equals(this.inputChecked, o.inputChecked)
1638                &&  Objects.equals(this.optionSelected, o.optionSelected)
1639                &&  Objects.equals(this.contentDocumentIndex, o.contentDocumentIndex)
1640                &&  Objects.equals(this.pseudoType, o.pseudoType)
1641                &&  Objects.equals(this.isClickable, o.isClickable)
1642                &&  Objects.equals(this.currentSourceURL, o.currentSourceURL)
1643                &&  Objects.equals(this.originURL, o.originURL);
1644        }
1645        
1646        /** Generates a Hash-Code for {@code 'this'} instance */
1647        public int hashCode()
1648        {
1649            return
1650                    Arrays.hashCode(this.parentIndex)
1651                +   Arrays.hashCode(this.nodeType)
1652                +   this.shadowRootType.hashCode()
1653                +   Arrays.hashCode(this.nodeName)
1654                +   Arrays.hashCode(this.nodeValue)
1655                +   Arrays.hashCode(this.backendNodeId)
1656                +   Arrays.hashCode(this.attributes)
1657                +   this.textValue.hashCode()
1658                +   this.inputValue.hashCode()
1659                +   this.inputChecked.hashCode()
1660                +   this.optionSelected.hashCode()
1661                +   this.contentDocumentIndex.hashCode()
1662                +   this.pseudoType.hashCode()
1663                +   this.isClickable.hashCode()
1664                +   this.currentSourceURL.hashCode()
1665                +   this.originURL.hashCode();
1666        }
1667    }
1668    
1669    /** Table of details of an element in the DOM tree with a LayoutObject. */
1670    public static class LayoutTreeSnapshot
1671        extends BaseType
1672        implements java.io.Serializable
1673    {
1674        /** For Object Serialization.  java.io.Serializable */
1675        protected static final long serialVersionUID = 1;
1676        
1677        public boolean[] optionals()
1678        { return new boolean[] { false, false, false, false, false, true, true, true, true, true, true, }; }
1679        
1680        /** Index of the corresponding node in the <CODE>NodeTreeSnapshot</CODE> array returned by <CODE>captureSnapshot</CODE>. */
1681        public final int[] nodeIndex;
1682        
1683        /** Array of indexes specifying computed style strings, filtered according to the <CODE>computedStyles</CODE> parameter passed to <CODE>captureSnapshot</CODE>. */
1684        public final int[][] styles;
1685        
1686        /** The absolute position bounding box. */
1687        public final Number[][] bounds;
1688        
1689        /** Contents of the LayoutText, if any. */
1690        public final int[] text;
1691        
1692        /** Stacking context information. */
1693        public final DOMSnapshot.RareBooleanData stackingContexts;
1694        
1695        /**
1696         * Global paint order index, which is determined by the stacking order of the nodes. Nodes
1697         * that are painted together will have the same index. Only provided if includePaintOrder in
1698         * captureSnapshot was true.
1699         * <BR />
1700         * <BR /><B>OPTIONAL</B>
1701         */
1702        public final int[] paintOrders;
1703        
1704        /**
1705         * The offset rect of nodes. Only available when includeDOMRects is set to true
1706         * <BR />
1707         * <BR /><B>OPTIONAL</B>
1708         */
1709        public final Number[][] offsetRects;
1710        
1711        /**
1712         * The scroll rect of nodes. Only available when includeDOMRects is set to true
1713         * <BR />
1714         * <BR /><B>OPTIONAL</B>
1715         */
1716        public final Number[][] scrollRects;
1717        
1718        /**
1719         * The client rect of nodes. Only available when includeDOMRects is set to true
1720         * <BR />
1721         * <BR /><B>OPTIONAL</B>
1722         */
1723        public final Number[][] clientRects;
1724        
1725        /**
1726         * The list of background colors that are blended with colors of overlapping elements.
1727         * <BR />
1728         * <BR /><B>OPTIONAL</B>
1729         * <BR /><B>EXPERIMENTAL</B>
1730         */
1731        public final int[] blendedBackgroundColors;
1732        
1733        /**
1734         * The list of computed text opacities.
1735         * <BR />
1736         * <BR /><B>OPTIONAL</B>
1737         * <BR /><B>EXPERIMENTAL</B>
1738         */
1739        public final Number[] textColorOpacities;
1740        
1741        /**
1742         * Constructor
1743         *
1744         * @param nodeIndex Index of the corresponding node in the <CODE>NodeTreeSnapshot</CODE> array returned by <CODE>captureSnapshot</CODE>.
1745         * 
1746         * @param styles Array of indexes specifying computed style strings, filtered according to the <CODE>computedStyles</CODE> parameter passed to <CODE>captureSnapshot</CODE>.
1747         * 
1748         * @param bounds The absolute position bounding box.
1749         * 
1750         * @param text Contents of the LayoutText, if any.
1751         * 
1752         * @param stackingContexts Stacking context information.
1753         * 
1754         * @param paintOrders 
1755         * Global paint order index, which is determined by the stacking order of the nodes. Nodes
1756         * that are painted together will have the same index. Only provided if includePaintOrder in
1757         * captureSnapshot was true.
1758         * <BR /><B>OPTIONAL</B>
1759         * 
1760         * @param offsetRects The offset rect of nodes. Only available when includeDOMRects is set to true
1761         * <BR /><B>OPTIONAL</B>
1762         * 
1763         * @param scrollRects The scroll rect of nodes. Only available when includeDOMRects is set to true
1764         * <BR /><B>OPTIONAL</B>
1765         * 
1766         * @param clientRects The client rect of nodes. Only available when includeDOMRects is set to true
1767         * <BR /><B>OPTIONAL</B>
1768         * 
1769         * @param blendedBackgroundColors The list of background colors that are blended with colors of overlapping elements.
1770         * <BR /><B>OPTIONAL</B>
1771         * <BR /><B>EXPERIMENTAL</B>
1772         * 
1773         * @param textColorOpacities The list of computed text opacities.
1774         * <BR /><B>OPTIONAL</B>
1775         * <BR /><B>EXPERIMENTAL</B>
1776         */
1777        public LayoutTreeSnapshot(
1778                int[] nodeIndex, int[][] styles, Number[][] bounds, int[] text, 
1779                DOMSnapshot.RareBooleanData stackingContexts, int[] paintOrders, 
1780                Number[][] offsetRects, Number[][] scrollRects, Number[][] clientRects, 
1781                int[] blendedBackgroundColors, Number[] textColorOpacities
1782            )
1783        {
1784            // Exception-Check(s) to ensure that if any parameters which are not declared as
1785            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1786            
1787            if (nodeIndex == null)        BRDPC.throwNPE("nodeIndex");
1788            if (styles == null)           BRDPC.throwNPE("styles");
1789            if (bounds == null)           BRDPC.throwNPE("bounds");
1790            if (text == null)             BRDPC.throwNPE("text");
1791            if (stackingContexts == null) BRDPC.throwNPE("stackingContexts");
1792            
1793            this.nodeIndex                = nodeIndex;
1794            this.styles                   = styles;
1795            this.bounds                   = bounds;
1796            this.text                     = text;
1797            this.stackingContexts         = stackingContexts;
1798            this.paintOrders              = paintOrders;
1799            this.offsetRects              = offsetRects;
1800            this.scrollRects              = scrollRects;
1801            this.clientRects              = clientRects;
1802            this.blendedBackgroundColors  = blendedBackgroundColors;
1803            this.textColorOpacities       = textColorOpacities;
1804        }
1805        
1806        /**
1807         * JSON Object Constructor
1808         * @param jo A Json-Object having data about an instance of {@code 'LayoutTreeSnapshot'}.
1809         */
1810        public LayoutTreeSnapshot (JsonObject jo)
1811        {
1812            this.nodeIndex = (jo.getJsonArray("nodeIndex") == null)
1813                ? null
1814                : ReadArrJSON.DimN.intArr(jo.getJsonArray("nodeIndex"), -1, 0, null, int[].class);
1815        
1816            this.styles = (jo.getJsonArray("styles") == null)
1817                ? null
1818                : ReadArrJSON.DimN.intArr(jo.getJsonArray("styles"), -1, 0, null, int[][].class);
1819        
1820            this.bounds = (jo.getJsonArray("bounds") == null)
1821                ? null
1822                : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("bounds"), -1, 0, null, Number[][].class);
1823        
1824            this.text = (jo.getJsonArray("text") == null)
1825                ? null
1826                : ReadArrJSON.DimN.intArr(jo.getJsonArray("text"), -1, 0, null, int[].class);
1827        
1828            this.stackingContexts         = ReadJSON.getObject(jo, "stackingContexts", DOMSnapshot.RareBooleanData.class, false, true);
1829            this.paintOrders = (jo.getJsonArray("paintOrders") == null)
1830                ? null
1831                : ReadArrJSON.DimN.intArr(jo.getJsonArray("paintOrders"), -1, 0, null, int[].class);
1832        
1833            this.offsetRects = (jo.getJsonArray("offsetRects") == null)
1834                ? null
1835                : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("offsetRects"), -1, 0, null, Number[][].class);
1836        
1837            this.scrollRects = (jo.getJsonArray("scrollRects") == null)
1838                ? null
1839                : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("scrollRects"), -1, 0, null, Number[][].class);
1840        
1841            this.clientRects = (jo.getJsonArray("clientRects") == null)
1842                ? null
1843                : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("clientRects"), -1, 0, null, Number[][].class);
1844        
1845            this.blendedBackgroundColors = (jo.getJsonArray("blendedBackgroundColors") == null)
1846                ? null
1847                : ReadArrJSON.DimN.intArr(jo.getJsonArray("blendedBackgroundColors"), -1, 0, null, int[].class);
1848        
1849            this.textColorOpacities = (jo.getJsonArray("textColorOpacities") == null)
1850                ? null
1851                : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("textColorOpacities"), -1, 0, null, Number[].class);
1852        
1853        }
1854        
1855        
1856        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
1857        public boolean equals(Object other)
1858        {
1859            if (other == null)                       return false;
1860            if (other.getClass() != this.getClass()) return false;
1861        
1862            LayoutTreeSnapshot o = (LayoutTreeSnapshot) other;
1863        
1864            return
1865                    Arrays.equals(this.nodeIndex, o.nodeIndex)
1866                &&  Arrays.equals(this.styles, o.styles)
1867                &&  Arrays.deepEquals(this.bounds, o.bounds)
1868                &&  Arrays.equals(this.text, o.text)
1869                &&  Objects.equals(this.stackingContexts, o.stackingContexts)
1870                &&  Arrays.equals(this.paintOrders, o.paintOrders)
1871                &&  Arrays.deepEquals(this.offsetRects, o.offsetRects)
1872                &&  Arrays.deepEquals(this.scrollRects, o.scrollRects)
1873                &&  Arrays.deepEquals(this.clientRects, o.clientRects)
1874                &&  Arrays.equals(this.blendedBackgroundColors, o.blendedBackgroundColors)
1875                &&  Arrays.deepEquals(this.textColorOpacities, o.textColorOpacities);
1876        }
1877        
1878        /** Generates a Hash-Code for {@code 'this'} instance */
1879        public int hashCode()
1880        {
1881            return
1882                    Arrays.hashCode(this.nodeIndex)
1883                +   Arrays.hashCode(this.styles)
1884                +   Arrays.deepHashCode(this.bounds)
1885                +   Arrays.hashCode(this.text)
1886                +   this.stackingContexts.hashCode()
1887                +   Arrays.hashCode(this.paintOrders)
1888                +   Arrays.deepHashCode(this.offsetRects)
1889                +   Arrays.deepHashCode(this.scrollRects)
1890                +   Arrays.deepHashCode(this.clientRects)
1891                +   Arrays.hashCode(this.blendedBackgroundColors)
1892                +   Arrays.deepHashCode(this.textColorOpacities);
1893        }
1894    }
1895    
1896    /**
1897     * Table of details of the post layout rendered text positions. The exact layout should not be regarded as
1898     * stable and may change between versions.
1899     */
1900    public static class TextBoxSnapshot
1901        extends BaseType
1902        implements java.io.Serializable
1903    {
1904        /** For Object Serialization.  java.io.Serializable */
1905        protected static final long serialVersionUID = 1;
1906        
1907        public boolean[] optionals()
1908        { return new boolean[] { false, false, false, false, }; }
1909        
1910        /** Index of the layout tree node that owns this box collection. */
1911        public final int[] layoutIndex;
1912        
1913        /** The absolute position bounding box. */
1914        public final Number[][] bounds;
1915        
1916        /**
1917         * The starting index in characters, for this post layout textbox substring. Characters that
1918         * would be represented as a surrogate pair in UTF-16 have length 2.
1919         */
1920        public final int[] start;
1921        
1922        /**
1923         * The number of characters in this post layout textbox substring. Characters that would be
1924         * represented as a surrogate pair in UTF-16 have length 2.
1925         */
1926        public final int[] length;
1927        
1928        /**
1929         * Constructor
1930         *
1931         * @param layoutIndex Index of the layout tree node that owns this box collection.
1932         * 
1933         * @param bounds The absolute position bounding box.
1934         * 
1935         * @param start 
1936         * The starting index in characters, for this post layout textbox substring. Characters that
1937         * would be represented as a surrogate pair in UTF-16 have length 2.
1938         * 
1939         * @param length 
1940         * The number of characters in this post layout textbox substring. Characters that would be
1941         * represented as a surrogate pair in UTF-16 have length 2.
1942         */
1943        public TextBoxSnapshot(int[] layoutIndex, Number[][] bounds, int[] start, int[] length)
1944        {
1945            // Exception-Check(s) to ensure that if any parameters which are not declared as
1946            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
1947            
1948            if (layoutIndex == null) BRDPC.throwNPE("layoutIndex");
1949            if (bounds == null)      BRDPC.throwNPE("bounds");
1950            if (start == null)       BRDPC.throwNPE("start");
1951            if (length == null)      BRDPC.throwNPE("length");
1952            
1953            this.layoutIndex  = layoutIndex;
1954            this.bounds       = bounds;
1955            this.start        = start;
1956            this.length       = length;
1957        }
1958        
1959        /**
1960         * JSON Object Constructor
1961         * @param jo A Json-Object having data about an instance of {@code 'TextBoxSnapshot'}.
1962         */
1963        public TextBoxSnapshot (JsonObject jo)
1964        {
1965            this.layoutIndex = (jo.getJsonArray("layoutIndex") == null)
1966                ? null
1967                : ReadArrJSON.DimN.intArr(jo.getJsonArray("layoutIndex"), -1, 0, null, int[].class);
1968        
1969            this.bounds = (jo.getJsonArray("bounds") == null)
1970                ? null
1971                : ReadArrJSON.DimN.arrNumber(jo.getJsonArray("bounds"), -1, 0, null, Number[][].class);
1972        
1973            this.start = (jo.getJsonArray("start") == null)
1974                ? null
1975                : ReadArrJSON.DimN.intArr(jo.getJsonArray("start"), -1, 0, null, int[].class);
1976        
1977            this.length = (jo.getJsonArray("length") == null)
1978                ? null
1979                : ReadArrJSON.DimN.intArr(jo.getJsonArray("length"), -1, 0, null, int[].class);
1980        
1981        }
1982        
1983        
1984        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
1985        public boolean equals(Object other)
1986        {
1987            if (other == null)                       return false;
1988            if (other.getClass() != this.getClass()) return false;
1989        
1990            TextBoxSnapshot o = (TextBoxSnapshot) other;
1991        
1992            return
1993                    Arrays.equals(this.layoutIndex, o.layoutIndex)
1994                &&  Arrays.deepEquals(this.bounds, o.bounds)
1995                &&  Arrays.equals(this.start, o.start)
1996                &&  Arrays.equals(this.length, o.length);
1997        }
1998        
1999        /** Generates a Hash-Code for {@code 'this'} instance */
2000        public int hashCode()
2001        {
2002            return
2003                    Arrays.hashCode(this.layoutIndex)
2004                +   Arrays.deepHashCode(this.bounds)
2005                +   Arrays.hashCode(this.start)
2006                +   Arrays.hashCode(this.length);
2007        }
2008    }
2009    
2010    
2011    // Counter for keeping the WebSocket Request ID's distinct.
2012    private static int counter = 1;
2013    
2014    /**
2015     * Disables DOM snapshot agent for the given page.
2016     * 
2017     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
2018     * {@link Ret0}&gt;</CODE>
2019     *
2020     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
2021     * browser receives the invocation-request.
2022     *
2023     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
2024     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
2025     * {@code >} to ensure the Browser Function has run to completion.
2026     */
2027    public static Script<String, JsonObject, Ret0> disable()
2028    {
2029        final int          webSocketID = 17000000 + counter++;
2030        final boolean[]    optionals   = new boolean[0];
2031        
2032        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
2033        String requestJSON = WriteJSON.get(
2034            parameterTypes.get("disable"),
2035            parameterNames.get("disable"),
2036            optionals, webSocketID,
2037            "DOMSnapshot.disable"
2038        );
2039        
2040        // This Remote Command does not have a Return-Value.
2041        return new Script<>
2042            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
2043    }
2044    
2045    /**
2046     * Enables DOM snapshot agent for the given page.
2047     * 
2048     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
2049     * {@link Ret0}&gt;</CODE>
2050     *
2051     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
2052     * browser receives the invocation-request.
2053     *
2054     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
2055     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
2056     * {@code >} to ensure the Browser Function has run to completion.
2057     */
2058    public static Script<String, JsonObject, Ret0> enable()
2059    {
2060        final int          webSocketID = 17001000 + counter++;
2061        final boolean[]    optionals   = new boolean[0];
2062        
2063        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
2064        String requestJSON = WriteJSON.get(
2065            parameterTypes.get("enable"),
2066            parameterNames.get("enable"),
2067            optionals, webSocketID,
2068            "DOMSnapshot.enable"
2069        );
2070        
2071        // This Remote Command does not have a Return-Value.
2072        return new Script<>
2073            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
2074    }
2075    
2076    /**
2077     * Returns a document snapshot, including the full DOM tree of the root node (including iframes,
2078     * template contents, and imported documents) in a flattened array, as well as layout and
2079     * white-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is
2080     * flattened.
2081     * <BR /><B>DEPRECATED</B>
2082     * 
2083     * @param computedStyleWhitelist Whitelist of computed styles to return.
2084     * 
2085     * @param includeEventListeners Whether or not to retrieve details of DOM listeners (default false).
2086     * <BR /><B>OPTIONAL</B>
2087     * 
2088     * @param includePaintOrder Whether to determine and include the paint order index of LayoutTreeNodes (default false).
2089     * <BR /><B>OPTIONAL</B>
2090     * 
2091     * @param includeUserAgentShadowTree Whether to include UA shadow tree in the snapshot (default false).
2092     * <BR /><B>OPTIONAL</B>
2093     * 
2094     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
2095     * {@link Ret3}&gt;</CODE>
2096     *
2097     * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 
2098     * {@link Script#exec()}), and a {@link Promise} returned.
2099     *
2100     * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B>
2101     * (using {@link Promise#await()}), the {@code Ret3} will subsequently
2102     * be returned from that call.
2103     * 
2104     * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated
2105     * in an instance of <B>{@link Ret3}</B>
2106     *
2107     * <BR /><BR /><UL CLASS=JDUL>
2108     * <LI><CODE><B>Ret3.a:</B> {@link DOMSnapshot.DOMNode}[] (<B>domNodes</B>)</CODE>
2109     *     <BR />The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document.
2110     *     <BR /><BR /></LI>
2111     * <LI><CODE><B>Ret3.b:</B> {@link DOMSnapshot.LayoutTreeNode}[] (<B>layoutTreeNodes</B>)</CODE>
2112     *     <BR />The nodes in the layout tree.
2113     *     <BR /><BR /></LI>
2114     * <LI><CODE><B>Ret3.c:</B> {@link DOMSnapshot.ComputedStyle}[] (<B>computedStyles</B>)</CODE>
2115     *     <BR />Whitelisted ComputedStyle properties for each node in the layout tree.
2116     *     </LI>
2117     * </UL>
2118     */
2119    public static Script<String, JsonObject, Ret3<DOMSnapshot.DOMNode[], DOMSnapshot.LayoutTreeNode[], DOMSnapshot.ComputedStyle[]>> 
2120        getSnapshot(
2121            String[] computedStyleWhitelist, Boolean includeEventListeners, 
2122            Boolean includePaintOrder, Boolean includeUserAgentShadowTree
2123        )
2124    {
2125        // Exception-Check(s) to ensure that if any parameters which are not declared as
2126        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
2127        
2128        if (computedStyleWhitelist == null) BRDPC.throwNPE("computedStyleWhitelist");
2129        
2130        final int       webSocketID = 17002000 + counter++;
2131        final boolean[] optionals   = { false, true, true, true, };
2132        
2133        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
2134        String requestJSON = WriteJSON.get(
2135            parameterTypes.get("getSnapshot"),
2136            parameterNames.get("getSnapshot"),
2137            optionals, webSocketID,
2138            "DOMSnapshot.getSnapshot",
2139            computedStyleWhitelist, includeEventListeners, includePaintOrder,
2140            includeUserAgentShadowTree
2141        );
2142        
2143        // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret3'
2144        Function<JsonObject, Ret3<DOMSnapshot.DOMNode[], DOMSnapshot.LayoutTreeNode[], DOMSnapshot.ComputedStyle[]>> 
2145            responseProcessor = (JsonObject jo) -> new Ret3<>(
2146                (jo.getJsonArray("domNodes") == null)
2147                    ? null
2148                    : ReadArrJSON.DimN.objArr(jo.getJsonArray("domNodes"), null, 0, DOMSnapshot.DOMNode[].class),
2149                (jo.getJsonArray("layoutTreeNodes") == null)
2150                    ? null
2151                    : ReadArrJSON.DimN.objArr(jo.getJsonArray("layoutTreeNodes"), null, 0, DOMSnapshot.LayoutTreeNode[].class),
2152                (jo.getJsonArray("computedStyles") == null)
2153                    ? null
2154                    : ReadArrJSON.DimN.objArr(jo.getJsonArray("computedStyles"), null, 0, DOMSnapshot.ComputedStyle[].class)
2155            );
2156        
2157        // Pass the 'defaultSender' to Script-Constructor
2158        // The sender that is used can be changed before executing script.
2159        return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor);
2160    }
2161    
2162    /**
2163     * Returns a document snapshot, including the full DOM tree of the root node (including iframes,
2164     * template contents, and imported documents) in a flattened array, as well as layout and
2165     * white-listed computed style information for the nodes. Shadow DOM in the returned DOM tree is
2166     * flattened.
2167     * 
2168     * @param computedStyles Whitelist of computed styles to return.
2169     * 
2170     * @param includePaintOrder Whether to include layout object paint orders into the snapshot.
2171     * <BR /><B>OPTIONAL</B>
2172     * 
2173     * @param includeDOMRects Whether to include DOM rectangles (offsetRects, clientRects, scrollRects) into the snapshot
2174     * <BR /><B>OPTIONAL</B>
2175     * 
2176     * @param includeBlendedBackgroundColors 
2177     * Whether to include blended background colors in the snapshot (default: false).
2178     * Blended background color is achieved by blending background colors of all elements
2179     * that overlap with the current element.
2180     * <BR /><B>OPTIONAL</B>
2181     * <BR /><B>EXPERIMENTAL</B>
2182     * 
2183     * @param includeTextColorOpacities 
2184     * Whether to include text color opacity in the snapshot (default: false).
2185     * An element might have the opacity property set that affects the text color of the element.
2186     * The final text color opacity is computed based on the opacity of all overlapping elements.
2187     * <BR /><B>OPTIONAL</B>
2188     * <BR /><B>EXPERIMENTAL</B>
2189     * 
2190     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
2191     * {@link Ret2}&gt;</CODE>
2192     *
2193     * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 
2194     * {@link Script#exec()}), and a {@link Promise} returned.
2195     *
2196     * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B>
2197     * (using {@link Promise#await()}), the {@code Ret2} will subsequently
2198     * be returned from that call.
2199     * 
2200     * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated
2201     * in an instance of <B>{@link Ret2}</B>
2202     *
2203     * <BR /><BR /><UL CLASS=JDUL>
2204     * <LI><CODE><B>Ret2.a:</B> {@link DOMSnapshot.DocumentSnapshot}[] (<B>documents</B>)</CODE>
2205     *     <BR />The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document.
2206     *     <BR /><BR /></LI>
2207     * <LI><CODE><B>Ret2.b:</B> String[] (<B>strings</B>)</CODE>
2208     *     <BR />Shared string table that all string properties refer to with indexes.
2209     *     </LI>
2210     * </UL>
2211     */
2212    public static Script<String, JsonObject, Ret2<DOMSnapshot.DocumentSnapshot[], String[]>> captureSnapshot(
2213            String[] computedStyles, Boolean includePaintOrder, Boolean includeDOMRects, 
2214            Boolean includeBlendedBackgroundColors, Boolean includeTextColorOpacities
2215        )
2216    {
2217        // Exception-Check(s) to ensure that if any parameters which are not declared as
2218        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
2219        
2220        if (computedStyles == null) BRDPC.throwNPE("computedStyles");
2221        
2222        final int       webSocketID = 17003000 + counter++;
2223        final boolean[] optionals   = { false, true, true, true, true, };
2224        
2225        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
2226        String requestJSON = WriteJSON.get(
2227            parameterTypes.get("captureSnapshot"),
2228            parameterNames.get("captureSnapshot"),
2229            optionals, webSocketID,
2230            "DOMSnapshot.captureSnapshot",
2231            computedStyles, includePaintOrder, includeDOMRects, includeBlendedBackgroundColors,
2232            includeTextColorOpacities
2233        );
2234        
2235        // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret2'
2236        Function<JsonObject, Ret2<DOMSnapshot.DocumentSnapshot[], String[]>> 
2237            responseProcessor = (JsonObject jo) -> new Ret2<>(
2238                (jo.getJsonArray("documents") == null)
2239                    ? null
2240                    : ReadArrJSON.DimN.objArr(jo.getJsonArray("documents"), null, 0, DOMSnapshot.DocumentSnapshot[].class),
2241                (jo.getJsonArray("strings") == null)
2242                    ? null
2243                    : ReadArrJSON.DimN.strArr(jo.getJsonArray("strings"), null, 0, String[].class)
2244            );
2245        
2246        // Pass the 'defaultSender' to Script-Constructor
2247        // The sender that is used can be changed before executing script.
2248        return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor);
2249    }
2250    
2251}