From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thorsten Jolitz Subject: ORG and ASCII documentation for org-elements.el Date: Tue, 18 Jun 2013 15:37:44 +0200 Message-ID: <878v27letz.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:53004) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uow8u-0003Ki-9I for emacs-orgmode@gnu.org; Tue, 18 Jun 2013 09:40:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uow8k-00064D-3P for emacs-orgmode@gnu.org; Tue, 18 Jun 2013 09:40:16 -0400 Received: from plane.gmane.org ([80.91.229.3]:50150) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uow8j-0005zm-6K for emacs-orgmode@gnu.org; Tue, 18 Jun 2013 09:40:06 -0400 Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1Uow8h-0006Tn-Rg for emacs-orgmode@gnu.org; Tue, 18 Jun 2013 15:40:03 +0200 Received: from e178188064.adsl.alicedsl.de ([85.178.188.64]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 18 Jun 2013 15:40:03 +0200 Received: from tjolitz by e178188064.adsl.alicedsl.de with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 18 Jun 2013 15:40:03 +0200 List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org --=-=-= Content-Type: text/plain see attached documents: --=-=-= Content-Type: text/plain Content-Disposition: inline; filename=org-element-docstrings.txt Content-Description: Docstrings from org-elements.el (as txt file) ___________________________________ DOCSTRINGS FROM 'ORG-ELEMENTS.EL' Thorsten Jolitz ___________________________________ Table of Contents _________________ org-element.el --- Parser And Applications for Org syntax Commentary: Code: Definitions And Rules Accessors and Setters Greater elements .. Center Block .. Drawer .. Dynamic Block .. Footnote Definition .. Headline .. Inlinetask .. Item .. Plain List .. Property Drawer .. Quote Block .. Section .. Special Block Elements .. Babel Call .. Clock .. Comment .. Comment Block .. Diary Sexp .. Example Block .. Table .. Table Row .. Verse Block Objects .. Bold .. Code .. Entity .. Export Snippet .. Footnote Reference .. Inline Babel Call .. Inline Src Block .. Italic .. Latex Fragment .. Line Break .. Link .. Macro .. Radio-target .. Statistics Cookie .. Strike-Through .. Subscript .. Superscript .. Table Cell .. Target .. Timestamp .. Underline .. Verbatim Parsing Element Starting At Point The Org Parser Towards A Bijective Process The Toolbox org-element.el ends here [{Back to Worg's index}] [{Back to Worg's index}] file:index.org org-element.el --- Parser And Applications for Org syntax ========================================================= Copyright (C) 2012-2013 Free Software Foundation, Inc. Author: Nicolas Goaziou Keywords: outlines, hypermedia, calendar, wp This file is part of GNU Emacs. GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see [http://www.gnu.org/licenses/]. Commentary: =========== Org syntax can be divided into three categories: "Greater elements", "Elements" and "Objects". Elements are related to the structure of the document. Indeed, all elements are a cover for the document: each position within belongs to at least one element. An element always starts and ends at the beginning of a line. With a few exceptions (`clock', `headline', `inlinetask', `item', `planning', `node-property', `quote-section' `section' and `table-row' types), it can also accept a fixed set of keywords as attributes. Those are called "affiliated keywords" to distinguish them from other keywords, which are full-fledged elements. Almost all affiliated keywords are referenced in `org-element-affiliated-keywords'; the others are export attributes and start with "ATTR_" prefix. Element containing other elements (and only elements) are called greater elements. Concerned types are: `center-block', `drawer', `dynamic-block', `footnote-definition', `headline', `inlinetask', `item', `plain-list', `property-drawer', `quote-block', `section' and `special-block'. Other element types are: `babel-call', `clock', `comment', `comment-block', `diary-sexp', `example-block', `export-block', `fixed-width', `horizontal-rule', `keyword', `latex-environment', `node-property', `paragraph', `planning', `quote-section', `src-block', `table', `table-row' and `verse-block'. Among them, `paragraph' and `verse-block' types can contain Org objects and plain text. Objects are related to document's contents. Some of them are recursive. Associated types are of the following: `bold', `code', `entity', `export-snippet', `footnote-reference', `inline-babel-call', `inline-src-block', `italic', `latex-fragment', `line-break', `link', `macro', `radio-target', `statistics-cookie', `strike-through', `subscript', `superscript', `table-cell', `target', `timestamp', `underline' and `verbatim'. Some elements also have special properties whose value can hold objects themselves (i.e. an item tag or a headline name). Such values are called "secondary strings". Any object belongs to either an element or a secondary string. Notwithstanding affiliated keywords, each greater element, element and object has a fixed set of properties attached to it. Among them, four are shared by all types: `:begin' and `:end', which refer to the beginning and ending buffer positions of the considered element or object, `:post-blank', which holds the number of blank lines, or white spaces, at its end and `:parent' which refers to the element or object containing it. Greater elements, elements and objects containing objects will also have `:contents-begin' and `:contents-end' properties to delimit contents. Eventually, greater elements and elements accepting affiliated keywords will have a `:post-affiliated' property, referring to the buffer position after all such keywords. At the lowest level, a `:parent' property is also attached to any string, as a text property. Lisp-wise, an element or an object can be represented as a list. It follows the pattern (TYPE PROPERTIES CONTENTS), where: TYPE is a symbol describing the Org element or object. PROPERTIES is the property list attached to it. See docstring of appropriate parsing function to get an exhaustive list. CONTENTS is a list of elements, objects or raw strings contained in the current element or object, when applicable. An Org buffer is a nested list of such elements and objects, whose type is `org-data' and properties is nil. The first part of this file defines Org syntax, while the second one provide accessors and setters functions. The next part implements a parser and an interpreter for each element and object type in Org syntax. The following part creates a fully recursive buffer parser. It also provides a tool to map a function to elements or objects matching some criteria in the parse tree. Functions of interest are `org-element-parse-buffer', `org-element-map' and, to a lesser extent, `org-element-parse-secondary-string'. The penultimate part is the cradle of an interpreter for the obtained parse tree: `org-element-interpret-data'. The library ends by furnishing `org-element-at-point' function, and a way to give information about document structure around point with `org-element-context'. Code: ===== ,---- | (eval-when-compile (require 'cl)) | (require 'org) `---- Definitions And Rules ===================== Define elements, greater elements and specify recursive objects, along with the affiliated keywords recognized. Also set up restrictions on recursive objects combinations. These variables really act as a control center for the parsing process. ,---- | (defconst org-element-paragraph-separate | (concat "^\\(?:" | ;; Headlines, inlinetasks. | org-outline-regexp "\\|" | ;; Footnote definitions. | "\\[\\(?:[0-9]+\\|fn:[-_[:word:]]+\\)\\]" "\\|" | ;; Diary sexps. | "%%(" "\\|" | "[ \t]*\\(?:" | ;; Empty lines. | "$" "\\|" | ;; Tables (any type). | "\\(?:|\\|\\+-[-+]\\)" "\\|" | ;; Blocks (any type), Babel calls, drawers (any type), | ;; fixed-width areas and keywords. Note: this is only an | ;; indication and need some thorough check. | "[#:]" "\\|" | ;; Horizontal rules. | "-\\{5,\\}[ \t]*$" "\\|" | ;; LaTeX environments. | "\\\\begin{\\([A-Za-z0-9]+\\*?\\)}" "\\|" | ;; Planning and Clock lines. | (regexp-opt (list org-scheduled-string | org-deadline-string | org-closed-string | org-clock-string)) | "\\|" | ;; Lists. | (let ((term (case org-plain-list-ordered-item-terminator | (?\) ")") (?. "\\.") (otherwise "[.)]"))) | (alpha (and org-list-allow-alphabetical "\\|[A-Za-z]"))) | (concat "\\(?:[-+*]\\|\\(?:[0-9]+" alpha "\\)" term "\\)" | "\\(?:[ \t]\\|$\\)")) | "\\)\\)") | "Regexp to separate paragraphs in an Org buffer. | In the case of lines starting with \"#\" and \":\", this regexp | is not sufficient to know if point is at a paragraph ending. See | `org-element-paragraph-parser' for more information.") | | (defconst org-element-all-elements | '(babel-call center-block clock comment comment-block diary-sexp drawer | dynamic-block example-block export-block fixed-width | footnote-definition headline horizontal-rule inlinetask item | keyword latex-environment node-property paragraph plain-list | planning property-drawer quote-block quote-section section | special-block src-block table table-row verse-block) | "Complete list of element types.") | | (defconst org-element-greater-elements | '(center-block drawer dynamic-block footnote-definition headline inlinetask | item plain-list property-drawer quote-block section | special-block table) | "List of recursive element types aka Greater Elements.") | | (defconst org-element-all-successors | '(export-snippet footnote-reference inline-babel-call inline-src-block | latex-or-entity line-break link macro plain-link radio-target | statistics-cookie sub/superscript table-cell target | text-markup timestamp) | "Complete list of successors.") | | (defconst org-element-object-successor-alist | '((subscript . sub/superscript) (superscript . sub/superscript) | (bold . text-markup) (code . text-markup) (italic . text-markup) | (strike-through . text-markup) (underline . text-markup) | (verbatim . text-markup) (entity . latex-or-entity) | (latex-fragment . latex-or-entity)) | "Alist of translations between object type and successor name. | Sharing the same successor comes handy when, for example, the | regexp matching one object can also match the other object.") | | (defconst org-element-all-objects | '(bold code entity export-snippet footnote-reference inline-babel-call | inline-src-block italic line-break latex-fragment link macro | radio-target statistics-cookie strike-through subscript superscript | table-cell target timestamp underline verbatim) | "Complete list of object types.") | | (defconst org-element-recursive-objects | '(bold italic link subscript radio-target strike-through superscript | table-cell underline) | "List of recursive object types.") | | (defvar org-element-block-name-alist | '(("CENTER" . org-element-center-block-parser) | ("COMMENT" . org-element-comment-block-parser) | ("EXAMPLE" . org-element-example-block-parser) | ("QUOTE" . org-element-quote-block-parser) | ("SRC" . org-element-src-block-parser) | ("VERSE" . org-element-verse-block-parser)) | "Alist between block names and the associated parsing function. | Names must be uppercase. Any block whose name has no association | is parsed with `org-element-special-block-parser'.") | | (defconst org-element-link-type-is-file | '("file" "file+emacs" "file+sys" "docview") | "List of link types equivalent to \"file\". | Only these types can accept search options and an explicit | application to open them.") | | (defconst org-element-affiliated-keywords | '("CAPTION" "DATA" "HEADER" "HEADERS" "LABEL" "NAME" "PLOT" "RESNAME" "RESULT" | "RESULTS" "SOURCE" "SRCNAME" "TBLNAME") | "List of affiliated keywords as strings. | By default, all keywords setting attributes (i.e. \"ATTR_LATEX\") | are affiliated keywords and need not to be in this list.") | | (defconst org-element--affiliated-re | (format "[ \t]*#\\+%s:" | ;; Regular affiliated keywords. | (format "\\(%s\\|ATTR_[-_A-Za-z0-9]+\\)\\(?:\\[\\(.*\\)\\]\\)?" | (regexp-opt org-element-affiliated-keywords))) | "Regexp matching any affiliated keyword. | | Keyword name is put in match group 1. Moreover, if keyword | belongs to `org-element-dual-keywords', put the dual value in | match group 2. | | Don't modify it, set `org-element-affiliated-keywords' instead.") | | (defconst org-element-keyword-translation-alist | '(("DATA" . "NAME") ("LABEL" . "NAME") ("RESNAME" . "NAME") | ("SOURCE" . "NAME") ("SRCNAME" . "NAME") ("TBLNAME" . "NAME") | ("RESULT" . "RESULTS") ("HEADERS" . "HEADER")) | "Alist of usual translations for keywords. | The key is the old name and the value the new one. The property | holding their value will be named after the translated name.") | | (defconst org-element-multiple-keywords '("CAPTION" "HEADER") | "List of affiliated keywords that can occur more than once in an element. | | Their value will be consed into a list of strings, which will be | returned as the value of the property. | | This list is checked after translations have been applied. See | `org-element-keyword-translation-alist'. | | By default, all keywords setting attributes (i.e. \"ATTR_LATEX\") | allow multiple occurrences and need not to be in this list.") | | (defconst org-element-parsed-keywords '("CAPTION") | "List of affiliated keywords whose value can be parsed. | | Their value will be stored as a secondary string: a list of | strings and objects. | | This list is checked after translations have been applied. See | `org-element-keyword-translation-alist'.") | | (defconst org-element-dual-keywords '("CAPTION" "RESULTS") | "List of affiliated keywords which can have a secondary value. | | In Org syntax, they can be written with optional square brackets | before the colons. For example, RESULTS keyword can be | associated to a hash value with the following: | | #+RESULTS[hash-string]: some-source | | This list is checked after translations have been applied. See | `org-element-keyword-translation-alist'.") | | (defconst org-element-document-properties '("AUTHOR" "DATE" "TITLE") | "List of properties associated to the whole document. | Any keyword in this list will have its value parsed and stored as | a secondary string.") | | (defconst org-element-object-restrictions | (let* ((standard-set | (remq 'plain-link (remq 'table-cell org-element-all-successors))) | (standard-set-no-line-break (remq 'line-break standard-set))) | `((bold ,@standard-set) | (footnote-reference ,@standard-set) | (headline ,@standard-set-no-line-break) | (inlinetask ,@standard-set-no-line-break) | (italic ,@standard-set) | (item ,@standard-set-no-line-break) | (keyword ,@standard-set) | ;; Ignore all links excepted plain links in a link description. | ;; Also ignore radio-targets and line breaks. | (link export-snippet inline-babel-call inline-src-block latex-or-entity | macro plain-link statistics-cookie sub/superscript text-markup) | (paragraph ,@standard-set) | ;; Remove any variable object from radio target as it would | ;; prevent it from being properly recognized. | (radio-target latex-or-entity sub/superscript) | (strike-through ,@standard-set) | (subscript ,@standard-set) | (superscript ,@standard-set) | ;; Ignore inline babel call and inline src block as formulas are | ;; possible. Also ignore line breaks and statistics cookies. | (table-cell export-snippet footnote-reference latex-or-entity link macro | radio-target sub/superscript target text-markup timestamp) | (table-row table-cell) | (underline ,@standard-set) | (verse-block ,@standard-set))) | "Alist of objects restrictions. | | CAR is an element or object type containing objects and CDR is | a list of successors that will be called within an element or | object of such type. | | For example, in a `radio-target' object, one can only find | entities, latex-fragments, subscript and superscript. | | This alist also applies to secondary string. For example, an | `headline' type element doesn't directly contain objects, but | still has an entry since one of its properties (`:title') does.") | | (defconst org-element-secondary-value-alist | '((headline . :title) | (inlinetask . :title) | (item . :tag) | (footnote-reference . :inline-definition)) | "Alist between element types and location of secondary value.") | | (defconst org-element-object-variables '(org-link-abbrev-alist-local) | "List of buffer-local variables used when parsing objects. | These variables are copied to the temporary buffer created by | `org-export-secondary-string'.") `---- Accessors and Setters ===================== Provide four accessors: `org-element-type', `org-element-property' `org-element-contents' and `org-element-restriction'. Setter functions allow to modify elements by side effect. There is `org-element-put-property', `org-element-set-contents', `org-element-set-element' and `org-element-adopt-element'. Note that `org-element-set-element' and `org-element-adopt-elements' are higher level functions since also update `:parent' property. ,---- | (defsubst org-element-type (element) | "Return type of ELEMENT. | | The function returns the type of the element or object provided. | It can also return the following special value: | `plain-text' for a string | `org-data' for a complete document | nil in any other case.") | | (defsubst org-element-property (property element) | "Extract the value from the PROPERTY of an ELEMENT.") | | (defsubst org-element-contents (element) | "Extract contents from an ELEMENT.") | | (defsubst org-element-restriction (element) | "Return restriction associated to ELEMENT. | ELEMENT can be an element, an object or a symbol representing an | element or object type.") | | (defsubst org-element-put-property (element property value) | "In ELEMENT set PROPERTY to VALUE. | Return modified element.") | | (defsubst org-element-set-contents (element &rest contents) | "Set ELEMENT contents to CONTENTS. | Return modified element.") | | (defsubst org-element-set-element (old new) | "Replace element or object OLD with element or object NEW. | The function takes care of setting `:parent' property for NEW.") | | (defsubst org-element-adopt-elements (parent &rest children) | "Append elements to the contents of another element. | | PARENT is an element or object. CHILDREN can be elements, | objects, or a strings. | | The function takes care of setting `:parent' property for CHILD. | Return parent element.") `---- Greater elements ================ For each greater element type, we define a parser and an interpreter. A parser returns the element or object as the list described above. Most of them accepts no argument. Though, exceptions exist. Hence every element containing a secondary string (see `org-element-secondary-value-alist') will accept an optional argument to toggle parsing of that secondary string. Moreover, `item' parser requires current list's structure as its first element. An interpreter accepts two arguments: the list representation of the element or object, and its contents. The latter may be nil, depending on the element or object considered. It returns the appropriate Org syntax, as a string. Parsing functions must follow the naming convention: org-element-TYPE-parser, where TYPE is greater element's type, as defined in `org-element-greater-elements'. Similarly, interpreting functions must follow the naming convention: org-element-TYPE-interpreter. With the exception of `headline' and `item' types, greater elements cannot contain other greater elements of their own type. Beside implementing a parser and an interpreter, adding a new greater element requires to tweak `org-element--current-element'. Moreover, the newly defined type must be added to both `org-element-all-elements' and `org-element-greater-elements'. Center Block ~~~~~~~~~~~~ ,---- | (defun org-element-center-block-parser (limit affiliated) | "Parse a center block. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `center-block' and CDR is a plist | containing `:begin', `:end', `:hiddenp', `:contents-begin', | `:contents-end', `:post-blank' and `:post-affiliated' keywords. | | Assume point is at the beginning of the block.") | | (defun org-element-center-block-interpreter (center-block contents) | "Interpret CENTER-BLOCK element as Org syntax. | CONTENTS is the contents of the element.") `---- Drawer ~~~~~~ ,---- | (defun org-element-drawer-parser (limit affiliated) | "Parse a drawer. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `drawer' and CDR is a plist containing | `:drawer-name', `:begin', `:end', `:hiddenp', `:contents-begin', | `:contents-end', `:post-blank' and `:post-affiliated' keywords. | | Assume point is at beginning of drawer.") | | (defun org-element-drawer-interpreter (drawer contents) | "Interpret DRAWER element as Org syntax. | CONTENTS is the contents of the element.") `---- Dynamic Block ~~~~~~~~~~~~~ ,---- | (defun org-element-dynamic-block-parser (limit affiliated) | "Parse a dynamic block. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `dynamic-block' and CDR is a plist | containing `:block-name', `:begin', `:end', `:hiddenp', | `:contents-begin', `:contents-end', `:arguments', `:post-blank' | and `:post-affiliated' keywords. | | Assume point is at beginning of dynamic block.") | | (defun org-element-dynamic-block-interpreter (dynamic-block contents) | "Interpret DYNAMIC-BLOCK element as Org syntax. | CONTENTS is the contents of the element.") `---- Footnote Definition ~~~~~~~~~~~~~~~~~~~ ,---- | (defun org-element-footnote-definition-parser (limit affiliated) | "Parse a footnote definition. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `footnote-definition' and CDR is | a plist containing `:label', `:begin' `:end', `:contents-begin', | `:contents-end', `:post-blank' and `:post-affiliated' keywords. | | Assume point is at the beginning of the footnote definition.") | | (defun org-element-footnote-definition-interpreter (footnote-definition contents) | "Interpret FOOTNOTE-DEFINITION element as Org syntax. | CONTENTS is the contents of the footnote-definition.") `---- Headline ~~~~~~~~ ,---- | (defun org-element-headline-parser (limit &optional raw-secondary-p) | "Parse a headline. | | Return a list whose CAR is `headline' and CDR is a plist | containing `:raw-value', `:title', `:alt-title', `:begin', | `:end', `:pre-blank', `:hiddenp', `:contents-begin' and | `:contents-end', `:level', `:priority', `:tags', | `:todo-keyword',`:todo-type', `:scheduled', `:deadline', | `:closed', `:quotedp', `:archivedp', `:commentedp' and | `:footnote-section-p' keywords. | | The plist also contains any property set in the property drawer, | with its name in upper cases and colons added at the | beginning (i.e. `:CUSTOM_ID'). | | When RAW-SECONDARY-P is non-nil, headline's title will not be | parsed as a secondary string, but as a plain string instead. | | Assume point is at beginning of the headline.") | | (defun org-element-headline-interpreter (headline contents) | "Interpret HEADLINE element as Org syntax. | CONTENTS is the contents of the element.") `---- Inlinetask ~~~~~~~~~~ ,---- | (defun org-element-inlinetask-parser (limit &optional raw-secondary-p) | "Parse an inline task. | | Return a list whose CAR is `inlinetask' and CDR is a plist | containing `:title', `:begin', `:end', `:hiddenp', | `:contents-begin' and `:contents-end', `:level', `:priority', | `:raw-value', `:tags', `:todo-keyword', `:todo-type', | `:scheduled', `:deadline', `:closed' and `:post-blank' keywords. | | The plist also contains any property set in the property drawer, | with its name in upper cases and colons added at the | beginning (i.e. `:CUSTOM_ID'). | | When optional argument RAW-SECONDARY-P is non-nil, inline-task's | title will not be parsed as a secondary string, but as a plain | string instead. | | Assume point is at beginning of the inline task.") | | (defun org-element-inlinetask-interpreter (inlinetask contents) | "Interpret INLINETASK element as Org syntax. | CONTENTS is the contents of inlinetask.") `---- Item ~~~~ ,---- | (defun org-element-item-parser (limit struct &optional raw-secondary-p) | "Parse an item. | | STRUCT is the structure of the plain list. | | Return a list whose CAR is `item' and CDR is a plist containing | `:bullet', `:begin', `:end', `:contents-begin', `:contents-end', | `:checkbox', `:counter', `:tag', `:structure', `:hiddenp' and | `:post-blank' keywords. | | When optional argument RAW-SECONDARY-P is non-nil, item's tag, if | any, will not be parsed as a secondary string, but as a plain | string instead. | | Assume point is at the beginning of the item.") | | (defun org-element-item-interpreter (item contents) | "Interpret ITEM element as Org syntax. | CONTENTS is the contents of the element.") `---- Plain List ~~~~~~~~~~ ,---- | (defun org-element-plain-list-parser (limit affiliated structure) | "Parse a plain list. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. STRUCTURE is the structure of the plain list being | parsed. | | Return a list whose CAR is `plain-list' and CDR is a plist | containing `:type', `:begin', `:end', `:contents-begin' and | `:contents-end', `:structure', `:post-blank' and | `:post-affiliated' keywords. | | Assume point is at the beginning of the list.") | | (defun org-element-plain-list-interpreter (plain-list contents) | "Interpret PLAIN-LIST element as Org syntax. | CONTENTS is the contents of the element.") `---- Property Drawer ~~~~~~~~~~~~~~~ ,---- | (defun org-element-property-drawer-parser (limit affiliated) | "Parse a property drawer. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `property-drawer' and CDR is a plist | containing `:begin', `:end', `:hiddenp', `:contents-begin', | `:contents-end', `:post-blank' and `:post-affiliated' keywords. | | Assume point is at the beginning of the property drawer.") | | (defun org-element-property-drawer-interpreter (property-drawer contents) | "Interpret PROPERTY-DRAWER element as Org syntax. | CONTENTS is the properties within the drawer.") `---- Quote Block ~~~~~~~~~~~ ,---- | (defun org-element-quote-block-parser (limit affiliated) | "Parse a quote block. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `quote-block' and CDR is a plist | containing `:begin', `:end', `:hiddenp', `:contents-begin', | `:contents-end', `:post-blank' and `:post-affiliated' keywords. | | Assume point is at the beginning of the block.") | | (defun org-element-quote-block-interpreter (quote-block contents) | "Interpret QUOTE-BLOCK element as Org syntax. | CONTENTS is the contents of the element.") `---- Section ~~~~~~~ ,---- | (defun org-element-section-parser (limit) | "Parse a section. | | LIMIT bounds the search. | | Return a list whose CAR is `section' and CDR is a plist | containing `:begin', `:end', `:contents-begin', `contents-end' | and `:post-blank' keywords.") | | (defun org-element-section-interpreter (section contents) | "Interpret SECTION element as Org syntax. | CONTENTS is the contents of the element." | ) `---- Special Block ~~~~~~~~~~~~~ ,---- | (defun org-element-special-block-parser (limit affiliated) | "Parse a special block. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `special-block' and CDR is a plist | containing `:type', `:begin', `:end', `:hiddenp', | `:contents-begin', `:contents-end', `:post-blank' and | `:post-affiliated' keywords. | | Assume point is at the beginning of the block.") | | (defun org-element-special-block-interpreter (special-block contents) | "Interpret SPECIAL-BLOCK element as Org syntax. | CONTENTS is the contents of the element.") `---- Elements ======== For each element, a parser and an interpreter are also defined. Both follow the same naming convention used for greater elements. Also, as for greater elements, adding a new element type is done through the following steps: implement a parser and an interpreter, tweak `org-element--current-element' so that it recognizes the new type and add that new type to `org-element-all-elements'. As a special case, when the newly defined type is a block type, `org-element-block-name-alist' has to be modified accordingly. Babel Call ~~~~~~~~~~ ,---- | (defun org-element-babel-call-parser (limit affiliated) | "Parse a babel call. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `babel-call' and CDR is a plist | containing `:begin', `:end', `:info', `:post-blank' and | `:post-affiliated' as keywords.") | | (defun org-element-babel-call-interpreter (babel-call contents) | "Interpret BABEL-CALL element as Org syntax. | CONTENTS is nil.") `---- Clock ~~~~~ ,---- | (defun org-element-clock-parser (limit) | "Parse a clock. | | LIMIT bounds the search. | | Return a list whose CAR is `clock' and CDR is a plist containing | `:status', `:value', `:time', `:begin', `:end' and `:post-blank' | as keywords.") | | (defun org-element-clock-interpreter (clock contents) | "Interpret CLOCK element as Org syntax. | CONTENTS is nil.") `---- Comment ~~~~~~~ ,---- | (defun org-element-comment-parser (limit affiliated) | "Parse a comment. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `comment' and CDR is a plist | containing `:begin', `:end', `:value', `:post-blank', | `:post-affiliated' keywords. | | Assume point is at comment beginning.") | | (defun org-element-comment-interpreter (comment contents) | "Interpret COMMENT element as Org syntax. | CONTENTS is nil.") `---- Comment Block ~~~~~~~~~~~~~ ,---- | (defun org-element-comment-block-parser (limit affiliated) | "Parse an export block. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `comment-block' and CDR is a plist | containing `:begin', `:end', `:hiddenp', `:value', `:post-blank' | and `:post-affiliated' keywords. | | Assume point is at comment block beginning.") | | (defun org-element-comment-block-interpreter (comment-block contents) | "Interpret COMMENT-BLOCK element as Org syntax. | CONTENTS is nil.") `---- Diary Sexp ~~~~~~~~~~ ,---- | (defun org-element-diary-sexp-parser (limit affiliated) | "Parse a diary sexp. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `diary-sexp' and CDR is a plist | containing `:begin', `:end', `:value', `:post-blank' and | `:post-affiliated' keywords.") | | (defun org-element-diary-sexp-interpreter (diary-sexp contents) | "Interpret DIARY-SEXP as Org syntax. | CONTENTS is nil.") `---- Example Block ~~~~~~~~~~~~~ ,---- | (defun org-element--remove-indentation (s &optional n) | "Remove maximum common indentation in string S and return it. | When optional argument N is a positive integer, remove exactly | that much characters from indentation, if possible, or return | S as-is otherwise. Unlike to `org-remove-indentation', this | function doesn't call `untabify' on S.") | | (defun org-element-example-block-parser (limit affiliated) | "Parse an example block. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `example-block' and CDR is a plist | containing `:begin', `:end', `:number-lines', `:preserve-indent', | `:retain-labels', `:use-labels', `:label-fmt', `:hiddenp', | `:switches', `:value', `:post-blank' and `:post-affiliated' | keywords.") | | (defun org-element-src-block-interpreter (src-block contents) | "Interpret SRC-BLOCK element as Org syntax. | CONTENTS is nil.") `---- Table ~~~~~ ,---- | (defun org-element-table-parser (limit affiliated) | "Parse a table at point. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `table' and CDR is a plist containing | `:begin', `:end', `:tblfm', `:type', `:contents-begin', | `:contents-end', `:value', `:post-blank' and `:post-affiliated' | keywords. | | Assume point is at the beginning of the table.") | | (defun org-element-table-interpreter (table contents) | "Interpret TABLE element as Org syntax. | CONTENTS is nil.") `---- Table Row ~~~~~~~~~ ,---- | (defun org-element-table-row-parser (limit) | "Parse table row at point. | | LIMIT bounds the search. | | Return a list whose CAR is `table-row' and CDR is a plist | containing `:begin', `:end', `:contents-begin', `:contents-end', | `:type' and `:post-blank' keywords.") | | (defun org-element-table-row-interpreter (table-row contents) | "Interpret TABLE-ROW element as Org syntax. | CONTENTS is the contents of the table row.") `---- Verse Block ~~~~~~~~~~~ ,---- | (defun org-element-verse-block-parser (limit affiliated) | "Parse a verse block. | | LIMIT bounds the search. AFFILIATED is a list of which CAR is | the buffer position at the beginning of the first affiliated | keyword and CDR is a plist of affiliated keywords along with | their value. | | Return a list whose CAR is `verse-block' and CDR is a plist | containing `:begin', `:end', `:contents-begin', `:contents-end', | `:hiddenp', `:post-blank' and `:post-affiliated' keywords. | | Assume point is at beginning of the block.") | | (defun org-element-verse-block-interpreter (verse-block contents) | "Interpret VERSE-BLOCK element as Org syntax. | CONTENTS is verse block contents.") `---- Objects ======= Unlike to elements, interstices can be found between objects. That's why, along with the parser, successor functions are provided for each object. Some objects share the same successor (i.e. `code' and `verbatim' objects). A successor must accept a single argument bounding the search. It will return either a cons cell whose CAR is the object's type, as a symbol, and CDR the position of its next occurrence, or nil. Successors follow the naming convention: org-element-NAME-successor, where NAME is the name of the successor, as defined in `org-element-all-successors'. Some object types (i.e. `italic') are recursive. Restrictions on object types they can contain will be specified in `org-element-object-restrictions'. Adding a new type of object is simple. Implement a successor, a parser, and an interpreter for it, all following the naming convention. Register type in `org-element-all-objects' and successor in `org-element-all-successors'. Maybe tweak restrictions about it, and that's it. Bold ~~~~ ,---- | (defun org-element-bold-parser () | "Parse bold object at point. | | Return a list whose CAR is `bold' and CDR is a plist with | `:begin', `:end', `:contents-begin' and `:contents-end' and | `:post-blank' keywords. | | Assume point is at the first star marker.") | | (defun org-element-bold-interpreter (bold contents) | "Interpret BOLD object as Org syntax. | CONTENTS is the contents of the object.") | | (defun org-element-text-markup-successor (limit) | "Search for the next text-markup object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is a symbol among `bold', | `italic', `underline', `strike-through', `code' and `verbatim' | and CDR is beginning position.") `---- Code ~~~~ ,---- | (defun org-element-code-parser () | "Parse code object at point. | | Return a list whose CAR is `code' and CDR is a plist with | `:value', `:begin', `:end' and `:post-blank' keywords. | | Assume point is at the first tilde marker.") | | (defun org-element-code-interpreter (code contents) | "Interpret CODE object as Org syntax. | CONTENTS is nil.") `---- Entity ~~~~~~ ,---- | (defun org-element-entity-parser () | "Parse entity at point. | | Return a list whose CAR is `entity' and CDR a plist with | `:begin', `:end', `:latex', `:latex-math-p', `:html', `:latin1', | `:utf-8', `:ascii', `:use-brackets-p' and `:post-blank' as | keywords. | | Assume point is at the beginning of the entity.") | | (defun org-element-entity-interpreter (entity contents) | "Interpret ENTITY object as Org syntax. | CONTENTS is nil.") | | (defun org-element-latex-or-entity-successor (limit) | "Search for the next latex-fragment or entity object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `entity' or | `latex-fragment' and CDR is beginning position.") `---- Export Snippet ~~~~~~~~~~~~~~ ,---- | (defun org-element-export-snippet-parser () | "Parse export snippet at point. | | Return a list whose CAR is `export-snippet' and CDR a plist with | `:begin', `:end', `:back-end', `:value' and `:post-blank' as | keywords. | | Assume point is at the beginning of the snippet.") | | (defun org-element-export-snippet-interpreter (export-snippet contents) | "Interpret EXPORT-SNIPPET object as Org syntax. | CONTENTS is nil.") | | (defun org-element-export-snippet-successor (limit) | "Search for the next export-snippet object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `export-snippet' and CDR | its beginning position.") `---- Footnote Reference ~~~~~~~~~~~~~~~~~~ ,---- | (defun org-element-footnote-reference-parser () | "Parse footnote reference at point. | | Return a list whose CAR is `footnote-reference' and CDR a plist | with `:label', `:type', `:inline-definition', `:begin', `:end' | and `:post-blank' as keywords.") | | (defun org-element-footnote-reference-interpreter (footnote-reference contents) | "Interpret FOOTNOTE-REFERENCE object as Org syntax. | CONTENTS is nil.") | | (defun org-element-footnote-reference-successor (limit) | "Search for the next footnote-reference object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `footnote-reference' and | CDR is beginning position.") `---- Inline Babel Call ~~~~~~~~~~~~~~~~~ ,---- | (defun org-element-inline-babel-call-parser () | "Parse inline babel call at point. | | Return a list whose CAR is `inline-babel-call' and CDR a plist | with `:begin', `:end', `:info' and `:post-blank' as keywords. | | Assume point is at the beginning of the babel call.") | | (defun org-element-inline-babel-call-interpreter (inline-babel-call contents) | "Interpret INLINE-BABEL-CALL object as Org syntax. | CONTENTS is nil.") | | (defun org-element-inline-babel-call-successor (limit) | "Search for the next inline-babel-call object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `inline-babel-call' and | CDR is beginning position.") `---- Inline Src Block ~~~~~~~~~~~~~~~~ ,---- | (defun org-element-inline-src-block-parser () | "Parse inline source block at point. | | LIMIT bounds the search. | | Return a list whose CAR is `inline-src-block' and CDR a plist | with `:begin', `:end', `:language', `:value', `:parameters' and | `:post-blank' as keywords. | | Assume point is at the beginning of the inline src block.") | | (defun org-element-inline-src-block-interpreter (inline-src-block contents) | "Interpret INLINE-SRC-BLOCK object as Org syntax. | CONTENTS is nil.") | | (defun org-element-inline-src-block-successor (limit) | "Search for the next inline-babel-call element. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `inline-babel-call' and | CDR is beginning position.") `---- Italic ~~~~~~ ,---- | (defun org-element-italic-parser () | "Parse italic object at point. | | Return a list whose CAR is `italic' and CDR is a plist with | `:begin', `:end', `:contents-begin' and `:contents-end' and | `:post-blank' keywords. | | Assume point is at the first slash marker.") | | (defun org-element-italic-interpreter (italic contents) | "Interpret ITALIC object as Org syntax. | CONTENTS is the contents of the object.") `---- Latex Fragment ~~~~~~~~~~~~~~ ,---- | (defun org-element-latex-fragment-parser () | "Parse latex fragment at point. | | Return a list whose CAR is `latex-fragment' and CDR a plist with | `:value', `:begin', `:end', and `:post-blank' as keywords. | | Assume point is at the beginning of the latex fragment.") | | (defun org-element-latex-fragment-interpreter (latex-fragment contents) | "Interpret LATEX-FRAGMENT object as Org syntax. | CONTENTS is nil.") `---- Line Break ~~~~~~~~~~ ,---- | (defun org-element-line-break-parser () | "Parse line break at point. | | Return a list whose CAR is `line-break', and CDR a plist with | `:begin', `:end' and `:post-blank' keywords. | | Assume point is at the beginning of the line break.") | | (defun org-element-line-break-interpreter (line-break contents) | "Interpret LINE-BREAK object as Org syntax. | CONTENTS is nil.") | | (defun org-element-line-break-successor (limit) | "Search for the next line-break object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `line-break' and CDR is | beginning position.") `---- Link ~~~~ ,---- | (defun org-element-link-parser () | "Parse link at point. | | Return a list whose CAR is `link' and CDR a plist with `:type', | `:path', `:raw-link', `:application', `:search-option', `:begin', | `:end', `:contents-begin', `:contents-end' and `:post-blank' as | keywords. | | Assume point is at the beginning of the link.") | | (defun org-element-link-interpreter (link contents) | "Interpret LINK object as Org syntax. | CONTENTS is the contents of the object, or nil.") | | (defun org-element-link-successor (limit) | "Search for the next link object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `link' and CDR is | beginning position.") | | (defun org-element-plain-link-successor (limit) | "Search for the next plain link object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `link' and CDR is | beginning position.") `---- Macro ~~~~~ ,---- | (defun org-element-macro-parser () | "Parse macro at point. | | Return a list whose CAR is `macro' and CDR a plist with `:key', | `:args', `:begin', `:end', `:value' and `:post-blank' as | keywords. | | Assume point is at the macro.") | | (defun org-element-macro-interpreter (macro contents) | "Interpret MACRO object as Org syntax. | CONTENTS is nil.") | | (defun org-element-macro-successor (limit) | "Search for the next macro object. | | LIMIT bounds the search. | | Return value is cons cell whose CAR is `macro' and CDR is | beginning position.") `---- Radio-target ~~~~~~~~~~~~ ,---- | (defun org-element-radio-target-parser () | "Parse radio target at point. | | Return a list whose CAR is `radio-target' and CDR a plist with | `:begin', `:end', `:contents-begin', `:contents-end', `:value' | and `:post-blank' as keywords. | | Assume point is at the radio target.") | | (defun org-element-radio-target-interpreter (target contents) | "Interpret TARGET object as Org syntax. | CONTENTS is the contents of the object.") | | (defun org-element-radio-target-successor (limit) | "Search for the next radio-target object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `radio-target' and CDR | is beginning position.") `---- Statistics Cookie ~~~~~~~~~~~~~~~~~ ,---- | (defun org-element-statistics-cookie-parser () | "Parse statistics cookie at point. | | Return a list whose CAR is `statistics-cookie', and CDR a plist | with `:begin', `:end', `:value' and `:post-blank' keywords. | | Assume point is at the beginning of the statistics-cookie.") | | (defun org-element-statistics-cookie-interpreter (statistics-cookie contents) | "Interpret STATISTICS-COOKIE object as Org syntax. | CONTENTS is nil.") | | (defun org-element-statistics-cookie-successor (limit) | "Search for the next statistics cookie object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `statistics-cookie' and | CDR is beginning position.") `---- Strike-Through ~~~~~~~~~~~~~~ ,---- | (defun org-element-strike-through-parser () | "Parse strike-through object at point. | | Return a list whose CAR is `strike-through' and CDR is a plist | with `:begin', `:end', `:contents-begin' and `:contents-end' and | `:post-blank' keywords. | | Assume point is at the first plus sign marker.") | | (defun org-element-strike-through-interpreter (strike-through contents) | "Interpret STRIKE-THROUGH object as Org syntax. | CONTENTS is the contents of the object.") `---- Subscript ~~~~~~~~~ ,---- | (defun org-element-subscript-parser () | "Parse subscript at point. | | Return a list whose CAR is `subscript' and CDR a plist with | `:begin', `:end', `:contents-begin', `:contents-end', | `:use-brackets-p' and `:post-blank' as keywords. | | Assume point is at the underscore.") | | (defun org-element-subscript-interpreter (subscript contents) | "Interpret SUBSCRIPT object as Org syntax. | CONTENTS is the contents of the object.") | | (defun org-element-sub/superscript-successor (limit) | "Search for the next sub/superscript object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is either `subscript' or | `superscript' and CDR is beginning position.") `---- Superscript ~~~~~~~~~~~ ,---- | (defun org-element-superscript-parser () | "Parse superscript at point. | | Return a list whose CAR is `superscript' and CDR a plist with | `:begin', `:end', `:contents-begin', `:contents-end', | `:use-brackets-p' and `:post-blank' as keywords. | | Assume point is at the caret.") | | (defun org-element-superscript-interpreter (superscript contents) | "Interpret SUPERSCRIPT object as Org syntax. | CONTENTS is the contents of the object.") `---- Table Cell ~~~~~~~~~~ ,---- | (defun org-element-table-cell-parser () | "Parse table cell at point. | | Return a list whose CAR is `table-cell' and CDR is a plist | containing `:begin', `:end', `:contents-begin', `:contents-end' | and `:post-blank' keywords.") | | (defun org-element-table-cell-interpreter (table-cell contents) | "Interpret TABLE-CELL element as Org syntax. | CONTENTS is the contents of the cell, or nil.") | | (defun org-element-table-cell-successor (limit) | "Search for the next table-cell object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `table-cell' and CDR is | beginning position.") `---- Target ~~~~~~ ,---- | (defun org-element-target-parser () | "Parse target at point. | | Return a list whose CAR is `target' and CDR a plist with | `:begin', `:end', `:value' and `:post-blank' as keywords. | | Assume point is at the target.") | | (defun org-element-target-interpreter (target contents) | "Interpret TARGET object as Org syntax. | CONTENTS is nil.") | | (defun org-element-target-successor (limit) | "Search for the next target object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `target' and CDR is | beginning position.") `---- Timestamp ~~~~~~~~~ ,---- | (defun org-element-timestamp-parser () | "Parse time stamp at point. | | Return a list whose CAR is `timestamp', and CDR a plist with | `:type', `:begin', `:end', `:value' and `:post-blank' keywords. | | Assume point is at the beginning of the timestamp.") | | (defun org-element-timestamp-interpreter (timestamp contents) | "Interpret TIMESTAMP object as Org syntax. | CONTENTS is nil.") | | (defun org-element-timestamp-successor (limit) | "Search for the next timestamp object. | | LIMIT bounds the search. | | Return value is a cons cell whose CAR is `timestamp' and CDR is | beginning position.") `---- Underline ~~~~~~~~~ ,---- | (defun org-element-underline-parser () | "Parse underline object at point. | | Return a list whose CAR is `underline' and CDR is a plist with | `:begin', `:end', `:contents-begin' and `:contents-end' and | `:post-blank' keywords. | | Assume point is at the first underscore marker.") | | (defun org-element-underline-interpreter (underline contents) | "Interpret UNDERLINE object as Org syntax. | CONTENTS is the contents of the object.") `---- Verbatim ~~~~~~~~ ,---- | (defun org-element-verbatim-parser () | "Parse verbatim object at point. | | Return a list whose CAR is `verbatim' and CDR is a plist with | `:value', `:begin', `:end' and `:post-blank' keywords. | | Assume point is at the first equal sign marker.") | | (defun org-element-verbatim-interpreter (verbatim contents) | "Interpret VERBATIM object as Org syntax. | CONTENTS is nil.") `---- Parsing Element Starting At Point ================================= `org-element--current-element' is the core function of this section. It returns the Lisp representation of the element starting at point. `org-element--current-element' makes use of special modes. They are activated for fixed element chaining (i.e. `plain-list' > `item') or fixed conditional element chaining (i.e. `headline' > `section'). Special modes are: `first-section', `item', `node-property', `quote-section', `section' and `table-row'. ,---- | (defun org-element--current-element | (limit &optional granularity special structure) | "Parse the element starting at point. | | LIMIT bounds the search. | | Return value is a list like (TYPE PROPS) where TYPE is the type | of the element and PROPS a plist of properties associated to the | element. | | Possible types are defined in `org-element-all-elements'. | | Optional argument GRANULARITY determines the depth of the | recursion. Allowed values are `headline', `greater-element', | `element', `object' or nil. When it is broader than `object' (or | nil), secondary values will not be parsed, since they only | contain objects. | | Optional argument SPECIAL, when non-nil, can be either | `first-section', `item', `node-property', `quote-section', | `section', and `table-row'. | | If STRUCTURE isn't provided but SPECIAL is set to `item', it will | be computed. | | This function assumes point is always at the beginning of the | element it has to parse.") `---- Most elements can have affiliated keywords. When looking for an element beginning, we want to move before them, as they belong to that element, and, in the meantime, collect information they give into appropriate properties. Hence the following function. ,---- | (defun org-element--collect-affiliated-keywords (limit) | "Collect affiliated keywords from point down to LIMIT. | | Return a list whose CAR is the position at the first of them and | CDR a plist of keywords and values and move point to the | beginning of the first line after them. | | As a special case, if element doesn't start at the beginning of | the line (i.e. a paragraph starting an item), CAR is current | position of point and CDR is nil.") `---- The Org Parser ============== The two major functions here are `org-element-parse-buffer', which parses Org syntax inside the current buffer, taking into account region, narrowing, or even visibility if specified, and `org-element-parse-secondary-string', which parses objects within a given string. The (almost) almighty `org-element-map' allows to apply a function on elements or objects matching some type, and accumulate the resulting values. In an export situation, it also skips unneeded parts of the parse tree. ,---- | (defun org-element-parse-buffer (&optional granularity visible-only) | "Recursively parse the buffer and return structure. | If narrowing is in effect, only parse the visible part of the | buffer. | | Optional argument GRANULARITY determines the depth of the | recursion. It can be set to the following symbols: | | `headline' Only parse headlines. | `greater-element' Don't recurse into greater elements excepted | headlines and sections. Thus, elements | parsed are the top-level ones. | `element' Parse everything but objects and plain text. | `object' Parse the complete buffer (default). | | When VISIBLE-ONLY is non-nil, don't parse contents of hidden | elements. | | An element or an objects is represented as a list with the | pattern (TYPE PROPERTIES CONTENTS), where : | | TYPE is a symbol describing the element or object. See | `org-element-all-elements' and `org-element-all-objects' for an | exhaustive list of such symbols. One can retrieve it with | `org-element-type' function. | | PROPERTIES is the list of attributes attached to the element or | object, as a plist. Although most of them are specific to the | element or object type, all types share `:begin', `:end', | `:post-blank' and `:parent' properties, which respectively | refer to buffer position where the element or object starts, | ends, the number of white spaces or blank lines after it, and | the element or object containing it. Properties values can be | obtained by using `org-element-property' function. | | CONTENTS is a list of elements, objects or raw strings | contained in the current element or object, when applicable. | One can access them with `org-element-contents' function. | | The Org buffer has `org-data' as type and nil as properties. | `org-element-map' function can be used to find specific elements | or objects within the parse tree. | | This function assumes that current major mode is `org-mode'.") | | (defun org-element-parse-secondary-string (string restriction &optional parent) | "Recursively parse objects in STRING and return structure. | | RESTRICTION is a symbol limiting the object types that will be | looked after. | | Optional argument PARENT, when non-nil, is the element or object | containing the secondary string. It is used to set correctly | `:parent' property within the string." | ;; Copy buffer-local variables listed in | ;; `org-element-object-variables' into temporary buffer. This is | ;; required since object parsing is dependent on these variables.) | | (defun org-element-map | (data types fun &optional info first-match no-recursion with-affiliated) | "Map a function on selected elements or objects. | | DATA is a parse tree, an element, an object, a string, or a list | of such constructs. TYPES is a symbol or list of symbols of | elements or objects types (see `org-element-all-elements' and | `org-element-all-objects' for a complete list of types). FUN is | the function called on the matching element or object. It has to | accept one argument: the element or object itself. | | When optional argument INFO is non-nil, it should be a plist | holding export options. In that case, parts of the parse tree | not exportable according to that property list will be skipped. | | When optional argument FIRST-MATCH is non-nil, stop at the first | match for which FUN doesn't return nil, and return that value. | | Optional argument NO-RECURSION is a symbol or a list of symbols | representing elements or objects types. `org-element-map' won't | enter any recursive element or object whose type belongs to that | list. Though, FUN can still be applied on them. | | When optional argument WITH-AFFILIATED is non-nil, FUN will also | apply to matching objects within parsed affiliated keywords (see | `org-element-parsed-keywords'). | | Nil values returned from FUN do not appear in the results. | | | Examples: | --------- | | Assuming TREE is a variable containing an Org buffer parse tree, | the following example will return a flat list of all `src-block' | and `example-block' elements in it: | | \(org-element-map tree '(example-block src-block) 'identity) | | The following snippet will find the first headline with a level | of 1 and a \"phone\" tag, and will return its beginning position: | | \(org-element-map tree 'headline | \(lambda (hl) | \(and (= (org-element-property :level hl) 1) | \(member \"phone\" (org-element-property :tags hl)) | \(org-element-property :begin hl))) | nil t) | | The next example will return a flat list of all `plain-list' type | elements in TREE that are not a sub-list themselves: | | \(org-element-map tree 'plain-list 'identity nil nil 'plain-list) | | Eventually, this example will return a flat list of all `bold' | type objects containing a `latex-snippet' type object, even | looking into captions: | | \(org-element-map tree 'bold | \(lambda (b) | \(and (org-element-map b 'latex-snippet 'identity nil t) b)) | nil nil nil t)" | ;; Ensure TYPES and NO-RECURSION are a list, even of one element. | (unless (listp types) (setq types (list types))) | (unless (listp no-recursion) (setq no-recursion (list no-recursion))) | ;; Recursion depth is determined by --CATEGORY. | (let* ((--category | (catch 'found | (let ((category 'greater-elements)) | (mapc (lambda (type) | (cond ((or (memq type org-element-all-objects) | (eq type 'plain-text)) | ;; If one object is found, the function | ;; has to recurse into every object. | (throw 'found 'objects)) | ((not (memq type org-element-greater-elements)) | ;; If one regular element is found, the | ;; function has to recurse, at least, | ;; into every element it encounters. | (and (not (eq category 'elements)) | (setq category 'elements))))) | types) | category))) | ;; Compute properties for affiliated keywords if necessary. | (--affiliated-alist | (and with-affiliated | (mapcar (lambda (kwd) | (cons kwd (intern (concat ":" (downcase kwd))))) | org-element-affiliated-keywords))) | --acc | --walk-tree | (--walk-tree | (function | (lambda (--data) | ;; Recursively walk DATA. INFO, if non-nil, is a plist | ;; holding contextual information. | (let ((--type (org-element-type --data))) | (cond | ((not --data)) | ;; Ignored element in an export context. | ((and info (memq --data (plist-get info :ignore-list)))) | ;; List of elements or objects. | ((not --type) (mapc --walk-tree --data)) | ;; Unconditionally enter parse trees. | ((eq --type 'org-data) | (mapc --walk-tree (org-element-contents --data))) | (t | ;; Check if TYPE is matching among TYPES. If so, | ;; apply FUN to --DATA and accumulate return value | ;; into --ACC (or exit if FIRST-MATCH is non-nil). | (when (memq --type types) | (let ((result (funcall fun --data))) | (cond ((not result)) | (first-match (throw '--map-first-match result)) | (t (push result --acc))))) | ;; If --DATA has a secondary string that can contain | ;; objects with their type among TYPES, look into it. | (when (and (eq --category 'objects) (not (stringp --data))) | (let ((sec-prop | (assq --type org-element-secondary-value-alist))) | (when sec-prop | (funcall --walk-tree | (org-element-property (cdr sec-prop) --data))))) | ;; If --DATA has any affiliated keywords and | ;; WITH-AFFILIATED is non-nil, look for objects in | ;; them. | (when (and with-affiliated | (eq --category 'objects) | (memq --type org-element-all-elements)) | (mapc (lambda (kwd-pair) | (let ((kwd (car kwd-pair)) | (value (org-element-property | (cdr kwd-pair) --data))) | ;; Pay attention to the type of value. | ;; Preserve order for multiple keywords. | (cond | ((not value)) | ((and (member kwd org-element-multiple-keywords) | (member kwd org-element-dual-keywords)) | (mapc (lambda (line) | (funcall --walk-tree (cdr line)) | (funcall --walk-tree (car line))) | (reverse value))) | ((member kwd org-element-multiple-keywords) | (mapc (lambda (line) (funcall --walk-tree line)) | (reverse value))) | ((member kwd org-element-dual-keywords) | (funcall --walk-tree (cdr value)) | (funcall --walk-tree (car value))) | (t (funcall --walk-tree value))))) | --affiliated-alist)) | ;; Determine if a recursion into --DATA is possible. | (cond | ;; --TYPE is explicitly removed from recursion. | ((memq --type no-recursion)) | ;; --DATA has no contents. | ((not (org-element-contents --data))) | ;; Looking for greater elements but --DATA is simply | ;; an element or an object. | ((and (eq --category 'greater-elements) | (not (memq --type org-element-greater-elements)))) | ;; Looking for elements but --DATA is an object. | ((and (eq --category 'elements) | (memq --type org-element-all-objects))) | ;; In any other case, map contents. | (t (mapc --walk-tree (org-element-contents --data))))))))))) | (catch '--map-first-match | (funcall --walk-tree data) | ;; Return value in a proper order. | (nreverse --acc)))) | (put 'org-element-map 'lisp-indent-function 2) `---- The following functions are internal parts of the parser. The first one, `org-element--parse-elements' acts at the element's level. The second one, `org-element--parse-objects' applies on all objects of a paragraph or a secondary string. It uses `org-element--get-next-object-candidates' to optimize the search of the next object in the buffer. More precisely, that function looks for every allowed object type first. Then, it discards failed searches, keeps further matches, and searches again types matched behind point, for subsequent calls. Thus, searching for a given type fails only once, and every object is searched only once at top level (but sometimes more for nested types). ,---- | (defun org-element--parse-elements | (beg end special structure granularity visible-only acc) | "Parse elements between BEG and END positions. | | SPECIAL prioritize some elements over the others. It can be set | to `first-section', `quote-section', `section' `item' or | `table-row'. | | When value is `item', STRUCTURE will be used as the current list | structure. | | GRANULARITY determines the depth of the recursion. See | `org-element-parse-buffer' for more information. | | When VISIBLE-ONLY is non-nil, don't parse contents of hidden | elements. | | Elements are accumulated into ACC.") | | (defun org-element--parse-objects (beg end acc restriction) | "Parse objects between BEG and END and return recursive structure. | | Objects are accumulated in ACC. | | RESTRICTION is a list of object successors which are allowed in | the current object.") | | (defun org-element--get-next-object-candidates (limit restriction objects) | "Return an alist of candidates for the next object. | | LIMIT bounds the search, and RESTRICTION narrows candidates to | some object successors. | | OBJECTS is the previous candidates alist. If it is set to | `initial', no search has been done before, and all symbols in | RESTRICTION should be looked after. | | Return value is an alist whose CAR is the object type and CDR its | beginning position.") `---- Towards A Bijective Process =========================== The parse tree obtained with `org-element-parse-buffer' is really a snapshot of the corresponding Org buffer. Therefore, it can be interpreted and expanded into a string with canonical Org syntax. Hence `org-element-interpret-data'. The function relies internally on `org-element--interpret-affiliated-keywords'. ###autoload ,---- | (defun org-element-interpret-data (data &optional parent) | "Interpret DATA as Org syntax. | | DATA is a parse tree, an element, an object or a secondary string | to interpret. | | Optional argument PARENT is used for recursive calls. It contains | the element or object containing data, or nil. | | Return Org syntax as a string.") | | (defun org-element--interpret-affiliated-keywords (element) | "Return ELEMENT's affiliated keywords as Org syntax. | If there is no affiliated keyword, return the empty string.") `---- Because interpretation of the parse tree must return the same number of blank lines between elements and the same number of white space after objects, some special care must be given to white spaces. The first function, `org-element-normalize-string', ensures any string different from the empty string will end with a single newline character. The second function, `org-element-normalize-contents', removes global indentation from the contents of the current element. ,---- | (defun org-element-normalize-string (s) | "Ensure string S ends with a single newline character. | | If S isn't a string return it unchanged. If S is the empty | string, return it. Otherwise, return a new string with a single | newline character at its end.") | | (defun org-element-normalize-contents (element &optional ignore-first) | "Normalize plain text in ELEMENT's contents. | | ELEMENT must only contain plain text and objects. | | If optional argument IGNORE-FIRST is non-nil, ignore first line's | indentation to compute maximal common indentation. | | Return the normalized element that is element with global | indentation removed from its contents. The function assumes that | indentation is not done with TAB characters.") `---- The Toolbox =========== The first move is to implement a way to obtain the smallest element containing point. This is the job of `org-element-at-point'. It basically jumps back to the beginning of section containing point and moves, element after element, with `org-element--current-element' until the container is found. Note: When using `org-element-at-point', secondary values are never parsed since the function focuses on elements, not on objects. At a deeper level, `org-element-context' lists all elements and objects containing point. `org-element-nested-p' and `org-element-swap-A-B' may be used internally by navigation and manipulation tools. ###autoload ,---- | (defun org-element-at-point (&optional keep-trail) | "Determine closest element around point. | | Return value is a list like (TYPE PROPS) where TYPE is the type | of the element and PROPS a plist of properties associated to the | element. | | Possible types are defined in `org-element-all-elements'. | Properties depend on element or object type, but always include | `:begin', `:end', `:parent' and `:post-blank' properties. | | As a special case, if point is at the very beginning of a list or | sub-list, returned element will be that list instead of the first | item. In the same way, if point is at the beginning of the first | row of a table, returned element will be the table instead of the | first row. | | If optional argument KEEP-TRAIL is non-nil, the function returns | a list of elements leading to element at point. The list's CAR | is always the element at point. The following positions contain | element's siblings, then parents, siblings of parents, until the | first element of current section.") `---- ###autoload ,---- | (defun org-element-context (&optional element) | "Return closest element or object around point. | | Return value is a list like (TYPE PROPS) where TYPE is the type | of the element or object and PROPS a plist of properties | associated to it. | | Possible types are defined in `org-element-all-elements' and | `org-element-all-objects'. Properties depend on element or | object type, but always include `:begin', `:end', `:parent' and | `:post-blank'. | | Optional argument ELEMENT, when non-nil, is the closest element | containing point, as returned by `org-element-at-point'. | Providing it allows for quicker computation.") | | (defun org-element-nested-p (elem-A elem-B) | "Non-nil when elements ELEM-A and ELEM-B are nested.") | | (defun org-element-swap-A-B (elem-A elem-B) | "Swap elements ELEM-A and ELEM-B. | Assume ELEM-B is after ELEM-A in the buffer. Leave point at the | end of ELEM-A.") | | (provide 'org-element) `---- Local variables: generated-autoload-file: "org-loaddefs.el" End: org-element.el ends here ======================== --=-=-= Content-Type: application/vnd.lotus-organizer Content-Disposition: attachment; filename=org-element-docstrings.org Content-Transfer-Encoding: base64 Content-Description: Docstrings from org-elements.el (as org file) IytPUFRJT05TOiAgICBIOjMgbnVtOm5pbCB0b2M6dCBcbjpuaWwgOjp0IHw6dCBeOnQgLTp0IGY6 dCAqOnQgdGV4OnQgZDooSElERSkgdGFnczpub3QtaW4tdG9jCiMrU1RBUlRVUDogICAgYWxpZ24g Zm9sZCBub2RsY2hlY2sgaGlkZXN0YXJzIG9kZGV2ZW4gbG9nbm90ZXN0YXRlIGhpZGVibG9ja3MK IytTRVFfVE9ETzogICBUT0RPKHQpIElOUFJPR1JFU1MoaSkgV0FJVElORyh3QCkgfCBET05FKGQp IENBTkNFTEVEKGNAKQojK1RBR1M6ICAgICAgIFdyaXRlKHcpIFVwZGF0ZSh1KSBGaXgoZikgQ2hl Y2soYykgbm9leHBvcnQobikKIytUSVRMRTogICAgICBEb2NzdHJpbmdzIGZyb20gJ29yZy1lbGVt ZW50cy5lbCcgCiMrQVVUSE9SOiAgICAgVGhvcnN0ZW4gSm9saXR6CiMrRU1BSUw6ICAgICAgdGpv bGl0elthdF1nbWFpbFtkb3RdY29tCiMrTEFOR1VBR0U6ICAgZW4KIytTVFlMRTogICAgICA8c3R5 bGUgdHlwZT0idGV4dC9jc3MiPiNvdXRsaW5lLWNvbnRhaW5lci1pbnRyb2R1Y3Rpb257IGNsZWFy OmJvdGg7IH08L3N0eWxlPgojK0xJTktfVVA6ICAgIC4uL294LW92ZXJ2aWV3Lmh0bWwKIytMSU5L X0hPTUU6ICBodHRwOi8vb3JnbW9kZS5vcmcvd29yZy8KIytFWENMVURFX1RBR1M6IG5vZXhwb3J0 CgpbW2ZpbGU6aW5kZXgub3JnXVt7QmFjayB0byBXb3JnJ3MgaW5kZXh9XV0KCgoqIG9yZy1lbGVt ZW50LmVsIC0tLSBQYXJzZXIgQW5kIEFwcGxpY2F0aW9ucyBmb3IgT3JnIHN5bnRheAoKQ29weXJp Z2h0IChDKSAyMDEyLTIwMTMgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuCgpBdXRob3I6 IE5pY29sYXMgR29hemlvdSA8bi5nb2F6aW91IGF0IGdtYWlsIGRvdCBjb20+CktleXdvcmRzOiBv dXRsaW5lcywgaHlwZXJtZWRpYSwgY2FsZW5kYXIsIHdwCgpUaGlzIGZpbGUgaXMgcGFydCBvZiBH TlUgRW1hY3MuCgpHTlUgRW1hY3MgaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1 dGUgaXQgYW5kL29yIG1vZGlmeQppdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFs IFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQp0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0 aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvcgooYXQgeW91ciBvcHRpb24p IGFueSBsYXRlciB2ZXJzaW9uLgoKR05VIEVtYWNzIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3Bl IHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCmJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91 dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCk1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNT IEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKR05VIEdlbmVyYWwgUHVibGljIExp Y2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCllvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkg b2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCmFsb25nIHdpdGggR05VIEVtYWNzLiAg SWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LgoKKiBDb21tZW50YXJ5 OgoKT3JnIHN5bnRheCBjYW4gYmUgZGl2aWRlZCBpbnRvIHRocmVlIGNhdGVnb3JpZXM6ICJHcmVh dGVyIGVsZW1lbnRzIiwKIkVsZW1lbnRzIiBhbmQgIk9iamVjdHMiLgoKRWxlbWVudHMgYXJlIHJl bGF0ZWQgdG8gdGhlIHN0cnVjdHVyZSBvZiB0aGUgZG9jdW1lbnQuICBJbmRlZWQsIGFsbAplbGVt ZW50cyBhcmUgYSBjb3ZlciBmb3IgdGhlIGRvY3VtZW50OiBlYWNoIHBvc2l0aW9uIHdpdGhpbiBi ZWxvbmdzCnRvIGF0IGxlYXN0IG9uZSBlbGVtZW50LgoKQW4gZWxlbWVudCBhbHdheXMgc3RhcnRz IGFuZCBlbmRzIGF0IHRoZSBiZWdpbm5pbmcgb2YgYSBsaW5lLiAgV2l0aAphIGZldyBleGNlcHRp b25zIChgY2xvY2snLCBgaGVhZGxpbmUnLCBgaW5saW5ldGFzaycsIGBpdGVtJywKYHBsYW5uaW5n JywgYG5vZGUtcHJvcGVydHknLCBgcXVvdGUtc2VjdGlvbicgYHNlY3Rpb24nIGFuZApgdGFibGUt cm93JyB0eXBlcyksIGl0IGNhbiBhbHNvIGFjY2VwdCBhIGZpeGVkIHNldCBvZiBrZXl3b3JkcyBh cwphdHRyaWJ1dGVzLiAgVGhvc2UgYXJlIGNhbGxlZCAiYWZmaWxpYXRlZCBrZXl3b3JkcyIgdG8g ZGlzdGluZ3Vpc2gKdGhlbSBmcm9tIG90aGVyIGtleXdvcmRzLCB3aGljaCBhcmUgZnVsbC1mbGVk Z2VkIGVsZW1lbnRzLiAgQWxtb3N0CmFsbCBhZmZpbGlhdGVkIGtleXdvcmRzIGFyZSByZWZlcmVu Y2VkIGluCmBvcmctZWxlbWVudC1hZmZpbGlhdGVkLWtleXdvcmRzJzsgdGhlIG90aGVycyBhcmUg ZXhwb3J0IGF0dHJpYnV0ZXMKYW5kIHN0YXJ0IHdpdGggIkFUVFJfIiBwcmVmaXguCgpFbGVtZW50 IGNvbnRhaW5pbmcgb3RoZXIgZWxlbWVudHMgKGFuZCBvbmx5IGVsZW1lbnRzKSBhcmUgY2FsbGVk CmdyZWF0ZXIgZWxlbWVudHMuICBDb25jZXJuZWQgdHlwZXMgYXJlOiBgY2VudGVyLWJsb2NrJywg YGRyYXdlcicsCmBkeW5hbWljLWJsb2NrJywgYGZvb3Rub3RlLWRlZmluaXRpb24nLCBgaGVhZGxp bmUnLCBgaW5saW5ldGFzaycsCmBpdGVtJywgYHBsYWluLWxpc3QnLCBgcHJvcGVydHktZHJhd2Vy JywgYHF1b3RlLWJsb2NrJywgYHNlY3Rpb24nCmFuZCBgc3BlY2lhbC1ibG9jaycuCgpPdGhlciBl bGVtZW50IHR5cGVzIGFyZTogYGJhYmVsLWNhbGwnLCBgY2xvY2snLCBgY29tbWVudCcsCmBjb21t ZW50LWJsb2NrJywgYGRpYXJ5LXNleHAnLCBgZXhhbXBsZS1ibG9jaycsIGBleHBvcnQtYmxvY2sn LApgZml4ZWQtd2lkdGgnLCBgaG9yaXpvbnRhbC1ydWxlJywgYGtleXdvcmQnLCBgbGF0ZXgtZW52 aXJvbm1lbnQnLApgbm9kZS1wcm9wZXJ0eScsIGBwYXJhZ3JhcGgnLCBgcGxhbm5pbmcnLCBgcXVv dGUtc2VjdGlvbicsCmBzcmMtYmxvY2snLCBgdGFibGUnLCBgdGFibGUtcm93JyBhbmQgYHZlcnNl LWJsb2NrJy4gIEFtb25nIHRoZW0sCmBwYXJhZ3JhcGgnIGFuZCBgdmVyc2UtYmxvY2snIHR5cGVz IGNhbiBjb250YWluIE9yZyBvYmplY3RzIGFuZApwbGFpbiB0ZXh0LgoKT2JqZWN0cyBhcmUgcmVs YXRlZCB0byBkb2N1bWVudCdzIGNvbnRlbnRzLiAgU29tZSBvZiB0aGVtIGFyZQpyZWN1cnNpdmUu ICBBc3NvY2lhdGVkIHR5cGVzIGFyZSBvZiB0aGUgZm9sbG93aW5nOiBgYm9sZCcsIGBjb2RlJywK YGVudGl0eScsIGBleHBvcnQtc25pcHBldCcsIGBmb290bm90ZS1yZWZlcmVuY2UnLApgaW5saW5l LWJhYmVsLWNhbGwnLCBgaW5saW5lLXNyYy1ibG9jaycsIGBpdGFsaWMnLApgbGF0ZXgtZnJhZ21l bnQnLCBgbGluZS1icmVhaycsIGBsaW5rJywgYG1hY3JvJywgYHJhZGlvLXRhcmdldCcsCmBzdGF0 aXN0aWNzLWNvb2tpZScsIGBzdHJpa2UtdGhyb3VnaCcsIGBzdWJzY3JpcHQnLCBgc3VwZXJzY3Jp cHQnLApgdGFibGUtY2VsbCcsIGB0YXJnZXQnLCBgdGltZXN0YW1wJywgYHVuZGVybGluZScgYW5k IGB2ZXJiYXRpbScuCgpTb21lIGVsZW1lbnRzIGFsc28gaGF2ZSBzcGVjaWFsIHByb3BlcnRpZXMg d2hvc2UgdmFsdWUgY2FuIGhvbGQKb2JqZWN0cyB0aGVtc2VsdmVzIChpLmUuIGFuIGl0ZW0gdGFn IG9yIGEgaGVhZGxpbmUgbmFtZSkuICBTdWNoCnZhbHVlcyBhcmUgY2FsbGVkICJzZWNvbmRhcnkg c3RyaW5ncyIuICBBbnkgb2JqZWN0IGJlbG9uZ3MgdG8KZWl0aGVyIGFuIGVsZW1lbnQgb3IgYSBz ZWNvbmRhcnkgc3RyaW5nLgoKTm90d2l0aHN0YW5kaW5nIGFmZmlsaWF0ZWQga2V5d29yZHMsIGVh Y2ggZ3JlYXRlciBlbGVtZW50LCBlbGVtZW50CmFuZCBvYmplY3QgaGFzIGEgZml4ZWQgc2V0IG9m IHByb3BlcnRpZXMgYXR0YWNoZWQgdG8gaXQuICBBbW9uZwp0aGVtLCBmb3VyIGFyZSBzaGFyZWQg YnkgYWxsIHR5cGVzOiBgOmJlZ2luJyBhbmQgYDplbmQnLCB3aGljaApyZWZlciB0byB0aGUgYmVn aW5uaW5nIGFuZCBlbmRpbmcgYnVmZmVyIHBvc2l0aW9ucyBvZiB0aGUKY29uc2lkZXJlZCBlbGVt ZW50IG9yIG9iamVjdCwgYDpwb3N0LWJsYW5rJywgd2hpY2ggaG9sZHMgdGhlIG51bWJlcgpvZiBi bGFuayBsaW5lcywgb3Igd2hpdGUgc3BhY2VzLCBhdCBpdHMgZW5kIGFuZCBgOnBhcmVudCcgd2hp Y2gKcmVmZXJzIHRvIHRoZSBlbGVtZW50IG9yIG9iamVjdCBjb250YWluaW5nIGl0LiAgR3JlYXRl ciBlbGVtZW50cywKZWxlbWVudHMgYW5kIG9iamVjdHMgY29udGFpbmluZyBvYmplY3RzIHdpbGwg YWxzbyBoYXZlCmA6Y29udGVudHMtYmVnaW4nIGFuZCBgOmNvbnRlbnRzLWVuZCcgcHJvcGVydGll cyB0byBkZWxpbWl0CmNvbnRlbnRzLiAgRXZlbnR1YWxseSwgZ3JlYXRlciBlbGVtZW50cyBhbmQg ZWxlbWVudHMgYWNjZXB0aW5nCmFmZmlsaWF0ZWQga2V5d29yZHMgd2lsbCBoYXZlIGEgYDpwb3N0 LWFmZmlsaWF0ZWQnIHByb3BlcnR5LApyZWZlcnJpbmcgdG8gdGhlIGJ1ZmZlciBwb3NpdGlvbiBh ZnRlciBhbGwgc3VjaCBrZXl3b3Jkcy4KCkF0IHRoZSBsb3dlc3QgbGV2ZWwsIGEgYDpwYXJlbnQn IHByb3BlcnR5IGlzIGFsc28gYXR0YWNoZWQgdG8gYW55CnN0cmluZywgYXMgYSB0ZXh0IHByb3Bl cnR5LgoKTGlzcC13aXNlLCBhbiBlbGVtZW50IG9yIGFuIG9iamVjdCBjYW4gYmUgcmVwcmVzZW50 ZWQgYXMgYSBsaXN0LgpJdCBmb2xsb3dzIHRoZSBwYXR0ZXJuIChUWVBFIFBST1BFUlRJRVMgQ09O VEVOVFMpLCB3aGVyZToKICBUWVBFIGlzIGEgc3ltYm9sIGRlc2NyaWJpbmcgdGhlIE9yZyBlbGVt ZW50IG9yIG9iamVjdC4KICBQUk9QRVJUSUVTIGlzIHRoZSBwcm9wZXJ0eSBsaXN0IGF0dGFjaGVk IHRvIGl0LiAgU2VlIGRvY3N0cmluZyBvZgogICAgICAgICAgICAgYXBwcm9wcmlhdGUgcGFyc2lu ZyBmdW5jdGlvbiB0byBnZXQgYW4gZXhoYXVzdGl2ZQogICAgICAgICAgICAgbGlzdC4KICBDT05U RU5UUyBpcyBhIGxpc3Qgb2YgZWxlbWVudHMsIG9iamVjdHMgb3IgcmF3IHN0cmluZ3MgY29udGFp bmVkCiAgICAgICAgICAgaW4gdGhlIGN1cnJlbnQgZWxlbWVudCBvciBvYmplY3QsIHdoZW4gYXBw bGljYWJsZS4KCkFuIE9yZyBidWZmZXIgaXMgYSBuZXN0ZWQgbGlzdCBvZiBzdWNoIGVsZW1lbnRz IGFuZCBvYmplY3RzLCB3aG9zZQp0eXBlIGlzIGBvcmctZGF0YScgYW5kIHByb3BlcnRpZXMgaXMg bmlsLgoKVGhlIGZpcnN0IHBhcnQgb2YgdGhpcyBmaWxlIGRlZmluZXMgT3JnIHN5bnRheCwgd2hp bGUgdGhlIHNlY29uZApvbmUgcHJvdmlkZSBhY2Nlc3NvcnMgYW5kIHNldHRlcnMgZnVuY3Rpb25z LgoKVGhlIG5leHQgcGFydCBpbXBsZW1lbnRzIGEgcGFyc2VyIGFuZCBhbiBpbnRlcnByZXRlciBm b3IgZWFjaAplbGVtZW50IGFuZCBvYmplY3QgdHlwZSBpbiBPcmcgc3ludGF4LgoKVGhlIGZvbGxv d2luZyBwYXJ0IGNyZWF0ZXMgYSBmdWxseSByZWN1cnNpdmUgYnVmZmVyIHBhcnNlci4gIEl0CmFs c28gcHJvdmlkZXMgYSB0b29sIHRvIG1hcCBhIGZ1bmN0aW9uIHRvIGVsZW1lbnRzIG9yIG9iamVj dHMKbWF0Y2hpbmcgc29tZSBjcml0ZXJpYSBpbiB0aGUgcGFyc2UgdHJlZS4gIEZ1bmN0aW9ucyBv ZiBpbnRlcmVzdAphcmUgYG9yZy1lbGVtZW50LXBhcnNlLWJ1ZmZlcicsIGBvcmctZWxlbWVudC1t YXAnIGFuZCwgdG8gYSBsZXNzZXIKZXh0ZW50LCBgb3JnLWVsZW1lbnQtcGFyc2Utc2Vjb25kYXJ5 LXN0cmluZycuCgpUaGUgcGVudWx0aW1hdGUgcGFydCBpcyB0aGUgY3JhZGxlIG9mIGFuIGludGVy cHJldGVyIGZvciB0aGUKb2J0YWluZWQgcGFyc2UgdHJlZTogYG9yZy1lbGVtZW50LWludGVycHJl dC1kYXRhJy4KClRoZSBsaWJyYXJ5IGVuZHMgYnkgZnVybmlzaGluZyBgb3JnLWVsZW1lbnQtYXQt cG9pbnQnIGZ1bmN0aW9uLCBhbmQKYSB3YXkgdG8gZ2l2ZSBpbmZvcm1hdGlvbiBhYm91dCBkb2N1 bWVudCBzdHJ1Y3R1cmUgYXJvdW5kIHBvaW50CndpdGggYG9yZy1lbGVtZW50LWNvbnRleHQnLgoK CiogQ29kZToKCiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGV2YWwtd2hlbi1jb21waWxlIChyZXF1 aXJlICdjbCkpCihyZXF1aXJlICdvcmcpCiMrZW5kX3NyYwoKKiBEZWZpbml0aW9ucyBBbmQgUnVs ZXMKCkRlZmluZSBlbGVtZW50cywgZ3JlYXRlciBlbGVtZW50cyBhbmQgc3BlY2lmeSByZWN1cnNp dmUgb2JqZWN0cywKYWxvbmcgd2l0aCB0aGUgYWZmaWxpYXRlZCBrZXl3b3JkcyByZWNvZ25pemVk LiAgQWxzbyBzZXQgdXAKcmVzdHJpY3Rpb25zIG9uIHJlY3Vyc2l2ZSBvYmplY3RzIGNvbWJpbmF0 aW9ucy4KClRoZXNlIHZhcmlhYmxlcyByZWFsbHkgYWN0IGFzIGEgY29udHJvbCBjZW50ZXIgZm9y IHRoZSBwYXJzaW5nCnByb2Nlc3MuCgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZjb25zdCBv cmctZWxlbWVudC1wYXJhZ3JhcGgtc2VwYXJhdGUKICAoY29uY2F0ICJeXFwoPzoiCiAgICAgICAg ICA7OyBIZWFkbGluZXMsIGlubGluZXRhc2tzLgogICAgICAgICAgb3JnLW91dGxpbmUtcmVnZXhw ICJcXHwiCiAgICAgICAgICA7OyBGb290bm90ZSBkZWZpbml0aW9ucy4KCSAgIlxcW1xcKD86WzAt OV0rXFx8Zm46Wy1fWzp3b3JkOl1dK1xcKVxcXSIgIlxcfCIKCSAgOzsgRGlhcnkgc2V4cHMuCgkg ICIlJSgiICJcXHwiCiAgICAgICAgICAiWyBcdF0qXFwoPzoiCiAgICAgICAgICA7OyBFbXB0eSBs aW5lcy4KICAgICAgICAgICIkIiAiXFx8IgoJICA7OyBUYWJsZXMgKGFueSB0eXBlKS4KCSAgIlxc KD86fFxcfFxcKy1bLStdXFwpIiAiXFx8IgogICAgICAgICAgOzsgQmxvY2tzIChhbnkgdHlwZSks IEJhYmVsIGNhbGxzLCBkcmF3ZXJzIChhbnkgdHlwZSksCgkgIDs7IGZpeGVkLXdpZHRoIGFyZWFz IGFuZCBrZXl3b3Jkcy4gIE5vdGU6IHRoaXMgaXMgb25seSBhbgoJICA7OyBpbmRpY2F0aW9uIGFu ZCBuZWVkIHNvbWUgdGhvcm91Z2ggY2hlY2suCiAgICAgICAgICAiWyM6XSIgIlxcfCIKICAgICAg ICAgIDs7IEhvcml6b250YWwgcnVsZXMuCiAgICAgICAgICAiLVxcezUsXFx9WyBcdF0qJCIgIlxc fCIKICAgICAgICAgIDs7IExhVGVYIGVudmlyb25tZW50cy4KICAgICAgICAgICJcXFxcYmVnaW57 XFwoW0EtWmEtejAtOV0rXFwqP1xcKX0iICJcXHwiCiAgICAgICAgICA7OyBQbGFubmluZyBhbmQg Q2xvY2sgbGluZXMuCiAgICAgICAgICAocmVnZXhwLW9wdCAobGlzdCBvcmctc2NoZWR1bGVkLXN0 cmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnLWRlYWRsaW5lLXN0cmluZwogICAg ICAgICAgICAgICAgICAgICAgICAgICAgb3JnLWNsb3NlZC1zdHJpbmcKICAgICAgICAgICAgICAg ICAgICAgICAgICAgIG9yZy1jbG9jay1zdHJpbmcpKQogICAgICAgICAgIlxcfCIKICAgICAgICAg IDs7IExpc3RzLgogICAgICAgICAgKGxldCAoKHRlcm0gKGNhc2Ugb3JnLXBsYWluLWxpc3Qtb3Jk ZXJlZC1pdGVtLXRlcm1pbmF0b3IKICAgICAgICAgICAgICAgICAgICAgICAgKD9cKSAiKSIpICg/ LiAiXFwuIikgKG90aGVyd2lzZSAiWy4pXSIpKSkKICAgICAgICAgICAgICAgIChhbHBoYSAoYW5k IG9yZy1saXN0LWFsbG93LWFscGhhYmV0aWNhbCAiXFx8W0EtWmEtel0iKSkpCiAgICAgICAgICAg IChjb25jYXQgIlxcKD86Wy0rKl1cXHxcXCg/OlswLTldKyIgYWxwaGEgIlxcKSIgdGVybSAiXFwp IgogICAgICAgICAgICAgICAgICAgICJcXCg/OlsgXHRdXFx8JFxcKSIpKQogICAgICAgICAgIlxc KVxcKSIpCiAgIlJlZ2V4cCB0byBzZXBhcmF0ZSBwYXJhZ3JhcGhzIGluIGFuIE9yZyBidWZmZXIu CkluIHRoZSBjYXNlIG9mIGxpbmVzIHN0YXJ0aW5nIHdpdGggXCIjXCIgYW5kIFwiOlwiLCB0aGlz IHJlZ2V4cAppcyBub3Qgc3VmZmljaWVudCB0byBrbm93IGlmIHBvaW50IGlzIGF0IGEgcGFyYWdy YXBoIGVuZGluZy4gIFNlZQpgb3JnLWVsZW1lbnQtcGFyYWdyYXBoLXBhcnNlcicgZm9yIG1vcmUg aW5mb3JtYXRpb24uIikKCihkZWZjb25zdCBvcmctZWxlbWVudC1hbGwtZWxlbWVudHMKICAnKGJh YmVsLWNhbGwgY2VudGVyLWJsb2NrIGNsb2NrIGNvbW1lbnQgY29tbWVudC1ibG9jayBkaWFyeS1z ZXhwIGRyYXdlcgoJICAgICAgIGR5bmFtaWMtYmxvY2sgZXhhbXBsZS1ibG9jayBleHBvcnQtYmxv Y2sgZml4ZWQtd2lkdGgKCSAgICAgICBmb290bm90ZS1kZWZpbml0aW9uIGhlYWRsaW5lIGhvcml6 b250YWwtcnVsZSBpbmxpbmV0YXNrIGl0ZW0KCSAgICAgICBrZXl3b3JkIGxhdGV4LWVudmlyb25t ZW50IG5vZGUtcHJvcGVydHkgcGFyYWdyYXBoIHBsYWluLWxpc3QKCSAgICAgICBwbGFubmluZyBw cm9wZXJ0eS1kcmF3ZXIgcXVvdGUtYmxvY2sgcXVvdGUtc2VjdGlvbiBzZWN0aW9uCgkgICAgICAg c3BlY2lhbC1ibG9jayBzcmMtYmxvY2sgdGFibGUgdGFibGUtcm93IHZlcnNlLWJsb2NrKQogICJD b21wbGV0ZSBsaXN0IG9mIGVsZW1lbnQgdHlwZXMuIikKCihkZWZjb25zdCBvcmctZWxlbWVudC1n cmVhdGVyLWVsZW1lbnRzCiAgJyhjZW50ZXItYmxvY2sgZHJhd2VyIGR5bmFtaWMtYmxvY2sgZm9v dG5vdGUtZGVmaW5pdGlvbiBoZWFkbGluZSBpbmxpbmV0YXNrCgkJIGl0ZW0gcGxhaW4tbGlzdCBw cm9wZXJ0eS1kcmF3ZXIgcXVvdGUtYmxvY2sgc2VjdGlvbgoJCSBzcGVjaWFsLWJsb2NrIHRhYmxl KQogICJMaXN0IG9mIHJlY3Vyc2l2ZSBlbGVtZW50IHR5cGVzIGFrYSBHcmVhdGVyIEVsZW1lbnRz LiIpCgooZGVmY29uc3Qgb3JnLWVsZW1lbnQtYWxsLXN1Y2Nlc3NvcnMKICAnKGV4cG9ydC1zbmlw cGV0IGZvb3Rub3RlLXJlZmVyZW5jZSBpbmxpbmUtYmFiZWwtY2FsbCBpbmxpbmUtc3JjLWJsb2Nr CgkJICAgbGF0ZXgtb3ItZW50aXR5IGxpbmUtYnJlYWsgbGluayBtYWNybyBwbGFpbi1saW5rIHJh ZGlvLXRhcmdldAoJCSAgIHN0YXRpc3RpY3MtY29va2llIHN1Yi9zdXBlcnNjcmlwdCB0YWJsZS1j ZWxsIHRhcmdldAoJCSAgIHRleHQtbWFya3VwIHRpbWVzdGFtcCkKICAiQ29tcGxldGUgbGlzdCBv ZiBzdWNjZXNzb3JzLiIpCgooZGVmY29uc3Qgb3JnLWVsZW1lbnQtb2JqZWN0LXN1Y2Nlc3Nvci1h bGlzdAogICcoKHN1YnNjcmlwdCAuIHN1Yi9zdXBlcnNjcmlwdCkgKHN1cGVyc2NyaXB0IC4gc3Vi L3N1cGVyc2NyaXB0KQogICAgKGJvbGQgLiB0ZXh0LW1hcmt1cCkgKGNvZGUgLiB0ZXh0LW1hcmt1 cCkgKGl0YWxpYyAuIHRleHQtbWFya3VwKQogICAgKHN0cmlrZS10aHJvdWdoIC4gdGV4dC1tYXJr dXApICh1bmRlcmxpbmUgLiB0ZXh0LW1hcmt1cCkKICAgICh2ZXJiYXRpbSAuIHRleHQtbWFya3Vw KSAoZW50aXR5IC4gbGF0ZXgtb3ItZW50aXR5KQogICAgKGxhdGV4LWZyYWdtZW50IC4gbGF0ZXgt b3ItZW50aXR5KSkKICAiQWxpc3Qgb2YgdHJhbnNsYXRpb25zIGJldHdlZW4gb2JqZWN0IHR5cGUg YW5kIHN1Y2Nlc3NvciBuYW1lLgpTaGFyaW5nIHRoZSBzYW1lIHN1Y2Nlc3NvciBjb21lcyBoYW5k eSB3aGVuLCBmb3IgZXhhbXBsZSwgdGhlCnJlZ2V4cCBtYXRjaGluZyBvbmUgb2JqZWN0IGNhbiBh bHNvIG1hdGNoIHRoZSBvdGhlciBvYmplY3QuIikKCihkZWZjb25zdCBvcmctZWxlbWVudC1hbGwt b2JqZWN0cwogICcoYm9sZCBjb2RlIGVudGl0eSBleHBvcnQtc25pcHBldCBmb290bm90ZS1yZWZl cmVuY2UgaW5saW5lLWJhYmVsLWNhbGwKCSBpbmxpbmUtc3JjLWJsb2NrIGl0YWxpYyBsaW5lLWJy ZWFrIGxhdGV4LWZyYWdtZW50IGxpbmsgbWFjcm8KCSByYWRpby10YXJnZXQgc3RhdGlzdGljcy1j b29raWUgc3RyaWtlLXRocm91Z2ggc3Vic2NyaXB0IHN1cGVyc2NyaXB0CgkgdGFibGUtY2VsbCB0 YXJnZXQgdGltZXN0YW1wIHVuZGVybGluZSB2ZXJiYXRpbSkKICAiQ29tcGxldGUgbGlzdCBvZiBv YmplY3QgdHlwZXMuIikKCihkZWZjb25zdCBvcmctZWxlbWVudC1yZWN1cnNpdmUtb2JqZWN0cwog ICcoYm9sZCBpdGFsaWMgbGluayBzdWJzY3JpcHQgcmFkaW8tdGFyZ2V0IHN0cmlrZS10aHJvdWdo IHN1cGVyc2NyaXB0CgkgdGFibGUtY2VsbCB1bmRlcmxpbmUpCiAgIkxpc3Qgb2YgcmVjdXJzaXZl IG9iamVjdCB0eXBlcy4iKQoKKGRlZnZhciBvcmctZWxlbWVudC1ibG9jay1uYW1lLWFsaXN0CiAg JygoIkNFTlRFUiIgLiBvcmctZWxlbWVudC1jZW50ZXItYmxvY2stcGFyc2VyKQogICAgKCJDT01N RU5UIiAuIG9yZy1lbGVtZW50LWNvbW1lbnQtYmxvY2stcGFyc2VyKQogICAgKCJFWEFNUExFIiAu IG9yZy1lbGVtZW50LWV4YW1wbGUtYmxvY2stcGFyc2VyKQogICAgKCJRVU9URSIgLiBvcmctZWxl bWVudC1xdW90ZS1ibG9jay1wYXJzZXIpCiAgICAoIlNSQyIgLiBvcmctZWxlbWVudC1zcmMtYmxv Y2stcGFyc2VyKQogICAgKCJWRVJTRSIgLiBvcmctZWxlbWVudC12ZXJzZS1ibG9jay1wYXJzZXIp KQogICJBbGlzdCBiZXR3ZWVuIGJsb2NrIG5hbWVzIGFuZCB0aGUgYXNzb2NpYXRlZCBwYXJzaW5n IGZ1bmN0aW9uLgpOYW1lcyBtdXN0IGJlIHVwcGVyY2FzZS4gIEFueSBibG9jayB3aG9zZSBuYW1l IGhhcyBubyBhc3NvY2lhdGlvbgppcyBwYXJzZWQgd2l0aCBgb3JnLWVsZW1lbnQtc3BlY2lhbC1i bG9jay1wYXJzZXInLiIpCgooZGVmY29uc3Qgb3JnLWVsZW1lbnQtbGluay10eXBlLWlzLWZpbGUK ICAnKCJmaWxlIiAiZmlsZStlbWFjcyIgImZpbGUrc3lzIiAiZG9jdmlldyIpCiAgIkxpc3Qgb2Yg bGluayB0eXBlcyBlcXVpdmFsZW50IHRvIFwiZmlsZVwiLgpPbmx5IHRoZXNlIHR5cGVzIGNhbiBh Y2NlcHQgc2VhcmNoIG9wdGlvbnMgYW5kIGFuIGV4cGxpY2l0CmFwcGxpY2F0aW9uIHRvIG9wZW4g dGhlbS4iKQoKKGRlZmNvbnN0IG9yZy1lbGVtZW50LWFmZmlsaWF0ZWQta2V5d29yZHMKICAnKCJD QVBUSU9OIiAiREFUQSIgIkhFQURFUiIgIkhFQURFUlMiICJMQUJFTCIgIk5BTUUiICJQTE9UIiAi UkVTTkFNRSIgIlJFU1VMVCIKICAgICJSRVNVTFRTIiAiU09VUkNFIiAiU1JDTkFNRSIgIlRCTE5B TUUiKQogICJMaXN0IG9mIGFmZmlsaWF0ZWQga2V5d29yZHMgYXMgc3RyaW5ncy4KQnkgZGVmYXVs dCwgYWxsIGtleXdvcmRzIHNldHRpbmcgYXR0cmlidXRlcyAoaS5lLiBcIkFUVFJfTEFURVhcIikK YXJlIGFmZmlsaWF0ZWQga2V5d29yZHMgYW5kIG5lZWQgbm90IHRvIGJlIGluIHRoaXMgbGlzdC4i KQoKKGRlZmNvbnN0IG9yZy1lbGVtZW50LS1hZmZpbGlhdGVkLXJlCiAgKGZvcm1hdCAiWyBcdF0q I1xcKyVzOiIKCSAgOzsgUmVndWxhciBhZmZpbGlhdGVkIGtleXdvcmRzLgoJICAoZm9ybWF0ICJc XCglc1xcfEFUVFJfWy1fQS1aYS16MC05XStcXClcXCg/OlxcW1xcKC4qXFwpXFxdXFwpPyIKCQkg IChyZWdleHAtb3B0IG9yZy1lbGVtZW50LWFmZmlsaWF0ZWQta2V5d29yZHMpKSkKICAiUmVnZXhw IG1hdGNoaW5nIGFueSBhZmZpbGlhdGVkIGtleXdvcmQuCgpLZXl3b3JkIG5hbWUgaXMgcHV0IGlu IG1hdGNoIGdyb3VwIDEuICBNb3Jlb3ZlciwgaWYga2V5d29yZApiZWxvbmdzIHRvIGBvcmctZWxl bWVudC1kdWFsLWtleXdvcmRzJywgcHV0IHRoZSBkdWFsIHZhbHVlIGluCm1hdGNoIGdyb3VwIDIu CgpEb24ndCBtb2RpZnkgaXQsIHNldCBgb3JnLWVsZW1lbnQtYWZmaWxpYXRlZC1rZXl3b3Jkcycg aW5zdGVhZC4iKQoKKGRlZmNvbnN0IG9yZy1lbGVtZW50LWtleXdvcmQtdHJhbnNsYXRpb24tYWxp c3QKICAnKCgiREFUQSIgLiAiTkFNRSIpICAoIkxBQkVMIiAuICJOQU1FIikgKCJSRVNOQU1FIiAu ICJOQU1FIikKICAgICgiU09VUkNFIiAuICJOQU1FIikgKCJTUkNOQU1FIiAuICJOQU1FIikgKCJU QkxOQU1FIiAuICJOQU1FIikKICAgICgiUkVTVUxUIiAuICJSRVNVTFRTIikgKCJIRUFERVJTIiAu ICJIRUFERVIiKSkKICAiQWxpc3Qgb2YgdXN1YWwgdHJhbnNsYXRpb25zIGZvciBrZXl3b3Jkcy4K VGhlIGtleSBpcyB0aGUgb2xkIG5hbWUgYW5kIHRoZSB2YWx1ZSB0aGUgbmV3IG9uZS4gIFRoZSBw cm9wZXJ0eQpob2xkaW5nIHRoZWlyIHZhbHVlIHdpbGwgYmUgbmFtZWQgYWZ0ZXIgdGhlIHRyYW5z bGF0ZWQgbmFtZS4iKQoKKGRlZmNvbnN0IG9yZy1lbGVtZW50LW11bHRpcGxlLWtleXdvcmRzICco IkNBUFRJT04iICJIRUFERVIiKQogICJMaXN0IG9mIGFmZmlsaWF0ZWQga2V5d29yZHMgdGhhdCBj YW4gb2NjdXIgbW9yZSB0aGFuIG9uY2UgaW4gYW4gZWxlbWVudC4KClRoZWlyIHZhbHVlIHdpbGwg YmUgY29uc2VkIGludG8gYSBsaXN0IG9mIHN0cmluZ3MsIHdoaWNoIHdpbGwgYmUKcmV0dXJuZWQg YXMgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eS4KClRoaXMgbGlzdCBpcyBjaGVja2VkIGFmdGVy IHRyYW5zbGF0aW9ucyBoYXZlIGJlZW4gYXBwbGllZC4gIFNlZQpgb3JnLWVsZW1lbnQta2V5d29y ZC10cmFuc2xhdGlvbi1hbGlzdCcuCgpCeSBkZWZhdWx0LCBhbGwga2V5d29yZHMgc2V0dGluZyBh dHRyaWJ1dGVzIChpLmUuIFwiQVRUUl9MQVRFWFwiKQphbGxvdyBtdWx0aXBsZSBvY2N1cnJlbmNl cyBhbmQgbmVlZCBub3QgdG8gYmUgaW4gdGhpcyBsaXN0LiIpCgooZGVmY29uc3Qgb3JnLWVsZW1l bnQtcGFyc2VkLWtleXdvcmRzICcoIkNBUFRJT04iKQogICJMaXN0IG9mIGFmZmlsaWF0ZWQga2V5 d29yZHMgd2hvc2UgdmFsdWUgY2FuIGJlIHBhcnNlZC4KClRoZWlyIHZhbHVlIHdpbGwgYmUgc3Rv cmVkIGFzIGEgc2Vjb25kYXJ5IHN0cmluZzogYSBsaXN0IG9mCnN0cmluZ3MgYW5kIG9iamVjdHMu CgpUaGlzIGxpc3QgaXMgY2hlY2tlZCBhZnRlciB0cmFuc2xhdGlvbnMgaGF2ZSBiZWVuIGFwcGxp ZWQuICBTZWUKYG9yZy1lbGVtZW50LWtleXdvcmQtdHJhbnNsYXRpb24tYWxpc3QnLiIpCgooZGVm Y29uc3Qgb3JnLWVsZW1lbnQtZHVhbC1rZXl3b3JkcyAnKCJDQVBUSU9OIiAiUkVTVUxUUyIpCiAg Ikxpc3Qgb2YgYWZmaWxpYXRlZCBrZXl3b3JkcyB3aGljaCBjYW4gaGF2ZSBhIHNlY29uZGFyeSB2 YWx1ZS4KCkluIE9yZyBzeW50YXgsIHRoZXkgY2FuIGJlIHdyaXR0ZW4gd2l0aCBvcHRpb25hbCBz cXVhcmUgYnJhY2tldHMKYmVmb3JlIHRoZSBjb2xvbnMuICBGb3IgZXhhbXBsZSwgUkVTVUxUUyBr ZXl3b3JkIGNhbiBiZQphc3NvY2lhdGVkIHRvIGEgaGFzaCB2YWx1ZSB3aXRoIHRoZSBmb2xsb3dp bmc6CgogICMrUkVTVUxUU1toYXNoLXN0cmluZ106IHNvbWUtc291cmNlCgpUaGlzIGxpc3QgaXMg Y2hlY2tlZCBhZnRlciB0cmFuc2xhdGlvbnMgaGF2ZSBiZWVuIGFwcGxpZWQuICBTZWUKYG9yZy1l bGVtZW50LWtleXdvcmQtdHJhbnNsYXRpb24tYWxpc3QnLiIpCgooZGVmY29uc3Qgb3JnLWVsZW1l bnQtZG9jdW1lbnQtcHJvcGVydGllcyAnKCJBVVRIT1IiICJEQVRFIiAiVElUTEUiKQogICJMaXN0 IG9mIHByb3BlcnRpZXMgYXNzb2NpYXRlZCB0byB0aGUgd2hvbGUgZG9jdW1lbnQuCkFueSBrZXl3 b3JkIGluIHRoaXMgbGlzdCB3aWxsIGhhdmUgaXRzIHZhbHVlIHBhcnNlZCBhbmQgc3RvcmVkIGFz CmEgc2Vjb25kYXJ5IHN0cmluZy4iKQoKKGRlZmNvbnN0IG9yZy1lbGVtZW50LW9iamVjdC1yZXN0 cmljdGlvbnMKICAobGV0KiAoKHN0YW5kYXJkLXNldAoJICAocmVtcSAncGxhaW4tbGluayAocmVt cSAndGFibGUtY2VsbCBvcmctZWxlbWVudC1hbGwtc3VjY2Vzc29ycykpKQoJIChzdGFuZGFyZC1z ZXQtbm8tbGluZS1icmVhayAocmVtcSAnbGluZS1icmVhayBzdGFuZGFyZC1zZXQpKSkKICAgIGAo KGJvbGQgLEBzdGFuZGFyZC1zZXQpCiAgICAgIChmb290bm90ZS1yZWZlcmVuY2UgLEBzdGFuZGFy ZC1zZXQpCiAgICAgIChoZWFkbGluZSAsQHN0YW5kYXJkLXNldC1uby1saW5lLWJyZWFrKQogICAg ICAoaW5saW5ldGFzayAsQHN0YW5kYXJkLXNldC1uby1saW5lLWJyZWFrKQogICAgICAoaXRhbGlj ICxAc3RhbmRhcmQtc2V0KQogICAgICAoaXRlbSAsQHN0YW5kYXJkLXNldC1uby1saW5lLWJyZWFr KQogICAgICAoa2V5d29yZCAsQHN0YW5kYXJkLXNldCkKICAgICAgOzsgSWdub3JlIGFsbCBsaW5r cyBleGNlcHRlZCBwbGFpbiBsaW5rcyBpbiBhIGxpbmsgZGVzY3JpcHRpb24uCiAgICAgIDs7IEFs c28gaWdub3JlIHJhZGlvLXRhcmdldHMgYW5kIGxpbmUgYnJlYWtzLgogICAgICAobGluayBleHBv cnQtc25pcHBldCBpbmxpbmUtYmFiZWwtY2FsbCBpbmxpbmUtc3JjLWJsb2NrIGxhdGV4LW9yLWVu dGl0eQoJICAgIG1hY3JvIHBsYWluLWxpbmsgc3RhdGlzdGljcy1jb29raWUgc3ViL3N1cGVyc2Ny aXB0IHRleHQtbWFya3VwKQogICAgICAocGFyYWdyYXBoICxAc3RhbmRhcmQtc2V0KQogICAgICA7 OyBSZW1vdmUgYW55IHZhcmlhYmxlIG9iamVjdCBmcm9tIHJhZGlvIHRhcmdldCBhcyBpdCB3b3Vs ZAogICAgICA7OyBwcmV2ZW50IGl0IGZyb20gYmVpbmcgcHJvcGVybHkgcmVjb2duaXplZC4KICAg ICAgKHJhZGlvLXRhcmdldCBsYXRleC1vci1lbnRpdHkgc3ViL3N1cGVyc2NyaXB0KQogICAgICAo c3RyaWtlLXRocm91Z2ggLEBzdGFuZGFyZC1zZXQpCiAgICAgIChzdWJzY3JpcHQgLEBzdGFuZGFy ZC1zZXQpCiAgICAgIChzdXBlcnNjcmlwdCAsQHN0YW5kYXJkLXNldCkKICAgICAgOzsgSWdub3Jl IGlubGluZSBiYWJlbCBjYWxsIGFuZCBpbmxpbmUgc3JjIGJsb2NrIGFzIGZvcm11bGFzIGFyZQog ICAgICA7OyBwb3NzaWJsZS4gIEFsc28gaWdub3JlIGxpbmUgYnJlYWtzIGFuZCBzdGF0aXN0aWNz IGNvb2tpZXMuCiAgICAgICh0YWJsZS1jZWxsIGV4cG9ydC1zbmlwcGV0IGZvb3Rub3RlLXJlZmVy ZW5jZSBsYXRleC1vci1lbnRpdHkgbGluayBtYWNybwoJCSAgcmFkaW8tdGFyZ2V0IHN1Yi9zdXBl cnNjcmlwdCB0YXJnZXQgdGV4dC1tYXJrdXAgdGltZXN0YW1wKQogICAgICAodGFibGUtcm93IHRh YmxlLWNlbGwpCiAgICAgICh1bmRlcmxpbmUgLEBzdGFuZGFyZC1zZXQpCiAgICAgICh2ZXJzZS1i bG9jayAsQHN0YW5kYXJkLXNldCkpKQogICJBbGlzdCBvZiBvYmplY3RzIHJlc3RyaWN0aW9ucy4K CkNBUiBpcyBhbiBlbGVtZW50IG9yIG9iamVjdCB0eXBlIGNvbnRhaW5pbmcgb2JqZWN0cyBhbmQg Q0RSIGlzCmEgbGlzdCBvZiBzdWNjZXNzb3JzIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2l0aGluIGFu IGVsZW1lbnQgb3IKb2JqZWN0IG9mIHN1Y2ggdHlwZS4KCkZvciBleGFtcGxlLCBpbiBhIGByYWRp by10YXJnZXQnIG9iamVjdCwgb25lIGNhbiBvbmx5IGZpbmQKZW50aXRpZXMsIGxhdGV4LWZyYWdt ZW50cywgc3Vic2NyaXB0IGFuZCBzdXBlcnNjcmlwdC4KClRoaXMgYWxpc3QgYWxzbyBhcHBsaWVz IHRvIHNlY29uZGFyeSBzdHJpbmcuICBGb3IgZXhhbXBsZSwgYW4KYGhlYWRsaW5lJyB0eXBlIGVs ZW1lbnQgZG9lc24ndCBkaXJlY3RseSBjb250YWluIG9iamVjdHMsIGJ1dApzdGlsbCBoYXMgYW4g ZW50cnkgc2luY2Ugb25lIG9mIGl0cyBwcm9wZXJ0aWVzIChgOnRpdGxlJykgZG9lcy4iKQoKKGRl ZmNvbnN0IG9yZy1lbGVtZW50LXNlY29uZGFyeS12YWx1ZS1hbGlzdAogICcoKGhlYWRsaW5lIC4g OnRpdGxlKQogICAgKGlubGluZXRhc2sgLiA6dGl0bGUpCiAgICAoaXRlbSAuIDp0YWcpCiAgICAo Zm9vdG5vdGUtcmVmZXJlbmNlIC4gOmlubGluZS1kZWZpbml0aW9uKSkKICAiQWxpc3QgYmV0d2Vl biBlbGVtZW50IHR5cGVzIGFuZCBsb2NhdGlvbiBvZiBzZWNvbmRhcnkgdmFsdWUuIikKCihkZWZj b25zdCBvcmctZWxlbWVudC1vYmplY3QtdmFyaWFibGVzICcob3JnLWxpbmstYWJicmV2LWFsaXN0 LWxvY2FsKQogICJMaXN0IG9mIGJ1ZmZlci1sb2NhbCB2YXJpYWJsZXMgdXNlZCB3aGVuIHBhcnNp bmcgb2JqZWN0cy4KVGhlc2UgdmFyaWFibGVzIGFyZSBjb3BpZWQgdG8gdGhlIHRlbXBvcmFyeSBi dWZmZXIgY3JlYXRlZCBieQpgb3JnLWV4cG9ydC1zZWNvbmRhcnktc3RyaW5nJy4iKQoKCiMrZW5k X3NyYwoKKiBBY2Nlc3NvcnMgYW5kIFNldHRlcnMKClByb3ZpZGUgZm91ciBhY2Nlc3NvcnM6IGBv cmctZWxlbWVudC10eXBlJywgYG9yZy1lbGVtZW50LXByb3BlcnR5Jwpgb3JnLWVsZW1lbnQtY29u dGVudHMnIGFuZCBgb3JnLWVsZW1lbnQtcmVzdHJpY3Rpb24nLgoKU2V0dGVyIGZ1bmN0aW9ucyBh bGxvdyB0byBtb2RpZnkgZWxlbWVudHMgYnkgc2lkZSBlZmZlY3QuICBUaGVyZSBpcwpgb3JnLWVs ZW1lbnQtcHV0LXByb3BlcnR5JywgYG9yZy1lbGVtZW50LXNldC1jb250ZW50cycsCmBvcmctZWxl bWVudC1zZXQtZWxlbWVudCcgYW5kIGBvcmctZWxlbWVudC1hZG9wdC1lbGVtZW50Jy4gIE5vdGUK dGhhdCBgb3JnLWVsZW1lbnQtc2V0LWVsZW1lbnQnIGFuZCBgb3JnLWVsZW1lbnQtYWRvcHQtZWxl bWVudHMnIGFyZQpoaWdoZXIgbGV2ZWwgZnVuY3Rpb25zIHNpbmNlIGFsc28gdXBkYXRlIGA6cGFy ZW50JyBwcm9wZXJ0eS4KCiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnN1YnN0IG9yZy1lbGVt ZW50LXR5cGUgKGVsZW1lbnQpCiAgIlJldHVybiB0eXBlIG9mIEVMRU1FTlQuCgpUaGUgZnVuY3Rp b24gcmV0dXJucyB0aGUgdHlwZSBvZiB0aGUgZWxlbWVudCBvciBvYmplY3QgcHJvdmlkZWQuCkl0 IGNhbiBhbHNvIHJldHVybiB0aGUgZm9sbG93aW5nIHNwZWNpYWwgdmFsdWU6CiAgYHBsYWluLXRl eHQnICAgICAgIGZvciBhIHN0cmluZwogIGBvcmctZGF0YScgICAgICAgICBmb3IgYSBjb21wbGV0 ZSBkb2N1bWVudAogIG5pbCAgICAgICAgICAgICAgICBpbiBhbnkgb3RoZXIgY2FzZS4iKQoKKGRl ZnN1YnN0IG9yZy1lbGVtZW50LXByb3BlcnR5IChwcm9wZXJ0eSBlbGVtZW50KQogICJFeHRyYWN0 IHRoZSB2YWx1ZSBmcm9tIHRoZSBQUk9QRVJUWSBvZiBhbiBFTEVNRU5ULiIpCgooZGVmc3Vic3Qg b3JnLWVsZW1lbnQtY29udGVudHMgKGVsZW1lbnQpCiAgIkV4dHJhY3QgY29udGVudHMgZnJvbSBh biBFTEVNRU5ULiIpCgooZGVmc3Vic3Qgb3JnLWVsZW1lbnQtcmVzdHJpY3Rpb24gKGVsZW1lbnQp CiAgIlJldHVybiByZXN0cmljdGlvbiBhc3NvY2lhdGVkIHRvIEVMRU1FTlQuCkVMRU1FTlQgY2Fu IGJlIGFuIGVsZW1lbnQsIGFuIG9iamVjdCBvciBhIHN5bWJvbCByZXByZXNlbnRpbmcgYW4KZWxl bWVudCBvciBvYmplY3QgdHlwZS4iKQoKKGRlZnN1YnN0IG9yZy1lbGVtZW50LXB1dC1wcm9wZXJ0 eSAoZWxlbWVudCBwcm9wZXJ0eSB2YWx1ZSkKICAiSW4gRUxFTUVOVCBzZXQgUFJPUEVSVFkgdG8g VkFMVUUuClJldHVybiBtb2RpZmllZCBlbGVtZW50LiIpCgooZGVmc3Vic3Qgb3JnLWVsZW1lbnQt c2V0LWNvbnRlbnRzIChlbGVtZW50ICZyZXN0IGNvbnRlbnRzKQogICJTZXQgRUxFTUVOVCBjb250 ZW50cyB0byBDT05URU5UUy4KUmV0dXJuIG1vZGlmaWVkIGVsZW1lbnQuIikKCihkZWZzdWJzdCBv cmctZWxlbWVudC1zZXQtZWxlbWVudCAob2xkIG5ldykKICAiUmVwbGFjZSBlbGVtZW50IG9yIG9i amVjdCBPTEQgd2l0aCBlbGVtZW50IG9yIG9iamVjdCBORVcuClRoZSBmdW5jdGlvbiB0YWtlcyBj YXJlIG9mIHNldHRpbmcgYDpwYXJlbnQnIHByb3BlcnR5IGZvciBORVcuIikKCihkZWZzdWJzdCBv cmctZWxlbWVudC1hZG9wdC1lbGVtZW50cyAocGFyZW50ICZyZXN0IGNoaWxkcmVuKQogICJBcHBl bmQgZWxlbWVudHMgdG8gdGhlIGNvbnRlbnRzIG9mIGFub3RoZXIgZWxlbWVudC4KClBBUkVOVCBp cyBhbiBlbGVtZW50IG9yIG9iamVjdC4gIENISUxEUkVOIGNhbiBiZSBlbGVtZW50cywKb2JqZWN0 cywgb3IgYSBzdHJpbmdzLgoKVGhlIGZ1bmN0aW9uIHRha2VzIGNhcmUgb2Ygc2V0dGluZyBgOnBh cmVudCcgcHJvcGVydHkgZm9yIENISUxELgpSZXR1cm4gcGFyZW50IGVsZW1lbnQuIikKCgojK2Vu ZF9zcmMKCiogR3JlYXRlciBlbGVtZW50cwoKRm9yIGVhY2ggZ3JlYXRlciBlbGVtZW50IHR5cGUs IHdlIGRlZmluZSBhIHBhcnNlciBhbmQgYW4KaW50ZXJwcmV0ZXIuCgpBIHBhcnNlciByZXR1cm5z IHRoZSBlbGVtZW50IG9yIG9iamVjdCBhcyB0aGUgbGlzdCBkZXNjcmliZWQgYWJvdmUuCk1vc3Qg b2YgdGhlbSBhY2NlcHRzIG5vIGFyZ3VtZW50LiAgVGhvdWdoLCBleGNlcHRpb25zIGV4aXN0LiAg SGVuY2UKZXZlcnkgZWxlbWVudCBjb250YWluaW5nIGEgc2Vjb25kYXJ5IHN0cmluZyAoc2VlCmBv cmctZWxlbWVudC1zZWNvbmRhcnktdmFsdWUtYWxpc3QnKSB3aWxsIGFjY2VwdCBhbiBvcHRpb25h bAphcmd1bWVudCB0byB0b2dnbGUgcGFyc2luZyBvZiB0aGF0IHNlY29uZGFyeSBzdHJpbmcuICBN b3Jlb3ZlciwKYGl0ZW0nIHBhcnNlciByZXF1aXJlcyBjdXJyZW50IGxpc3QncyBzdHJ1Y3R1cmUg YXMgaXRzIGZpcnN0CmVsZW1lbnQuCgpBbiBpbnRlcnByZXRlciBhY2NlcHRzIHR3byBhcmd1bWVu dHM6IHRoZSBsaXN0IHJlcHJlc2VudGF0aW9uIG9mCnRoZSBlbGVtZW50IG9yIG9iamVjdCwgYW5k IGl0cyBjb250ZW50cy4gIFRoZSBsYXR0ZXIgbWF5IGJlIG5pbCwKZGVwZW5kaW5nIG9uIHRoZSBl bGVtZW50IG9yIG9iamVjdCBjb25zaWRlcmVkLiAgSXQgcmV0dXJucyB0aGUKYXBwcm9wcmlhdGUg T3JnIHN5bnRheCwgYXMgYSBzdHJpbmcuCgpQYXJzaW5nIGZ1bmN0aW9ucyBtdXN0IGZvbGxvdyB0 aGUgbmFtaW5nIGNvbnZlbnRpb246Cm9yZy1lbGVtZW50LVRZUEUtcGFyc2VyLCB3aGVyZSBUWVBF IGlzIGdyZWF0ZXIgZWxlbWVudCdzIHR5cGUsIGFzCmRlZmluZWQgaW4gYG9yZy1lbGVtZW50LWdy ZWF0ZXItZWxlbWVudHMnLgoKU2ltaWxhcmx5LCBpbnRlcnByZXRpbmcgZnVuY3Rpb25zIG11c3Qg Zm9sbG93IHRoZSBuYW1pbmcKY29udmVudGlvbjogb3JnLWVsZW1lbnQtVFlQRS1pbnRlcnByZXRl ci4KCldpdGggdGhlIGV4Y2VwdGlvbiBvZiBgaGVhZGxpbmUnIGFuZCBgaXRlbScgdHlwZXMsIGdy ZWF0ZXIgZWxlbWVudHMKY2Fubm90IGNvbnRhaW4gb3RoZXIgZ3JlYXRlciBlbGVtZW50cyBvZiB0 aGVpciBvd24gdHlwZS4KCkJlc2lkZSBpbXBsZW1lbnRpbmcgYSBwYXJzZXIgYW5kIGFuIGludGVy cHJldGVyLCBhZGRpbmcgYSBuZXcKZ3JlYXRlciBlbGVtZW50IHJlcXVpcmVzIHRvIHR3ZWFrIGBv cmctZWxlbWVudC0tY3VycmVudC1lbGVtZW50Jy4KTW9yZW92ZXIsIHRoZSBuZXdseSBkZWZpbmVk IHR5cGUgbXVzdCBiZSBhZGRlZCB0byBib3RoCmBvcmctZWxlbWVudC1hbGwtZWxlbWVudHMnIGFu ZCBgb3JnLWVsZW1lbnQtZ3JlYXRlci1lbGVtZW50cycuCgoKKiogQ2VudGVyIEJsb2NrCgojK2Jl Z2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBvcmctZWxlbWVudC1jZW50ZXItYmxvY2stcGFyc2Vy IChsaW1pdCBhZmZpbGlhdGVkKQogICJQYXJzZSBhIGNlbnRlciBibG9jay4KCkxJTUlUIGJvdW5k cyB0aGUgc2VhcmNoLiAgQUZGSUxJQVRFRCBpcyBhIGxpc3Qgb2Ygd2hpY2ggQ0FSIGlzCnRoZSBi dWZmZXIgcG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZmlyc3QgYWZmaWxpYXRlZApr ZXl3b3JkIGFuZCBDRFIgaXMgYSBwbGlzdCBvZiBhZmZpbGlhdGVkIGtleXdvcmRzIGFsb25nIHdp dGgKdGhlaXIgdmFsdWUuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgY2VudGVyLWJsb2Nr JyBhbmQgQ0RSIGlzIGEgcGxpc3QKY29udGFpbmluZyBgOmJlZ2luJywgYDplbmQnLCBgOmhpZGRl bnAnLCBgOmNvbnRlbnRzLWJlZ2luJywKYDpjb250ZW50cy1lbmQnLCBgOnBvc3QtYmxhbmsnIGFu ZCBgOnBvc3QtYWZmaWxpYXRlZCcga2V5d29yZHMuCgpBc3N1bWUgcG9pbnQgaXMgYXQgdGhlIGJl Z2lubmluZyBvZiB0aGUgYmxvY2suIikKCihkZWZ1biBvcmctZWxlbWVudC1jZW50ZXItYmxvY2st aW50ZXJwcmV0ZXIgKGNlbnRlci1ibG9jayBjb250ZW50cykKICAiSW50ZXJwcmV0IENFTlRFUi1C TE9DSyBlbGVtZW50IGFzIE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIHRoZSBjb250ZW50cyBvZiB0 aGUgZWxlbWVudC4iKQoKIytlbmRfc3JjCgoqKiBEcmF3ZXIKCiMrYmVnaW5fc3JjIGVtYWNzLWxp c3AKKGRlZnVuIG9yZy1lbGVtZW50LWRyYXdlci1wYXJzZXIgKGxpbWl0IGFmZmlsaWF0ZWQpCiAg IlBhcnNlIGEgZHJhd2VyLgoKTElNSVQgYm91bmRzIHRoZSBzZWFyY2guICBBRkZJTElBVEVEIGlz IGEgbGlzdCBvZiB3aGljaCBDQVIgaXMKdGhlIGJ1ZmZlciBwb3NpdGlvbiBhdCB0aGUgYmVnaW5u aW5nIG9mIHRoZSBmaXJzdCBhZmZpbGlhdGVkCmtleXdvcmQgYW5kIENEUiBpcyBhIHBsaXN0IG9m IGFmZmlsaWF0ZWQga2V5d29yZHMgYWxvbmcgd2l0aAp0aGVpciB2YWx1ZS4KClJldHVybiBhIGxp c3Qgd2hvc2UgQ0FSIGlzIGBkcmF3ZXInIGFuZCBDRFIgaXMgYSBwbGlzdCBjb250YWluaW5nCmA6 ZHJhd2VyLW5hbWUnLCBgOmJlZ2luJywgYDplbmQnLCBgOmhpZGRlbnAnLCBgOmNvbnRlbnRzLWJl Z2luJywKYDpjb250ZW50cy1lbmQnLCBgOnBvc3QtYmxhbmsnIGFuZCBgOnBvc3QtYWZmaWxpYXRl ZCcga2V5d29yZHMuCgpBc3N1bWUgcG9pbnQgaXMgYXQgYmVnaW5uaW5nIG9mIGRyYXdlci4iKQoK KGRlZnVuIG9yZy1lbGVtZW50LWRyYXdlci1pbnRlcnByZXRlciAoZHJhd2VyIGNvbnRlbnRzKQog ICJJbnRlcnByZXQgRFJBV0VSIGVsZW1lbnQgYXMgT3JnIHN5bnRheC4KQ09OVEVOVFMgaXMgdGhl IGNvbnRlbnRzIG9mIHRoZSBlbGVtZW50LiIpCgojK2VuZF9zcmMKCioqIER5bmFtaWMgQmxvY2sK CiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9yZy1lbGVtZW50LWR5bmFtaWMtYmxvY2st cGFyc2VyIChsaW1pdCBhZmZpbGlhdGVkKQogICJQYXJzZSBhIGR5bmFtaWMgYmxvY2suCgpMSU1J VCBib3VuZHMgdGhlIHNlYXJjaC4gIEFGRklMSUFURUQgaXMgYSBsaXN0IG9mIHdoaWNoIENBUiBp cwp0aGUgYnVmZmVyIHBvc2l0aW9uIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpcnN0IGFmZmls aWF0ZWQKa2V5d29yZCBhbmQgQ0RSIGlzIGEgcGxpc3Qgb2YgYWZmaWxpYXRlZCBrZXl3b3JkcyBh bG9uZyB3aXRoCnRoZWlyIHZhbHVlLgoKUmV0dXJuIGEgbGlzdCB3aG9zZSBDQVIgaXMgYGR5bmFt aWMtYmxvY2snIGFuZCBDRFIgaXMgYSBwbGlzdApjb250YWluaW5nIGA6YmxvY2stbmFtZScsIGA6 YmVnaW4nLCBgOmVuZCcsIGA6aGlkZGVucCcsCmA6Y29udGVudHMtYmVnaW4nLCBgOmNvbnRlbnRz LWVuZCcsIGA6YXJndW1lbnRzJywgYDpwb3N0LWJsYW5rJwphbmQgYDpwb3N0LWFmZmlsaWF0ZWQn IGtleXdvcmRzLgoKQXNzdW1lIHBvaW50IGlzIGF0IGJlZ2lubmluZyBvZiBkeW5hbWljIGJsb2Nr LiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtZHluYW1pYy1ibG9jay1pbnRlcnByZXRlciAoZHluYW1p Yy1ibG9jayBjb250ZW50cykKICAiSW50ZXJwcmV0IERZTkFNSUMtQkxPQ0sgZWxlbWVudCBhcyBP cmcgc3ludGF4LgpDT05URU5UUyBpcyB0aGUgY29udGVudHMgb2YgdGhlIGVsZW1lbnQuIikKCiMr ZW5kX3NyYwoKKiogRm9vdG5vdGUgRGVmaW5pdGlvbgoKIytiZWdpbl9zcmMgZW1hY3MtbGlzcAoo ZGVmdW4gb3JnLWVsZW1lbnQtZm9vdG5vdGUtZGVmaW5pdGlvbi1wYXJzZXIgKGxpbWl0IGFmZmls aWF0ZWQpCiAgIlBhcnNlIGEgZm9vdG5vdGUgZGVmaW5pdGlvbi4KCkxJTUlUIGJvdW5kcyB0aGUg c2VhcmNoLiAgQUZGSUxJQVRFRCBpcyBhIGxpc3Qgb2Ygd2hpY2ggQ0FSIGlzCnRoZSBidWZmZXIg cG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZmlyc3QgYWZmaWxpYXRlZAprZXl3b3Jk IGFuZCBDRFIgaXMgYSBwbGlzdCBvZiBhZmZpbGlhdGVkIGtleXdvcmRzIGFsb25nIHdpdGgKdGhl aXIgdmFsdWUuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgZm9vdG5vdGUtZGVmaW5pdGlv bicgYW5kIENEUiBpcwphIHBsaXN0IGNvbnRhaW5pbmcgYDpsYWJlbCcsIGA6YmVnaW4nIGA6ZW5k JywgYDpjb250ZW50cy1iZWdpbicsCmA6Y29udGVudHMtZW5kJywgYDpwb3N0LWJsYW5rJyBhbmQg YDpwb3N0LWFmZmlsaWF0ZWQnIGtleXdvcmRzLgoKQXNzdW1lIHBvaW50IGlzIGF0IHRoZSBiZWdp bm5pbmcgb2YgdGhlIGZvb3Rub3RlIGRlZmluaXRpb24uIikKCihkZWZ1biBvcmctZWxlbWVudC1m b290bm90ZS1kZWZpbml0aW9uLWludGVycHJldGVyIChmb290bm90ZS1kZWZpbml0aW9uIGNvbnRl bnRzKQogICJJbnRlcnByZXQgRk9PVE5PVEUtREVGSU5JVElPTiBlbGVtZW50IGFzIE9yZyBzeW50 YXguCkNPTlRFTlRTIGlzIHRoZSBjb250ZW50cyBvZiB0aGUgZm9vdG5vdGUtZGVmaW5pdGlvbi4i KQoKIytlbmRfc3JjCgoqKiBIZWFkbGluZQoKIytiZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVmdW4g b3JnLWVsZW1lbnQtaGVhZGxpbmUtcGFyc2VyIChsaW1pdCAmb3B0aW9uYWwgcmF3LXNlY29uZGFy eS1wKQogICJQYXJzZSBhIGhlYWRsaW5lLgoKUmV0dXJuIGEgbGlzdCB3aG9zZSBDQVIgaXMgYGhl YWRsaW5lJyBhbmQgQ0RSIGlzIGEgcGxpc3QKY29udGFpbmluZyBgOnJhdy12YWx1ZScsIGA6dGl0 bGUnLCBgOmFsdC10aXRsZScsIGA6YmVnaW4nLApgOmVuZCcsIGA6cHJlLWJsYW5rJywgYDpoaWRk ZW5wJywgYDpjb250ZW50cy1iZWdpbicgYW5kCmA6Y29udGVudHMtZW5kJywgYDpsZXZlbCcsIGA6 cHJpb3JpdHknLCBgOnRhZ3MnLApgOnRvZG8ta2V5d29yZCcsYDp0b2RvLXR5cGUnLCBgOnNjaGVk dWxlZCcsIGA6ZGVhZGxpbmUnLApgOmNsb3NlZCcsIGA6cXVvdGVkcCcsIGA6YXJjaGl2ZWRwJywg YDpjb21tZW50ZWRwJyBhbmQKYDpmb290bm90ZS1zZWN0aW9uLXAnIGtleXdvcmRzLgoKVGhlIHBs aXN0IGFsc28gY29udGFpbnMgYW55IHByb3BlcnR5IHNldCBpbiB0aGUgcHJvcGVydHkgZHJhd2Vy LAp3aXRoIGl0cyBuYW1lIGluIHVwcGVyIGNhc2VzIGFuZCBjb2xvbnMgYWRkZWQgYXQgdGhlCmJl Z2lubmluZyAoaS5lLiBgOkNVU1RPTV9JRCcpLgoKV2hlbiBSQVctU0VDT05EQVJZLVAgaXMgbm9u LW5pbCwgaGVhZGxpbmUncyB0aXRsZSB3aWxsIG5vdCBiZQpwYXJzZWQgYXMgYSBzZWNvbmRhcnkg c3RyaW5nLCBidXQgYXMgYSBwbGFpbiBzdHJpbmcgaW5zdGVhZC4KCkFzc3VtZSBwb2ludCBpcyBh dCBiZWdpbm5pbmcgb2YgdGhlIGhlYWRsaW5lLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtaGVhZGxp bmUtaW50ZXJwcmV0ZXIgKGhlYWRsaW5lIGNvbnRlbnRzKQogICJJbnRlcnByZXQgSEVBRExJTkUg ZWxlbWVudCBhcyBPcmcgc3ludGF4LgpDT05URU5UUyBpcyB0aGUgY29udGVudHMgb2YgdGhlIGVs ZW1lbnQuIikKCiMrZW5kX3NyYwoKKiogSW5saW5ldGFzawoKIytiZWdpbl9zcmMgZW1hY3MtbGlz cAooZGVmdW4gb3JnLWVsZW1lbnQtaW5saW5ldGFzay1wYXJzZXIgKGxpbWl0ICZvcHRpb25hbCBy YXctc2Vjb25kYXJ5LXApCiAgIlBhcnNlIGFuIGlubGluZSB0YXNrLgoKUmV0dXJuIGEgbGlzdCB3 aG9zZSBDQVIgaXMgYGlubGluZXRhc2snIGFuZCBDRFIgaXMgYSBwbGlzdApjb250YWluaW5nIGA6 dGl0bGUnLCBgOmJlZ2luJywgYDplbmQnLCBgOmhpZGRlbnAnLApgOmNvbnRlbnRzLWJlZ2luJyBh bmQgYDpjb250ZW50cy1lbmQnLCBgOmxldmVsJywgYDpwcmlvcml0eScsCmA6cmF3LXZhbHVlJywg YDp0YWdzJywgYDp0b2RvLWtleXdvcmQnLCBgOnRvZG8tdHlwZScsCmA6c2NoZWR1bGVkJywgYDpk ZWFkbGluZScsIGA6Y2xvc2VkJyBhbmQgYDpwb3N0LWJsYW5rJyBrZXl3b3Jkcy4KClRoZSBwbGlz dCBhbHNvIGNvbnRhaW5zIGFueSBwcm9wZXJ0eSBzZXQgaW4gdGhlIHByb3BlcnR5IGRyYXdlciwK d2l0aCBpdHMgbmFtZSBpbiB1cHBlciBjYXNlcyBhbmQgY29sb25zIGFkZGVkIGF0IHRoZQpiZWdp bm5pbmcgKGkuZS4gYDpDVVNUT01fSUQnKS4KCldoZW4gb3B0aW9uYWwgYXJndW1lbnQgUkFXLVNF Q09OREFSWS1QIGlzIG5vbi1uaWwsIGlubGluZS10YXNrJ3MKdGl0bGUgd2lsbCBub3QgYmUgcGFy c2VkIGFzIGEgc2Vjb25kYXJ5IHN0cmluZywgYnV0IGFzIGEgcGxhaW4Kc3RyaW5nIGluc3RlYWQu CgpBc3N1bWUgcG9pbnQgaXMgYXQgYmVnaW5uaW5nIG9mIHRoZSBpbmxpbmUgdGFzay4iKQoKKGRl ZnVuIG9yZy1lbGVtZW50LWlubGluZXRhc2staW50ZXJwcmV0ZXIgKGlubGluZXRhc2sgY29udGVu dHMpCiAgIkludGVycHJldCBJTkxJTkVUQVNLIGVsZW1lbnQgYXMgT3JnIHN5bnRheC4KQ09OVEVO VFMgaXMgdGhlIGNvbnRlbnRzIG9mIGlubGluZXRhc2suIikKCiMrZW5kX3NyYwoKKiogSXRlbQoK IytiZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVmdW4gb3JnLWVsZW1lbnQtaXRlbS1wYXJzZXIgKGxp bWl0IHN0cnVjdCAmb3B0aW9uYWwgcmF3LXNlY29uZGFyeS1wKQogICJQYXJzZSBhbiBpdGVtLgoK U1RSVUNUIGlzIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIHBsYWluIGxpc3QuCgpSZXR1cm4gYSBsaXN0 IHdob3NlIENBUiBpcyBgaXRlbScgYW5kIENEUiBpcyBhIHBsaXN0IGNvbnRhaW5pbmcKYDpidWxs ZXQnLCBgOmJlZ2luJywgYDplbmQnLCBgOmNvbnRlbnRzLWJlZ2luJywgYDpjb250ZW50cy1lbmQn LApgOmNoZWNrYm94JywgYDpjb3VudGVyJywgYDp0YWcnLCBgOnN0cnVjdHVyZScsIGA6aGlkZGVu cCcgYW5kCmA6cG9zdC1ibGFuaycga2V5d29yZHMuCgpXaGVuIG9wdGlvbmFsIGFyZ3VtZW50IFJB Vy1TRUNPTkRBUlktUCBpcyBub24tbmlsLCBpdGVtJ3MgdGFnLCBpZgphbnksIHdpbGwgbm90IGJl IHBhcnNlZCBhcyBhIHNlY29uZGFyeSBzdHJpbmcsIGJ1dCBhcyBhIHBsYWluCnN0cmluZyBpbnN0 ZWFkLgoKQXNzdW1lIHBvaW50IGlzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGl0ZW0uIikKCihk ZWZ1biBvcmctZWxlbWVudC1pdGVtLWludGVycHJldGVyIChpdGVtIGNvbnRlbnRzKQogICJJbnRl cnByZXQgSVRFTSBlbGVtZW50IGFzIE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIHRoZSBjb250ZW50 cyBvZiB0aGUgZWxlbWVudC4iKQoKIytlbmRfc3JjCgoqKiBQbGFpbiBMaXN0CgojK2JlZ2luX3Ny YyBlbWFjcy1saXNwCihkZWZ1biBvcmctZWxlbWVudC1wbGFpbi1saXN0LXBhcnNlciAobGltaXQg YWZmaWxpYXRlZCBzdHJ1Y3R1cmUpCiAgIlBhcnNlIGEgcGxhaW4gbGlzdC4KCkxJTUlUIGJvdW5k cyB0aGUgc2VhcmNoLiAgQUZGSUxJQVRFRCBpcyBhIGxpc3Qgb2Ygd2hpY2ggQ0FSIGlzCnRoZSBi dWZmZXIgcG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZmlyc3QgYWZmaWxpYXRlZApr ZXl3b3JkIGFuZCBDRFIgaXMgYSBwbGlzdCBvZiBhZmZpbGlhdGVkIGtleXdvcmRzIGFsb25nIHdp dGgKdGhlaXIgdmFsdWUuICBTVFJVQ1RVUkUgaXMgdGhlIHN0cnVjdHVyZSBvZiB0aGUgcGxhaW4g bGlzdCBiZWluZwpwYXJzZWQuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgcGxhaW4tbGlz dCcgYW5kIENEUiBpcyBhIHBsaXN0CmNvbnRhaW5pbmcgYDp0eXBlJywgYDpiZWdpbicsIGA6ZW5k JywgYDpjb250ZW50cy1iZWdpbicgYW5kCmA6Y29udGVudHMtZW5kJywgYDpzdHJ1Y3R1cmUnLCBg OnBvc3QtYmxhbmsnIGFuZApgOnBvc3QtYWZmaWxpYXRlZCcga2V5d29yZHMuCgpBc3N1bWUgcG9p bnQgaXMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlzdC4iKQoKKGRlZnVuIG9yZy1lbGVtZW50 LXBsYWluLWxpc3QtaW50ZXJwcmV0ZXIgKHBsYWluLWxpc3QgY29udGVudHMpCiAgIkludGVycHJl dCBQTEFJTi1MSVNUIGVsZW1lbnQgYXMgT3JnIHN5bnRheC4KQ09OVEVOVFMgaXMgdGhlIGNvbnRl bnRzIG9mIHRoZSBlbGVtZW50LiIpCgojK2VuZF9zcmMKCioqIFByb3BlcnR5IERyYXdlcgoKIyti ZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVmdW4gb3JnLWVsZW1lbnQtcHJvcGVydHktZHJhd2VyLXBh cnNlciAobGltaXQgYWZmaWxpYXRlZCkKICAiUGFyc2UgYSBwcm9wZXJ0eSBkcmF3ZXIuCgpMSU1J VCBib3VuZHMgdGhlIHNlYXJjaC4gIEFGRklMSUFURUQgaXMgYSBsaXN0IG9mIHdoaWNoIENBUiBp cwp0aGUgYnVmZmVyIHBvc2l0aW9uIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpcnN0IGFmZmls aWF0ZWQKa2V5d29yZCBhbmQgQ0RSIGlzIGEgcGxpc3Qgb2YgYWZmaWxpYXRlZCBrZXl3b3JkcyBh bG9uZyB3aXRoCnRoZWlyIHZhbHVlLgoKUmV0dXJuIGEgbGlzdCB3aG9zZSBDQVIgaXMgYHByb3Bl cnR5LWRyYXdlcicgYW5kIENEUiBpcyBhIHBsaXN0CmNvbnRhaW5pbmcgYDpiZWdpbicsIGA6ZW5k JywgYDpoaWRkZW5wJywgYDpjb250ZW50cy1iZWdpbicsCmA6Y29udGVudHMtZW5kJywgYDpwb3N0 LWJsYW5rJyBhbmQgYDpwb3N0LWFmZmlsaWF0ZWQnIGtleXdvcmRzLgoKQXNzdW1lIHBvaW50IGlz IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHByb3BlcnR5IGRyYXdlci4iKQoKKGRlZnVuIG9yZy1l bGVtZW50LXByb3BlcnR5LWRyYXdlci1pbnRlcnByZXRlciAocHJvcGVydHktZHJhd2VyIGNvbnRl bnRzKQogICJJbnRlcnByZXQgUFJPUEVSVFktRFJBV0VSIGVsZW1lbnQgYXMgT3JnIHN5bnRheC4K Q09OVEVOVFMgaXMgdGhlIHByb3BlcnRpZXMgd2l0aGluIHRoZSBkcmF3ZXIuIikKCiMrZW5kX3Ny YwoKKiogUXVvdGUgQmxvY2sKCiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9yZy1lbGVt ZW50LXF1b3RlLWJsb2NrLXBhcnNlciAobGltaXQgYWZmaWxpYXRlZCkKICAiUGFyc2UgYSBxdW90 ZSBibG9jay4KCkxJTUlUIGJvdW5kcyB0aGUgc2VhcmNoLiAgQUZGSUxJQVRFRCBpcyBhIGxpc3Qg b2Ygd2hpY2ggQ0FSIGlzCnRoZSBidWZmZXIgcG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0 aGUgZmlyc3QgYWZmaWxpYXRlZAprZXl3b3JkIGFuZCBDRFIgaXMgYSBwbGlzdCBvZiBhZmZpbGlh dGVkIGtleXdvcmRzIGFsb25nIHdpdGgKdGhlaXIgdmFsdWUuCgpSZXR1cm4gYSBsaXN0IHdob3Nl IENBUiBpcyBgcXVvdGUtYmxvY2snIGFuZCBDRFIgaXMgYSBwbGlzdApjb250YWluaW5nIGA6YmVn aW4nLCBgOmVuZCcsIGA6aGlkZGVucCcsIGA6Y29udGVudHMtYmVnaW4nLApgOmNvbnRlbnRzLWVu ZCcsIGA6cG9zdC1ibGFuaycgYW5kIGA6cG9zdC1hZmZpbGlhdGVkJyBrZXl3b3Jkcy4KCkFzc3Vt ZSBwb2ludCBpcyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBibG9jay4iKQoKKGRlZnVuIG9yZy1l bGVtZW50LXF1b3RlLWJsb2NrLWludGVycHJldGVyIChxdW90ZS1ibG9jayBjb250ZW50cykKICAi SW50ZXJwcmV0IFFVT1RFLUJMT0NLIGVsZW1lbnQgYXMgT3JnIHN5bnRheC4KQ09OVEVOVFMgaXMg dGhlIGNvbnRlbnRzIG9mIHRoZSBlbGVtZW50LiIpCgojK2VuZF9zcmMKCioqIFNlY3Rpb24KCiMr YmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9yZy1lbGVtZW50LXNlY3Rpb24tcGFyc2VyIChs aW1pdCkKICAiUGFyc2UgYSBzZWN0aW9uLgoKTElNSVQgYm91bmRzIHRoZSBzZWFyY2guCgpSZXR1 cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgc2VjdGlvbicgYW5kIENEUiBpcyBhIHBsaXN0CmNvbnRh aW5pbmcgYDpiZWdpbicsIGA6ZW5kJywgYDpjb250ZW50cy1iZWdpbicsIGBjb250ZW50cy1lbmQn CmFuZCBgOnBvc3QtYmxhbmsnIGtleXdvcmRzLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtc2VjdGlv bi1pbnRlcnByZXRlciAoc2VjdGlvbiBjb250ZW50cykKICAiSW50ZXJwcmV0IFNFQ1RJT04gZWxl bWVudCBhcyBPcmcgc3ludGF4LgpDT05URU5UUyBpcyB0aGUgY29udGVudHMgb2YgdGhlIGVsZW1l bnQuIgogKQoKIytlbmRfc3JjCgoqKiBTcGVjaWFsIEJsb2NrCgojK2JlZ2luX3NyYyBlbWFjcy1s aXNwCihkZWZ1biBvcmctZWxlbWVudC1zcGVjaWFsLWJsb2NrLXBhcnNlciAobGltaXQgYWZmaWxp YXRlZCkKICAiUGFyc2UgYSBzcGVjaWFsIGJsb2NrLgoKTElNSVQgYm91bmRzIHRoZSBzZWFyY2gu ICBBRkZJTElBVEVEIGlzIGEgbGlzdCBvZiB3aGljaCBDQVIgaXMKdGhlIGJ1ZmZlciBwb3NpdGlv biBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmaXJzdCBhZmZpbGlhdGVkCmtleXdvcmQgYW5kIENE UiBpcyBhIHBsaXN0IG9mIGFmZmlsaWF0ZWQga2V5d29yZHMgYWxvbmcgd2l0aAp0aGVpciB2YWx1 ZS4KClJldHVybiBhIGxpc3Qgd2hvc2UgQ0FSIGlzIGBzcGVjaWFsLWJsb2NrJyBhbmQgQ0RSIGlz IGEgcGxpc3QKY29udGFpbmluZyBgOnR5cGUnLCBgOmJlZ2luJywgYDplbmQnLCBgOmhpZGRlbnAn LApgOmNvbnRlbnRzLWJlZ2luJywgYDpjb250ZW50cy1lbmQnLCBgOnBvc3QtYmxhbmsnIGFuZApg OnBvc3QtYWZmaWxpYXRlZCcga2V5d29yZHMuCgpBc3N1bWUgcG9pbnQgaXMgYXQgdGhlIGJlZ2lu bmluZyBvZiB0aGUgYmxvY2suIikKCihkZWZ1biBvcmctZWxlbWVudC1zcGVjaWFsLWJsb2NrLWlu dGVycHJldGVyIChzcGVjaWFsLWJsb2NrIGNvbnRlbnRzKQogICJJbnRlcnByZXQgU1BFQ0lBTC1C TE9DSyBlbGVtZW50IGFzIE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIHRoZSBjb250ZW50cyBvZiB0 aGUgZWxlbWVudC4iKQoKCiMrZW5kX3NyYwoKKiBFbGVtZW50cwoKRm9yIGVhY2ggZWxlbWVudCwg YSBwYXJzZXIgYW5kIGFuIGludGVycHJldGVyIGFyZSBhbHNvIGRlZmluZWQuCkJvdGggZm9sbG93 IHRoZSBzYW1lIG5hbWluZyBjb252ZW50aW9uIHVzZWQgZm9yIGdyZWF0ZXIgZWxlbWVudHMuCgpB bHNvLCBhcyBmb3IgZ3JlYXRlciBlbGVtZW50cywgYWRkaW5nIGEgbmV3IGVsZW1lbnQgdHlwZSBp cyBkb25lCnRocm91Z2ggdGhlIGZvbGxvd2luZyBzdGVwczogaW1wbGVtZW50IGEgcGFyc2VyIGFu ZCBhbiBpbnRlcnByZXRlciwKdHdlYWsgYG9yZy1lbGVtZW50LS1jdXJyZW50LWVsZW1lbnQnIHNv IHRoYXQgaXQgcmVjb2duaXplcyB0aGUgbmV3CnR5cGUgYW5kIGFkZCB0aGF0IG5ldyB0eXBlIHRv IGBvcmctZWxlbWVudC1hbGwtZWxlbWVudHMnLgoKQXMgYSBzcGVjaWFsIGNhc2UsIHdoZW4gdGhl IG5ld2x5IGRlZmluZWQgdHlwZSBpcyBhIGJsb2NrIHR5cGUsCmBvcmctZWxlbWVudC1ibG9jay1u YW1lLWFsaXN0JyBoYXMgdG8gYmUgbW9kaWZpZWQgYWNjb3JkaW5nbHkuCgoKKiogQmFiZWwgQ2Fs bAoKIytiZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVmdW4gb3JnLWVsZW1lbnQtYmFiZWwtY2FsbC1w YXJzZXIgKGxpbWl0IGFmZmlsaWF0ZWQpCiAgIlBhcnNlIGEgYmFiZWwgY2FsbC4KCkxJTUlUIGJv dW5kcyB0aGUgc2VhcmNoLiAgQUZGSUxJQVRFRCBpcyBhIGxpc3Qgb2Ygd2hpY2ggQ0FSIGlzCnRo ZSBidWZmZXIgcG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZmlyc3QgYWZmaWxpYXRl ZAprZXl3b3JkIGFuZCBDRFIgaXMgYSBwbGlzdCBvZiBhZmZpbGlhdGVkIGtleXdvcmRzIGFsb25n IHdpdGgKdGhlaXIgdmFsdWUuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgYmFiZWwtY2Fs bCcgYW5kIENEUiBpcyBhIHBsaXN0CmNvbnRhaW5pbmcgYDpiZWdpbicsIGA6ZW5kJywgYDppbmZv JywgYDpwb3N0LWJsYW5rJyBhbmQKYDpwb3N0LWFmZmlsaWF0ZWQnIGFzIGtleXdvcmRzLiIpCgoo ZGVmdW4gb3JnLWVsZW1lbnQtYmFiZWwtY2FsbC1pbnRlcnByZXRlciAoYmFiZWwtY2FsbCBjb250 ZW50cykKICAiSW50ZXJwcmV0IEJBQkVMLUNBTEwgZWxlbWVudCBhcyBPcmcgc3ludGF4LgpDT05U RU5UUyBpcyBuaWwuIikKCiMrZW5kX3NyYwoKKiogQ2xvY2sKCiMrYmVnaW5fc3JjIGVtYWNzLWxp c3AKKGRlZnVuIG9yZy1lbGVtZW50LWNsb2NrLXBhcnNlciAobGltaXQpCiAgIlBhcnNlIGEgY2xv Y2suCgpMSU1JVCBib3VuZHMgdGhlIHNlYXJjaC4KClJldHVybiBhIGxpc3Qgd2hvc2UgQ0FSIGlz IGBjbG9jaycgYW5kIENEUiBpcyBhIHBsaXN0IGNvbnRhaW5pbmcKYDpzdGF0dXMnLCBgOnZhbHVl JywgYDp0aW1lJywgYDpiZWdpbicsIGA6ZW5kJyBhbmQgYDpwb3N0LWJsYW5rJwphcyBrZXl3b3Jk cy4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LWNsb2NrLWludGVycHJldGVyIChjbG9jayBjb250ZW50 cykKICAiSW50ZXJwcmV0IENMT0NLIGVsZW1lbnQgYXMgT3JnIHN5bnRheC4KQ09OVEVOVFMgaXMg bmlsLiIpCgojK2VuZF9zcmMKCioqIENvbW1lbnQKCiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRl ZnVuIG9yZy1lbGVtZW50LWNvbW1lbnQtcGFyc2VyIChsaW1pdCBhZmZpbGlhdGVkKQogICJQYXJz ZSBhIGNvbW1lbnQuCgpMSU1JVCBib3VuZHMgdGhlIHNlYXJjaC4gIEFGRklMSUFURUQgaXMgYSBs aXN0IG9mIHdoaWNoIENBUiBpcwp0aGUgYnVmZmVyIHBvc2l0aW9uIGF0IHRoZSBiZWdpbm5pbmcg b2YgdGhlIGZpcnN0IGFmZmlsaWF0ZWQKa2V5d29yZCBhbmQgQ0RSIGlzIGEgcGxpc3Qgb2YgYWZm aWxpYXRlZCBrZXl3b3JkcyBhbG9uZyB3aXRoCnRoZWlyIHZhbHVlLgoKUmV0dXJuIGEgbGlzdCB3 aG9zZSBDQVIgaXMgYGNvbW1lbnQnIGFuZCBDRFIgaXMgYSBwbGlzdApjb250YWluaW5nIGA6YmVn aW4nLCBgOmVuZCcsIGA6dmFsdWUnLCBgOnBvc3QtYmxhbmsnLApgOnBvc3QtYWZmaWxpYXRlZCcg a2V5d29yZHMuCgpBc3N1bWUgcG9pbnQgaXMgYXQgY29tbWVudCBiZWdpbm5pbmcuIikKCihkZWZ1 biBvcmctZWxlbWVudC1jb21tZW50LWludGVycHJldGVyIChjb21tZW50IGNvbnRlbnRzKQogICJJ bnRlcnByZXQgQ09NTUVOVCBlbGVtZW50IGFzIE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIG5pbC4i KQoKIytlbmRfc3JjCgoqKiBDb21tZW50IEJsb2NrCgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihk ZWZ1biBvcmctZWxlbWVudC1jb21tZW50LWJsb2NrLXBhcnNlciAobGltaXQgYWZmaWxpYXRlZCkK ICAiUGFyc2UgYW4gZXhwb3J0IGJsb2NrLgoKTElNSVQgYm91bmRzIHRoZSBzZWFyY2guICBBRkZJ TElBVEVEIGlzIGEgbGlzdCBvZiB3aGljaCBDQVIgaXMKdGhlIGJ1ZmZlciBwb3NpdGlvbiBhdCB0 aGUgYmVnaW5uaW5nIG9mIHRoZSBmaXJzdCBhZmZpbGlhdGVkCmtleXdvcmQgYW5kIENEUiBpcyBh IHBsaXN0IG9mIGFmZmlsaWF0ZWQga2V5d29yZHMgYWxvbmcgd2l0aAp0aGVpciB2YWx1ZS4KClJl dHVybiBhIGxpc3Qgd2hvc2UgQ0FSIGlzIGBjb21tZW50LWJsb2NrJyBhbmQgQ0RSIGlzIGEgcGxp c3QKY29udGFpbmluZyBgOmJlZ2luJywgYDplbmQnLCBgOmhpZGRlbnAnLCBgOnZhbHVlJywgYDpw b3N0LWJsYW5rJwphbmQgYDpwb3N0LWFmZmlsaWF0ZWQnIGtleXdvcmRzLgoKQXNzdW1lIHBvaW50 IGlzIGF0IGNvbW1lbnQgYmxvY2sgYmVnaW5uaW5nLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtY29t bWVudC1ibG9jay1pbnRlcnByZXRlciAoY29tbWVudC1ibG9jayBjb250ZW50cykKICAiSW50ZXJw cmV0IENPTU1FTlQtQkxPQ0sgZWxlbWVudCBhcyBPcmcgc3ludGF4LgpDT05URU5UUyBpcyBuaWwu IikKCiMrZW5kX3NyYwoKKiogRGlhcnkgU2V4cAoKIytiZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVm dW4gb3JnLWVsZW1lbnQtZGlhcnktc2V4cC1wYXJzZXIgKGxpbWl0IGFmZmlsaWF0ZWQpCiAgIlBh cnNlIGEgZGlhcnkgc2V4cC4KCkxJTUlUIGJvdW5kcyB0aGUgc2VhcmNoLiAgQUZGSUxJQVRFRCBp cyBhIGxpc3Qgb2Ygd2hpY2ggQ0FSIGlzCnRoZSBidWZmZXIgcG9zaXRpb24gYXQgdGhlIGJlZ2lu bmluZyBvZiB0aGUgZmlyc3QgYWZmaWxpYXRlZAprZXl3b3JkIGFuZCBDRFIgaXMgYSBwbGlzdCBv ZiBhZmZpbGlhdGVkIGtleXdvcmRzIGFsb25nIHdpdGgKdGhlaXIgdmFsdWUuCgpSZXR1cm4gYSBs aXN0IHdob3NlIENBUiBpcyBgZGlhcnktc2V4cCcgYW5kIENEUiBpcyBhIHBsaXN0CmNvbnRhaW5p bmcgYDpiZWdpbicsIGA6ZW5kJywgYDp2YWx1ZScsIGA6cG9zdC1ibGFuaycgYW5kCmA6cG9zdC1h ZmZpbGlhdGVkJyBrZXl3b3Jkcy4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LWRpYXJ5LXNleHAtaW50 ZXJwcmV0ZXIgKGRpYXJ5LXNleHAgY29udGVudHMpCiAgIkludGVycHJldCBESUFSWS1TRVhQIGFz IE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIG5pbC4iKQoKIytlbmRfc3JjCgoqKiBFeGFtcGxlIEJs b2NrCgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBvcmctZWxlbWVudC0tcmVtb3ZlLWlu ZGVudGF0aW9uIChzICZvcHRpb25hbCBuKQogICJSZW1vdmUgbWF4aW11bSBjb21tb24gaW5kZW50 YXRpb24gaW4gc3RyaW5nIFMgYW5kIHJldHVybiBpdC4KV2hlbiBvcHRpb25hbCBhcmd1bWVudCBO IGlzIGEgcG9zaXRpdmUgaW50ZWdlciwgcmVtb3ZlIGV4YWN0bHkKdGhhdCBtdWNoIGNoYXJhY3Rl cnMgZnJvbSBpbmRlbnRhdGlvbiwgaWYgcG9zc2libGUsIG9yIHJldHVybgpTIGFzLWlzIG90aGVy d2lzZS4gIFVubGlrZSB0byBgb3JnLXJlbW92ZS1pbmRlbnRhdGlvbicsIHRoaXMKZnVuY3Rpb24g ZG9lc24ndCBjYWxsIGB1bnRhYmlmeScgb24gUy4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LWV4YW1w bGUtYmxvY2stcGFyc2VyIChsaW1pdCBhZmZpbGlhdGVkKQogICJQYXJzZSBhbiBleGFtcGxlIGJs b2NrLgoKTElNSVQgYm91bmRzIHRoZSBzZWFyY2guICBBRkZJTElBVEVEIGlzIGEgbGlzdCBvZiB3 aGljaCBDQVIgaXMKdGhlIGJ1ZmZlciBwb3NpdGlvbiBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBm aXJzdCBhZmZpbGlhdGVkCmtleXdvcmQgYW5kIENEUiBpcyBhIHBsaXN0IG9mIGFmZmlsaWF0ZWQg a2V5d29yZHMgYWxvbmcgd2l0aAp0aGVpciB2YWx1ZS4KClJldHVybiBhIGxpc3Qgd2hvc2UgQ0FS IGlzIGBleGFtcGxlLWJsb2NrJyBhbmQgQ0RSIGlzIGEgcGxpc3QKY29udGFpbmluZyBgOmJlZ2lu JywgYDplbmQnLCBgOm51bWJlci1saW5lcycsIGA6cHJlc2VydmUtaW5kZW50JywKYDpyZXRhaW4t bGFiZWxzJywgYDp1c2UtbGFiZWxzJywgYDpsYWJlbC1mbXQnLCBgOmhpZGRlbnAnLApgOnN3aXRj aGVzJywgYDp2YWx1ZScsIGA6cG9zdC1ibGFuaycgYW5kIGA6cG9zdC1hZmZpbGlhdGVkJwprZXl3 b3Jkcy4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LXNyYy1ibG9jay1pbnRlcnByZXRlciAoc3JjLWJs b2NrIGNvbnRlbnRzKQogICJJbnRlcnByZXQgU1JDLUJMT0NLIGVsZW1lbnQgYXMgT3JnIHN5bnRh eC4KQ09OVEVOVFMgaXMgbmlsLiIpCgojK2VuZF9zcmMKCioqIFRhYmxlCgojK2JlZ2luX3NyYyBl bWFjcy1saXNwCihkZWZ1biBvcmctZWxlbWVudC10YWJsZS1wYXJzZXIgKGxpbWl0IGFmZmlsaWF0 ZWQpCiAgIlBhcnNlIGEgdGFibGUgYXQgcG9pbnQuCgpMSU1JVCBib3VuZHMgdGhlIHNlYXJjaC4g IEFGRklMSUFURUQgaXMgYSBsaXN0IG9mIHdoaWNoIENBUiBpcwp0aGUgYnVmZmVyIHBvc2l0aW9u IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpcnN0IGFmZmlsaWF0ZWQKa2V5d29yZCBhbmQgQ0RS IGlzIGEgcGxpc3Qgb2YgYWZmaWxpYXRlZCBrZXl3b3JkcyBhbG9uZyB3aXRoCnRoZWlyIHZhbHVl LgoKUmV0dXJuIGEgbGlzdCB3aG9zZSBDQVIgaXMgYHRhYmxlJyBhbmQgQ0RSIGlzIGEgcGxpc3Qg Y29udGFpbmluZwpgOmJlZ2luJywgYDplbmQnLCBgOnRibGZtJywgYDp0eXBlJywgYDpjb250ZW50 cy1iZWdpbicsCmA6Y29udGVudHMtZW5kJywgYDp2YWx1ZScsIGA6cG9zdC1ibGFuaycgYW5kIGA6 cG9zdC1hZmZpbGlhdGVkJwprZXl3b3Jkcy4KCkFzc3VtZSBwb2ludCBpcyBhdCB0aGUgYmVnaW5u aW5nIG9mIHRoZSB0YWJsZS4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LXRhYmxlLWludGVycHJldGVy ICh0YWJsZSBjb250ZW50cykKICAiSW50ZXJwcmV0IFRBQkxFIGVsZW1lbnQgYXMgT3JnIHN5bnRh eC4KQ09OVEVOVFMgaXMgbmlsLiIpCgojK2VuZF9zcmMKCioqIFRhYmxlIFJvdwoKIytiZWdpbl9z cmMgZW1hY3MtbGlzcAooZGVmdW4gb3JnLWVsZW1lbnQtdGFibGUtcm93LXBhcnNlciAobGltaXQp CiAgIlBhcnNlIHRhYmxlIHJvdyBhdCBwb2ludC4KCkxJTUlUIGJvdW5kcyB0aGUgc2VhcmNoLgoK UmV0dXJuIGEgbGlzdCB3aG9zZSBDQVIgaXMgYHRhYmxlLXJvdycgYW5kIENEUiBpcyBhIHBsaXN0 CmNvbnRhaW5pbmcgYDpiZWdpbicsIGA6ZW5kJywgYDpjb250ZW50cy1iZWdpbicsIGA6Y29udGVu dHMtZW5kJywKYDp0eXBlJyBhbmQgYDpwb3N0LWJsYW5rJyBrZXl3b3Jkcy4iKQoKKGRlZnVuIG9y Zy1lbGVtZW50LXRhYmxlLXJvdy1pbnRlcnByZXRlciAodGFibGUtcm93IGNvbnRlbnRzKQogICJJ bnRlcnByZXQgVEFCTEUtUk9XIGVsZW1lbnQgYXMgT3JnIHN5bnRheC4KQ09OVEVOVFMgaXMgdGhl IGNvbnRlbnRzIG9mIHRoZSB0YWJsZSByb3cuIikKCiMrZW5kX3NyYwoKKiogVmVyc2UgQmxvY2sK CiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9yZy1lbGVtZW50LXZlcnNlLWJsb2NrLXBh cnNlciAobGltaXQgYWZmaWxpYXRlZCkKICAiUGFyc2UgYSB2ZXJzZSBibG9jay4KCkxJTUlUIGJv dW5kcyB0aGUgc2VhcmNoLiAgQUZGSUxJQVRFRCBpcyBhIGxpc3Qgb2Ygd2hpY2ggQ0FSIGlzCnRo ZSBidWZmZXIgcG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZmlyc3QgYWZmaWxpYXRl ZAprZXl3b3JkIGFuZCBDRFIgaXMgYSBwbGlzdCBvZiBhZmZpbGlhdGVkIGtleXdvcmRzIGFsb25n IHdpdGgKdGhlaXIgdmFsdWUuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgdmVyc2UtYmxv Y2snIGFuZCBDRFIgaXMgYSBwbGlzdApjb250YWluaW5nIGA6YmVnaW4nLCBgOmVuZCcsIGA6Y29u dGVudHMtYmVnaW4nLCBgOmNvbnRlbnRzLWVuZCcsCmA6aGlkZGVucCcsIGA6cG9zdC1ibGFuaycg YW5kIGA6cG9zdC1hZmZpbGlhdGVkJyBrZXl3b3Jkcy4KCkFzc3VtZSBwb2ludCBpcyBhdCBiZWdp bm5pbmcgb2YgdGhlIGJsb2NrLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtdmVyc2UtYmxvY2staW50 ZXJwcmV0ZXIgKHZlcnNlLWJsb2NrIGNvbnRlbnRzKQogICJJbnRlcnByZXQgVkVSU0UtQkxPQ0sg ZWxlbWVudCBhcyBPcmcgc3ludGF4LgpDT05URU5UUyBpcyB2ZXJzZSBibG9jayBjb250ZW50cy4i KQoKCiMrZW5kX3NyYwoKKiBPYmplY3RzCgpVbmxpa2UgdG8gZWxlbWVudHMsIGludGVyc3RpY2Vz IGNhbiBiZSBmb3VuZCBiZXR3ZWVuIG9iamVjdHMuClRoYXQncyB3aHksIGFsb25nIHdpdGggdGhl IHBhcnNlciwgc3VjY2Vzc29yIGZ1bmN0aW9ucyBhcmUgcHJvdmlkZWQKZm9yIGVhY2ggb2JqZWN0 LiAgU29tZSBvYmplY3RzIHNoYXJlIHRoZSBzYW1lIHN1Y2Nlc3NvciAoaS5lLiBgY29kZScKYW5k IGB2ZXJiYXRpbScgb2JqZWN0cykuCgpBIHN1Y2Nlc3NvciBtdXN0IGFjY2VwdCBhIHNpbmdsZSBh cmd1bWVudCBib3VuZGluZyB0aGUgc2VhcmNoLiAgSXQKd2lsbCByZXR1cm4gZWl0aGVyIGEgY29u cyBjZWxsIHdob3NlIENBUiBpcyB0aGUgb2JqZWN0J3MgdHlwZSwgYXMKYSBzeW1ib2wsIGFuZCBD RFIgdGhlIHBvc2l0aW9uIG9mIGl0cyBuZXh0IG9jY3VycmVuY2UsIG9yIG5pbC4KClN1Y2Nlc3Nv cnMgZm9sbG93IHRoZSBuYW1pbmcgY29udmVudGlvbjoKb3JnLWVsZW1lbnQtTkFNRS1zdWNjZXNz b3IsIHdoZXJlIE5BTUUgaXMgdGhlIG5hbWUgb2YgdGhlCnN1Y2Nlc3NvciwgYXMgZGVmaW5lZCBp biBgb3JnLWVsZW1lbnQtYWxsLXN1Y2Nlc3NvcnMnLgoKU29tZSBvYmplY3QgdHlwZXMgKGkuZS4g YGl0YWxpYycpIGFyZSByZWN1cnNpdmUuICBSZXN0cmljdGlvbnMgb24Kb2JqZWN0IHR5cGVzIHRo ZXkgY2FuIGNvbnRhaW4gd2lsbCBiZSBzcGVjaWZpZWQgaW4KYG9yZy1lbGVtZW50LW9iamVjdC1y ZXN0cmljdGlvbnMnLgoKQWRkaW5nIGEgbmV3IHR5cGUgb2Ygb2JqZWN0IGlzIHNpbXBsZS4gIElt cGxlbWVudCBhIHN1Y2Nlc3NvciwKYSBwYXJzZXIsIGFuZCBhbiBpbnRlcnByZXRlciBmb3IgaXQs IGFsbCBmb2xsb3dpbmcgdGhlIG5hbWluZwpjb252ZW50aW9uLiAgUmVnaXN0ZXIgdHlwZSBpbiBg b3JnLWVsZW1lbnQtYWxsLW9iamVjdHMnIGFuZApzdWNjZXNzb3IgaW4gYG9yZy1lbGVtZW50LWFs bC1zdWNjZXNzb3JzJy4gIE1heWJlIHR3ZWFrCnJlc3RyaWN0aW9ucyBhYm91dCBpdCwgYW5kIHRo YXQncyBpdC4KCgoqKiBCb2xkCgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBvcmctZWxl bWVudC1ib2xkLXBhcnNlciAoKQogICJQYXJzZSBib2xkIG9iamVjdCBhdCBwb2ludC4KClJldHVy biBhIGxpc3Qgd2hvc2UgQ0FSIGlzIGBib2xkJyBhbmQgQ0RSIGlzIGEgcGxpc3Qgd2l0aApgOmJl Z2luJywgYDplbmQnLCBgOmNvbnRlbnRzLWJlZ2luJyBhbmQgYDpjb250ZW50cy1lbmQnIGFuZApg OnBvc3QtYmxhbmsnIGtleXdvcmRzLgoKQXNzdW1lIHBvaW50IGlzIGF0IHRoZSBmaXJzdCBzdGFy IG1hcmtlci4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LWJvbGQtaW50ZXJwcmV0ZXIgKGJvbGQgY29u dGVudHMpCiAgIkludGVycHJldCBCT0xEIG9iamVjdCBhcyBPcmcgc3ludGF4LgpDT05URU5UUyBp cyB0aGUgY29udGVudHMgb2YgdGhlIG9iamVjdC4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LXRleHQt bWFya3VwLXN1Y2Nlc3NvciAobGltaXQpCiAgIlNlYXJjaCBmb3IgdGhlIG5leHQgdGV4dC1tYXJr dXAgb2JqZWN0LgoKTElNSVQgYm91bmRzIHRoZSBzZWFyY2guCgpSZXR1cm4gdmFsdWUgaXMgYSBj b25zIGNlbGwgd2hvc2UgQ0FSIGlzIGEgc3ltYm9sIGFtb25nIGBib2xkJywKYGl0YWxpYycsIGB1 bmRlcmxpbmUnLCBgc3RyaWtlLXRocm91Z2gnLCBgY29kZScgYW5kIGB2ZXJiYXRpbScKYW5kIENE UiBpcyBiZWdpbm5pbmcgcG9zaXRpb24uIikKCiMrZW5kX3NyYwoKKiogQ29kZQoKIytiZWdpbl9z cmMgZW1hY3MtbGlzcAooZGVmdW4gb3JnLWVsZW1lbnQtY29kZS1wYXJzZXIgKCkKICAiUGFyc2Ug Y29kZSBvYmplY3QgYXQgcG9pbnQuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgY29kZScg YW5kIENEUiBpcyBhIHBsaXN0IHdpdGgKYDp2YWx1ZScsIGA6YmVnaW4nLCBgOmVuZCcgYW5kIGA6 cG9zdC1ibGFuaycga2V5d29yZHMuCgpBc3N1bWUgcG9pbnQgaXMgYXQgdGhlIGZpcnN0IHRpbGRl IG1hcmtlci4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LWNvZGUtaW50ZXJwcmV0ZXIgKGNvZGUgY29u dGVudHMpCiAgIkludGVycHJldCBDT0RFIG9iamVjdCBhcyBPcmcgc3ludGF4LgpDT05URU5UUyBp cyBuaWwuIikKCiMrZW5kX3NyYwoKKiogRW50aXR5CgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihk ZWZ1biBvcmctZWxlbWVudC1lbnRpdHktcGFyc2VyICgpCiAgIlBhcnNlIGVudGl0eSBhdCBwb2lu dC4KClJldHVybiBhIGxpc3Qgd2hvc2UgQ0FSIGlzIGBlbnRpdHknIGFuZCBDRFIgYSBwbGlzdCB3 aXRoCmA6YmVnaW4nLCBgOmVuZCcsIGA6bGF0ZXgnLCBgOmxhdGV4LW1hdGgtcCcsIGA6aHRtbCcs IGA6bGF0aW4xJywKYDp1dGYtOCcsIGA6YXNjaWknLCBgOnVzZS1icmFja2V0cy1wJyBhbmQgYDpw b3N0LWJsYW5rJyBhcwprZXl3b3Jkcy4KCkFzc3VtZSBwb2ludCBpcyBhdCB0aGUgYmVnaW5uaW5n IG9mIHRoZSBlbnRpdHkuIikKCihkZWZ1biBvcmctZWxlbWVudC1lbnRpdHktaW50ZXJwcmV0ZXIg KGVudGl0eSBjb250ZW50cykKICAiSW50ZXJwcmV0IEVOVElUWSBvYmplY3QgYXMgT3JnIHN5bnRh eC4KQ09OVEVOVFMgaXMgbmlsLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtbGF0ZXgtb3ItZW50aXR5 LXN1Y2Nlc3NvciAobGltaXQpCiAgIlNlYXJjaCBmb3IgdGhlIG5leHQgbGF0ZXgtZnJhZ21lbnQg b3IgZW50aXR5IG9iamVjdC4KCkxJTUlUIGJvdW5kcyB0aGUgc2VhcmNoLgoKUmV0dXJuIHZhbHVl IGlzIGEgY29ucyBjZWxsIHdob3NlIENBUiBpcyBgZW50aXR5JyBvcgpgbGF0ZXgtZnJhZ21lbnQn IGFuZCBDRFIgaXMgYmVnaW5uaW5nIHBvc2l0aW9uLiIpCgojK2VuZF9zcmMKCioqIEV4cG9ydCBT bmlwcGV0CgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBvcmctZWxlbWVudC1leHBvcnQt c25pcHBldC1wYXJzZXIgKCkKICAiUGFyc2UgZXhwb3J0IHNuaXBwZXQgYXQgcG9pbnQuCgpSZXR1 cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgZXhwb3J0LXNuaXBwZXQnIGFuZCBDRFIgYSBwbGlzdCB3 aXRoCmA6YmVnaW4nLCBgOmVuZCcsIGA6YmFjay1lbmQnLCBgOnZhbHVlJyBhbmQgYDpwb3N0LWJs YW5rJyBhcwprZXl3b3Jkcy4KCkFzc3VtZSBwb2ludCBpcyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRo ZSBzbmlwcGV0LiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtZXhwb3J0LXNuaXBwZXQtaW50ZXJwcmV0 ZXIgKGV4cG9ydC1zbmlwcGV0IGNvbnRlbnRzKQogICJJbnRlcnByZXQgRVhQT1JULVNOSVBQRVQg b2JqZWN0IGFzIE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIG5pbC4iKQoKKGRlZnVuIG9yZy1lbGVt ZW50LWV4cG9ydC1zbmlwcGV0LXN1Y2Nlc3NvciAobGltaXQpCiAgIlNlYXJjaCBmb3IgdGhlIG5l eHQgZXhwb3J0LXNuaXBwZXQgb2JqZWN0LgoKTElNSVQgYm91bmRzIHRoZSBzZWFyY2guCgpSZXR1 cm4gdmFsdWUgaXMgYSBjb25zIGNlbGwgd2hvc2UgQ0FSIGlzIGBleHBvcnQtc25pcHBldCcgYW5k IENEUgppdHMgYmVnaW5uaW5nIHBvc2l0aW9uLiIpCgojK2VuZF9zcmMKCioqIEZvb3Rub3RlIFJl ZmVyZW5jZQoKIytiZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVmdW4gb3JnLWVsZW1lbnQtZm9vdG5v dGUtcmVmZXJlbmNlLXBhcnNlciAoKQogICJQYXJzZSBmb290bm90ZSByZWZlcmVuY2UgYXQgcG9p bnQuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgZm9vdG5vdGUtcmVmZXJlbmNlJyBhbmQg Q0RSIGEgcGxpc3QKd2l0aCBgOmxhYmVsJywgYDp0eXBlJywgYDppbmxpbmUtZGVmaW5pdGlvbics IGA6YmVnaW4nLCBgOmVuZCcKYW5kIGA6cG9zdC1ibGFuaycgYXMga2V5d29yZHMuIikKCihkZWZ1 biBvcmctZWxlbWVudC1mb290bm90ZS1yZWZlcmVuY2UtaW50ZXJwcmV0ZXIgKGZvb3Rub3RlLXJl ZmVyZW5jZSBjb250ZW50cykKICAiSW50ZXJwcmV0IEZPT1ROT1RFLVJFRkVSRU5DRSBvYmplY3Qg YXMgT3JnIHN5bnRheC4KQ09OVEVOVFMgaXMgbmlsLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtZm9v dG5vdGUtcmVmZXJlbmNlLXN1Y2Nlc3NvciAobGltaXQpCiAgIlNlYXJjaCBmb3IgdGhlIG5leHQg Zm9vdG5vdGUtcmVmZXJlbmNlIG9iamVjdC4KCkxJTUlUIGJvdW5kcyB0aGUgc2VhcmNoLgoKUmV0 dXJuIHZhbHVlIGlzIGEgY29ucyBjZWxsIHdob3NlIENBUiBpcyBgZm9vdG5vdGUtcmVmZXJlbmNl JyBhbmQKQ0RSIGlzIGJlZ2lubmluZyBwb3NpdGlvbi4iKQoKIytlbmRfc3JjCgoqKiBJbmxpbmUg QmFiZWwgQ2FsbAoKIytiZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVmdW4gb3JnLWVsZW1lbnQtaW5s aW5lLWJhYmVsLWNhbGwtcGFyc2VyICgpCiAgIlBhcnNlIGlubGluZSBiYWJlbCBjYWxsIGF0IHBv aW50LgoKUmV0dXJuIGEgbGlzdCB3aG9zZSBDQVIgaXMgYGlubGluZS1iYWJlbC1jYWxsJyBhbmQg Q0RSIGEgcGxpc3QKd2l0aCBgOmJlZ2luJywgYDplbmQnLCBgOmluZm8nIGFuZCBgOnBvc3QtYmxh bmsnIGFzIGtleXdvcmRzLgoKQXNzdW1lIHBvaW50IGlzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhl IGJhYmVsIGNhbGwuIikKCihkZWZ1biBvcmctZWxlbWVudC1pbmxpbmUtYmFiZWwtY2FsbC1pbnRl cnByZXRlciAoaW5saW5lLWJhYmVsLWNhbGwgY29udGVudHMpCiAgIkludGVycHJldCBJTkxJTkUt QkFCRUwtQ0FMTCBvYmplY3QgYXMgT3JnIHN5bnRheC4KQ09OVEVOVFMgaXMgbmlsLiIpCgooZGVm dW4gb3JnLWVsZW1lbnQtaW5saW5lLWJhYmVsLWNhbGwtc3VjY2Vzc29yIChsaW1pdCkKICAiU2Vh cmNoIGZvciB0aGUgbmV4dCBpbmxpbmUtYmFiZWwtY2FsbCBvYmplY3QuCgpMSU1JVCBib3VuZHMg dGhlIHNlYXJjaC4KClJldHVybiB2YWx1ZSBpcyBhIGNvbnMgY2VsbCB3aG9zZSBDQVIgaXMgYGlu bGluZS1iYWJlbC1jYWxsJyBhbmQKQ0RSIGlzIGJlZ2lubmluZyBwb3NpdGlvbi4iKQoKIytlbmRf c3JjCgoqKiBJbmxpbmUgU3JjIEJsb2NrCgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBv cmctZWxlbWVudC1pbmxpbmUtc3JjLWJsb2NrLXBhcnNlciAoKQogICJQYXJzZSBpbmxpbmUgc291 cmNlIGJsb2NrIGF0IHBvaW50LgoKTElNSVQgYm91bmRzIHRoZSBzZWFyY2guCgpSZXR1cm4gYSBs aXN0IHdob3NlIENBUiBpcyBgaW5saW5lLXNyYy1ibG9jaycgYW5kIENEUiBhIHBsaXN0CndpdGgg YDpiZWdpbicsIGA6ZW5kJywgYDpsYW5ndWFnZScsIGA6dmFsdWUnLCBgOnBhcmFtZXRlcnMnIGFu ZApgOnBvc3QtYmxhbmsnIGFzIGtleXdvcmRzLgoKQXNzdW1lIHBvaW50IGlzIGF0IHRoZSBiZWdp bm5pbmcgb2YgdGhlIGlubGluZSBzcmMgYmxvY2suIikKCihkZWZ1biBvcmctZWxlbWVudC1pbmxp bmUtc3JjLWJsb2NrLWludGVycHJldGVyIChpbmxpbmUtc3JjLWJsb2NrIGNvbnRlbnRzKQogICJJ bnRlcnByZXQgSU5MSU5FLVNSQy1CTE9DSyBvYmplY3QgYXMgT3JnIHN5bnRheC4KQ09OVEVOVFMg aXMgbmlsLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtaW5saW5lLXNyYy1ibG9jay1zdWNjZXNzb3Ig KGxpbWl0KQogICJTZWFyY2ggZm9yIHRoZSBuZXh0IGlubGluZS1iYWJlbC1jYWxsIGVsZW1lbnQu CgpMSU1JVCBib3VuZHMgdGhlIHNlYXJjaC4KClJldHVybiB2YWx1ZSBpcyBhIGNvbnMgY2VsbCB3 aG9zZSBDQVIgaXMgYGlubGluZS1iYWJlbC1jYWxsJyBhbmQKQ0RSIGlzIGJlZ2lubmluZyBwb3Np dGlvbi4iKQojK2VuZF9zcmMKCioqIEl0YWxpYwoKIytiZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVm dW4gb3JnLWVsZW1lbnQtaXRhbGljLXBhcnNlciAoKQogICJQYXJzZSBpdGFsaWMgb2JqZWN0IGF0 IHBvaW50LgoKUmV0dXJuIGEgbGlzdCB3aG9zZSBDQVIgaXMgYGl0YWxpYycgYW5kIENEUiBpcyBh IHBsaXN0IHdpdGgKYDpiZWdpbicsIGA6ZW5kJywgYDpjb250ZW50cy1iZWdpbicgYW5kIGA6Y29u dGVudHMtZW5kJyBhbmQKYDpwb3N0LWJsYW5rJyBrZXl3b3Jkcy4KCkFzc3VtZSBwb2ludCBpcyBh dCB0aGUgZmlyc3Qgc2xhc2ggbWFya2VyLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtaXRhbGljLWlu dGVycHJldGVyIChpdGFsaWMgY29udGVudHMpCiAgIkludGVycHJldCBJVEFMSUMgb2JqZWN0IGFz IE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIHRoZSBjb250ZW50cyBvZiB0aGUgb2JqZWN0LiIpCgoj K2VuZF9zcmMKCioqIExhdGV4IEZyYWdtZW50CgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1 biBvcmctZWxlbWVudC1sYXRleC1mcmFnbWVudC1wYXJzZXIgKCkKICAiUGFyc2UgbGF0ZXggZnJh Z21lbnQgYXQgcG9pbnQuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgbGF0ZXgtZnJhZ21l bnQnIGFuZCBDRFIgYSBwbGlzdCB3aXRoCmA6dmFsdWUnLCBgOmJlZ2luJywgYDplbmQnLCBhbmQg YDpwb3N0LWJsYW5rJyBhcyBrZXl3b3Jkcy4KCkFzc3VtZSBwb2ludCBpcyBhdCB0aGUgYmVnaW5u aW5nIG9mIHRoZSBsYXRleCBmcmFnbWVudC4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LWxhdGV4LWZy YWdtZW50LWludGVycHJldGVyIChsYXRleC1mcmFnbWVudCBjb250ZW50cykKICAiSW50ZXJwcmV0 IExBVEVYLUZSQUdNRU5UIG9iamVjdCBhcyBPcmcgc3ludGF4LgpDT05URU5UUyBpcyBuaWwuIikK IytlbmRfc3JjCgoqKiBMaW5lIEJyZWFrCgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBv cmctZWxlbWVudC1saW5lLWJyZWFrLXBhcnNlciAoKQogICJQYXJzZSBsaW5lIGJyZWFrIGF0IHBv aW50LgoKUmV0dXJuIGEgbGlzdCB3aG9zZSBDQVIgaXMgYGxpbmUtYnJlYWsnLCBhbmQgQ0RSIGEg cGxpc3Qgd2l0aApgOmJlZ2luJywgYDplbmQnIGFuZCBgOnBvc3QtYmxhbmsnIGtleXdvcmRzLgoK QXNzdW1lIHBvaW50IGlzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpbmUgYnJlYWsuIikKCihk ZWZ1biBvcmctZWxlbWVudC1saW5lLWJyZWFrLWludGVycHJldGVyIChsaW5lLWJyZWFrIGNvbnRl bnRzKQogICJJbnRlcnByZXQgTElORS1CUkVBSyBvYmplY3QgYXMgT3JnIHN5bnRheC4KQ09OVEVO VFMgaXMgbmlsLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtbGluZS1icmVhay1zdWNjZXNzb3IgKGxp bWl0KQogICJTZWFyY2ggZm9yIHRoZSBuZXh0IGxpbmUtYnJlYWsgb2JqZWN0LgoKTElNSVQgYm91 bmRzIHRoZSBzZWFyY2guCgpSZXR1cm4gdmFsdWUgaXMgYSBjb25zIGNlbGwgd2hvc2UgQ0FSIGlz IGBsaW5lLWJyZWFrJyBhbmQgQ0RSIGlzCmJlZ2lubmluZyBwb3NpdGlvbi4iKQoKIytlbmRfc3Jj CgoqKiBMaW5rCgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBvcmctZWxlbWVudC1saW5r LXBhcnNlciAoKQogICJQYXJzZSBsaW5rIGF0IHBvaW50LgoKUmV0dXJuIGEgbGlzdCB3aG9zZSBD QVIgaXMgYGxpbmsnIGFuZCBDRFIgYSBwbGlzdCB3aXRoIGA6dHlwZScsCmA6cGF0aCcsIGA6cmF3 LWxpbmsnLCBgOmFwcGxpY2F0aW9uJywgYDpzZWFyY2gtb3B0aW9uJywgYDpiZWdpbicsCmA6ZW5k JywgYDpjb250ZW50cy1iZWdpbicsIGA6Y29udGVudHMtZW5kJyBhbmQgYDpwb3N0LWJsYW5rJyBh cwprZXl3b3Jkcy4KCkFzc3VtZSBwb2ludCBpcyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaW5r LiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtbGluay1pbnRlcnByZXRlciAobGluayBjb250ZW50cykK ICAiSW50ZXJwcmV0IExJTksgb2JqZWN0IGFzIE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIHRoZSBj b250ZW50cyBvZiB0aGUgb2JqZWN0LCBvciBuaWwuIikKCihkZWZ1biBvcmctZWxlbWVudC1saW5r LXN1Y2Nlc3NvciAobGltaXQpCiAgIlNlYXJjaCBmb3IgdGhlIG5leHQgbGluayBvYmplY3QuCgpM SU1JVCBib3VuZHMgdGhlIHNlYXJjaC4KClJldHVybiB2YWx1ZSBpcyBhIGNvbnMgY2VsbCB3aG9z ZSBDQVIgaXMgYGxpbmsnIGFuZCBDRFIgaXMKYmVnaW5uaW5nIHBvc2l0aW9uLiIpCgooZGVmdW4g b3JnLWVsZW1lbnQtcGxhaW4tbGluay1zdWNjZXNzb3IgKGxpbWl0KQogICJTZWFyY2ggZm9yIHRo ZSBuZXh0IHBsYWluIGxpbmsgb2JqZWN0LgoKTElNSVQgYm91bmRzIHRoZSBzZWFyY2guCgpSZXR1 cm4gdmFsdWUgaXMgYSBjb25zIGNlbGwgd2hvc2UgQ0FSIGlzIGBsaW5rJyBhbmQgQ0RSIGlzCmJl Z2lubmluZyBwb3NpdGlvbi4iKQoKIytlbmRfc3JjCgoqKiBNYWNybwoKIytiZWdpbl9zcmMgZW1h Y3MtbGlzcAooZGVmdW4gb3JnLWVsZW1lbnQtbWFjcm8tcGFyc2VyICgpCiAgIlBhcnNlIG1hY3Jv IGF0IHBvaW50LgoKUmV0dXJuIGEgbGlzdCB3aG9zZSBDQVIgaXMgYG1hY3JvJyBhbmQgQ0RSIGEg cGxpc3Qgd2l0aCBgOmtleScsCmA6YXJncycsIGA6YmVnaW4nLCBgOmVuZCcsIGA6dmFsdWUnIGFu ZCBgOnBvc3QtYmxhbmsnIGFzCmtleXdvcmRzLgoKQXNzdW1lIHBvaW50IGlzIGF0IHRoZSBtYWNy by4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LW1hY3JvLWludGVycHJldGVyIChtYWNybyBjb250ZW50 cykKICAiSW50ZXJwcmV0IE1BQ1JPIG9iamVjdCBhcyBPcmcgc3ludGF4LgpDT05URU5UUyBpcyBu aWwuIikKCihkZWZ1biBvcmctZWxlbWVudC1tYWNyby1zdWNjZXNzb3IgKGxpbWl0KQogICJTZWFy Y2ggZm9yIHRoZSBuZXh0IG1hY3JvIG9iamVjdC4KCkxJTUlUIGJvdW5kcyB0aGUgc2VhcmNoLgoK UmV0dXJuIHZhbHVlIGlzIGNvbnMgY2VsbCB3aG9zZSBDQVIgaXMgYG1hY3JvJyBhbmQgQ0RSIGlz CmJlZ2lubmluZyBwb3NpdGlvbi4iKQoKIytlbmRfc3JjCgoqKiBSYWRpby10YXJnZXQKCiMrYmVn aW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9yZy1lbGVtZW50LXJhZGlvLXRhcmdldC1wYXJzZXIg KCkKICAiUGFyc2UgcmFkaW8gdGFyZ2V0IGF0IHBvaW50LgoKUmV0dXJuIGEgbGlzdCB3aG9zZSBD QVIgaXMgYHJhZGlvLXRhcmdldCcgYW5kIENEUiBhIHBsaXN0IHdpdGgKYDpiZWdpbicsIGA6ZW5k JywgYDpjb250ZW50cy1iZWdpbicsIGA6Y29udGVudHMtZW5kJywgYDp2YWx1ZScKYW5kIGA6cG9z dC1ibGFuaycgYXMga2V5d29yZHMuCgpBc3N1bWUgcG9pbnQgaXMgYXQgdGhlIHJhZGlvIHRhcmdl dC4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LXJhZGlvLXRhcmdldC1pbnRlcnByZXRlciAodGFyZ2V0 IGNvbnRlbnRzKQogICJJbnRlcnByZXQgVEFSR0VUIG9iamVjdCBhcyBPcmcgc3ludGF4LgpDT05U RU5UUyBpcyB0aGUgY29udGVudHMgb2YgdGhlIG9iamVjdC4iKQoKKGRlZnVuIG9yZy1lbGVtZW50 LXJhZGlvLXRhcmdldC1zdWNjZXNzb3IgKGxpbWl0KQogICJTZWFyY2ggZm9yIHRoZSBuZXh0IHJh ZGlvLXRhcmdldCBvYmplY3QuCgpMSU1JVCBib3VuZHMgdGhlIHNlYXJjaC4KClJldHVybiB2YWx1 ZSBpcyBhIGNvbnMgY2VsbCB3aG9zZSBDQVIgaXMgYHJhZGlvLXRhcmdldCcgYW5kIENEUgppcyBi ZWdpbm5pbmcgcG9zaXRpb24uIikKCiMrZW5kX3NyYwoKKiogU3RhdGlzdGljcyBDb29raWUKCiMr YmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9yZy1lbGVtZW50LXN0YXRpc3RpY3MtY29va2ll LXBhcnNlciAoKQogICJQYXJzZSBzdGF0aXN0aWNzIGNvb2tpZSBhdCBwb2ludC4KClJldHVybiBh IGxpc3Qgd2hvc2UgQ0FSIGlzIGBzdGF0aXN0aWNzLWNvb2tpZScsIGFuZCBDRFIgYSBwbGlzdAp3 aXRoIGA6YmVnaW4nLCBgOmVuZCcsIGA6dmFsdWUnIGFuZCBgOnBvc3QtYmxhbmsnIGtleXdvcmRz LgoKQXNzdW1lIHBvaW50IGlzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0YXRpc3RpY3MtY29v a2llLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtc3RhdGlzdGljcy1jb29raWUtaW50ZXJwcmV0ZXIg KHN0YXRpc3RpY3MtY29va2llIGNvbnRlbnRzKQogICJJbnRlcnByZXQgU1RBVElTVElDUy1DT09L SUUgb2JqZWN0IGFzIE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIG5pbC4iKQoKKGRlZnVuIG9yZy1l bGVtZW50LXN0YXRpc3RpY3MtY29va2llLXN1Y2Nlc3NvciAobGltaXQpCiAgIlNlYXJjaCBmb3Ig dGhlIG5leHQgc3RhdGlzdGljcyBjb29raWUgb2JqZWN0LgoKTElNSVQgYm91bmRzIHRoZSBzZWFy Y2guCgpSZXR1cm4gdmFsdWUgaXMgYSBjb25zIGNlbGwgd2hvc2UgQ0FSIGlzIGBzdGF0aXN0aWNz LWNvb2tpZScgYW5kCkNEUiBpcyBiZWdpbm5pbmcgcG9zaXRpb24uIikKCiMrZW5kX3NyYwoKKiog U3RyaWtlLVRocm91Z2gKCiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9yZy1lbGVtZW50 LXN0cmlrZS10aHJvdWdoLXBhcnNlciAoKQogICJQYXJzZSBzdHJpa2UtdGhyb3VnaCBvYmplY3Qg YXQgcG9pbnQuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBpcyBgc3RyaWtlLXRocm91Z2gnIGFu ZCBDRFIgaXMgYSBwbGlzdAp3aXRoIGA6YmVnaW4nLCBgOmVuZCcsIGA6Y29udGVudHMtYmVnaW4n IGFuZCBgOmNvbnRlbnRzLWVuZCcgYW5kCmA6cG9zdC1ibGFuaycga2V5d29yZHMuCgpBc3N1bWUg cG9pbnQgaXMgYXQgdGhlIGZpcnN0IHBsdXMgc2lnbiBtYXJrZXIuIikKCihkZWZ1biBvcmctZWxl bWVudC1zdHJpa2UtdGhyb3VnaC1pbnRlcnByZXRlciAoc3RyaWtlLXRocm91Z2ggY29udGVudHMp CiAgIkludGVycHJldCBTVFJJS0UtVEhST1VHSCBvYmplY3QgYXMgT3JnIHN5bnRheC4KQ09OVEVO VFMgaXMgdGhlIGNvbnRlbnRzIG9mIHRoZSBvYmplY3QuIikKCiMrZW5kX3NyYwoKKiogU3Vic2Ny aXB0CgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBvcmctZWxlbWVudC1zdWJzY3JpcHQt cGFyc2VyICgpCiAgIlBhcnNlIHN1YnNjcmlwdCBhdCBwb2ludC4KClJldHVybiBhIGxpc3Qgd2hv c2UgQ0FSIGlzIGBzdWJzY3JpcHQnIGFuZCBDRFIgYSBwbGlzdCB3aXRoCmA6YmVnaW4nLCBgOmVu ZCcsIGA6Y29udGVudHMtYmVnaW4nLCBgOmNvbnRlbnRzLWVuZCcsCmA6dXNlLWJyYWNrZXRzLXAn IGFuZCBgOnBvc3QtYmxhbmsnIGFzIGtleXdvcmRzLgoKQXNzdW1lIHBvaW50IGlzIGF0IHRoZSB1 bmRlcnNjb3JlLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtc3Vic2NyaXB0LWludGVycHJldGVyIChz dWJzY3JpcHQgY29udGVudHMpCiAgIkludGVycHJldCBTVUJTQ1JJUFQgb2JqZWN0IGFzIE9yZyBz eW50YXguCkNPTlRFTlRTIGlzIHRoZSBjb250ZW50cyBvZiB0aGUgb2JqZWN0LiIpCgooZGVmdW4g b3JnLWVsZW1lbnQtc3ViL3N1cGVyc2NyaXB0LXN1Y2Nlc3NvciAgKGxpbWl0KQogICJTZWFyY2gg Zm9yIHRoZSBuZXh0IHN1Yi9zdXBlcnNjcmlwdCBvYmplY3QuCgpMSU1JVCBib3VuZHMgdGhlIHNl YXJjaC4KClJldHVybiB2YWx1ZSBpcyBhIGNvbnMgY2VsbCB3aG9zZSBDQVIgaXMgZWl0aGVyIGBz dWJzY3JpcHQnIG9yCmBzdXBlcnNjcmlwdCcgYW5kIENEUiBpcyBiZWdpbm5pbmcgcG9zaXRpb24u IikKCiMrZW5kX3NyYwoKKiogU3VwZXJzY3JpcHQKCiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRl ZnVuIG9yZy1lbGVtZW50LXN1cGVyc2NyaXB0LXBhcnNlciAoKQogICJQYXJzZSBzdXBlcnNjcmlw dCBhdCBwb2ludC4KClJldHVybiBhIGxpc3Qgd2hvc2UgQ0FSIGlzIGBzdXBlcnNjcmlwdCcgYW5k IENEUiBhIHBsaXN0IHdpdGgKYDpiZWdpbicsIGA6ZW5kJywgYDpjb250ZW50cy1iZWdpbicsIGA6 Y29udGVudHMtZW5kJywKYDp1c2UtYnJhY2tldHMtcCcgYW5kIGA6cG9zdC1ibGFuaycgYXMga2V5 d29yZHMuCgpBc3N1bWUgcG9pbnQgaXMgYXQgdGhlIGNhcmV0LiIpCgooZGVmdW4gb3JnLWVsZW1l bnQtc3VwZXJzY3JpcHQtaW50ZXJwcmV0ZXIgKHN1cGVyc2NyaXB0IGNvbnRlbnRzKQogICJJbnRl cnByZXQgU1VQRVJTQ1JJUFQgb2JqZWN0IGFzIE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIHRoZSBj b250ZW50cyBvZiB0aGUgb2JqZWN0LiIpCgojK2VuZF9zcmMKCioqIFRhYmxlIENlbGwKCiMrYmVn aW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9yZy1lbGVtZW50LXRhYmxlLWNlbGwtcGFyc2VyICgp CiAgIlBhcnNlIHRhYmxlIGNlbGwgYXQgcG9pbnQuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBp cyBgdGFibGUtY2VsbCcgYW5kIENEUiBpcyBhIHBsaXN0CmNvbnRhaW5pbmcgYDpiZWdpbicsIGA6 ZW5kJywgYDpjb250ZW50cy1iZWdpbicsIGA6Y29udGVudHMtZW5kJwphbmQgYDpwb3N0LWJsYW5r JyBrZXl3b3Jkcy4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LXRhYmxlLWNlbGwtaW50ZXJwcmV0ZXIg KHRhYmxlLWNlbGwgY29udGVudHMpCiAgIkludGVycHJldCBUQUJMRS1DRUxMIGVsZW1lbnQgYXMg T3JnIHN5bnRheC4KQ09OVEVOVFMgaXMgdGhlIGNvbnRlbnRzIG9mIHRoZSBjZWxsLCBvciBuaWwu IikKCihkZWZ1biBvcmctZWxlbWVudC10YWJsZS1jZWxsLXN1Y2Nlc3NvciAobGltaXQpCiAgIlNl YXJjaCBmb3IgdGhlIG5leHQgdGFibGUtY2VsbCBvYmplY3QuCgpMSU1JVCBib3VuZHMgdGhlIHNl YXJjaC4KClJldHVybiB2YWx1ZSBpcyBhIGNvbnMgY2VsbCB3aG9zZSBDQVIgaXMgYHRhYmxlLWNl bGwnIGFuZCBDRFIgaXMKYmVnaW5uaW5nIHBvc2l0aW9uLiIpCgojK2VuZF9zcmMKCioqIFRhcmdl dAoKIytiZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVmdW4gb3JnLWVsZW1lbnQtdGFyZ2V0LXBhcnNl ciAoKQogICJQYXJzZSB0YXJnZXQgYXQgcG9pbnQuCgpSZXR1cm4gYSBsaXN0IHdob3NlIENBUiBp cyBgdGFyZ2V0JyBhbmQgQ0RSIGEgcGxpc3Qgd2l0aApgOmJlZ2luJywgYDplbmQnLCBgOnZhbHVl JyBhbmQgYDpwb3N0LWJsYW5rJyBhcyBrZXl3b3Jkcy4KCkFzc3VtZSBwb2ludCBpcyBhdCB0aGUg dGFyZ2V0LiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtdGFyZ2V0LWludGVycHJldGVyICh0YXJnZXQg Y29udGVudHMpCiAgIkludGVycHJldCBUQVJHRVQgb2JqZWN0IGFzIE9yZyBzeW50YXguCkNPTlRF TlRTIGlzIG5pbC4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LXRhcmdldC1zdWNjZXNzb3IgKGxpbWl0 KQogICJTZWFyY2ggZm9yIHRoZSBuZXh0IHRhcmdldCBvYmplY3QuCgpMSU1JVCBib3VuZHMgdGhl IHNlYXJjaC4KClJldHVybiB2YWx1ZSBpcyBhIGNvbnMgY2VsbCB3aG9zZSBDQVIgaXMgYHRhcmdl dCcgYW5kIENEUiBpcwpiZWdpbm5pbmcgcG9zaXRpb24uIikKCiMrZW5kX3NyYwoKKiogVGltZXN0 YW1wCgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBvcmctZWxlbWVudC10aW1lc3RhbXAt cGFyc2VyICgpCiAgIlBhcnNlIHRpbWUgc3RhbXAgYXQgcG9pbnQuCgpSZXR1cm4gYSBsaXN0IHdo b3NlIENBUiBpcyBgdGltZXN0YW1wJywgYW5kIENEUiBhIHBsaXN0IHdpdGgKYDp0eXBlJywgYDpi ZWdpbicsIGA6ZW5kJywgYDp2YWx1ZScgYW5kIGA6cG9zdC1ibGFuaycga2V5d29yZHMuCgpBc3N1 bWUgcG9pbnQgaXMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdGltZXN0YW1wLiIpCgooZGVmdW4g b3JnLWVsZW1lbnQtdGltZXN0YW1wLWludGVycHJldGVyICh0aW1lc3RhbXAgY29udGVudHMpCiAg IkludGVycHJldCBUSU1FU1RBTVAgb2JqZWN0IGFzIE9yZyBzeW50YXguCkNPTlRFTlRTIGlzIG5p bC4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LXRpbWVzdGFtcC1zdWNjZXNzb3IgKGxpbWl0KQogICJT ZWFyY2ggZm9yIHRoZSBuZXh0IHRpbWVzdGFtcCBvYmplY3QuCgpMSU1JVCBib3VuZHMgdGhlIHNl YXJjaC4KClJldHVybiB2YWx1ZSBpcyBhIGNvbnMgY2VsbCB3aG9zZSBDQVIgaXMgYHRpbWVzdGFt cCcgYW5kIENEUiBpcwpiZWdpbm5pbmcgcG9zaXRpb24uIikKCiMrZW5kX3NyYwoKKiogVW5kZXJs aW5lCgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBvcmctZWxlbWVudC11bmRlcmxpbmUt cGFyc2VyICgpCiAgIlBhcnNlIHVuZGVybGluZSBvYmplY3QgYXQgcG9pbnQuCgpSZXR1cm4gYSBs aXN0IHdob3NlIENBUiBpcyBgdW5kZXJsaW5lJyBhbmQgQ0RSIGlzIGEgcGxpc3Qgd2l0aApgOmJl Z2luJywgYDplbmQnLCBgOmNvbnRlbnRzLWJlZ2luJyBhbmQgYDpjb250ZW50cy1lbmQnIGFuZApg OnBvc3QtYmxhbmsnIGtleXdvcmRzLgoKQXNzdW1lIHBvaW50IGlzIGF0IHRoZSBmaXJzdCB1bmRl cnNjb3JlIG1hcmtlci4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LXVuZGVybGluZS1pbnRlcnByZXRl ciAodW5kZXJsaW5lIGNvbnRlbnRzKQogICJJbnRlcnByZXQgVU5ERVJMSU5FIG9iamVjdCBhcyBP cmcgc3ludGF4LgpDT05URU5UUyBpcyB0aGUgY29udGVudHMgb2YgdGhlIG9iamVjdC4iKQoKIytl bmRfc3JjCgoqKiBWZXJiYXRpbQoKIytiZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVmdW4gb3JnLWVs ZW1lbnQtdmVyYmF0aW0tcGFyc2VyICgpCiAgIlBhcnNlIHZlcmJhdGltIG9iamVjdCBhdCBwb2lu dC4KClJldHVybiBhIGxpc3Qgd2hvc2UgQ0FSIGlzIGB2ZXJiYXRpbScgYW5kIENEUiBpcyBhIHBs aXN0IHdpdGgKYDp2YWx1ZScsIGA6YmVnaW4nLCBgOmVuZCcgYW5kIGA6cG9zdC1ibGFuaycga2V5 d29yZHMuCgpBc3N1bWUgcG9pbnQgaXMgYXQgdGhlIGZpcnN0IGVxdWFsIHNpZ24gbWFya2VyLiIp CgooZGVmdW4gb3JnLWVsZW1lbnQtdmVyYmF0aW0taW50ZXJwcmV0ZXIgKHZlcmJhdGltIGNvbnRl bnRzKQogICJJbnRlcnByZXQgVkVSQkFUSU0gb2JqZWN0IGFzIE9yZyBzeW50YXguCkNPTlRFTlRT IGlzIG5pbC4iKQoKCiMrZW5kX3NyYwoKKiBQYXJzaW5nIEVsZW1lbnQgU3RhcnRpbmcgQXQgUG9p bnQKCmBvcmctZWxlbWVudC0tY3VycmVudC1lbGVtZW50JyBpcyB0aGUgY29yZSBmdW5jdGlvbiBv ZiB0aGlzIHNlY3Rpb24uCkl0IHJldHVybnMgdGhlIExpc3AgcmVwcmVzZW50YXRpb24gb2YgdGhl IGVsZW1lbnQgc3RhcnRpbmcgYXQKcG9pbnQuCgpgb3JnLWVsZW1lbnQtLWN1cnJlbnQtZWxlbWVu dCcgbWFrZXMgdXNlIG9mIHNwZWNpYWwgbW9kZXMuICBUaGV5CmFyZSBhY3RpdmF0ZWQgZm9yIGZp eGVkIGVsZW1lbnQgY2hhaW5pbmcgKGkuZS4gYHBsYWluLWxpc3QnID4KYGl0ZW0nKSBvciBmaXhl ZCBjb25kaXRpb25hbCBlbGVtZW50IGNoYWluaW5nIChpLmUuIGBoZWFkbGluZScgPgpgc2VjdGlv bicpLiAgU3BlY2lhbCBtb2RlcyBhcmU6IGBmaXJzdC1zZWN0aW9uJywgYGl0ZW0nLApgbm9kZS1w cm9wZXJ0eScsIGBxdW90ZS1zZWN0aW9uJywgYHNlY3Rpb24nIGFuZCBgdGFibGUtcm93Jy4KCiMr YmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9yZy1lbGVtZW50LS1jdXJyZW50LWVsZW1lbnQK ICAobGltaXQgJm9wdGlvbmFsIGdyYW51bGFyaXR5IHNwZWNpYWwgc3RydWN0dXJlKQogICJQYXJz ZSB0aGUgZWxlbWVudCBzdGFydGluZyBhdCBwb2ludC4KCkxJTUlUIGJvdW5kcyB0aGUgc2VhcmNo LgoKUmV0dXJuIHZhbHVlIGlzIGEgbGlzdCBsaWtlIChUWVBFIFBST1BTKSB3aGVyZSBUWVBFIGlz IHRoZSB0eXBlCm9mIHRoZSBlbGVtZW50IGFuZCBQUk9QUyBhIHBsaXN0IG9mIHByb3BlcnRpZXMg YXNzb2NpYXRlZCB0byB0aGUKZWxlbWVudC4KClBvc3NpYmxlIHR5cGVzIGFyZSBkZWZpbmVkIGlu IGBvcmctZWxlbWVudC1hbGwtZWxlbWVudHMnLgoKT3B0aW9uYWwgYXJndW1lbnQgR1JBTlVMQVJJ VFkgZGV0ZXJtaW5lcyB0aGUgZGVwdGggb2YgdGhlCnJlY3Vyc2lvbi4gIEFsbG93ZWQgdmFsdWVz IGFyZSBgaGVhZGxpbmUnLCBgZ3JlYXRlci1lbGVtZW50JywKYGVsZW1lbnQnLCBgb2JqZWN0JyBv ciBuaWwuICBXaGVuIGl0IGlzIGJyb2FkZXIgdGhhbiBgb2JqZWN0JyAob3IKbmlsKSwgc2Vjb25k YXJ5IHZhbHVlcyB3aWxsIG5vdCBiZSBwYXJzZWQsIHNpbmNlIHRoZXkgb25seQpjb250YWluIG9i amVjdHMuCgpPcHRpb25hbCBhcmd1bWVudCBTUEVDSUFMLCB3aGVuIG5vbi1uaWwsIGNhbiBiZSBl aXRoZXIKYGZpcnN0LXNlY3Rpb24nLCBgaXRlbScsIGBub2RlLXByb3BlcnR5JywgYHF1b3RlLXNl Y3Rpb24nLApgc2VjdGlvbicsIGFuZCBgdGFibGUtcm93Jy4KCklmIFNUUlVDVFVSRSBpc24ndCBw cm92aWRlZCBidXQgU1BFQ0lBTCBpcyBzZXQgdG8gYGl0ZW0nLCBpdCB3aWxsCmJlIGNvbXB1dGVk LgoKVGhpcyBmdW5jdGlvbiBhc3N1bWVzIHBvaW50IGlzIGFsd2F5cyBhdCB0aGUgYmVnaW5uaW5n IG9mIHRoZQplbGVtZW50IGl0IGhhcyB0byBwYXJzZS4iKQoKIytlbmRfc3JjCgpNb3N0IGVsZW1l bnRzIGNhbiBoYXZlIGFmZmlsaWF0ZWQga2V5d29yZHMuICBXaGVuIGxvb2tpbmcgZm9yIGFuCmVs ZW1lbnQgYmVnaW5uaW5nLCB3ZSB3YW50IHRvIG1vdmUgYmVmb3JlIHRoZW0sIGFzIHRoZXkgYmVs b25nIHRvCnRoYXQgZWxlbWVudCwgYW5kLCBpbiB0aGUgbWVhbnRpbWUsIGNvbGxlY3QgaW5mb3Jt YXRpb24gdGhleSBnaXZlCmludG8gYXBwcm9wcmlhdGUgcHJvcGVydGllcy4gIEhlbmNlIHRoZSBm b2xsb3dpbmcgZnVuY3Rpb24uCgojK2JlZ2luX3NyYyBlbWFjcy1saXNwCihkZWZ1biBvcmctZWxl bWVudC0tY29sbGVjdC1hZmZpbGlhdGVkLWtleXdvcmRzIChsaW1pdCkKICAiQ29sbGVjdCBhZmZp bGlhdGVkIGtleXdvcmRzIGZyb20gcG9pbnQgZG93biB0byBMSU1JVC4KClJldHVybiBhIGxpc3Qg d2hvc2UgQ0FSIGlzIHRoZSBwb3NpdGlvbiBhdCB0aGUgZmlyc3Qgb2YgdGhlbSBhbmQKQ0RSIGEg cGxpc3Qgb2Yga2V5d29yZHMgYW5kIHZhbHVlcyBhbmQgbW92ZSBwb2ludCB0byB0aGUKYmVnaW5u aW5nIG9mIHRoZSBmaXJzdCBsaW5lIGFmdGVyIHRoZW0uCgpBcyBhIHNwZWNpYWwgY2FzZSwgaWYg ZWxlbWVudCBkb2Vzbid0IHN0YXJ0IGF0IHRoZSBiZWdpbm5pbmcgb2YKdGhlIGxpbmUgKGkuZS4g YSBwYXJhZ3JhcGggc3RhcnRpbmcgYW4gaXRlbSksIENBUiBpcyBjdXJyZW50CnBvc2l0aW9uIG9m IHBvaW50IGFuZCBDRFIgaXMgbmlsLiIpCgoKIytlbmRfc3JjCgoqIFRoZSBPcmcgUGFyc2VyCgpU aGUgdHdvIG1ham9yIGZ1bmN0aW9ucyBoZXJlIGFyZSBgb3JnLWVsZW1lbnQtcGFyc2UtYnVmZmVy Jywgd2hpY2gKcGFyc2VzIE9yZyBzeW50YXggaW5zaWRlIHRoZSBjdXJyZW50IGJ1ZmZlciwgdGFr aW5nIGludG8gYWNjb3VudApyZWdpb24sIG5hcnJvd2luZywgb3IgZXZlbiB2aXNpYmlsaXR5IGlm IHNwZWNpZmllZCwgYW5kCmBvcmctZWxlbWVudC1wYXJzZS1zZWNvbmRhcnktc3RyaW5nJywgd2hp Y2ggcGFyc2VzIG9iamVjdHMgd2l0aGluCmEgZ2l2ZW4gc3RyaW5nLgoKVGhlIChhbG1vc3QpIGFs bWlnaHR5IGBvcmctZWxlbWVudC1tYXAnIGFsbG93cyB0byBhcHBseSBhIGZ1bmN0aW9uCm9uIGVs ZW1lbnRzIG9yIG9iamVjdHMgbWF0Y2hpbmcgc29tZSB0eXBlLCBhbmQgYWNjdW11bGF0ZSB0aGUK cmVzdWx0aW5nIHZhbHVlcy4gIEluIGFuIGV4cG9ydCBzaXR1YXRpb24sIGl0IGFsc28gc2tpcHMg dW5uZWVkZWQKcGFydHMgb2YgdGhlIHBhcnNlIHRyZWUuCgojK2JlZ2luX3NyYyBlbWFjcy1saXNw CihkZWZ1biBvcmctZWxlbWVudC1wYXJzZS1idWZmZXIgKCZvcHRpb25hbCBncmFudWxhcml0eSB2 aXNpYmxlLW9ubHkpCiAgIlJlY3Vyc2l2ZWx5IHBhcnNlIHRoZSBidWZmZXIgYW5kIHJldHVybiBz dHJ1Y3R1cmUuCklmIG5hcnJvd2luZyBpcyBpbiBlZmZlY3QsIG9ubHkgcGFyc2UgdGhlIHZpc2li bGUgcGFydCBvZiB0aGUKYnVmZmVyLgoKT3B0aW9uYWwgYXJndW1lbnQgR1JBTlVMQVJJVFkgZGV0 ZXJtaW5lcyB0aGUgZGVwdGggb2YgdGhlCnJlY3Vyc2lvbi4gIEl0IGNhbiBiZSBzZXQgdG8gdGhl IGZvbGxvd2luZyBzeW1ib2xzOgoKYGhlYWRsaW5lJyAgICAgICAgICBPbmx5IHBhcnNlIGhlYWRs aW5lcy4KYGdyZWF0ZXItZWxlbWVudCcgICBEb24ndCByZWN1cnNlIGludG8gZ3JlYXRlciBlbGVt ZW50cyBleGNlcHRlZAoJCSAgICBoZWFkbGluZXMgYW5kIHNlY3Rpb25zLiAgVGh1cywgZWxlbWVu dHMKCQkgICAgcGFyc2VkIGFyZSB0aGUgdG9wLWxldmVsIG9uZXMuCmBlbGVtZW50JyAgICAgICAg ICAgUGFyc2UgZXZlcnl0aGluZyBidXQgb2JqZWN0cyBhbmQgcGxhaW4gdGV4dC4KYG9iamVjdCcg ICAgICAgICAgICBQYXJzZSB0aGUgY29tcGxldGUgYnVmZmVyIChkZWZhdWx0KS4KCldoZW4gVklT SUJMRS1PTkxZIGlzIG5vbi1uaWwsIGRvbid0IHBhcnNlIGNvbnRlbnRzIG9mIGhpZGRlbgplbGVt ZW50cy4KCkFuIGVsZW1lbnQgb3IgYW4gb2JqZWN0cyBpcyByZXByZXNlbnRlZCBhcyBhIGxpc3Qg d2l0aCB0aGUKcGF0dGVybiAoVFlQRSBQUk9QRVJUSUVTIENPTlRFTlRTKSwgd2hlcmUgOgoKICBU WVBFIGlzIGEgc3ltYm9sIGRlc2NyaWJpbmcgdGhlIGVsZW1lbnQgb3Igb2JqZWN0LiAgU2VlCiAg YG9yZy1lbGVtZW50LWFsbC1lbGVtZW50cycgYW5kIGBvcmctZWxlbWVudC1hbGwtb2JqZWN0cycg Zm9yIGFuCiAgZXhoYXVzdGl2ZSBsaXN0IG9mIHN1Y2ggc3ltYm9scy4gIE9uZSBjYW4gcmV0cmll dmUgaXQgd2l0aAogIGBvcmctZWxlbWVudC10eXBlJyBmdW5jdGlvbi4KCiAgUFJPUEVSVElFUyBp cyB0aGUgbGlzdCBvZiBhdHRyaWJ1dGVzIGF0dGFjaGVkIHRvIHRoZSBlbGVtZW50IG9yCiAgb2Jq ZWN0LCBhcyBhIHBsaXN0LiAgQWx0aG91Z2ggbW9zdCBvZiB0aGVtIGFyZSBzcGVjaWZpYyB0byB0 aGUKICBlbGVtZW50IG9yIG9iamVjdCB0eXBlLCBhbGwgdHlwZXMgc2hhcmUgYDpiZWdpbicsIGA6 ZW5kJywKICBgOnBvc3QtYmxhbmsnIGFuZCBgOnBhcmVudCcgcHJvcGVydGllcywgd2hpY2ggcmVz cGVjdGl2ZWx5CiAgcmVmZXIgdG8gYnVmZmVyIHBvc2l0aW9uIHdoZXJlIHRoZSBlbGVtZW50IG9y IG9iamVjdCBzdGFydHMsCiAgZW5kcywgdGhlIG51bWJlciBvZiB3aGl0ZSBzcGFjZXMgb3IgYmxh bmsgbGluZXMgYWZ0ZXIgaXQsIGFuZAogIHRoZSBlbGVtZW50IG9yIG9iamVjdCBjb250YWluaW5n IGl0LiAgUHJvcGVydGllcyB2YWx1ZXMgY2FuIGJlCiAgb2J0YWluZWQgYnkgdXNpbmcgYG9yZy1l bGVtZW50LXByb3BlcnR5JyBmdW5jdGlvbi4KCiAgQ09OVEVOVFMgaXMgYSBsaXN0IG9mIGVsZW1l bnRzLCBvYmplY3RzIG9yIHJhdyBzdHJpbmdzCiAgY29udGFpbmVkIGluIHRoZSBjdXJyZW50IGVs ZW1lbnQgb3Igb2JqZWN0LCB3aGVuIGFwcGxpY2FibGUuCiAgT25lIGNhbiBhY2Nlc3MgdGhlbSB3 aXRoIGBvcmctZWxlbWVudC1jb250ZW50cycgZnVuY3Rpb24uCgpUaGUgT3JnIGJ1ZmZlciBoYXMg YG9yZy1kYXRhJyBhcyB0eXBlIGFuZCBuaWwgYXMgcHJvcGVydGllcy4KYG9yZy1lbGVtZW50LW1h cCcgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZmluZCBzcGVjaWZpYyBlbGVtZW50cwpvciBvYmpl Y3RzIHdpdGhpbiB0aGUgcGFyc2UgdHJlZS4KClRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGF0IGN1 cnJlbnQgbWFqb3IgbW9kZSBpcyBgb3JnLW1vZGUnLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtcGFy c2Utc2Vjb25kYXJ5LXN0cmluZyAoc3RyaW5nIHJlc3RyaWN0aW9uICZvcHRpb25hbCBwYXJlbnQp CiAgIlJlY3Vyc2l2ZWx5IHBhcnNlIG9iamVjdHMgaW4gU1RSSU5HIGFuZCByZXR1cm4gc3RydWN0 dXJlLgoKUkVTVFJJQ1RJT04gaXMgYSBzeW1ib2wgbGltaXRpbmcgdGhlIG9iamVjdCB0eXBlcyB0 aGF0IHdpbGwgYmUKbG9va2VkIGFmdGVyLgoKT3B0aW9uYWwgYXJndW1lbnQgUEFSRU5ULCB3aGVu IG5vbi1uaWwsIGlzIHRoZSBlbGVtZW50IG9yIG9iamVjdApjb250YWluaW5nIHRoZSBzZWNvbmRh cnkgc3RyaW5nLiAgSXQgaXMgdXNlZCB0byBzZXQgY29ycmVjdGx5CmA6cGFyZW50JyBwcm9wZXJ0 eSB3aXRoaW4gdGhlIHN0cmluZy4iCiAgOzsgQ29weSBidWZmZXItbG9jYWwgdmFyaWFibGVzIGxp c3RlZCBpbgogIDs7IGBvcmctZWxlbWVudC1vYmplY3QtdmFyaWFibGVzJyBpbnRvIHRlbXBvcmFy eSBidWZmZXIuICBUaGlzIGlzCiAgOzsgcmVxdWlyZWQgc2luY2Ugb2JqZWN0IHBhcnNpbmcgaXMg ZGVwZW5kZW50IG9uIHRoZXNlIHZhcmlhYmxlcy4pCgooZGVmdW4gb3JnLWVsZW1lbnQtbWFwCiAg KGRhdGEgdHlwZXMgZnVuICZvcHRpb25hbCBpbmZvIGZpcnN0LW1hdGNoIG5vLXJlY3Vyc2lvbiB3 aXRoLWFmZmlsaWF0ZWQpCiAgIk1hcCBhIGZ1bmN0aW9uIG9uIHNlbGVjdGVkIGVsZW1lbnRzIG9y IG9iamVjdHMuCgpEQVRBIGlzIGEgcGFyc2UgdHJlZSwgYW4gZWxlbWVudCwgYW4gb2JqZWN0LCBh IHN0cmluZywgb3IgYSBsaXN0Cm9mIHN1Y2ggY29uc3RydWN0cy4gIFRZUEVTIGlzIGEgc3ltYm9s IG9yIGxpc3Qgb2Ygc3ltYm9scyBvZgplbGVtZW50cyBvciBvYmplY3RzIHR5cGVzIChzZWUgYG9y Zy1lbGVtZW50LWFsbC1lbGVtZW50cycgYW5kCmBvcmctZWxlbWVudC1hbGwtb2JqZWN0cycgZm9y IGEgY29tcGxldGUgbGlzdCBvZiB0eXBlcykuICBGVU4gaXMKdGhlIGZ1bmN0aW9uIGNhbGxlZCBv biB0aGUgbWF0Y2hpbmcgZWxlbWVudCBvciBvYmplY3QuICBJdCBoYXMgdG8KYWNjZXB0IG9uZSBh cmd1bWVudDogdGhlIGVsZW1lbnQgb3Igb2JqZWN0IGl0c2VsZi4KCldoZW4gb3B0aW9uYWwgYXJn dW1lbnQgSU5GTyBpcyBub24tbmlsLCBpdCBzaG91bGQgYmUgYSBwbGlzdApob2xkaW5nIGV4cG9y dCBvcHRpb25zLiAgSW4gdGhhdCBjYXNlLCBwYXJ0cyBvZiB0aGUgcGFyc2UgdHJlZQpub3QgZXhw b3J0YWJsZSBhY2NvcmRpbmcgdG8gdGhhdCBwcm9wZXJ0eSBsaXN0IHdpbGwgYmUgc2tpcHBlZC4K CldoZW4gb3B0aW9uYWwgYXJndW1lbnQgRklSU1QtTUFUQ0ggaXMgbm9uLW5pbCwgc3RvcCBhdCB0 aGUgZmlyc3QKbWF0Y2ggZm9yIHdoaWNoIEZVTiBkb2Vzbid0IHJldHVybiBuaWwsIGFuZCByZXR1 cm4gdGhhdCB2YWx1ZS4KCk9wdGlvbmFsIGFyZ3VtZW50IE5PLVJFQ1VSU0lPTiBpcyBhIHN5bWJv bCBvciBhIGxpc3Qgb2Ygc3ltYm9scwpyZXByZXNlbnRpbmcgZWxlbWVudHMgb3Igb2JqZWN0cyB0 eXBlcy4gIGBvcmctZWxlbWVudC1tYXAnIHdvbid0CmVudGVyIGFueSByZWN1cnNpdmUgZWxlbWVu dCBvciBvYmplY3Qgd2hvc2UgdHlwZSBiZWxvbmdzIHRvIHRoYXQKbGlzdC4gIFRob3VnaCwgRlVO IGNhbiBzdGlsbCBiZSBhcHBsaWVkIG9uIHRoZW0uCgpXaGVuIG9wdGlvbmFsIGFyZ3VtZW50IFdJ VEgtQUZGSUxJQVRFRCBpcyBub24tbmlsLCBGVU4gd2lsbCBhbHNvCmFwcGx5IHRvIG1hdGNoaW5n IG9iamVjdHMgd2l0aGluIHBhcnNlZCBhZmZpbGlhdGVkIGtleXdvcmRzIChzZWUKYG9yZy1lbGVt ZW50LXBhcnNlZC1rZXl3b3JkcycpLgoKTmlsIHZhbHVlcyByZXR1cm5lZCBmcm9tIEZVTiBkbyBu b3QgYXBwZWFyIGluIHRoZSByZXN1bHRzLgoKCkV4YW1wbGVzOgotLS0tLS0tLS0KCkFzc3VtaW5n IFRSRUUgaXMgYSB2YXJpYWJsZSBjb250YWluaW5nIGFuIE9yZyBidWZmZXIgcGFyc2UgdHJlZSwK dGhlIGZvbGxvd2luZyBleGFtcGxlIHdpbGwgcmV0dXJuIGEgZmxhdCBsaXN0IG9mIGFsbCBgc3Jj LWJsb2NrJwphbmQgYGV4YW1wbGUtYmxvY2snIGVsZW1lbnRzIGluIGl0OgoKICBcKG9yZy1lbGVt ZW50LW1hcCB0cmVlICcoZXhhbXBsZS1ibG9jayBzcmMtYmxvY2spICdpZGVudGl0eSkKClRoZSBm b2xsb3dpbmcgc25pcHBldCB3aWxsIGZpbmQgdGhlIGZpcnN0IGhlYWRsaW5lIHdpdGggYSBsZXZl bApvZiAxIGFuZCBhIFwicGhvbmVcIiB0YWcsIGFuZCB3aWxsIHJldHVybiBpdHMgYmVnaW5uaW5n IHBvc2l0aW9uOgoKICBcKG9yZy1lbGVtZW50LW1hcCB0cmVlICdoZWFkbGluZQogICBcKGxhbWJk YSAoaGwpCiAgICAgXChhbmQgKD0gKG9yZy1lbGVtZW50LXByb3BlcnR5IDpsZXZlbCBobCkgMSkK ICAgICAgICAgIFwobWVtYmVyIFwicGhvbmVcIiAob3JnLWVsZW1lbnQtcHJvcGVydHkgOnRhZ3Mg aGwpKQogICAgICAgICAgXChvcmctZWxlbWVudC1wcm9wZXJ0eSA6YmVnaW4gaGwpKSkKICAgbmls IHQpCgpUaGUgbmV4dCBleGFtcGxlIHdpbGwgcmV0dXJuIGEgZmxhdCBsaXN0IG9mIGFsbCBgcGxh aW4tbGlzdCcgdHlwZQplbGVtZW50cyBpbiBUUkVFIHRoYXQgYXJlIG5vdCBhIHN1Yi1saXN0IHRo ZW1zZWx2ZXM6CgogIFwob3JnLWVsZW1lbnQtbWFwIHRyZWUgJ3BsYWluLWxpc3QgJ2lkZW50aXR5 IG5pbCBuaWwgJ3BsYWluLWxpc3QpCgpFdmVudHVhbGx5LCB0aGlzIGV4YW1wbGUgd2lsbCByZXR1 cm4gYSBmbGF0IGxpc3Qgb2YgYWxsIGBib2xkJwp0eXBlIG9iamVjdHMgY29udGFpbmluZyBhIGBs YXRleC1zbmlwcGV0JyB0eXBlIG9iamVjdCwgZXZlbgpsb29raW5nIGludG8gY2FwdGlvbnM6Cgog IFwob3JnLWVsZW1lbnQtbWFwIHRyZWUgJ2JvbGQKICAgXChsYW1iZGEgKGIpCiAgICAgXChhbmQg KG9yZy1lbGVtZW50LW1hcCBiICdsYXRleC1zbmlwcGV0ICdpZGVudGl0eSBuaWwgdCkgYikpCiAg IG5pbCBuaWwgbmlsIHQpIgogIDs7IEVuc3VyZSBUWVBFUyBhbmQgTk8tUkVDVVJTSU9OIGFyZSBh IGxpc3QsIGV2ZW4gb2Ygb25lIGVsZW1lbnQuCiAgKHVubGVzcyAobGlzdHAgdHlwZXMpIChzZXRx IHR5cGVzIChsaXN0IHR5cGVzKSkpCiAgKHVubGVzcyAobGlzdHAgbm8tcmVjdXJzaW9uKSAoc2V0 cSBuby1yZWN1cnNpb24gKGxpc3Qgbm8tcmVjdXJzaW9uKSkpCiAgOzsgUmVjdXJzaW9uIGRlcHRo IGlzIGRldGVybWluZWQgYnkgLS1DQVRFR09SWS4KICAobGV0KiAoKC0tY2F0ZWdvcnkKCSAgKGNh dGNoICdmb3VuZAoJICAgIChsZXQgKChjYXRlZ29yeSAnZ3JlYXRlci1lbGVtZW50cykpCgkgICAg ICAobWFwYyAobGFtYmRhICh0eXBlKQoJCSAgICAgIChjb25kICgob3IgKG1lbXEgdHlwZSBvcmct ZWxlbWVudC1hbGwtb2JqZWN0cykKCQkJCSAoZXEgdHlwZSAncGxhaW4tdGV4dCkpCgkJCSAgICAg OzsgSWYgb25lIG9iamVjdCBpcyBmb3VuZCwgdGhlIGZ1bmN0aW9uCgkJCSAgICAgOzsgaGFzIHRv IHJlY3Vyc2UgaW50byBldmVyeSBvYmplY3QuCgkJCSAgICAgKHRocm93ICdmb3VuZCAnb2JqZWN0 cykpCgkJCSAgICAoKG5vdCAobWVtcSB0eXBlIG9yZy1lbGVtZW50LWdyZWF0ZXItZWxlbWVudHMp KQoJCQkgICAgIDs7IElmIG9uZSByZWd1bGFyIGVsZW1lbnQgaXMgZm91bmQsIHRoZQoJCQkgICAg IDs7IGZ1bmN0aW9uIGhhcyB0byByZWN1cnNlLCBhdCBsZWFzdCwKCQkJICAgICA7OyBpbnRvIGV2 ZXJ5IGVsZW1lbnQgaXQgZW5jb3VudGVycy4KCQkJICAgICAoYW5kIChub3QgKGVxIGNhdGVnb3J5 ICdlbGVtZW50cykpCgkJCQkgIChzZXRxIGNhdGVnb3J5ICdlbGVtZW50cykpKSkpCgkJICAgIHR5 cGVzKQoJICAgICAgY2F0ZWdvcnkpKSkKCSA7OyBDb21wdXRlIHByb3BlcnRpZXMgZm9yIGFmZmls aWF0ZWQga2V5d29yZHMgaWYgbmVjZXNzYXJ5LgoJICgtLWFmZmlsaWF0ZWQtYWxpc3QKCSAgKGFu ZCB3aXRoLWFmZmlsaWF0ZWQKCSAgICAgICAobWFwY2FyIChsYW1iZGEgKGt3ZCkKCQkJIChjb25z IGt3ZCAoaW50ZXJuIChjb25jYXQgIjoiIChkb3duY2FzZSBrd2QpKSkpKQoJCSAgICAgICBvcmct ZWxlbWVudC1hZmZpbGlhdGVkLWtleXdvcmRzKSkpCgkgLS1hY2MKCSAtLXdhbGstdHJlZQoJICgt LXdhbGstdHJlZQoJICAoZnVuY3Rpb24KCSAgIChsYW1iZGEgKC0tZGF0YSkKCSAgICAgOzsgUmVj dXJzaXZlbHkgd2FsayBEQVRBLiAgSU5GTywgaWYgbm9uLW5pbCwgaXMgYSBwbGlzdAoJICAgICA7 OyBob2xkaW5nIGNvbnRleHR1YWwgaW5mb3JtYXRpb24uCgkgICAgIChsZXQgKCgtLXR5cGUgKG9y Zy1lbGVtZW50LXR5cGUgLS1kYXRhKSkpCgkgICAgICAgKGNvbmQKCQkoKG5vdCAtLWRhdGEpKQoJ CTs7IElnbm9yZWQgZWxlbWVudCBpbiBhbiBleHBvcnQgY29udGV4dC4KCQkoKGFuZCBpbmZvICht ZW1xIC0tZGF0YSAocGxpc3QtZ2V0IGluZm8gOmlnbm9yZS1saXN0KSkpKQoJCTs7IExpc3Qgb2Yg ZWxlbWVudHMgb3Igb2JqZWN0cy4KCQkoKG5vdCAtLXR5cGUpIChtYXBjIC0td2Fsay10cmVlIC0t ZGF0YSkpCgkJOzsgVW5jb25kaXRpb25hbGx5IGVudGVyIHBhcnNlIHRyZWVzLgoJCSgoZXEgLS10 eXBlICdvcmctZGF0YSkKCQkgKG1hcGMgLS13YWxrLXRyZWUgKG9yZy1lbGVtZW50LWNvbnRlbnRz IC0tZGF0YSkpKQoJCSh0CgkJIDs7IENoZWNrIGlmIFRZUEUgaXMgbWF0Y2hpbmcgYW1vbmcgVFlQ RVMuICBJZiBzbywKCQkgOzsgYXBwbHkgRlVOIHRvIC0tREFUQSBhbmQgYWNjdW11bGF0ZSByZXR1 cm4gdmFsdWUKCQkgOzsgaW50byAtLUFDQyAob3IgZXhpdCBpZiBGSVJTVC1NQVRDSCBpcyBub24t bmlsKS4KCQkgKHdoZW4gKG1lbXEgLS10eXBlIHR5cGVzKQoJCSAgIChsZXQgKChyZXN1bHQgKGZ1 bmNhbGwgZnVuIC0tZGF0YSkpKQoJCSAgICAgKGNvbmQgKChub3QgcmVzdWx0KSkKCQkJICAgKGZp cnN0LW1hdGNoICh0aHJvdyAnLS1tYXAtZmlyc3QtbWF0Y2ggcmVzdWx0KSkKCQkJICAgKHQgKHB1 c2ggcmVzdWx0IC0tYWNjKSkpKSkKCQkgOzsgSWYgLS1EQVRBIGhhcyBhIHNlY29uZGFyeSBzdHJp bmcgdGhhdCBjYW4gY29udGFpbgoJCSA7OyBvYmplY3RzIHdpdGggdGhlaXIgdHlwZSBhbW9uZyBU WVBFUywgbG9vayBpbnRvIGl0LgoJCSAod2hlbiAoYW5kIChlcSAtLWNhdGVnb3J5ICdvYmplY3Rz KSAobm90IChzdHJpbmdwIC0tZGF0YSkpKQoJCSAgIChsZXQgKChzZWMtcHJvcAoJCQkgIChhc3Nx IC0tdHlwZSBvcmctZWxlbWVudC1zZWNvbmRhcnktdmFsdWUtYWxpc3QpKSkKCQkgICAgICh3aGVu IHNlYy1wcm9wCgkJICAgICAgIChmdW5jYWxsIC0td2Fsay10cmVlCgkJCQkob3JnLWVsZW1lbnQt cHJvcGVydHkgKGNkciBzZWMtcHJvcCkgLS1kYXRhKSkpKSkKCQkgOzsgSWYgLS1EQVRBIGhhcyBh bnkgYWZmaWxpYXRlZCBrZXl3b3JkcyBhbmQKCQkgOzsgV0lUSC1BRkZJTElBVEVEIGlzIG5vbi1u aWwsIGxvb2sgZm9yIG9iamVjdHMgaW4KCQkgOzsgdGhlbS4KCQkgKHdoZW4gKGFuZCB3aXRoLWFm ZmlsaWF0ZWQKCQkJICAgIChlcSAtLWNhdGVnb3J5ICdvYmplY3RzKQoJCQkgICAgKG1lbXEgLS10 eXBlIG9yZy1lbGVtZW50LWFsbC1lbGVtZW50cykpCgkJICAgKG1hcGMgKGxhbWJkYSAoa3dkLXBh aXIpCgkJCSAgIChsZXQgKChrd2QgKGNhciBrd2QtcGFpcikpCgkJCQkgKHZhbHVlIChvcmctZWxl bWVudC1wcm9wZXJ0eQoJCQkJCSAoY2RyIGt3ZC1wYWlyKSAtLWRhdGEpKSkKCQkJICAgICA7OyBQ YXkgYXR0ZW50aW9uIHRvIHRoZSB0eXBlIG9mIHZhbHVlLgoJCQkgICAgIDs7IFByZXNlcnZlIG9y ZGVyIGZvciBtdWx0aXBsZSBrZXl3b3Jkcy4KCQkJICAgICAoY29uZAoJCQkgICAgICAoKG5vdCB2 YWx1ZSkpCgkJCSAgICAgICgoYW5kIChtZW1iZXIga3dkIG9yZy1lbGVtZW50LW11bHRpcGxlLWtl eXdvcmRzKQoJCQkJICAgIChtZW1iZXIga3dkIG9yZy1lbGVtZW50LWR1YWwta2V5d29yZHMpKQoJ CQkgICAgICAgKG1hcGMgKGxhbWJkYSAobGluZSkKCQkJCSAgICAgICAoZnVuY2FsbCAtLXdhbGst dHJlZSAoY2RyIGxpbmUpKQoJCQkJICAgICAgIChmdW5jYWxsIC0td2Fsay10cmVlIChjYXIgbGlu ZSkpKQoJCQkJICAgICAocmV2ZXJzZSB2YWx1ZSkpKQoJCQkgICAgICAoKG1lbWJlciBrd2Qgb3Jn LWVsZW1lbnQtbXVsdGlwbGUta2V5d29yZHMpCgkJCSAgICAgICAobWFwYyAobGFtYmRhIChsaW5l KSAoZnVuY2FsbCAtLXdhbGstdHJlZSBsaW5lKSkKCQkJCSAgICAgKHJldmVyc2UgdmFsdWUpKSkK CQkJICAgICAgKChtZW1iZXIga3dkIG9yZy1lbGVtZW50LWR1YWwta2V5d29yZHMpCgkJCSAgICAg ICAoZnVuY2FsbCAtLXdhbGstdHJlZSAoY2RyIHZhbHVlKSkKCQkJICAgICAgIChmdW5jYWxsIC0t d2Fsay10cmVlIChjYXIgdmFsdWUpKSkKCQkJICAgICAgKHQgKGZ1bmNhbGwgLS13YWxrLXRyZWUg dmFsdWUpKSkpKQoJCQkgLS1hZmZpbGlhdGVkLWFsaXN0KSkKCQkgOzsgRGV0ZXJtaW5lIGlmIGEg cmVjdXJzaW9uIGludG8gLS1EQVRBIGlzIHBvc3NpYmxlLgoJCSAoY29uZAoJCSAgOzsgLS1UWVBF IGlzIGV4cGxpY2l0bHkgcmVtb3ZlZCBmcm9tIHJlY3Vyc2lvbi4KCQkgICgobWVtcSAtLXR5cGUg bm8tcmVjdXJzaW9uKSkKCQkgIDs7IC0tREFUQSBoYXMgbm8gY29udGVudHMuCgkJICAoKG5vdCAo b3JnLWVsZW1lbnQtY29udGVudHMgLS1kYXRhKSkpCgkJICA7OyBMb29raW5nIGZvciBncmVhdGVy IGVsZW1lbnRzIGJ1dCAtLURBVEEgaXMgc2ltcGx5CgkJICA7OyBhbiBlbGVtZW50IG9yIGFuIG9i amVjdC4KCQkgICgoYW5kIChlcSAtLWNhdGVnb3J5ICdncmVhdGVyLWVsZW1lbnRzKQoJCQkobm90 IChtZW1xIC0tdHlwZSBvcmctZWxlbWVudC1ncmVhdGVyLWVsZW1lbnRzKSkpKQoJCSAgOzsgTG9v a2luZyBmb3IgZWxlbWVudHMgYnV0IC0tREFUQSBpcyBhbiBvYmplY3QuCgkJICAoKGFuZCAoZXEg LS1jYXRlZ29yeSAnZWxlbWVudHMpCgkJCShtZW1xIC0tdHlwZSBvcmctZWxlbWVudC1hbGwtb2Jq ZWN0cykpKQoJCSAgOzsgSW4gYW55IG90aGVyIGNhc2UsIG1hcCBjb250ZW50cy4KCQkgICh0ICht YXBjIC0td2Fsay10cmVlIChvcmctZWxlbWVudC1jb250ZW50cyAtLWRhdGEpKSkpKSkpKSkpKQog ICAgKGNhdGNoICctLW1hcC1maXJzdC1tYXRjaAogICAgICAoZnVuY2FsbCAtLXdhbGstdHJlZSBk YXRhKQogICAgICA7OyBSZXR1cm4gdmFsdWUgaW4gYSBwcm9wZXIgb3JkZXIuCiAgICAgIChucmV2 ZXJzZSAtLWFjYykpKSkKKHB1dCAnb3JnLWVsZW1lbnQtbWFwICdsaXNwLWluZGVudC1mdW5jdGlv biAyKQojK2VuZF9zcmMKClRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIGFyZSBpbnRlcm5hbCBwYXJ0 cyBvZiB0aGUgcGFyc2VyLgoKVGhlIGZpcnN0IG9uZSwgYG9yZy1lbGVtZW50LS1wYXJzZS1lbGVt ZW50cycgYWN0cyBhdCB0aGUgZWxlbWVudCdzCmxldmVsLgoKVGhlIHNlY29uZCBvbmUsIGBvcmct ZWxlbWVudC0tcGFyc2Utb2JqZWN0cycgYXBwbGllcyBvbiBhbGwgb2JqZWN0cwpvZiBhIHBhcmFn cmFwaCBvciBhIHNlY29uZGFyeSBzdHJpbmcuICBJdCB1c2VzCmBvcmctZWxlbWVudC0tZ2V0LW5l eHQtb2JqZWN0LWNhbmRpZGF0ZXMnIHRvIG9wdGltaXplIHRoZSBzZWFyY2ggb2YKdGhlIG5leHQg b2JqZWN0IGluIHRoZSBidWZmZXIuCgpNb3JlIHByZWNpc2VseSwgdGhhdCBmdW5jdGlvbiBsb29r cyBmb3IgZXZlcnkgYWxsb3dlZCBvYmplY3QgdHlwZQpmaXJzdC4gIFRoZW4sIGl0IGRpc2NhcmRz IGZhaWxlZCBzZWFyY2hlcywga2VlcHMgZnVydGhlciBtYXRjaGVzLAphbmQgc2VhcmNoZXMgYWdh aW4gdHlwZXMgbWF0Y2hlZCBiZWhpbmQgcG9pbnQsIGZvciBzdWJzZXF1ZW50CmNhbGxzLiAgVGh1 cywgc2VhcmNoaW5nIGZvciBhIGdpdmVuIHR5cGUgZmFpbHMgb25seSBvbmNlLCBhbmQgZXZlcnkK b2JqZWN0IGlzIHNlYXJjaGVkIG9ubHkgb25jZSBhdCB0b3AgbGV2ZWwgKGJ1dCBzb21ldGltZXMg bW9yZSBmb3IKbmVzdGVkIHR5cGVzKS4KCiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9y Zy1lbGVtZW50LS1wYXJzZS1lbGVtZW50cwogIChiZWcgZW5kIHNwZWNpYWwgc3RydWN0dXJlIGdy YW51bGFyaXR5IHZpc2libGUtb25seSBhY2MpCiAgIlBhcnNlIGVsZW1lbnRzIGJldHdlZW4gQkVH IGFuZCBFTkQgcG9zaXRpb25zLgoKU1BFQ0lBTCBwcmlvcml0aXplIHNvbWUgZWxlbWVudHMgb3Zl ciB0aGUgb3RoZXJzLiAgSXQgY2FuIGJlIHNldAp0byBgZmlyc3Qtc2VjdGlvbicsIGBxdW90ZS1z ZWN0aW9uJywgYHNlY3Rpb24nIGBpdGVtJyBvcgpgdGFibGUtcm93Jy4KCldoZW4gdmFsdWUgaXMg YGl0ZW0nLCBTVFJVQ1RVUkUgd2lsbCBiZSB1c2VkIGFzIHRoZSBjdXJyZW50IGxpc3QKc3RydWN0 dXJlLgoKR1JBTlVMQVJJVFkgZGV0ZXJtaW5lcyB0aGUgZGVwdGggb2YgdGhlIHJlY3Vyc2lvbi4g IFNlZQpgb3JnLWVsZW1lbnQtcGFyc2UtYnVmZmVyJyBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KCldo ZW4gVklTSUJMRS1PTkxZIGlzIG5vbi1uaWwsIGRvbid0IHBhcnNlIGNvbnRlbnRzIG9mIGhpZGRl bgplbGVtZW50cy4KCkVsZW1lbnRzIGFyZSBhY2N1bXVsYXRlZCBpbnRvIEFDQy4iKQoKKGRlZnVu IG9yZy1lbGVtZW50LS1wYXJzZS1vYmplY3RzIChiZWcgZW5kIGFjYyByZXN0cmljdGlvbikKICAi UGFyc2Ugb2JqZWN0cyBiZXR3ZWVuIEJFRyBhbmQgRU5EIGFuZCByZXR1cm4gcmVjdXJzaXZlIHN0 cnVjdHVyZS4KCk9iamVjdHMgYXJlIGFjY3VtdWxhdGVkIGluIEFDQy4KClJFU1RSSUNUSU9OIGlz IGEgbGlzdCBvZiBvYmplY3Qgc3VjY2Vzc29ycyB3aGljaCBhcmUgYWxsb3dlZCBpbgp0aGUgY3Vy cmVudCBvYmplY3QuIikKCihkZWZ1biBvcmctZWxlbWVudC0tZ2V0LW5leHQtb2JqZWN0LWNhbmRp ZGF0ZXMgKGxpbWl0IHJlc3RyaWN0aW9uIG9iamVjdHMpCiAgIlJldHVybiBhbiBhbGlzdCBvZiBj YW5kaWRhdGVzIGZvciB0aGUgbmV4dCBvYmplY3QuCgpMSU1JVCBib3VuZHMgdGhlIHNlYXJjaCwg YW5kIFJFU1RSSUNUSU9OIG5hcnJvd3MgY2FuZGlkYXRlcyB0bwpzb21lIG9iamVjdCBzdWNjZXNz b3JzLgoKT0JKRUNUUyBpcyB0aGUgcHJldmlvdXMgY2FuZGlkYXRlcyBhbGlzdC4gIElmIGl0IGlz IHNldCB0bwpgaW5pdGlhbCcsIG5vIHNlYXJjaCBoYXMgYmVlbiBkb25lIGJlZm9yZSwgYW5kIGFs bCBzeW1ib2xzIGluClJFU1RSSUNUSU9OIHNob3VsZCBiZSBsb29rZWQgYWZ0ZXIuCgpSZXR1cm4g dmFsdWUgaXMgYW4gYWxpc3Qgd2hvc2UgQ0FSIGlzIHRoZSBvYmplY3QgdHlwZSBhbmQgQ0RSIGl0 cwpiZWdpbm5pbmcgcG9zaXRpb24uIikKCgojK2VuZF9zcmMKCiogVG93YXJkcyBBIEJpamVjdGl2 ZSBQcm9jZXNzCgpUaGUgcGFyc2UgdHJlZSBvYnRhaW5lZCB3aXRoIGBvcmctZWxlbWVudC1wYXJz ZS1idWZmZXInIGlzIHJlYWxseQphIHNuYXBzaG90IG9mIHRoZSBjb3JyZXNwb25kaW5nIE9yZyBi dWZmZXIuICBUaGVyZWZvcmUsIGl0IGNhbiBiZQppbnRlcnByZXRlZCBhbmQgZXhwYW5kZWQgaW50 byBhIHN0cmluZyB3aXRoIGNhbm9uaWNhbCBPcmcgc3ludGF4LgpIZW5jZSBgb3JnLWVsZW1lbnQt aW50ZXJwcmV0LWRhdGEnLgoKVGhlIGZ1bmN0aW9uIHJlbGllcyBpbnRlcm5hbGx5IG9uCmBvcmct ZWxlbWVudC0taW50ZXJwcmV0LWFmZmlsaWF0ZWQta2V5d29yZHMnLgoKIyMjYXV0b2xvYWQKIyti ZWdpbl9zcmMgZW1hY3MtbGlzcAooZGVmdW4gb3JnLWVsZW1lbnQtaW50ZXJwcmV0LWRhdGEgKGRh dGEgJm9wdGlvbmFsIHBhcmVudCkKICAiSW50ZXJwcmV0IERBVEEgYXMgT3JnIHN5bnRheC4KCkRB VEEgaXMgYSBwYXJzZSB0cmVlLCBhbiBlbGVtZW50LCBhbiBvYmplY3Qgb3IgYSBzZWNvbmRhcnkg c3RyaW5nCnRvIGludGVycHJldC4KCk9wdGlvbmFsIGFyZ3VtZW50IFBBUkVOVCBpcyB1c2VkIGZv ciByZWN1cnNpdmUgY2FsbHMuICBJdCBjb250YWlucwp0aGUgZWxlbWVudCBvciBvYmplY3QgY29u dGFpbmluZyBkYXRhLCBvciBuaWwuCgpSZXR1cm4gT3JnIHN5bnRheCBhcyBhIHN0cmluZy4iKQoK KGRlZnVuIG9yZy1lbGVtZW50LS1pbnRlcnByZXQtYWZmaWxpYXRlZC1rZXl3b3JkcyAoZWxlbWVu dCkKICAiUmV0dXJuIEVMRU1FTlQncyBhZmZpbGlhdGVkIGtleXdvcmRzIGFzIE9yZyBzeW50YXgu CklmIHRoZXJlIGlzIG5vIGFmZmlsaWF0ZWQga2V5d29yZCwgcmV0dXJuIHRoZSBlbXB0eSBzdHJp bmcuIikKIytlbmRfc3JjCgpCZWNhdXNlIGludGVycHJldGF0aW9uIG9mIHRoZSBwYXJzZSB0cmVl IG11c3QgcmV0dXJuIHRoZSBzYW1lCm51bWJlciBvZiBibGFuayBsaW5lcyBiZXR3ZWVuIGVsZW1l bnRzIGFuZCB0aGUgc2FtZSBudW1iZXIgb2Ygd2hpdGUKc3BhY2UgYWZ0ZXIgb2JqZWN0cywgc29t ZSBzcGVjaWFsIGNhcmUgbXVzdCBiZSBnaXZlbiB0byB3aGl0ZQpzcGFjZXMuCgpUaGUgZmlyc3Qg ZnVuY3Rpb24sIGBvcmctZWxlbWVudC1ub3JtYWxpemUtc3RyaW5nJywgZW5zdXJlcyBhbnkKc3Ry aW5nIGRpZmZlcmVudCBmcm9tIHRoZSBlbXB0eSBzdHJpbmcgd2lsbCBlbmQgd2l0aCBhIHNpbmds ZQpuZXdsaW5lIGNoYXJhY3Rlci4KClRoZSBzZWNvbmQgZnVuY3Rpb24sIGBvcmctZWxlbWVudC1u b3JtYWxpemUtY29udGVudHMnLCByZW1vdmVzCmdsb2JhbCBpbmRlbnRhdGlvbiBmcm9tIHRoZSBj b250ZW50cyBvZiB0aGUgY3VycmVudCBlbGVtZW50LgoKIytiZWdpbl9zcmMgZW1hY3MtbGlzcAoo ZGVmdW4gb3JnLWVsZW1lbnQtbm9ybWFsaXplLXN0cmluZyAocykKICAiRW5zdXJlIHN0cmluZyBT IGVuZHMgd2l0aCBhIHNpbmdsZSBuZXdsaW5lIGNoYXJhY3Rlci4KCklmIFMgaXNuJ3QgYSBzdHJp bmcgcmV0dXJuIGl0IHVuY2hhbmdlZC4gIElmIFMgaXMgdGhlIGVtcHR5CnN0cmluZywgcmV0dXJu IGl0LiAgT3RoZXJ3aXNlLCByZXR1cm4gYSBuZXcgc3RyaW5nIHdpdGggYSBzaW5nbGUKbmV3bGlu ZSBjaGFyYWN0ZXIgYXQgaXRzIGVuZC4iKQoKKGRlZnVuIG9yZy1lbGVtZW50LW5vcm1hbGl6ZS1j b250ZW50cyAoZWxlbWVudCAmb3B0aW9uYWwgaWdub3JlLWZpcnN0KQogICJOb3JtYWxpemUgcGxh aW4gdGV4dCBpbiBFTEVNRU5UJ3MgY29udGVudHMuCgpFTEVNRU5UIG11c3Qgb25seSBjb250YWlu IHBsYWluIHRleHQgYW5kIG9iamVjdHMuCgpJZiBvcHRpb25hbCBhcmd1bWVudCBJR05PUkUtRklS U1QgaXMgbm9uLW5pbCwgaWdub3JlIGZpcnN0IGxpbmUncwppbmRlbnRhdGlvbiB0byBjb21wdXRl IG1heGltYWwgY29tbW9uIGluZGVudGF0aW9uLgoKUmV0dXJuIHRoZSBub3JtYWxpemVkIGVsZW1l bnQgdGhhdCBpcyBlbGVtZW50IHdpdGggZ2xvYmFsCmluZGVudGF0aW9uIHJlbW92ZWQgZnJvbSBp dHMgY29udGVudHMuICBUaGUgZnVuY3Rpb24gYXNzdW1lcyB0aGF0CmluZGVudGF0aW9uIGlzIG5v dCBkb25lIHdpdGggVEFCIGNoYXJhY3RlcnMuIikKCgojK2VuZF9zcmMKCiogVGhlIFRvb2xib3gK ClRoZSBmaXJzdCBtb3ZlIGlzIHRvIGltcGxlbWVudCBhIHdheSB0byBvYnRhaW4gdGhlIHNtYWxs ZXN0IGVsZW1lbnQKY29udGFpbmluZyBwb2ludC4gIFRoaXMgaXMgdGhlIGpvYiBvZiBgb3JnLWVs ZW1lbnQtYXQtcG9pbnQnLiAgSXQKYmFzaWNhbGx5IGp1bXBzIGJhY2sgdG8gdGhlIGJlZ2lubmlu ZyBvZiBzZWN0aW9uIGNvbnRhaW5pbmcgcG9pbnQKYW5kIG1vdmVzLCBlbGVtZW50IGFmdGVyIGVs ZW1lbnQsIHdpdGgKYG9yZy1lbGVtZW50LS1jdXJyZW50LWVsZW1lbnQnIHVudGlsIHRoZSBjb250 YWluZXIgaXMgZm91bmQuICBOb3RlOgpXaGVuIHVzaW5nIGBvcmctZWxlbWVudC1hdC1wb2ludCcs IHNlY29uZGFyeSB2YWx1ZXMgYXJlIG5ldmVyCnBhcnNlZCBzaW5jZSB0aGUgZnVuY3Rpb24gZm9j dXNlcyBvbiBlbGVtZW50cywgbm90IG9uIG9iamVjdHMuCgpBdCBhIGRlZXBlciBsZXZlbCwgYG9y Zy1lbGVtZW50LWNvbnRleHQnIGxpc3RzIGFsbCBlbGVtZW50cyBhbmQKb2JqZWN0cyBjb250YWlu aW5nIHBvaW50LgoKYG9yZy1lbGVtZW50LW5lc3RlZC1wJyBhbmQgYG9yZy1lbGVtZW50LXN3YXAt QS1CJyBtYXkgYmUgdXNlZAppbnRlcm5hbGx5IGJ5IG5hdmlnYXRpb24gYW5kIG1hbmlwdWxhdGlv biB0b29scy4KCiMjI2F1dG9sb2FkCiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVuIG9yZy1l bGVtZW50LWF0LXBvaW50ICgmb3B0aW9uYWwga2VlcC10cmFpbCkKICAiRGV0ZXJtaW5lIGNsb3Nl c3QgZWxlbWVudCBhcm91bmQgcG9pbnQuCgpSZXR1cm4gdmFsdWUgaXMgYSBsaXN0IGxpa2UgKFRZ UEUgUFJPUFMpIHdoZXJlIFRZUEUgaXMgdGhlIHR5cGUKb2YgdGhlIGVsZW1lbnQgYW5kIFBST1BT IGEgcGxpc3Qgb2YgcHJvcGVydGllcyBhc3NvY2lhdGVkIHRvIHRoZQplbGVtZW50LgoKUG9zc2li bGUgdHlwZXMgYXJlIGRlZmluZWQgaW4gYG9yZy1lbGVtZW50LWFsbC1lbGVtZW50cycuClByb3Bl cnRpZXMgZGVwZW5kIG9uIGVsZW1lbnQgb3Igb2JqZWN0IHR5cGUsIGJ1dCBhbHdheXMgaW5jbHVk ZQpgOmJlZ2luJywgYDplbmQnLCBgOnBhcmVudCcgYW5kIGA6cG9zdC1ibGFuaycgcHJvcGVydGll cy4KCkFzIGEgc3BlY2lhbCBjYXNlLCBpZiBwb2ludCBpcyBhdCB0aGUgdmVyeSBiZWdpbm5pbmcg b2YgYSBsaXN0IG9yCnN1Yi1saXN0LCByZXR1cm5lZCBlbGVtZW50IHdpbGwgYmUgdGhhdCBsaXN0 IGluc3RlYWQgb2YgdGhlIGZpcnN0Cml0ZW0uICBJbiB0aGUgc2FtZSB3YXksIGlmIHBvaW50IGlz IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpcnN0CnJvdyBvZiBhIHRhYmxlLCByZXR1cm5lZCBl bGVtZW50IHdpbGwgYmUgdGhlIHRhYmxlIGluc3RlYWQgb2YgdGhlCmZpcnN0IHJvdy4KCklmIG9w dGlvbmFsIGFyZ3VtZW50IEtFRVAtVFJBSUwgaXMgbm9uLW5pbCwgdGhlIGZ1bmN0aW9uIHJldHVy bnMKYSBsaXN0IG9mIGVsZW1lbnRzIGxlYWRpbmcgdG8gZWxlbWVudCBhdCBwb2ludC4gIFRoZSBs aXN0J3MgQ0FSCmlzIGFsd2F5cyB0aGUgZWxlbWVudCBhdCBwb2ludC4gIFRoZSBmb2xsb3dpbmcg cG9zaXRpb25zIGNvbnRhaW4KZWxlbWVudCdzIHNpYmxpbmdzLCB0aGVuIHBhcmVudHMsIHNpYmxp bmdzIG9mIHBhcmVudHMsIHVudGlsIHRoZQpmaXJzdCBlbGVtZW50IG9mIGN1cnJlbnQgc2VjdGlv bi4iKQojK2VuZF9zcmMKCiMjI2F1dG9sb2FkCiMrYmVnaW5fc3JjIGVtYWNzLWxpc3AKKGRlZnVu IG9yZy1lbGVtZW50LWNvbnRleHQgKCZvcHRpb25hbCBlbGVtZW50KQogICJSZXR1cm4gY2xvc2Vz dCBlbGVtZW50IG9yIG9iamVjdCBhcm91bmQgcG9pbnQuCgpSZXR1cm4gdmFsdWUgaXMgYSBsaXN0 IGxpa2UgKFRZUEUgUFJPUFMpIHdoZXJlIFRZUEUgaXMgdGhlIHR5cGUKb2YgdGhlIGVsZW1lbnQg b3Igb2JqZWN0IGFuZCBQUk9QUyBhIHBsaXN0IG9mIHByb3BlcnRpZXMKYXNzb2NpYXRlZCB0byBp dC4KClBvc3NpYmxlIHR5cGVzIGFyZSBkZWZpbmVkIGluIGBvcmctZWxlbWVudC1hbGwtZWxlbWVu dHMnIGFuZApgb3JnLWVsZW1lbnQtYWxsLW9iamVjdHMnLiAgUHJvcGVydGllcyBkZXBlbmQgb24g ZWxlbWVudCBvcgpvYmplY3QgdHlwZSwgYnV0IGFsd2F5cyBpbmNsdWRlIGA6YmVnaW4nLCBgOmVu ZCcsIGA6cGFyZW50JyBhbmQKYDpwb3N0LWJsYW5rJy4KCk9wdGlvbmFsIGFyZ3VtZW50IEVMRU1F TlQsIHdoZW4gbm9uLW5pbCwgaXMgdGhlIGNsb3Nlc3QgZWxlbWVudApjb250YWluaW5nIHBvaW50 LCBhcyByZXR1cm5lZCBieSBgb3JnLWVsZW1lbnQtYXQtcG9pbnQnLgpQcm92aWRpbmcgaXQgYWxs b3dzIGZvciBxdWlja2VyIGNvbXB1dGF0aW9uLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtbmVzdGVk LXAgKGVsZW0tQSBlbGVtLUIpCiAgIk5vbi1uaWwgd2hlbiBlbGVtZW50cyBFTEVNLUEgYW5kIEVM RU0tQiBhcmUgbmVzdGVkLiIpCgooZGVmdW4gb3JnLWVsZW1lbnQtc3dhcC1BLUIgKGVsZW0tQSBl bGVtLUIpCiAgIlN3YXAgZWxlbWVudHMgRUxFTS1BIGFuZCBFTEVNLUIuCkFzc3VtZSBFTEVNLUIg aXMgYWZ0ZXIgRUxFTS1BIGluIHRoZSBidWZmZXIuICBMZWF2ZSBwb2ludCBhdCB0aGUKZW5kIG9m IEVMRU0tQS4iKQoKKHByb3ZpZGUgJ29yZy1lbGVtZW50KQojK2VuZF9zcmMKCkxvY2FsIHZhcmlh YmxlczoKZ2VuZXJhdGVkLWF1dG9sb2FkLWZpbGU6ICJvcmctbG9hZGRlZnMuZWwiCkVuZDoKCiog b3JnLWVsZW1lbnQuZWwgZW5kcyBoZXJlCg== --=-=-= Content-Type: text/plain -- cheers, Thorsten --=-=-=--