From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christopher Genovese Subject: Re: full parser implementation for tag queries (parentheses, fast heading match, and more) Date: Sat, 4 Aug 2012 14:32:35 -0400 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=047d7b2e4f6e94631804c674df38 Return-path: Received: from eggs.gnu.org ([208.118.235.92]:48648) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sxj9r-0002jd-90 for emacs-orgmode@gnu.org; Sat, 04 Aug 2012 14:33:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Sxj9m-0005ka-2x for emacs-orgmode@gnu.org; Sat, 04 Aug 2012 14:33:03 -0400 Received: from mail-pb0-f41.google.com ([209.85.160.41]:37213) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sxj9l-0005kW-9A for emacs-orgmode@gnu.org; Sat, 04 Aug 2012 14:32:58 -0400 Received: by pbbrp2 with SMTP id rp2so3539065pbb.0 for ; Sat, 04 Aug 2012 11:32:56 -0700 (PDT) In-Reply-To: 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 Cc: Christopher Genovese --047d7b2e4f6e94631804c674df38 Content-Type: multipart/alternative; boundary=047d7b2e4f6e94631204c674df36 --047d7b2e4f6e94631204c674df36 Content-Type: text/plain; charset=ISO-8859-1 I have attached an updated version of the files org-tag-query-parse.el and tag-query-tests.el that I posted about last night, and I have updated them at http://www.stat.cmu.edu/~genovese/emacs/ as well. I've also appended an updated version of my original note below for reference. The issue had to do with the /!? todo-matches in the queries. The bug in the 7.8 code that I described in Note h of my original post had to do with properly detecting when a /!? todo match is present. The approximate fix I suggested was incorrect; the complete fix was unnecessarily complicated. I realized all this a few minutes after the post (d'oh) and have now simplified things accordingly. The new version unifies the parsing of both kinds of queries. I eliminated a few functions as a result, and the new org-make-tags-matcher is even simpler. As a result, todo matching deals with all those edge cases correctly (like "PROP={^.*//.*$}") for free, also allows the {m,n} construct in todo regexp matches, just like it does in the tag matches. (Braces are escaped by doubling, e.g. {^.*B{{1,7}}} as I mentioned last time.) All the tests pass in a fresh session, both with compiled and non-compiled code, on 23.2 and 24.1. I'd appreciate any comments, suggestions, or other feedback you have on all this. Thanks for your patience, Christopher === Updated version of original post follows for reference I am writing an application layer on top of org that uses the entry mapping API, but I needed both negation of complex selections and heading searches. Because the current tag query parser does not handle parenthesized expressions, it does not allow negating complex queries. At first, I wrote a workaround solution that mimics/specializes the mapping API, but that approach seemed inelegant and harder to maintain. So instead I implemented a full parser for tag queries with a number of useful features (see the labeled Notes at the bottom for further comments on these features): 1. Parenthesized expressions to arbitrary depth are allowed. 2. A '-' can be used to negate a parenthesized term. [Note a] 3. Regex's in {} can contain braces escaped by doubling: {{ }}. [Note b] 4. Supports fast property search on HEADING and PRIORITY. [Note c] 5. Handles hyphens in property names properly. [Note d,h] 6. Allows only the proper comparison operators, including ==. [Note e,h] 7. Allows spaces around operators and terms for readability. [Note f] 8. Matchers use the original expression order; not a big deal, but free. 9. The error messages during parsing are reasonably helpful. 10. Several bug fixes and a cleaner `org-make-tags-matcher'. [Note h] I'm submitting the code for your consideration, with the goal of eventually incorporating this into org.el. I would be happy to hear any comments or suggestions you have. As I'll describe below, this involves relatively minor changes to two existing functions and adding a few new support functions. I've attached two files org-tag-query-parse.el (the code) and tag-query-tests.el (a collection of tests built on a simple framework). I've also put the files in http://www.stat.cmu.edu/~genovese/emacs/. The comments in both files will I hope be helpful. At the risk of going on too long, I'd like to add a few comments about the code and tests. First, the two existing functions that are affected in the code are `org-make-tags-matcher' and `org-scan-tags'. In the new version of the former, I've unified both kinds of query parsing, leading to a shorter and cleaner function.. The new version of the latter differs in only a couple *very minor* places that capture two values that were already being computed anyway (see the diff reproduced in the comments). By the way, I'm working from the 7.8.11 code. Loading org-tag-query-parse.el does not change the original functions. Instead, I've added a `-NEW' to the names of these functions and saved the originals also with a `-ORIGINAL' added. After loading the file, you can choose a version to try by doing (org-tmp-use-tag-parser 'new) and (org-tmp-use-tag-parser 'original) or do (org-tmp-use-tag-parser) to toggle between versions. You can also just use the names with suffixes directly. I'd also suggest byte-compiling the file. I think the place to start looking at the code is the new version of `org-make-tags-matcher'. The main workhorse for the new parser is `org-tag-query-parse', with new function `org-todo-query-parse' handling the /!? todo parsing at the appropriate point.. The other substantial piece (in terms of lines of code) is a utility macro `org-match-cond' that is used throughout and makes the main parser much more readable IMHO. Admittedly, I went a bit overboard in optimizing it; the first version worked fine but this one produces really nice code. I'd suggest ignoring this code (in section "Parsing utility for readable matchers") on first pass. The docstring is pretty complete, and its use is more or less self-explanatory. To run the tests, load org-tag-query-parse.el and tag-query-tests.el and do (tag-test-run :results) ; use :summary for a brief summary of all runs (tag-test-other-tests) ; miscellaneous other tests, including scanning or name individual suites. They are at the moment: (tag-test-run :results 'org-comparison-1) ; or use :summary (tag-test-run :results 'org-comparison-2) (tag-test-run :results 'match-results-1) (tag-test-run :results 'match-results-2) (tag-test-run :results 'should-error-1) If you have other ideas for tests or find any bugs, please let me know. Sorry for the homegrown framework; it just sort of grew and then I was too tired to rewrite the tests. One complication here is that the original and new algorithms produce different term orders and use a few different functions. The function tag-test-transform transforms original results to the new algorithms conventions, but it does not handle PRIORITY or HEADING matches at the moment. Use the tree form of the tess (see match-results-1 for example) on these. Btw, I've run the tests on GNU Emacs 23.2 and 24.1 (running on OS X lion). Notes: a. There is no need to introduce a new character such as ! for negation because the semantics of the - are clear and are consistent with its use for tags. A - binds more tightly than & which in turn binds more tightly than |. A + selector can also be used for positive selection of a parenthesized term but it is equivalent to using no selector, just as for tags. b. Because \'s are so heavily used in regex's and because they have to be doubled in strings, using \'s for an additional escape layer would be messy, ambiguous, and hard to read. Only the {}'s need to be escaped and the doubling escapes {{ -> { and }} -> } are simple, readable, and fast to parse. For example: "+{abc\\{{3,7\\}}}" gives the regex "abc\\{3,7\\}". Parity makes correctness clear at a glance. c. Because headline (and priority) searches can be useful and powerful, and because the information on those fields is *already processed* in `org-scan-tags', we get those special searches *essentially for free*, requiring only two minor changes to `org-scan-tags'. See the unified diff in comments. The special PRIORITY property already exists; I added the special HEADING property for these purposes. I'm open to changing the name of course, but I do think the feature is both useful and elegant. (I'm using it in my application, for instance.) d. I did not see it in the manual, but I think that property names with hyphens should have these \-escaped -'s in the query string, with the escaping slashes removed in the produced matcher. This is not currently done, but the new version does. See Note h for details. e. It seems desirable to support both = and == as equality operators since the latter is so common by habit. The new version allows this explicitly. The original version does as well, but the regex for the comparison operator also allows other operators <<, ><, >>, =>, and >= as well, which can produce bad matchers. See Note h for details. f. Currently, spaces are ignored around &, |, the implicit & between terms, around the comparison operators in property searches, and around +/- selectors. Spaces are not ignored inside {}'s for a regexp match. g. The current code also allows +/- selectors before property comparisons. I don't really like this because +PROP<>"something" and -PROP="something" have the same meaning but look very different. But the new code does support this. As a side note, there's really no need for the & characters as +/- serve the and/and-not function completely. But again, no prob. h. A few bugs detected in the 7.8.11 code: + Faulty test for todo matcher in org-make-tags-matcher (string-match "/+" match) Ex: (org-make-tags-matcher "PROP={^\\s-*// .*$}") produces an erroneous matcher: ("PROP={^\\s-*// .*$}" progn (setq org-cached-props nil) (member "PROP" tags-list)) Because {}'s can appear in /!? todo-match expressions, and becauseA arbitrary strings can be TODO keywords, a simple pattern match will not give a complete solution. For instance, both PROP={/!} and PROP="/!{/!}" are valid TODO keywords (it works!) *and* valid property comparisons. We want to find the first slash that is not enclosed in {}'s or ""'s; if found, a todo match is needed. The new parser handles the two types of matching together and so automatically detects the todo matches correctly. + Property names with -'s are not handled properly (cf. Note d) Specifically, the escapes are not removed. Example: (org-make-tags-matcher "PROP\\-WITH\\-HYPHENS=2") produces ("PROP\\-WITH\\-HYPHENS=2" and (progn (setq org-cached-props nil) (= (string-to-number (or (org-cached-entry-get nil "PROP\\-WITH\\-HYPHENS") "")) 2)) t) The original code /does/ instead remove -'s from tag names, which shouldn't have them anyway. I suspect that this was intended for property names rather than tag names. The new version fixes up property names but does not allow -'s in tags. + Incorrect comparison operators allowed (cf. Note e) The regular expression used is "[<=>]\\{1,2\\}" is used to detect the comparison operators. But this can produce bad matchers that fail opaquely at match time rather than giving an appropriate error message at parse time. Ex: (org-make-tags-matcher "P<<2") produces ("P<<2" and (progn (setq org-cached-props nil) (nil (string-to-number (or (org-cached-entry-get nil "P") "")) 2)) t) This is fixed in the new version and delivers an error message at parse time. + missing org-re (line 7179 in org.el) with posix classes Minor consistency issue. This line does not occur in the new code. Thanks and regards, Christopher Genovese On Sat, Aug 4, 2012 at 6:07 AM, Christopher Genovese wrote: > A small addendum: > > Right after I posted (of course!), I noticed both a small mistake and an > opportunity for > simplification, relating to detecting and processing the todo expressions > after a /. > Specifically, the approximate fix I proposed to the bug in the 7.8 code is > insufficient > to handle regexp matching in todo expressions. The full solution using the > new function org-find-todo-query is needed in the code as I have it, and > that can just > be plugged in instead of the string-match. (See Note h in the original > post, specifically > the string-match given there, and org-find-todo-query.) > > But I realized that all that is unnecessary as the todo processing can be > easily built > into the new parser. I've mostly done that just now and will test and post > an update > Saturday, er...today. > > Sorry to muddy the waters by not catching that earlier, and sorrier still > if I'm rambling. > Off to bed... > > -- Christopher > > > > On Sat, Aug 4, 2012 at 3:50 AM, Christopher Genovese wrote: > >> I am writing an application layer on top of org that uses the >> entry mapping API, but I needed both negation of complex >> selections and heading searches. Because the current tag query >> parser does not handle parenthesized expressions, it does not >> allow negating complex queries. At first, I wrote a workaround >> solution that mimics/specializes the mapping API, but that >> approach seemed inelegant and harder to maintain. >> >> So instead I implemented a full parser for tag queries with a >> number of useful features (see the labeled Notes at the bottom >> for further comments on these features): >> >> 1. Parenthesized expressions to arbitrary depth are allowed. >> 2. A '-' can be used to negate a parenthesized term. [Note >> a] >> 3. Regex's in {} can contain braces escaped by doubling: {{ }}. [Note >> b] >> 4. Supports fast property search on HEADING and PRIORITY. [Note >> c] >> 5. Handles hyphens in property names properly. [Note >> d,h] >> 6. Allows only the proper comparison operators, including ==. [Note >> e,h] >> 7. Allows spaces around operators and terms for readability. [Note >> f] >> 8. Matchers use the original expression order; not a big >> deal, but free. >> 9. The error messages during parsing are reasonably helpful. >> 10. Several bug fixes and a cleaner `org-make-tags-matcher'. [Note >> h] >> >> I'm submitting the code for your consideration, with the >> goal of eventually incorporating this into org.el. I would be >> happy to hear any comments or suggestions you have. As I'll describe >> below, this involves relatively minor changes to two existing >> functions and adding a few new support functions. I've attached two >> files org-tag-query-parse.el (the code) and tag-query-tests.el (a >> collection of tests built on a simple framework). I've also >> put the files in http://www.stat.cmu.edu/~genovese/emacs/. The >> comments in both files will I hope be helpful. >> >> At the risk of going on too long, I'd like to add a few comments >> about the code and tests. First, the two existing functions that >> are affected in the code are `org-make-tags-matcher' and >> `org-scan-tags'. In the new version of the former, I've extracted >> out both kinds of query parsing, leading to a shorter and cleaner >> function. The new version of the latter differs in only a couple >> *very minor* places that capture two values that were already >> being computed anyway (see the diff reproduced in the comments). >> Btw, I'm working from the 7.8.11 code. >> >> Loading org-tag-query-parse.el does not change the original >> functions. Instead, I've added a `-NEW' to the names of these >> functions and saved the originals also with a `-ORIGINAL' added. >> After loading the file, you can choose a version to try by doing >> >> (org-tmp-use-tag-parser 'new) >> and >> (org-tmp-use-tag-parser 'original) >> >> or do (org-tmp-use-tag-parser) to toggle between versions. >> You can also just use the names with suffixes directly. >> I'd also suggest byte-compiling the file. >> >> I think the place to start looking at the code is the new version >> of `org-make-tags-matcher'. The main entry function for the new >> parser is `org-tag-query-parse', though the real workhorse is >> actually the function `org-tag-query-parse-1'. There is also a >> new function `org-todo-query-parse' which just extracts the >> existing todo matching method. (I didn't do anything with that >> method as the manual makes it clear that it is of secondary >> importance.) I think the modularity here makes >> `org-make-tags-matcher' and each separate parser easier to read >> and understand. >> >> The other substantial piece (in terms of lines of code) is a utility >> macro `org-match-cond' that is used throughout and makes the main >> parser much more readable IMHO. Admittedly, I went a bit >> overboard in optimizing it; the first version worked fine >> but this one produces really nice code. I'd suggest ignoring this >> code (in section "Parsing utility for readable matchers") on >> first pass. The docstring is pretty complete, and its use is more >> or less self-explanatory. Most of its work is done at compile time. >> >> To run the tests, load org-tag-query-parse.el and tag-query-tests.el >> and do >> >> (tag-test-run :results) ; use :summary for a brief summary of all runs >> (tag-test-other-tests) ; miscellaneous other tests, including scanning >> >> or name individual suites. They are at the moment: >> >> (tag-test-run :results 'org-comparison-1) ; or use :summary >> (tag-test-run :results 'org-comparison-2) >> (tag-test-run :results 'match-results-1) >> (tag-test-run :results 'match-results-2) >> (tag-test-run :results 'should-error-1) >> >> If you have other ideas for tests or find any bugs, please let me >> know. Sorry for the homegrown framework; it just sort of grew and >> then I was too tired to rewrite the tests. One complication here >> is that the original and new algorithms produce different term >> orders and use a few different functions. The function >> tag-test-transform transforms original results to the new >> algorithms conventions, but it does not handle PRIORITY or >> HEADING matches at the moment. Use the tree form of the tess (see >> match-results-1 for example) on these. Btw, I've run the tests on >> GNU Emacs 23.2 and 24.1 (running on OS X lion). >> >> Notes: >> a. There is no need to introduce a new character such as ! for >> negation because the semantics of the - are clear and are >> consistent with its use for tags. A - binds more tightly >> than & which in turn binds more tightly than |. A + >> selector can also be used for positive selection of a >> parenthesized term but it is equivalent to using no >> selector, just as for tags. >> >> b. Because \'s are so heavily used in regex's and because they >> have to be doubled in strings, using \'s for an additional >> escape layer would be messy, ambiguous, and hard to read. >> Only the {}'s need to be escaped and the doubling escapes >> {{ -> { and }} -> } are simple, readable, and fast to >> parse. For example: "+{abc\\{{3,7\\}}}" gives the regex >> "abc\\{3,7\\}". Parity makes correctness clear at a glance. >> >> c. Because headline (and priority) searches can be useful and >> powerful, and because the information on those fields is >> *already processed* in `org-scan-tags', we get those >> special searches *essentially for free*, requiring only two >> minor changes to `org-scan-tags'. See the unified diff in >> comments. The special PRIORITY property already exists; I >> added the special HEADING property for these purposes. I'm >> open to changing the name of course, but I do think the >> feature is both useful and elegant. (I'm using it in my >> application, for instance.) >> >> d. I did not see it in the manual, but I think that property names >> with hyphens should have these \-escaped -'s in the query >> string, with the escaping slashes removed in the produced >> matcher. This is not currently done, but the new version does. >> See Note h for details. >> >> e. It seems desirable to support both = and == as equality operators >> since the latter is so common by habit. The new version allows >> this explicitly. The original version does as well, but the >> regex for the comparison operator also allows other operators >> <<, ><, >>, =>, and >= as well, which can produce bad matchers. >> See Note h for details. >> >> f. Currently, spaces are ignored around &, |, the implicit & between >> terms, around the comparison operators in property searches, >> and around +/- selectors. Spaces are not ignored inside {}'s >> for a regexp match. >> >> g. The current code also allows +/- selectors before property >> comparisons. I don't really like this because >> +PROP<>"something" and -PROP="something" have the same >> meaning but look very different. But the new code does >> support this. As a side note, there's really no need for >> the & characters as +/- serve the and/and-not function >> completely. But again, no prob. >> >> h. A few bugs detected in the 7.8.11 code: >> >> + Faulty test for todo matcher in org-make-tags-matcher >> (string-match "/+" match) >> >> Ex: (org-make-tags-matcher "PROP={^\\s-*// .*$}") produces >> an erroneous matcher: >> >> ("PROP={^\\s-*// .*$}" progn >> (setq org-cached-props nil) >> (member "PROP" tags-list)) >> >> For all practical purposes it will be enough to do: >> >> (string-match "\\(/\\(!\\)?\\s-*\\)[^{}\"]*$" match) >> >> instead of the current test in org-make-tags-matcher. >> This works as long as the TODO keywords do not contain a >> right brace or quotation marks. (In most other cases, the >> new parser should give an error message at parse time.) >> >> A technicality: this is /not/ a complete solution because >> arbitrary strings can be TODO keywords. For instance, >> both PROP={/!} and PROP="/!{/!}" are valid TODO keywords >> (it works!) *and* valid property comparisons. So, a pattern >> alone is insufficient. We want to find the first slash >> that is not enclosed in {}'s or ""'s; if found, a todo >> match is needed. The function `org-find-todo-query' does >> this and (org-find-todo-query match) can be plugged in >> directly replacing the above (string-match ...) in then >> new `org-make-tags-matcher'. >> >> But because the todo parsing uses {}'s for regex matches, >> TODO keywords with {}'s are ignored anyway. So there's >> no need to go beyond the fixed string-match above. >> The function `org-todo-query-parse', which handles todo >> parsing in the new version, makes this explicit. >> >> + Property names with -'s are not handled properly (cf. Note d) >> >> Specifically, the escapes are not removed. Example: >> (org-make-tags-matcher "PROP\\-WITH\\-HYPHENS=2") >> produces >> >> ("PROP\\-WITH\\-HYPHENS=2" and >> (progn >> (setq org-cached-props nil) >> (= >> (string-to-number >> (or (org-cached-entry-get nil "PROP\\-WITH\\-HYPHENS") >> "")) >> 2)) >> t) >> >> The original code /does/ instead remove -'s from tag >> names, which shouldn't have them anyway. I suspect that >> this was intended for property names rather than tag >> names. The new version fixes up property names but does >> not allow -'s in tags. >> >> + Incorrect comparison operators allowed (cf. Note e) >> >> The regular expression used is "[<=>]\\{1,2\\}" is used to >> detect the comparison operators. But this can produce bad >> matchers that fail opaquely at match time rather than >> giving an appropriate error message at parse time. >> >> Ex: (org-make-tags-matcher "P<<2") produces >> >> ("P<<2" and >> (progn >> (setq org-cached-props nil) >> (nil >> (string-to-number (or (org-cached-entry-get nil "P") "")) 2)) >> t) >> >> This is fixed in the new version and delivers an error >> message at parse time. >> >> + missing org-re (line 7179 in org.el) with posix classes >> >> Minor consistency issue. This line does not occur in the new >> code. >> >> >> Thanks and regards, >> >> Christopher Genovese >> >> >> > --047d7b2e4f6e94631204c674df36 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable I have attached an updated version of the files org-tag-query-parse.el
a= nd tag-query-tests.el that I posted about last night, and I have
updated= them at http://www.st= at.cmu.edu/~genovese/emacs/ as well. I've
also appended an updated version of my original note below for
reference= .

The issue had to do with the /!? todo-matches in the queries. The = bug in
the 7.8 code that I described in Note h of my original post had t= o do
with properly detecting when a /!? todo match is present. The
approximat= e fix I suggested was incorrect; the complete fix was
unnecessarily comp= licated. I realized all this a few minutes after the
post (d'oh) and= have now simplified things accordingly.

The new version unifies the parsing of both kinds of queries. I
elim= inated a few functions as a result, and the new org-make-tags-matcher
is= even simpler. As a result, todo matching deals with all those edge
cases correctly (like "PROP=3D{^.*//.*$}") for free, also allows = the {m,n}
construct in todo regexp matches, just like it does in the tag= matches.
(Braces are escaped by doubling, e.g. {^.*B{{1,7}}} as I menti= oned last
time.) All the tests pass in a fresh session, both with compiled and
non= -compiled code, on 23.2 and 24.1.

I'd appreciate any comments, s= uggestions, or other feedback you have
on all this.

Thanks for y= our patience,

=A0 Christopher


=3D=3D=3D Updated version of original post f= ollows for reference

I am writing an application layer on top of org that uses the
entry mapping API, but I = needed both negation of complex
selections and= heading searches. Because the current tag query
parser does not handle pa= renthesized expressions, it does not
allow neg= ating complex queries. At first, I wrote a workaround
solution that mimics/spec= ializes the mapping API, but that
approach see= med inelegant and harder to maintain.

So instead I implemented a full parser for tag queri= es with a
number of useful features (see the l= abeled Notes at the bottom
for further comments on t= hese features):

=A0 1. Parenthesized expressions to arbitrary depth are a= llowed.
=A0 2. A '-' can = be used to negate a parenthesized term.=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= [Note a]
=A0 3. Regex's in {} can contain= braces escaped by doubling: {{ }}.=A0 [Note b]
=A0 4. Supports fast prop= erty search on HEADING and PRIORITY.=A0=A0=A0=A0=A0=A0=A0 [Note c]=A0 5. Handles hyphens in property names properly.=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [Note d,h]
=A0 6. Allows only the pr= oper comparison operators, including =3D=3D.=A0=A0=A0 [Note e,h]
=A0 7. Allows spaces around operators and terms for read= ability.=A0=A0=A0=A0 [Note f]
=A0 8. Matchers use the o= riginal expression order; not a big
=A0=A0=A0= =A0 deal, but free.
=A0 9. The error messages= during parsing are reasonably helpful.
=A0 10= . Several bug fixes and a cleaner `org-make-tags-matcher'.=A0=A0=A0=A0 = [Note h]

I'm submitting the code for your consideration, = with the
goal of eventually incorporating thi= s into org.el. I would
be happy to hear any comm= ents or suggestions you have. As
I'll desc= ribe below, this involves relatively minor changes
to two existing functions= and adding a few new support
functions. I'= ;ve attached two files org-tag-query-parse.el
(the code) and tag-query-= tests.el (a collection of tests
built on a sim= ple framework). I've also put the files in
http://www.stat.cmu.edu/~genovese/emacs/. T= he comments in
both files will I hope be helpf= ul.

At the risk of going on too long, I'd like to ad= d a few comments
about the code and tests. Fir= st, the two existing functions that
are affected in the code = are `org-make-tags-matcher' and
`org-scan-= tags'. In the new version of the former, I've unified
both kinds of query parsi= ng, leading to a shorter and cleaner
function.= . The new version of the latter differs in only a
couple *very minor* place= s that capture two values that were
already be= ing computed anyway (see the diff reproduced in the
comments). By the way, I&= #39;m working from the 7.8.11 code.

Loading org-tag-query-parse.el does = not change the original
functions. Instead, I'= ;ve added a `-NEW' to the names of these
f= unctions and saved the originals also with a `-ORIGINAL' added.<= br style=3D"font-family:courier new,monospace"> After loading the file, y= ou can choose a version to try by doing

=A0=A0=A0 (org-tmp-use-tag-parser= 'new)
and
=A0=A0=A0 (org-tmp-use-tag-parser 'original)

or do (org-tmp-use-tag-parser) to toggle between ver= sions.
You can also just use the names with su= ffixes directly.
I'd also suggest byte= -compiling the file.
=
I think the place to start looking at the code is th= e new
version of `org-make-tags= -matcher'. The main workhorse for the
new = parser is `org-tag-query-parse', with new function
`org-todo-query-parse'= ; handling the /!? todo parsing
at the appropr= iate point..

The other substantial piece (in terms of lines of co= de) is a
utility macro `org-match-cond' t= hat is used throughout and makes
the main parser much more= readable IMHO. Admittedly, I went a
bit overb= oard in optimizing it; the first version worked fine
but this one produces rea= lly nice code. I'd suggest ignoring
this c= ode (in section "Parsing utility for readable matchers") on first pass. The docstr= ing is pretty complete, and its use is
more or= less self-explanatory.

To run the tests, load org-tag-query-parse.el and ta= g-query-tests.el
and do

=A0=A0 (tag-test-run :results) ; use :summary for a = brief summary of all runs
=A0=A0 (tag-test-other-te= sts)=A0 ; miscellaneous other tests, including scanning

or name individual suites. They are at the moment:

=A0=A0 (tag-test-run :res= ults 'org-comparison-1)=A0 ; or use :summary
=A0=A0 (tag-test-run :results 'org-comparison-2)
=A0=A0 (tag-test-run :res= ults 'match-results-1)
=A0=A0 (tag-test-ru= n :results 'match-results-2)
=A0=A0 (tag-test-run :res= ults 'should-error-1)

If you have other ideas for tests or find any b= ugs, please let me
know. Sorry for the homeg= rown framework; it just sort of grew and
then = I was too tired to rewrite the tests. One complication here
is that the original and = new algorithms produce different term
orders a= nd use a few different functions. The function
tag-test-transform transf= orms original results to the new
algorithms co= nventions, but it does not handle PRIORITY or
HEADING matches at the mo= ment. Use the tree form of the tess (see
match= -results-1 for example) on these. Btw, I've run the tests on
GNU Emacs 23.2 and 24.1 (= running on OS X lion).

Notes:
=A0=A0 a. There is no nee= d to introduce a new character such as ! for
= =A0=A0=A0=A0=A0 negation because the semantics of the - are clear and are
=A0=A0=A0=A0=A0 consisten= t with its use for tags. A - binds more tightly
=A0=A0=A0=A0=A0 selector = can also be used for positive selection of a
= =A0=A0=A0=A0=A0 parenthesized term but it is equivalent to using no<= br style=3D"font-family:courier new,monospace"> =A0=A0=A0=A0=A0 selector,= just as for tags.
=A0=A0=A0=A0=A0

=A0=A0 b. Because \'s= are so heavily used in regex's and because they
=A0=A0=A0=A0=A0 have to be doubled in strings, using \'s for an = additional
=A0=A0=A0=A0=A0 escape la= yer would be messy, ambiguous, and hard to read.
=A0=A0=A0=A0=A0 Only the {}'s need to be escaped and the doubling es= capes
=A0=A0=A0=A0=A0 {{ -> = { and }} -> } are simple, readable, and fast to
=A0=A0=A0=A0=A0 parse. For example: "+{abc\\{{3,7\\}}}" give= s the regex
=A0=A0=A0=A0=A0 "abc= \\{3,7\\}". Parity makes correctness clear at a glance.
=A0=A0=A0=A0=A0
=A0=A0 c. Because headlin= e (and priority) searches can be useful and
= =A0=A0=A0=A0=A0 powerful, and because the information on those fields is
=A0=A0=A0=A0=A0 *already = processed* in `org-scan-tags', we get those
=A0=A0=A0=A0=A0 minor cha= nges to `org-scan-tags'. See the unified diff in
=A0=A0=A0=A0=A0 comments. The special PRIORITY property already exis= ts; I
=A0=A0=A0=A0=A0 added the= special HEADING property for these purposes. I'm
=A0=A0=A0=A0=A0 open to changing the name of course, but I do think= the
=A0=A0=A0=A0=A0 feature i= s both useful and elegant. (I'm using it in my
=A0=A0=A0=A0=A0 application, for instance.)

=A0=A0 d. I did not see it in the manual, but I thin= k that property names
=A0=A0=A0=A0=A0 with hyp= hens should have these \-escaped -'s in the query
=A0=A0=A0=A0=A0 string, w= ith the escaping slashes removed in the produced
=A0=A0=A0=A0=A0 matcher. This is not currently done, but the new version= does.
=A0=A0=A0=A0=A0 See Note = h for details.

=A0=A0 e. It seems desirable to support both =3D and =3D= =3D as equality operators
=A0=A0=A0=A0=A0 since the= latter is so common by habit. The new version allows
=A0=A0=A0=A0=A0 this explicitly. The original version does as well,= but the
=A0=A0=A0=A0=A0 regex for= the comparison operator also allows other operators
=A0=A0=A0=A0=A0 <<, ><, >>, =3D>, and >=3D a= s well, which can produce bad matchers.
=A0=A0=A0=A0=A0 See Note = h for details.

=A0=A0 f. Currently, spaces are ignored around &, |, t= he implicit & between
=A0=A0=A0=A0=A0 terms, ar= ound the comparison operators in property searches,
=A0=A0=A0=A0=A0 and around +/- selectors. Spaces are not ignored insi= de {}'s
=A0=A0=A0=A0=A0 for a reg= exp match.

=A0=A0 g. The current code also allows +/- selectors before p= roperty
=A0=A0=A0=A0=A0 compariso= ns. I don't really like this because
=A0= =A0=A0=A0=A0 +PROP<>"something" and -PROP=3D"something= " have the same
=A0=A0=A0=A0=A0 meaning b= ut look very different. But the new code does
= =A0=A0=A0=A0=A0 support this. As a side note, there's really no need fo= r
=A0=A0=A0=A0=A0 the &= characters as +/- serve the and/and-not function
=A0=A0=A0=A0=A0 completely. But again, no prob.

=A0=A0 h. A few bugs detected in the 7.8.11 code:

=A0=A0=A0=A0=A0 + Faulty = test for todo matcher in org-make-tags-matcher
=A0=A0=A0=A0=A0=A0=A0 (string-match "/+" match)

=A0=A0=A0=A0=A0=A0=A0 Ex: (org-make-tags-matcher &qu= ot;PROP=3D{^\\s-*// .*$}") produces
=A0=A0=A0=A0=A0=A0=A0 an = erroneous matcher:
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ("PROP=3D{^\\s-= *// .*$}" progn
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0 (setq org-cached-props nil)
=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (member "PROP" tags-list))


=A0=A0=A0=A0=A0=A0=A0 Because {}'s can appear in= /!? todo-match expressions, and
=A0=A0=A0=A0= =A0=A0=A0 becauseA arbitrary strings can be TODO keywords, a simple<= br style=3D"font-family:courier new,monospace"> =A0=A0=A0=A0=A0=A0=A0 pat= tern match will not give a complete solution. For
=A0=A0=A0=A0=A0=A0=A0 instance, both PROP=3D{/!} and PROP=3D"/!{/!= }" are valid TODO
=A0=A0=A0=A0=A0=A0=A0 key= words (it works!) *and* valid property comparisons. We
=A0=A0=A0=A0=A0=A0=A0 want to find the first slash that is not enc= losed in {}'s or
=A0=A0=A0=A0=A0=A0=A0 &qu= ot;"'s; if found, a todo match is needed. The new parser=A0=A0=A0=A0=A0=A0=A0 handles the two types of matching= together and so
=A0=A0=A0=A0=A0=A0=A0 aut= omatically detects the todo matches correctly.
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0 + Propert= y names with -'s are not handled properly (cf. Note d)
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 Spe= cifically, the escapes are not removed. Example:
=A0=A0=A0=A0=A0=A0=A0 (org-make-tags-matcher "PROP\\-WITH\\-HYPHENS= =3D2")
=A0=A0=A0=A0=A0=A0=A0 pro= duces
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 (&q= uot;PROP\\-WITH\\-HYPHENS=3D2" and
=A0=A0= =A0=A0=A0=A0=A0=A0 (progn
=A0=A0=A0=A0=A0=A0=A0=A0 = (setq org-cached-props nil)
=A0=A0=A0=A0=A0=A0= =A0=A0 (=3D
=A0=A0=A0=A0=A0=A0=A0=A0= =A0 (string-to-number
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 (or (org-cached-entry-get nil "PROP\\-WITH\\-HYPHENS")
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 ""))
=A0=A0=A0=A0=A0=A0=A0=A0= =A0 2))
=A0=A0=A0=A0=A0=A0=A0=A0 = t)
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 The= original code /does/ instead remove -'s from tag
=A0=A0=A0=A0=A0=A0=A0 names, which shouldn't have them anyway. = I suspect that
=A0=A0=A0=A0=A0=A0=A0 thi= s was intended for property names rather than tag
=A0=A0=A0=A0=A0=A0=A0 names. The new version fixes up property names bu= t does
=A0=A0=A0=A0=A0=A0=A0 not= allow -'s in tags.

=A0=A0=A0=A0=A0 + Incorrect comparison operators = allowed (cf. Note e)
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 The regular expression use= d is "[<=3D>]\\{1,2\\}" is used to
=A0=A0=A0=A0=A0=A0=A0 det= ect the comparison operators. But this can produce bad
=A0=A0=A0=A0=A0=A0=A0 matchers that fail opaquely at match time ra= ther than
=A0=A0=A0=A0=A0=A0=A0 giv= ing an appropriate error message at parse time.

= =A0=A0=A0=A0=A0=A0=A0 Ex:= (org-make-tags-matcher "P<<2") produces

=A0=A0=A0=A0=A0=A0=A0=A0 ("P<<2" and=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 (progn
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 (setq org-cached-props nil)
=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 (nil
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0 (string-to-number (or (org-cached-entry-get nil "P")= "")) 2))
<= span style=3D"font-family:courier new,monospace">=A0=A0=A0=A0=A0=A0=A0=A0= =A0 t)


=A0=A0=A0=A0=A0=A0=A0 This is fixed in the new versi= on and delivers an error
=A0=A0=A0=A0=A0=A0= =A0 message at parse time.

=A0=A0=A0=A0=A0 + missing org-re (line 7179 in org.e= l) with posix classes
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 Min= or consistency issue.=A0 This line does not occur in the new
=A0=A0=A0=A0=A0=A0=A0 code.


Than= ks and regards,

=A0=A0 Christopher Genove= se




On Sat= , Aug 4, 2012 at 6:07 AM, Christopher Genovese <genovese@cmu.edu> wrote:
A small addendum:

Right after I poste= d (of course!), I noticed both a small mistake and an opportunity for
si= mplification, relating to detecting and processing the todo expressions aft= er a /.
Specifically, the approximate fix I proposed to the bug in the 7.8 code is = insufficient
to handle regexp matching in todo expressions. The full solution using the<= br>new function org-find-todo-query is needed in the code as I have it, and= that can just
be plugged in instead of the string-match. (See Note h in= the original post, specifically
the string-match given there, and org-find-todo-query.)

But I reali= zed that all that is unnecessary as the todo processing can be easily built=
into the new parser. I've mostly done that just now and will test = and post an update
Saturday, er...today.

Sorry to muddy the waters by not catching tha= t earlier, and sorrier still if I'm rambling.=A0
Off to bed...

=A0-- Christopher
<= /span>



On Sat, Aug 4, 201= 2 at 3:50 AM, Christopher Genovese <genovese@cmu.edu> wrote:<= br>
I am writing an application layer on top of org that uses the<= br style=3D"font-family:courier new,monospace"> entry mapping API, but I = needed both negation of complex
selections and heading se= arches. Because the current tag query
parser d= oes not handle parenthesized expressions, it does not
allow negating complex qu= eries. At first, I wrote a workaround
solution= that mimics/specializes the mapping API, but that
approach seemed inelegant= and harder to maintain.

So instead I implemented a full parser for tag q= ueries with a
number of useful features= (see the labeled Notes at the bottom
for furt= her comments on these features):

=A0 1. Parenthesized expressions to arbitrary depth = are allowed.
=A0 2. A '-' can be used = to negate a parenthesized term.=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [Note a= ]
=A0 3. Regex's in {} = can contain braces escaped by doubling: {{ }}.=A0 [Note b]
=A0 4. Supports fast property search on HEADING and PRIORITY.= =A0=A0=A0=A0=A0=A0=A0 [Note c]
=A0 5. Handles hyphens in= property names properly.=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 [Note d,h]
=A0 6. Allows only the prope= r comparison operators, including =3D=3D.=A0=A0=A0 [Note e,h]
=A0 7. Allows spaces arou= nd operators and terms for readability.=A0=A0=A0=A0 [Note f]
=A0 8. Matchers use the original expression order; not a big=
=A0=A0=A0=A0 deal, but fr= ee.
=A0 9. The error messages during parsing a= re reasonably helpful.
=A0 10. Several bug fixes= and a cleaner `org-make-tags-matcher'.=A0=A0=A0=A0 [Note h]

I'm submitting the co= de for your consideration, with the
goal of eventually incorporating th= is into org.el. I would be

happy to hear any comment= s or suggestions you have. As I'll describe
functions and adding a fe= w new support functions. I've attached two
files org-tag-query-parse.el (the code) and tag-query-tests.el (a collection of tests built= on a simple framework). I've also
put the= files in http://www.stat.cmu.edu/~genovese/emacs/. The
comments in both files wi= ll I hope be helpful.

At the risk of going on too long, I'd like to a= dd a few comments
about the code and tests.= First, the two existing functions that
are af= fected in the code are `org-make-tags-matcher' and
`org-scan-tags'. In t= he new version of the former, I've extracted
out both kinds of query parsing, leading to a shorter and cleaner=
function. The new version= of the latter differs in only a couple
*very = minor* places that capture two values that were already
being computed anyway (se= e the diff reproduced in the comments).
Btw, I= 'm working from the 7.8.11 code.

Loading org-tag-query-parse.el does not change the o= riginal
functions. Instead, I've added a= `-NEW' to the names of these
functions and saved the o= riginals also with a `-ORIGINAL' added.
Af= ter loading the file, you can choose a version to try by doing

=A0=A0=A0 (org-tmp-use-tag-parser 'new)and
=A0=A0=A0 (org-tmp-use-ta= g-parser 'original)

or do (org-tmp-use-tag-parser) to toggle between = versions.
You can also just use the= names with suffixes directly.
I'd also s= uggest byte-compiling the file.

I think the place to start looking at the code is th= e new version
of `org-make-tags-matcher'. = The main entry function for the new
parser is `org-tag-query-= parse', though the real workhorse is
actua= lly the function `org-tag-query-parse-1'. There is also a
new function `org-todo-qu= ery-parse' which just extracts the
existin= g todo matching method. (I didn't do anything with that
method as the manual make= s it clear that it is of secondary
importance.= ) I think the modularity here makes
`org-make-tags-matcher= 9; and each separate parser easier to read
and= understand.

The other substantial piece (in terms of lines of co= de) is a utility
macro `org-match-cond' th= at is used throughout and makes the main

parser much more readable= IMHO. Admittedly, I went a bit
overboard in o= ptimizing it; the first version worked fine
but this one produces rea= lly nice code. I'd suggest ignoring this
c= ode (in section "Parsing utility for readable matchers") on
first pass. The docstring= is pretty complete, and its use is more
or le= ss self-explanatory. Most of its work is done at compile time.

To run the tests, load org-tag-query-parse.el and ta= g-query-tests.el
and do


=A0=A0 (tag-test-run :results) ; use :summary for a = brief summary of all runs
=A0=A0 (tag-test-other-te= sts)=A0 ; miscellaneous other tests, including scanning

or name individual suites. They are at the moment:

=A0=A0 (tag-test-run :res= ults 'org-comparison-1)=A0 ; or use :summary
=A0=A0 (tag-test-run :results 'org-comparison-2)
=A0=A0 (tag-test-run :res= ults 'match-results-1)
=A0=A0 (tag-test-ru= n :results 'match-results-2)
=A0=A0 (tag-test-run :res= ults 'should-error-1)

If you have other ideas for tests or find any b= ugs, please let me
know. Sorry for the homeg= rown framework; it just sort of grew and
then = I was too tired to rewrite the tests. One complication here
is that the original and = new algorithms produce different term
orders a= nd use a few different functions. The function
tag-test-transform transf= orms original results to the new
algorithms co= nventions, but it does not handle PRIORITY or
HEADING matches at the mo= ment. Use the tree form of the tess (see
match= -results-1 for example) on these. Btw, I've run the tests on
GNU Emacs 23.2 and 24.1 (= running on OS X lion).

Notes:
=A0=A0 a. There is no nee= d to introduce a new character such as ! for
= =A0=A0=A0=A0=A0 negation because the semantics of the - are clear and are
=A0=A0=A0=A0=A0 consisten= t with its use for tags. A - binds more tightly
=A0=A0=A0=A0=A0 selector = can also be used for positive selection of a
= =A0=A0=A0=A0=A0 parenthesized term but it is equivalent to using no<= br style=3D"font-family:courier new,monospace"> =A0=A0=A0=A0=A0 selector,= just as for tags.
=A0=A0=A0=A0=A0

=A0=A0 b. Because \'s= are so heavily used in regex's and because they
=A0=A0=A0=A0=A0 have to be doubled in strings, using \'s for an = additional
=A0=A0=A0=A0=A0 escape la= yer would be messy, ambiguous, and hard to read.
=A0=A0=A0=A0=A0 Only the {}'s need to be escaped and the doubling es= capes
=A0=A0=A0=A0=A0 {{ -> = { and }} -> } are simple, readable, and fast to
=A0=A0=A0=A0=A0 parse. For example: "+{abc\\{{3,7\\}}}" give= s the regex
=A0=A0=A0=A0=A0 "abc= \\{3,7\\}". Parity makes correctness clear at a glance.
=A0=A0=A0=A0=A0
=A0=A0 c. Because headlin= e (and priority) searches can be useful and
= =A0=A0=A0=A0=A0 powerful, and because the information on those fields is
=A0=A0=A0=A0=A0 *already = processed* in `org-scan-tags', we get those
=A0=A0=A0=A0=A0 minor cha= nges to `org-scan-tags'. See the unified diff in
=A0=A0=A0=A0=A0 comments. The special PRIORITY property already exis= ts; I
=A0=A0=A0=A0=A0 added the= special HEADING property for these purposes. I'm
=A0=A0=A0=A0=A0 open to changing the name of course, but I do think= the
=A0=A0=A0=A0=A0 feature i= s both useful and elegant. (I'm using it in my
=A0=A0=A0=A0=A0 application, for instance.)

=A0=A0 d. I did not see it in the manual, but I thin= k that property names
=A0=A0=A0=A0=A0 with hyp= hens should have these \-escaped -'s in the query
=A0=A0=A0=A0=A0 string, w= ith the escaping slashes removed in the produced
=A0=A0=A0=A0=A0 matcher. This is not currently done, but the new version= does.
=A0=A0=A0=A0=A0 See Note = h for details.

=A0=A0 e. It seems desirable to support both =3D and =3D= =3D as equality operators
=A0=A0=A0=A0=A0 since the= latter is so common by habit. The new version allows
=A0=A0=A0=A0=A0 this explicitly. The original version does as well,= but the
=A0=A0=A0=A0=A0 regex for= the comparison operator also allows other operators
=A0=A0=A0=A0=A0 <<, ><, >>, =3D>, and >=3D a= s well, which can produce bad matchers.
=A0=A0=A0=A0=A0 See Note = h for details.

=A0=A0 f. Currently, spaces are ignored around &, |, t= he implicit & between
=A0=A0=A0=A0=A0 terms, ar= ound the comparison operators in property searches,
=A0=A0=A0=A0=A0 and around +/- selectors. Spaces are not ignored insi= de {}'s
=A0=A0=A0=A0=A0 for a reg= exp match.

=A0=A0 g. The current code also allows +/- selectors before p= roperty
=A0=A0=A0=A0=A0 compariso= ns. I don't really like this because
=A0= =A0=A0=A0=A0 +PROP<>"something" and -PROP=3D"something= " have the same
=A0=A0=A0=A0=A0 meaning b= ut look very different. But the new code does
= =A0=A0=A0=A0=A0 support this. As a side note, there's really no need fo= r
=A0=A0=A0=A0=A0 the &= characters as +/- serve the and/and-not function
=A0=A0=A0=A0=A0 completely. But again, no prob.

=A0=A0 h. A few bugs detected in the 7.8.11 code:

=A0=A0=A0=A0=A0 + Faulty = test for todo matcher in org-make-tags-matcher
=A0=A0=A0=A0=A0=A0=A0 (string-match "/+" match)

=A0=A0=A0=A0=A0=A0=A0 Ex: (org-make-tags-matcher &qu= ot;PROP=3D{^\\s-*// .*$}") produces
=A0=A0=A0=A0=A0=A0=A0 an = erroneous matcher:
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ("PROP=3D{^\\s-= *// .*$}" progn
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0 (setq org-cached-props nil)
=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (member "PROP" tags-list))

=A0=A0=A0=A0=A0=A0=A0 For all practical purposes it = will be enough to do:
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0=A0 = (string-match "\\(/\\(!\\)?\\s-*\\)[^{}\"]*$" match)<= br style=3D"font-family:courier new,monospace">=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 ins= tead of the current test in org-make-tags-matcher.
=A0=A0=A0=A0=A0=A0=A0 This works as long as the TODO keywords do not c= ontain a
=A0=A0=A0=A0=A0=A0=A0 rig= ht brace or quotation marks. (In most other cases, the
=A0=A0=A0=A0=A0=A0=A0 new parser should give an error message at p= arse time.)
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 A technicality: this is /n= ot/ a complete solution because
=A0=A0=A0=A0=A0=A0=A0 arb= itrary strings can be TODO keywords. For instance,
=A0=A0=A0=A0=A0=A0=A0 both PROP=3D{/!} and PROP=3D"/!{/!}" a= re valid TODO keywords
=A0=A0=A0=A0=A0=A0=A0 (it= works!) *and* valid property comparisons. So, a pattern

=A0=A0=A0=A0=A0=A0=A0 alone is insufficient. We want to find the= first slash
=A0=A0=A0=A0=A0=A0=A0 tha= t is not enclosed in {}'s or ""'s; if found, a todo
=A0=A0=A0=A0=A0=A0=A0 match is needed. The function= `org-find-todo-query' does
=A0=A0=A0=A0=A0=A0=A0 thi= s and (org-find-todo-query match) can be plugged in
=A0=A0=A0=A0=A0=A0=A0 directly replacing the above (string-match ...)= in then
=A0=A0=A0=A0=A0=A0=A0 new= `org-make-tags-matcher'.
=A0=A0=A0=A0=A0= =A0=A0
=A0=A0=A0=A0=A0=A0=A0 But= because the todo parsing uses {}'s for regex matches,
=A0=A0=A0=A0=A0=A0=A0 TODO keywords with {}'s are ignored= anyway. So there's
=A0=A0=A0=A0=A0=A0=A0 no = need to go beyond the fixed string-match above.
=A0=A0=A0=A0=A0=A0=A0 par= sing in the new version, makes this explicit.
= =A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0 + Propert= y names with -'s are not handled properly (cf. Note d)

=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 Spe= cifically, the escapes are not removed. Example:
=A0=A0=A0=A0=A0=A0=A0 (org-make-tags-matcher "PROP\\-WITH\\-HYPHENS= =3D2")
=A0=A0=A0=A0=A0=A0=A0 pro= duces
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 (&q= uot;PROP\\-WITH\\-HYPHENS=3D2" and
=A0=A0= =A0=A0=A0=A0=A0=A0 (progn
=A0=A0=A0=A0=A0=A0=A0=A0 = (setq org-cached-props nil)
=A0=A0=A0=A0=A0=A0= =A0=A0 (=3D
=A0=A0=A0=A0=A0=A0=A0=A0= =A0 (string-to-number
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 (or (org-cached-entry-get nil "PROP\\-WITH\\-HYPHENS")

=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 ""))
=A0=A0=A0=A0=A0=A0=A0=A0= =A0 2))
=A0=A0=A0=A0=A0=A0=A0=A0 = t)
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 The= original code /does/ instead remove -'s from tag
=A0=A0=A0=A0=A0=A0=A0 names, which shouldn't have them anyway. = I suspect that
=A0=A0=A0=A0=A0=A0=A0 thi= s was intended for property names rather than tag
=A0=A0=A0=A0=A0=A0=A0 names. The new version fixes up property names bu= t does
=A0=A0=A0=A0=A0=A0=A0 not= allow -'s in tags.

=A0=A0=A0=A0=A0 + Incorrect comparison operators = allowed (cf. Note e)
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 The regular expression use= d is "[<=3D>]\\{1,2\\}" is used to
=A0=A0=A0=A0=A0=A0=A0 det= ect the comparison operators. But this can produce bad
=A0=A0=A0=A0=A0=A0=A0 matchers that fail opaquely at match time ra= ther than
=A0=A0=A0=A0=A0=A0=A0 giv= ing an appropriate error message at parse time.

= =A0=A0=A0=A0=A0=A0=A0 Ex:= (org-make-tags-matcher "P<<2") produces

=A0=A0=A0=A0=A0=A0=A0=A0 ("P<<2" and=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 (progn
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 (setq org-cached-props nil)
=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 (nil
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0 (string-to-number (or (org-cached-entry-get nil "P")= "")) 2))
<= span style=3D"font-family:courier new,monospace">=A0=A0=A0=A0=A0=A0=A0=A0= =A0 t)


=A0=A0=A0=A0=A0=A0=A0 This is fixed in the new versi= on and delivers an error
=A0=A0=A0=A0=A0=A0= =A0 message at parse time.

=A0=A0=A0=A0=A0 + missing org-re (line 7179 in org.e= l) with posix classes
=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0 Min= or consistency issue.=A0 This line does not occur in the new
=A0=A0=A0=A0=A0=A0=A0 code.


Than= ks and regards,

=A0=A0 Christopher Genove= se




--047d7b2e4f6e94631204c674df36-- --047d7b2e4f6e94631804c674df38 Content-Type: application/octet-stream; name="org-tag-query-parse.el" Content-Disposition: attachment; filename="org-tag-query-parse.el" Content-Transfer-Encoding: base64 X-Attachment-Id: f_h5h0xnc00 Ozs7IG9yZy10YWctcXVlcnktcGFyc2UuZWwgLS0gcHJvcG9zZWQgZnVsbCBwYXJzZXIgZm9yIHRh ZyBxdWVyaWVzCgo7OyBDb3B5cmlnaHQgKEMpIDIwMTIsIENocmlzdG9waGVyIFIuIEdlbm92ZXNl LCBhbGwgcmlnaHRzIHJlc2VydmVkLgoKOzsgQXV0aG9yOiAgQ2hyaXN0b3BoZXIgR2Vub3Zlc2Ug PGdlbm92ZXNlQGNtdS5lZHU+Cjs7IFZlcnNpb246IDAuOQo7Owo7OyBDcmVhdGVkOiAgICAgIFN1 biAyOSBKdWwgMjAxMiBhdCAxMDowNCBFRFQKOzsgTGFzdC1VcGRhdGVkOiBGcmkgMDMgQXVnIDIw MTIgYXQgMjM6NTIgRURUCjs7IFVwZGF0ZWQgQnk6ICAgQ2hyaXN0b3BoZXIgUi4gR2Vub3Zlc2UK OzsgS2V5d29yZHM6IG9yZy1tb2RlLCB0YWdzLCBxdWVyeSwgc2VhcmNoCjs7IFBhY2thZ2UtUmVx dWlyZXM6ICgob3JnLW1vZGUgNy44KSkKCgo7OzsgQ29tbWVudGFyeToKOzsKOzsgIFRoZSBjdXJy ZW50IHBhcnNlciBmb3IgdGFnIHF1ZXJ5IHNlYXJjaGVzIGRvZXMgbm90IGhhbmRsZQo7OyAgcGFy ZW50aGVzaXplZCBleHByZXNzaW9ucyBhbmQgdGh1cyBkb2VzIG5vdCBhbGxvdyBuZWdhdGluZyBj b21wbGV4Cjs7ICBxdWVyaWVzLiBUaGlzIGNvZGUgaW1wbGVtZW50cyBhIGZ1bGwgcGFyc2VyIGZv ciB0YWcgcXVlcmllcyB3aXRoCjs7ICBudW1iZXIgb2YgdXNlZnVsIGZlYXR1cmVzIChzZWUgdGhl IGxhYmVsZWQgTm90ZXMgYmVsb3cgZm9yIGZ1cnRoZXIKOzsgIGNvbW1lbnRzIG9uIHRoZXNlIGZl YXR1cmVzKToKOzsgCjs7ICAgMS4gUGFyZW50aGVzaXplZCBleHByZXNzaW9ucyB0byBhcmJpdHJh cnkgZGVwdGggYXJlIGFsbG93ZWQuCjs7ICAgMi4gQSAnLScgY2FuIGJlIHVzZWQgdG8gbmVnYXRl IGEgcGFyZW50aGVzaXplZCB0ZXJtLiAgICAgICAgICAgICBbTm90ZSBhXQo7OyAgIDMuIFJlZ2V4 J3MgaW4ge30gY2FuIGNvbnRhaW4gYnJhY2VzIGVzY2FwZWQgYnkgZG91Ymxpbmc6IHt7IH19LiAg W05vdGUgYl0KOzsgICA0LiBTdXBwb3J0cyBmYXN0IHByb3BlcnR5IHNlYXJjaCBvbiBIRUFESU5H IGFuZCBQUklPUklUWS4gICAgICAgIFtOb3RlIGNdCjs7ICAgNS4gSGFuZGxlcyBoeXBoZW5zIGlu IHByb3BlcnR5IG5hbWVzIHByb3Blcmx5LiAgICAgICAgICAgICAgICAgICBbTm90ZSBkXQo7OyAg IDYuIEFsbG93cyBvbmx5IHRoZSBwcm9wZXIgY29tcGFyaXNvbiBvcGVyYXRvcnMsIGluY2x1ZGlu ZyA9PS4gICAgW05vdGUgZV0KOzsgICA3LiBBbGxvd3Mgc3BhY2VzIGFyb3VuZCBvcGVyYXRvcnMg YW5kIHRlcm1zIGZvciByZWFkYWJpbGl0eS4gICAgIFtOb3RlIGZdCjs7ICAgOC4gUGFyc2UgdHJl ZXMgdXNlIHRoZSBvcmlnaW5hbCBleHByZXNzaW9uIG9yZGVyOyBub3QgYSBiaWcKOzsgICAgICBk ZWFsLCBidXQgZnJlZS4KOzsgICA5LiBSZXR1cm5lZCBwYXJzZSB0cmVlcyBhcmUgY2xlYW4sIHdp dGhvdXQgdHJpdmlhbCBvcGVyYXRvcnMsCjs7ICAgICAgYW5kIGVycm9yIG1lc3NhZ2VzIGR1cmlu ZyBwYXJzaW5nIGFyZSByZWFzb25hYmx5IGhlbHBmdWwuCjs7ICAgMTAuIEEgZmV3IGJ1ZyBmaXhl cyBhbmQgYSBjbGVhbmVyIGBvcmctbWFrZS10YWdzLW1hdGNoZXInLiAgICAgICBbTm90ZSBoXQo7 Owo7OyAgSSBwcm9wb3NlIHRoYXQgdGhpcyBuZXcgcGFyc2VyIGJlIGluY29ycG9yYXRlZCBpbnRv IG9yZy5lbC4KOzsgIAo7OyAgVGhlIHR3byBleGlzdGluZyBmdW5jdGlvbnMgdGhhdCBhcmUgYWZm ZWN0ZWQgaW4gdGhlIGNvZGUgYXJlCjs7ICBgb3JnLW1ha2UtdGFncy1tYXRjaGVyJyBhbmQgYG9y Zy1zY2FuLXRhZ3MnLiBJbiB0aGUgbmV3IHZlcnNpb24gb2YKOzsgIHRoZSBmb3JtZXIsIEkndmUg dW5pZmllZCBib3RoIGtpbmRzIG9mIHF1ZXJ5IHBhcnNpbmcsIGxlYWRpbmcgdG8gYQo7OyAgc2hv cnRlciBhbmQgY2xlYW5lciBmdW5jdGlvbi4uIFRoZSBuZXcgdmVyc2lvbiBvZiB0aGUgbGF0dGVy IGRpZmZlcnMKOzsgIGluIG9ubHkgYSBjb3VwbGUgKnZlcnkgbWlub3IqIHBsYWNlcyB0aGF0IGNh cHR1cmUgdHdvIHZhbHVlcyB0aGF0Cjs7ICB3ZXJlIGFscmVhZHkgYmVpbmcgY29tcHV0ZWQgYW55 d2F5IChzZWUgdGhlIGRpZmYgcmVwcm9kdWNlZCBpbiB0aGUKOzsgIGNvbW1lbnRzKS4KOzsgIAo7 OyAgTG9hZGluZyBvcmctdGFnLXF1ZXJ5LXBhcnNlLmVsIGRvZXMgbm90IGNoYW5nZSB0aGUgb3Jp Z2luYWwKOzsgIGZ1bmN0aW9ucy4gSW5zdGVhZCwgSSd2ZSBhZGRlZCBhIGAtTkVXJyB0byB0aGUg bmFtZXMgb2YgdGhlc2UKOzsgIGZ1bmN0aW9ucyBhbmQgc2F2ZWQgdGhlIG9yaWdpbmFscyBhbHNv IHdpdGggYSBgLU9SSUdJTkFMJyBhZGRlZC4KOzsgIEFmdGVyIGxvYWRpbmcgdGhlIGZpbGUsIHlv dSBjYW4gY2hvb3NlIGEgdmVyc2lvbiB0byB0cnkgYnkgZG9pbmcKOzsgIAo7OyAgICAgIChvcmct dG1wLXVzZS10YWctcGFyc2VyICduZXcpCjs7ICBhbmQKOzsgICAgICAob3JnLXRtcC11c2UtdGFn LXBhcnNlciAnb3JpZ2luYWwpCjs7ICAKOzsgIG9yIGRvIChvcmctdG1wLXVzZS10YWctcGFyc2Vy KSB0byB0b2dnbGUgYmV0d2VlbiB2ZXJzaW9ucy4KOzsgIFlvdSBjYW4gYWxzbyBqdXN0IHVzZSB0 aGUgbmFtZXMgd2l0aCBzdWZmaXhlcyBkaXJlY3RseS4gCjs7ICAKOzsgIEkgdGhpbmsgdGhlIHBs YWNlIHRvIHN0YXJ0IGxvb2tpbmcgYXQgdGhlIGNvZGUgaXMgdGhlIG5ldyB2ZXJzaW9uIG9mCjs7 ICBgb3JnLW1ha2UtdGFncy1tYXRjaGVyJy4gVGhlIG1haW4gd29ya2hvcnNlIGZvciB0aGUgbmV3 IHBhcnNlciBpcwo7OyAgYG9yZy10YWctcXVlcnktcGFyc2UnLCB3aXRoIG5ldyBmdW5jdGlvbiBg b3JnLXRvZG8tcXVlcnktcGFyc2UnCjs7ICBoYW5kbGluZyB0aGUgLyE/IHRvZG8gcGFyc2luZy4K OzsgIAo7OyAgVGhlIG90aGVyIHN1YnN0YW50aWFsIHBpZWNlIChpbiB0ZXJtcyBvZiBsaW5lcyBv ZiBjb2RlKSBpcyBhIHV0aWxpdHkKOzsgIG1hY3JvIGBvcmctbWF0Y2gtY29uZCcgdGhhdCBpcyB1 c2VkIHRocm91Z2hvdXQgYW5kIG1ha2VzIHRoZSBtYWluCjs7ICBwYXJzZXIgbXVjaCBtb3JlIHJl YWRhYmxlIElNSE8uIEFkbWl0dGVkbHksIEkgd2VudCBhIGJpdCBvdmVyYm9hcmQKOzsgIGluIG9w dGltaXppbmcgaXQ7IHRoZSBmaXJzdCB2ZXJzaW9uIHdvcmtlZCBmaW5lIGJ1dCB0aGlzIG9uZQo7 OyAgcHJvZHVjZXMgcmVhbGx5IG5pY2UgY29kZS4gSSdkIHN1Z2dlc3QgaWdub3JpbmcgdGhpcyBj b2RlIChpbgo7OyAgc2VjdGlvbiAiUGFyc2luZyB1dGlsaXR5IGZvciByZWFkYWJsZSBtYXRjaGVy cyIpIG9uIGZpcnN0IHBhc3MuIFRoZQo7OyAgZG9jc3RyaW5nIGlzIHByZXR0eSBjb21wbGV0ZSwg YW5kIGl0cyB1c2UgaXMgbW9yZSBvciBsZXNzCjs7ICBzZWxmLWV4cGxhbmF0b3J5Lgo7OyAgCjs7 ICBOb3RlczoKOzsgICAgYS4gVGhlcmUgaXMgbm8gbmVlZCB0byBpbnRyb2R1Y2UgYSBuZXcgY2hh cmFjdGVyIHN1Y2ggYXMgISBmb3IKOzsgICAgICAgbmVnYXRpb24gYmVjYXVzZSB0aGUgc2VtYW50 aWNzIG9mIHRoZSAtIGFyZSBjbGVhciBhbmQgYXJlCjs7ICAgICAgIGNvbnNpc3RlbnQgd2l0aCBp dHMgdXNlIGZvciB0YWdzLiBBIC0gYmluZHMgbW9yZSB0aWdodGx5Cjs7ICAgICAgIHRoYW4gJiB3 aGljaCBpbiB0dXJuIGJpbmRzIG1vcmUgdGlnaHRseSB0aGFuIHwuIEEgKwo7OyAgICAgICBzZWxl Y3RvciBjYW4gYWxzbyBiZSB1c2VkIGZvciBwb3NpdGl2ZSBzZWxlY3Rpb24gb2YgYQo7OyAgICAg ICBwYXJlbnRoZXNpemVkIHRlcm0gYnV0IGl0IGlzIGVxdWl2YWxlbnQgdG8gdXNpbmcgbm8KOzsg ICAgICAgc2VsZWN0b3IsIGp1c3QgYXMgZm9yIHRhZ3MuCjs7ICAgICAgIAo7OyAgICBiLiBCZWNh dXNlIFwncyBhcmUgc28gaGVhdmlseSB1c2VkIGluIHJlZ2V4J3MgYW5kIGJlY2F1c2UgdGhleQo7 OyAgICAgICBoYXZlIHRvIGJlIGRvdWJsZWQgaW4gc3RyaW5ncywgdXNpbmcgXCdzIGZvciBhbiBh ZGRpdGlvbmFsCjs7ICAgICAgIGVzY2FwZSBsYXllciB3b3VsZCBiZSBtZXNzeSwgYW1iaWd1b3Vz LCBhbmQgaGFyZCB0byByZWFkLgo7OyAgICAgICBPbmx5IHRoZSB7fSdzIG5lZWQgdG8gYmUgZXNj YXBlZCBhbmQgdGhlIGRvdWJsaW5nIGVzY2FwZXMKOzsgICAgICAge3sgLT4geyBhbmQgfX0gLT4g fSBhcmUgc2ltcGxlLCByZWFkYWJsZSwgYW5kIGZhc3QgdG8KOzsgICAgICAgcGFyc2UuIEZvciBl eGFtcGxlOiAiK3thYmNcXHt7Myw3XFx9fX0iIGdpdmVzIHRoZSByZWdleAo7OyAgICAgICAiYWJj XFx7Myw3XFx9Ii4gUGFyaXR5IG1ha2VzIGNvcnJlY3RuZXNzIGNsZWFyIGF0IGEgZ2xhbmNlLgo7 OyAgICAgICAKOzsgICAgYy4gQmVjYXVzZSBoZWFkbGluZSAoYW5kIHByaW9yaXR5KSBzZWFyY2hl cyBjYW4gYmUgdXNlZnVsIGFuZAo7OyAgICAgICBwb3dlcmZ1bCwgYW5kIGJlY2F1c2UgdGhlIGlu Zm9ybWF0aW9uIG9uIHRob3NlIGZpZWxkcyBpcwo7OyAgICAgICAqYWxyZWFkeSBwcm9jZXNzZWQq IGluIGBvcmctc2Nhbi10YWdzJywgd2UgZ2V0IHRob3NlCjs7ICAgICAgIHNwZWNpYWwgc2VhcmNo ZXMgKmVzc2VudGlhbGx5IGZvciBmcmVlKiwgcmVxdWlyaW5nIG9ubHkgdHdvCjs7ICAgICAgIG1p bm9yIGNoYW5nZXMgdG8gYG9yZy1zY2FuLXRhZ3MnLiBTZWUgdGhlIHVuaWZpZWQgZGlmZiBpbgo7 OyAgICAgICBjb21tZW50cy4gVGhlIHNwZWNpYWwgUFJJT1JJVFkgcHJvcGVydHkgYWxyZWFkeSBl eGlzdHM7IEkKOzsgICAgICAgYWRkZWQgdGhlIHNwZWNpYWwgSEVBRElORyBwcm9wZXJ0eSBmb3Ig dGhlc2UgcHVycG9zZXMuIEknbQo7OyAgICAgICBvcGVuIHRvIGNoYW5naW5nIHRoZSBuYW1lIG9m IGNvdXJzZSwgYnV0IEkgZG8gdGhpbmsgdGhlCjs7ICAgICAgIGZlYXR1cmUgaXMgdmVyeSB1c2Vm dWwuCjs7IAo7OyAgICBkLiBJIGRpZCBub3Qgc2VlIGl0IGluIHRoZSBtYW51YWwsIGJ1dCBJIHRo aW5rIHRoYXQgcHJvcGVydHkgbmFtZXMKOzsgICAgICAgd2l0aCBoeXBoZW5zIHNob3VsZCBoYXZl IHRoZXNlIFwtZXNjYXBlZCAtJ3MgaW4gdGhlIHF1ZXJ5Cjs7ICAgICAgIHN0cmluZywgd2l0aCB0 aGUgZXNjYXBpbmcgc2xhc2hlcyByZW1vdmVkIGluIHRoZSBwcm9kdWNlZAo7OyAgICAgICBtYXRj aGVyLiBUaGlzIGlzIG5vdCBjdXJyZW50bHkgZG9uZSwgYnV0IHRoZSBuZXcgdmVyc2lvbiBkb2Vz Lgo7OyAgICAgICBTZWUgTm90ZSBoIGZvciBkZXRhaWxzLgo7OyAKOzsgICAgZS4gSXQgc2VlbXMg ZGVzaXJhYmxlIHRvIHN1cHBvcnQgYm90aCA9IGFuZCA9PSBhcyBlcXVhbGl0eSBvcGVyYXRvcnMK OzsgICAgICAgc2luY2UgdGhlIGxhdHRlciBpcyBzbyBjb21tb24gYnkgaGFiaXQuIFRoZSBuZXcg dmVyc2lvbiBhbGxvd3MKOzsgICAgICAgdGhpcyBleHBsaWNpdGx5LiBUaGUgb3JpZ2luYWwgdmVy c2lvbiBkb2VzIGFzIHdlbGwsIGJ1dCB0aGUKOzsgICAgICAgcmVnZXggZm9yIHRoZSBjb21wYXJp c29uIG9wZXJhdG9yIGFsc28gYWxsb3dzIG90aGVyIG9wZXJhdG9ycwo7OyAgICAgICA8PCwgPjws ID4+LCA9PiwgYW5kID49IGFzIHdlbGwsIHdoaWNoIGNhbiBwcm9kdWNlIGJhZCBtYXRjaGVycy4K OzsgICAgICAgU2VlIE5vdGUgaCBmb3IgZGV0YWlscy4KOzsgCjs7ICAgIGYuIEN1cnJlbnRseSwg c3BhY2VzIGFyZSBpZ25vcmVkIGFyb3VuZCAmLCB8LCB0aGUgaW1wbGljaXQgJiBiZXR3ZWVuCjs7 ICAgICAgIHRlcm1zLCBhcm91bmQgdGhlIGNvbXBhcmlzb24gb3BlcmF0b3JzIGluIHByb3BlcnR5 IHNlYXJjaGVzLAo7OyAgICAgICBhbmQgYXJvdW5kICsvLSBzZWxlY3RvcnMuIFNwYWNlcyBhcmUg bm90IGlnbm9yZWQgaW5zaWRlIHt9J3MKOzsgICAgICAgZm9yIGEgcmVnZXhwIG1hdGNoLiBUcnV0 aCBiZSB0b2xkLCBJIHByZWZlciBoYXZpbmcgbm8gc3BhY2VzCjs7ICAgICAgIGFmdGVyIHRoZSAr Ly0gc2VsZWN0b3JzLCBidXQgaXQgc2VlbXMgc29tZXdoYXQuLi5oYXJzaCB0byBpbnNpc3QKOzsg ICAgICAgb24gdGhhdCBmb3IgZXZlcnlvbmUuIExpdmUgYW5kIGxldCBsaXZlLgo7OyAKOzsgICAg Zy4gVGhlIGN1cnJlbnQgY29kZSBhbHNvIGFsbG93cyArLy0gc2VsZWN0b3JzIGJlZm9yZSBwcm9w ZXJ0eQo7OyAgICAgICBjb21wYXJpc29ucy4gSSBkb24ndCByZWFsbHkgbGlrZSB0aGlzIGJlY2F1 c2UKOzsgICAgICAgK1BST1A8PiJzb21ldGhpbmciIGFuZCAtUFJPUD0ic29tZXRoaW5nIiBoYXZl IHRoZSBzYW1lCjs7ICAgICAgIG1lYW5pbmcgYnV0IGxvb2sgdmVyeSBkaWZmZXJlbnQuIEJ1dCB0 aGUgbmV3IGNvZGUgZG9lcwo7OyAgICAgICBzdXBwb3J0IHRoaXMuIEFzIGEgc2lkZSBub3RlLCB0 aGVyZSdzIHJlYWxseSBubyBuZWVkIGZvcgo7OyAgICAgICB0aGUgJiBjaGFyYWN0ZXJzIGFzICsv LSBzZXJ2ZSB0aGUgYW5kL2FuZC1ub3QgZnVuY3Rpb24KOzsgICAgICAgY29tcGxldGVseS4gQnV0 IGFnYWluLCBubyBwcm9iLgo7OyAKOzsgICAgaC4gQSBmZXcgYnVncyBkZXRlY3RlZCBpbiB0aGUg Ny44LjExIGNvZGU6Cjs7IAo7OyAgICAgICArIEZhdWx0eSB0ZXN0IGZvciB0b2RvIG1hdGNoZXIg aW4gb3JnLW1ha2UtdGFncy1tYXRjaGVyCjs7ICAgICAgICAgKHN0cmluZy1tYXRjaCAiLysiIG1h dGNoKQo7OyAKOzsgICAgICAgICBFeDogKG9yZy1tYWtlLXRhZ3MtbWF0Y2hlciAiUFJPUD17Xlxc cy0qLy8gLiokfSIpIHByb2R1Y2VzIAo7OyAgICAgICAgIGFuIGVycm9uZW91cyBtYXRjaGVyOgo7 OyAKOzsgICAgICAgICAgICAgKCJQUk9QPXteXFxzLSovLyAuKiR9IiBwcm9nbgo7OyAgICAgICAg ICAgICAgKHNldHEgb3JnLWNhY2hlZC1wcm9wcyBuaWwpCjs7ICAgICAgICAgICAgICAobWVtYmVy ICJQUk9QIiB0YWdzLWxpc3QpKQo7OyAKOzsgICAgICAgICBCZWNhdXNlIHt9J3MgY2FuIGFwcGVh ciBpbiAvIT8gdG9kby1tYXRjaCBleHByZXNzaW9ucywgYW5kCjs7ICAgICAgICAgYmVjYXVzZUEg YXJiaXRyYXJ5IHN0cmluZ3MgY2FuIGJlIFRPRE8ga2V5d29yZHMsIGEgc2ltcGxlCjs7ICAgICAg ICAgcGF0dGVybiBtYXRjaCB3aWxsIG5vdCBnaXZlIGEgY29tcGxldGUgc29sdXRpb24uIEZvcgo7 OyAgICAgICAgIGluc3RhbmNlLCBib3RoIFBST1A9ey8hfSBhbmQgUFJPUD0iLyF7LyF9IiBhcmUg dmFsaWQgVE9ETwo7OyAgICAgICAgIGtleXdvcmRzIChpdCB3b3JrcyEpICphbmQqIHZhbGlkIHBy b3BlcnR5IGNvbXBhcmlzb25zLiBXZQo7OyAgICAgICAgIHdhbnQgdG8gZmluZCB0aGUgZmlyc3Qg c2xhc2ggdGhhdCBpcyBub3QgZW5jbG9zZWQgaW4ge30ncyBvcgo7OyAgICAgICAgICIiJ3M7IGlm IGZvdW5kLCBhIHRvZG8gbWF0Y2ggaXMgbmVlZGVkLiBUaGUgbmV3IHBhcnNlcgo7OyAgICAgICAg IGhhbmRsZXMgdGhlIHR3byB0eXBlcyBvZiBtYXRjaGluZyB0b2dldGhlciBhbmQgc28KOzsgICAg ICAgICBhdXRvbWF0aWNhbGx5IGRldGVjdHMgdGhlIHRvZG8gbWF0Y2hlcyBjb3JyZWN0bHkuCjs7 ICAgICAgICAgCjs7ICAgICAgICsgUHJvcGVydHkgbmFtZXMgd2l0aCAtJ3MgYXJlIG5vdCBoYW5k bGVkIHByb3Blcmx5IChjZi4gTm90ZSBkKQo7OyAgICAgICAgIAo7OyAgICAgICAgIFNwZWNpZmlj YWxseSwgdGhlIGVzY2FwZXMgYXJlIG5vdCByZW1vdmVkLiBFeGFtcGxlOgo7OyAgICAgICAgIChv cmctbWFrZS10YWdzLW1hdGNoZXIgIlBST1BcXC1XSVRIXFwtSFlQSEVOUz0yIikKOzsgICAgICAg ICBwcm9kdWNlcwo7OyAgICAgICAgIAo7OyAgICAgICAgICgiUFJPUFxcLVdJVEhcXC1IWVBIRU5T PTIiIGFuZAo7OyAgICAgICAgICAocHJvZ24KOzsgICAgICAgICAgKHNldHEgb3JnLWNhY2hlZC1w cm9wcyBuaWwpCjs7ICAgICAgICAgICg9Cjs7ICAgICAgICAgICAoc3RyaW5nLXRvLW51bWJlcgo7 OyAgICAgICAgICAgIChvciAob3JnLWNhY2hlZC1lbnRyeS1nZXQgbmlsICJQUk9QXFwtV0lUSFxc LUhZUEhFTlMiKQo7OyAgICAgICAgICAgICIiKSkKOzsgICAgICAgICAgIDIpKQo7OyAgICAgICAg ICB0KQo7OyAgICAgICAgIAo7OyAgICAgICAgIFRoZSBvcmlnaW5hbCBjb2RlIC9kb2VzLyBpbnN0 ZWFkIHJlbW92ZSAtJ3MgZnJvbSB0YWcKOzsgICAgICAgICBuYW1lcywgd2hpY2ggc2hvdWxkbid0 IGhhdmUgdGhlbSBhbnl3YXkuIEkgc3VzcGVjdCB0aGF0Cjs7ICAgICAgICAgdGhpcyB3YXMgaW50 ZW5kZWQgZm9yIHByb3BlcnR5IG5hbWVzIHJhdGhlciB0aGFuIHRhZwo7OyAgICAgICAgIG5hbWVz LiBUaGUgbmV3IHZlcnNpb24gZml4ZXMgdXAgcHJvcGVydHkgbmFtZXMgYnV0IGRvZXMKOzsgICAg ICAgICBub3QgYWxsb3cgLSdzIGluIHRhZ3MuCjs7IAo7OyAgICAgICArIEluY29ycmVjdCBjb21w YXJpc29uIG9wZXJhdG9ycyBhbGxvd2VkIChjZi4gTm90ZSBlKQo7OyAgICAgICAgIAo7OyAgICAg ICAgIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gdXNlZCBpcyAiWzw9Pl1cXHsxLDJcXH0iIGlzIHVz ZWQgdG8KOzsgICAgICAgICBkZXRlY3QgdGhlIGNvbXBhcmlzb24gb3BlcmF0b3JzLiBCdXQgdGhp cyBjYW4gcHJvZHVjZSBiYWQKOzsgICAgICAgICBtYXRjaGVycyB0aGF0IGZhaWwgb3BhcXVlbHkg YXQgbWF0Y2ggdGltZSByYXRoZXIgdGhhbiAKOzsgICAgICAgICBnaXZpbmcgYW4gYXBwcm9wcmlh dGUgZXJyb3IgbWVzc2FnZSBhdCBwYXJzZSB0aW1lLgo7OyAKOzsgICAgICAgICBFeDogKG9yZy1t YWtlLXRhZ3MtbWF0Y2hlciAiUDw8MiIpIHByb2R1Y2VzCjs7IAo7OyAgICAgICAgICAoIlA8PDIi IGFuZAo7OyAgICAgICAgICAgKHByb2duCjs7ICAgICAgICAgICAgIChzZXRxIG9yZy1jYWNoZWQt cHJvcHMgbmlsKQo7OyAgICAgICAgICAgICAobmlsCjs7ICAgICAgICAgICAgICAoc3RyaW5nLXRv LW51bWJlciAob3IgKG9yZy1jYWNoZWQtZW50cnktZ2V0IG5pbCAiUCIpICIiKSkgMikpCjs7ICAg ICAgICAgICB0KQo7OyAKOzsgICAgICAgICBUaGlzIGlzIGZpeGVkIGluIHRoZSBuZXcgdmVyc2lv biBhbmQgZGVsaXZlcnMgYW4gZXJyb3IgCjs7ICAgICAgICAgbWVzc2FnZSBhdCBwYXJzZSB0aW1l Lgo7OyAKOzsgICAgICAgKyBtaXNzaW5nIG9yZy1yZSAobGluZSA3MTc5IGluIG9yZy5lbCkgd2l0 aCBwb3NpeCBjbGFzc2VzCjs7ICAgICAgICAgCjs7ICAgICAgICAgTWlub3IgY29uc2lzdGVuY3kg aXNzdWUuICBUaGlzIGxpbmUgZG9lcyBub3Qgb2NjdXIgaW4gdGhlIG5ldwo7OyAgICAgICAgIGNv ZGUuCjs7Cjs7ICBXaGF0IGZvbGxvd3MgaXMgYSBncmFtbWFyIGZvciB0aGUgdXBkYXRlZCB0YWcg cXVlcnkgZHNsLCB3aGljaCBpcwo7OyAgZ2l2ZW4gaW4gYW4gaW5mb3JtYWwgaHlicmlkIG9mIEJO RiBhbmQgcmVnZXggb3BlcmF0b3JzLiBIb3BlZnVsbHksIGl0J3MKOzsgIGNsZWFyIGVub3VnaC4g VGhlIG5vbi1vYnZpb3VzIHRlcm1pbmFscyBhcmUgQUxMIENBUFMgYW5kIGFyZSBsaXN0ZWQgYmVs b3cuCjs7IAo7OyAgR3JhbW1hcjoKOzsgICAgRXhwcmVzc2lvbiAgPC0gIENvbmp1bmN0aW9uIChP UiBDb25qdW5jdGlvbikqCjs7ICAgIENvbmp1bmN0aW9uIDwtICBUZXJtIChBTkQ/IFRlcm0pKgo7 OyAgICBUZXJtICAgICAgICA8LSAgU0VMRUNUT1I/IFRBR19JREVOVAo7OyAgICAgICAgICAgICAg ICAgfCAgU0VMRUNUT1I/IExCUkFDRSBSZWdleCBSQlJBQ0UKOzsgICAgICAgICAgICAgICAgIHwg IFNFTEVDVE9SPyBQUk9QX0lERU5UIENNUF9PUCBOVU1CRVIKOzsgICAgICAgICAgICAgICAgIHwg IFNFTEVDVE9SPyBQUk9QX0lERU5UIENNUF9PUCBTVFJJTkcKOzsgICAgICAgICAgICAgICAgIHwg IFNFTEVDVE9SPyBQUk9QX0lERU5UIENNUF9PUCBEQVRFX1NUUklORwo7OyAgICAgICAgICAgICAg ICAgfCAgU0VMRUNUT1I/IFBST1BfSURFTlQgTUFUQ0hfT1AgTEJSQUNFIFJFR0VYIFJCUkFDRQo7 OyAgICAgICAgICAgICAgICAgfCAgU0VMRUNUT1I/IExQQVJFTiBFeHByZXNzaW9uIFJQQVJFTgo7 OyAgICAgICAgICAgICAgICAgCjs7ICBUZXJtaW5hbHMgKHRoZSBub25vYnZpb3VzIG9uZXMpOgo7 OyAgICBPUiA9IHwKOzsgICAgQU5EID0gJgo7OyAgICBDTVBfT1AgPSAoPT18PXw8PXw8Pnw+PXw+ fDwpCjs7ICAgIE1BVENIX09QID0gKD09fD18PD4pCjs7ICAgIFRBR19JREVOVCA9IFtBLVphLXow LTlfQCMlXSsgICAgICAgICAKOzsgICAgUFJPUF9JREVOVCA9IChbQS1aYS16MC05X10rKFxcLSkq KSsgIAo7OyAgICBTRUxFQ1RPUj8gPSBbLStdPwo7OyAgICBTVFJJTkcgPSBiYWxhbmNlZCBkb3Vi bGUtcXVvdGVkIHN0cmluZyB3aXRoIGVzY2FwZXMKOzsgICAgREFURV9TVFJJTkcgPSBvcmcgc3R5 bGUgZGF0ZSBzdHJpbmcKOzsgICAgUkVHRVhQID0gcmVndWxhciBleHByZXNzaW9uIHdpdGggeyBh bmQgfSBkb3VibGVkIHRvIGVzY2FwZSwge3sgYW5kIH19Cjs7CgoKOzs7IExpY2Vuc2U6Cjs7Cjs7 IFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBh bmQvb3IKOzsgbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVi bGljIExpY2Vuc2UgYXMKOzsgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRp b247IGVpdGhlciB2ZXJzaW9uIDMsIG9yCjs7IChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZl cnNpb24uCjs7Cjs7IFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0 IGl0IHdpbGwgYmUgdXNlZnVsLAo7OyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQg ZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgo7OyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVT UyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQo7OyBHZW5lcmFsIFB1Ymxp YyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCjs7Cjs7IFlvdSBzaG91bGQgaGF2ZSByZWNlaXZl ZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCjs7IGFsb25nIHdpdGgg dGhpcyBwcm9ncmFtOyBzZWUgdGhlIGZpbGUgQ09QWUlORy4gIElmIG5vdCwgd3JpdGUgdG8KOzsg dGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBG aWZ0aAo7OyBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EuCjs7CgoKOzs7IENvZGU6 CgooZXZhbC13aGVuLWNvbXBpbGUKICAocmVxdWlyZSAnY2wpKQoocmVxdWlyZSAnb3JnKQoKCjs7 OyBVdGlsaXRpZXMKCihkZWZ1biBvcmctcmVhZC1iYWxhbmNlZC1zdHJpbmcgKG9wZW4tZGVsaW0g Y2xvc2UtZGVsaW0pCiAgIlJldHVybiBzdHJpbmcgZGVsaW1pdGVkIGJ5IE9QRU4tREVMSU0gYW5k IENMT1NFLURFTElNIHdpdGggZXNjYXBlcy4KT1BFTi1ERUxJTSBhbmQgQ0xPU0UtREVMSU0gbXVz dCBiZSAqZGlzdGluY3QqIGNoYXJhY3RlcnMuIFJlYWRpbmcKYmVnaW5zIGF0IHBvaW50IGluIHRo ZSBjdXJyZW50IGJ1ZmZlci4gVG8gaW5jbHVkZSBPUEVOLURFTElNIGFuZApDTE9TRS1ERUxJTSBp bnNpZGUgdGhlIHN0cmluZyBiZWluZyByZWFkLCB0aG9zZSBjaGFyYWN0ZXJzIG11c3QKYmUgKmRv dWJsZWQqIGFuZCBvbmx5IG9uZSBjb3B5IG9mIHRoZSBjaGFyYWN0ZXIgaXMga2VwdCBpbiB0aGUK c3RyaW5nLiBUaGUgb3BlbmluZyBhbmQgY2xvc2luZyBkZWxpbWl0ZXJzIGZvciB0aGUgcmVhZCBz ZXF1ZW5jZQptdXN0IGJlIHNpbmdsZSBjb3BpZXMsIGFuZCBhbiB1bmVzY2FwZWQgT1BFTi1ERUxJ TSB3aWxsIHJhaXNlIGFuCmVycm9yLiIKICAod2hlbiAoY2hhci1lcXVhbCBvcGVuLWRlbGltIGNs b3NlLWRlbGltKQogICAgKGVycm9yICJPcGVuIGFuZCBjbG9zZSBkZWxpbWl0ZXJzIG11c3QgYmUg ZGlzdGluY3QsICVjIiBvcGVuLWRlbGltKSkKICAodW5sZXNzIChjaGFyLWVxdWFsIChjaGFyLWFm dGVyKSBvcGVuLWRlbGltKQogICAgKGVycm9yICJNaXNzaW5nIG9wZW5pbmcgJWMgaW4gZGVsaW1p dGVkIHN0cmluZyIgb3Blbi1kZWxpbSkpCiAgKGZvcndhcmQtY2hhciAxKSA7IHNraXAgaW5pdGlh bCBkZWxpbWl0ZXIKICAobGV0ICgoZGVsaW0tcmUgKGZvcm1hdCAiWyVjJWNdIiBvcGVuLWRlbGlt IGNsb3NlLWRlbGltKSkKICAgICAgICAoZGVsaW1zLXVuYmFsYW5jZWQgdCkKICAgICAgICAoYmVn aW4gKHBvaW50KSkKICAgICAgICAoZnJhZ21lbnRzIG5pbCkKICAgICAgICAoY2ggbmlsKSkKICAg ICh3aGlsZSAoYW5kIGRlbGltcy11bmJhbGFuY2VkIChyZS1zZWFyY2gtZm9yd2FyZCBkZWxpbS1y ZSBuaWwgdCkpCiAgICAgIChzZXRxIGNoIChjaGFyLWJlZm9yZSkpCiAgICAgIChjb25kCiAgICAg ICAgKChjaGFyLWVxdWFsIGNoIG9wZW4tZGVsaW0pCiAgICAgICAgIChzZXRxIGNoIChjaGFyLWFm dGVyKSkKICAgICAgICAgKGlmIChub3QgKGFuZCBjaCAoY2hhci1lcXVhbCBjaCBvcGVuLWRlbGlt KSkpCiAgICAgICAgICAgICAoZXJyb3IgIlVuZXNjYXBlZCBvcGVuIGRlbGltaXRlciAlYyBpbiBi YWxhbmNlZCBzdHJpbmciIG9wZW4tZGVsaW0pCiAgICAgICAgICAgKHB1c2ggKGJ1ZmZlci1zdWJz dHJpbmctbm8tcHJvcGVydGllcyBiZWdpbiAoMS0gKHBvaW50KSkpIGZyYWdtZW50cykKICAgICAg ICAgICAoc2V0cSBiZWdpbiAocG9pbnQpKQogICAgICAgICAgIChmb3J3YXJkLWNoYXIgMSkpKQog ICAgICAgICgoY2hhci1lcXVhbCBjaCBjbG9zZS1kZWxpbSkKICAgICAgICAgKHNldHEgY2ggKGNo YXItYWZ0ZXIpKQogICAgICAgICAoaWYgKG5vdCAoYW5kIGNoIChjaGFyLWVxdWFsIGNoIGNsb3Nl LWRlbGltKSkpCiAgICAgICAgICAgICAoc2V0cSBkZWxpbXMtdW5iYWxhbmNlZCBuaWwpCiAgICAg ICAgICAgKHB1c2ggKGJ1ZmZlci1zdWJzdHJpbmctbm8tcHJvcGVydGllcyBiZWdpbiAoMS0gKHBv aW50KSkpIGZyYWdtZW50cykKICAgICAgICAgICAoc2V0cSBiZWdpbiAocG9pbnQpKQogICAgICAg ICAgIChmb3J3YXJkLWNoYXIgMSkpKSkpCiAgICAod2hlbiBkZWxpbXMtdW5iYWxhbmNlZAogICAg ICAoZXJyb3IgIlVuYmFsYW5jZWQgZGVsaW1pdGVycyAlYyVjIGluIGJhbGFuY2VkIHN0cmluZyBh dCBjaGFyICVkLiIKICAgICAgICAgICAgIG9wZW4tZGVsaW0gY2xvc2UtZGVsaW0gKHBvaW50KSkp CiAgICAocHVzaCAoYnVmZmVyLXN1YnN0cmluZy1uby1wcm9wZXJ0aWVzIGJlZ2luICgxLSAocG9p bnQpKSkgZnJhZ21lbnRzKQogICAgKGlmIChudWxsIChjZHIgZnJhZ21lbnRzKSkKICAgICAgICAo Y2FyIGZyYWdtZW50cykKICAgICAgKGFwcGx5ICdjb25jYXQgKG5yZXZlcnNlIGZyYWdtZW50cykp KSkpCgooZGVmdW4gb3JnLXJlYWQtcXVvdGVkLXN0cmluZy1pbi1xdWVyeSAoKQogICJSZWFkIGEg cXVvdGVkIHN0cmluZywgd2l0aCBlc2NhcGVzLCBzdGFydGluZyBhdCBwb2ludC4KQXNzdW1lIHRo YXQgYW4gb3BlbmluZyBxdW90ZSBoYXMgYWxyZWFkeSBiZWVuIHNlZW4uIFRoaXMgaXMganVzdAph IHdyYXBwZXIgZm9yIGByZWFkJyB0aGF0IHJlcG9ydHMgZXJyb3JzIG5pY2VseS4iCiAgKGxldCAo KHN0YXJ0IChwb2ludCkpKQogICAgKGNvbmRpdGlvbi1jYXNlIGV4Y2VwdGlvbgogICAgICAgIChy ZWFkIChjdXJyZW50LWJ1ZmZlcikpCiAgICAgIChlcnJvcgogICAgICAgKG9yZy10cXVlcnktZXJy b3IKICAgICAgICAiYmFkbHkgZm9ybWVkIHF1b3RlZCB2YWx1ZSBpbiBwcm9wZXJ0eSBjb21wYXJp c29uIiA6cG9zIHN0YXJ0KSkpKSkKCjs7IEknbSBpbmNsaW5lZCB0byBkZWZpbmUgYW4gZXJyb3Ig c3ltYm9scyBoZXJlIHRvIGFsbG93IGZpbmVyIGNvbnRyb2wuCjs7IEJ1dCBlcnJvciBzeW1ib2xz IGRvbid0IHNlZW0gdG8gYmUgdXNlZCBpbiB0aGUgbWFpbiBvcmcgY29kZSwgc28gSSdsbAo7OyBm b3JnbyB0aGVtIGhlcmUgYW5kIHVzZSBgZXJyb3InIGRpcmVjdGx5LiAgLS0gQ1JHIDMxIEp1bHkg MjAxMgooZGVmdW4gb3JnLXRxdWVyeS1lcnJvciAoaW5mbyAmcmVzdCBvdGhlci1hcmdzKQogICJS YWlzZSBhIHF1ZXJ5IHBhcnNpbmcgZXJyb3IuCklORk8gaXMgYW4gYXV4aWxsaWFyeSBtZXNzYWdl IHdoaWNoIGlzIGFwcGVuZGVkIHRvIHRoZSBzdGFuZGFyZAptZXNzYWdlIGFuZCB3aGljaCBpcyB0 cmVhdGVkIGFzIGEgZm9ybWF0IHN0cmluZyBmb3IgT1RIRVItQVJHUy4KVGhpcyBuZWVkL3Nob3Vs ZCBub3QgYmUgY2FwaXRhbGl6ZWQuIFRoZSBlbmQgb2YgT1RIRVItQVJHUyBjYW4KY29udGFpbiBr ZXl3b3JkLXZhbHVlIHBhaXJzIDpwb3MgPG51bWJlci1vci1tYXJrZXI+IGFuZCA6dHlwZQo8ZGVz Y3JpcHRpdmUgc3RyaW5nPiB0byBjb250cm9sIHRoZSBmaW5hbCBlcnJvciBtZXNzYWdlLiBUaGUK Zm9ybWVyIGRlZmF1bHRzIHRvIHBvaW50IChwb3NpdGlvbiBpbiB0aGUgcXVlcnkgc3RyaW5nKSBh bmQgdGhlCmxhdHRlciBkZWZhdWx0cyB0byBgdGFnJy4iCiAgKGxldCogKChwb3MgKG9yIChjYWRy IChtZW1xIDpwb3Mgb3RoZXItYXJncykpIChwb2ludCkpKQogICAgICAgICAocXR5cGUgKG9yIChj YWRyIChtZW1xIDp0eXBlIG90aGVyLWFyZ3MpKSAidGFnICIpKSkKICAgIChlcnJvciAoZm9ybWF0 ICJQYXJzZSBlcnJvciBpbiAlc3F1ZXJ5IGF0IGNoYXJhY3RlciAlZCwgJXMiCiAgICAgICAgICAg ICAgICAgICBxdHlwZSBwb3MgKGFwcGx5ICdmb3JtYXQgaW5mbyBvdGhlci1hcmdzKSkpKSkKCjs7 IFRoaXMgaXMgdXNlZCB0byBkZWZpbmUgdGhlIHBhcnNlciBzeW1ib2wgdGFibGUgYXQgY29tcGls ZSB0aW1lLgooZGVmbWFjcm8gb3JnLWRlZmhhc2gtYXQtY29tcGlsZSAobmFtZSBvcHRpb25zICZy ZXN0IGJvZHkpIAogICJEZWZpbmUgYSBoYXNoIHRhYmxlIE5BTUUgYXQgY29tcGlsZSB0aW1lIGFu ZC9vciBsb2FkLXRpbWUuCk9QVElPTlMgaXMgYSBsaXN0LCBwb3NzaWJseSBlbXB0eSwgb2Ygb3B0 aW9ucyB0byBwYXNzIHRvCmBtYWtlLWhhc2gtdGFibGUnLiBCT0RZIGlzIGEgbGlzdCBvZiBzZXF1 ZW5jZXMgKGxpc3RzIG9yCnZlY3RvcnMpLCBlYWNoIG9mIHdoaWNoIGNvbnRhaW5zIGEga2V5IHZh bHVlIHBhaXIuIFRoZSBrZXkgYW5kCnRoZSB2YWx1ZSB3aWxsIGJlIGV2YWx1YXRlZCwgc28gZm9y IGV4YW1wbGUsIGEgc3ltYm9sIGtleSBzaG91bGQKYmUgcXVvdGVkLiIKICAoZGVjbGFyZSAoaW5k ZW50IDIpKQogIChsZXQqICgoZG9jc3RyaW5nIChhbmQgKHN0cmluZ3AgKGNhciBib2R5KSkgKGNh ciBib2R5KSkpCiAgICAgICAgICh0YWJsZSAoaWYgZG9jc3RyaW5nIChjZHIgYm9keSkgYm9keSkp KQogICAgYChldmFsLWFuZC1jb21waWxlCiAgICAgICAoZGVmdmFyICxuYW1lIChtYWtlLWhhc2gt dGFibGUgLEBvcHRpb25zKSAsZG9jc3RyaW5nKQogICAgICAgLEAobWFwY2FyIChsYW1iZGEgKHMp IGAocHV0aGFzaCAsKGVsdCBzIDApICwoZWx0IHMgMSkgLG5hbWUpKSB0YWJsZSkpKSkKCgo7Ozsg UmVnZXggY29tcGFyaXNvbiBmdW5jdGlvbnMgaW4gYSBmb3JtIGxpa2UgdGhlIG90aGVyIGNvbXBh cmlzb24gb3BlcmF0b3JzCgooZGVmdW4gb3JnLXN0cmluZy1tYXRjaD0gKHN0cmluZyByZWdleHAp CiAgKHN0cmluZy1tYXRjaC1wIHJlZ2V4cCBzdHJpbmcpKQoKKGRlZnVuIG9yZy1zdHJpbmctbWF0 Y2g8PiAoc3RyaW5nIHJlZ2V4cCkKICAobm90IChzdHJpbmctbWF0Y2gtcCByZWdleHAgc3RyaW5n KSkpCgoKOzs7IFBhcnNpbmcgdXRpbGl0eSBmb3IgcmVhZGFibGUgbWF0Y2hlcnMKCihvcmctZGVm aGFzaC1hdC1jb21waWxlIG9yZy10YWctcXVlcnktdGVybWluYWxzICgpCiAgIkxleGljYWwgdG9r ZW4gcmVnZXhlcyBmb3IgdGFnIHF1ZXJ5IHBhcnNpbmcuCkhhc2ggdGFibGUgYWxzbyBjb250YWlu cyB0aGUgc3ltYm9scyArLCAqIGFuZCA/IHRoYXQgY2FuIGJlIHVzZWQKdG8gcmVwcmVzZW50IHJl cGV0aXRpb24gb3BlcmF0b3JzIGluIG1hdGNoZWQgZXhwcmVzc2lvbnMsCmUuZy4sIChOVU1CRVIp KyBvciAoU0VMRUNUT1IpXD8uICg/IG11c3QgYmUgZXNjYXBlZC4pIgogIFsnVEVSTS1CRUdJTiAg ICAob3JnLXJlICJbLStbOmFsbnVtOl1feyhdIildCiAgWydTRUxFQ1RPUiAgICAgICJbLStdIl0K ICBbJ1RBRy1JREVOVCAgICAgKG9yZy1yZSAgIltbOmFsbnVtOl1fQCMlOl0rIildCiAgWydQUk9Q LUlERU5UICAgIChvcmctcmUgIlxcKD86W1s6YWxudW06XV9dK1xcKD86XFxcXC1cXCkqXFwpKyIp XQogIFsnQ01QLU9QICAgICAgICAiXFwoPzo9PT9cXHw8PVxcfDw+XFx8Pj1cXHw8XFx8PlxcKSJd CiAgWydNQVRDSC1PUCAgICAgICJcXCg/Oj09P1xcfDw+XFwpIl0KICBbJ0NNUC1SSFMtQkVHSU4g KG9yZy1yZSAiXFwoPzp7XFx8XFxcIlxcfC0/Wy5bOmRpZ2l0Ol1dXFwpIildCiAgWydSRUdFWC1P UEVOICAgICJ7Il0KICBbJ0dST1VQLU9QRU4gICAgIigiXQogIFsnR1JPVVAtQ0xPU0UgICAiKSJd CiAgWydPUi1PUCAgICAgICAgICJ8Il0KICBbJ0FORC1PUCAgICAgICAgIiYiXQogIFsnREFURS1T VFJJTkcgICAiXCJbWzxdLio/W10+XVwiIl0KICBbJ0lOVEVHRVIgICAgICAgKG9yZy1yZSAiLT9b WzpkaWdpdDpdXSsiKV0KICBbJ05VTUJFUiAgICAgICAgIi0/XFwoPzpcXC5bMC05XStcXHxbMC05 XStcXChcXC5bMC05XSpcXCk/XFwpXFwoPzpbZUVdWy0rXVswLTldK1xcKT8iXQogIFsnU1BBQ0Ug ICAgICAgICAiW1s6Ymxhbms6XV0iXQogIFsnU1BBQ0UqICAgICAgICAiW1s6Ymxhbms6XV0qIl0K ICBbJ1RPRE8tTUFSS0VSICAgIi8iXQogIFsnVE9ETy1PTkxZLU0gICAiISJdCiAgWydUT0RPLUtF WSAgICAgICJbXi0rXCJ7fSZ8XSsiXQogIFsnKiAgICAgICAgICAgICAiKiJdCiAgWycrICAgICAg ICAgICAgICIrIl0KICBbJ1w/ICAgICAgICAgICAgIj8iXSkKCihvcmctZGVmaGFzaC1hdC1jb21w aWxlIG9yZy10YWctcXVlcnktY21wLW9wcyAoOnRlc3QgJ2VxdWFsKQogICJNYXBzIGNvbXBhcmlz b24gb3BlcmF0b3Igc3RyaW5ncyB0byBhIHZlY3RvciBvZiBjb21wYXJpc29uIGZ1bmN0aW9ucy4K VGhlIGZ1bmN0aW9ucyBhcmUgYXJyYW5nZWQgaW4gdGhlIHZlY3RvciBmb3IgZGlmZmVyZW50IHR5 cGVzIGFzIGZvbGxvd3M6CiAgICAgICAgIE5VTSAgIFNUUklORyAgICAgICBUSU1FICAgICAgIFJF R0VYIgogICgiPSIgIFs9ICAgICBzdHJpbmc9ICAgICAgb3JnLXRpbWU9ICBvcmctc3RyaW5nLW1h dGNoPV0pCiAgKCI9PSIgWz0gICAgIHN0cmluZz0gICAgICBvcmctdGltZT0gIG9yZy1zdHJpbmct bWF0Y2g9XSkKICAoIjw+IiBbb3JnPD4gb3JnLXN0cmluZzw+IG9yZy10aW1lPD4gb3JnLXN0cmlu Zy1tYXRjaDw+XSkKICAoIjwiICBbPCAgICAgc3RyaW5nPCAgICAgIG9yZy10aW1lPCAgbmlsXSkK ICAoIjw9IiBbPD0gICAgb3JnLXN0cmluZzw9IG9yZy10aW1lPD0gbmlsXSkKICAoIj49IiBbPj0g ICAgb3JnLXN0cmluZz49IG9yZy10aW1lPj0gbmlsXSkKICAoIj4iICBbPiAgICAgb3JnLXN0cmlu Zz4gIG9yZy10aW1lPiAgbmlsXSkpCgooZXZhbC1hbmQtY29tcGlsZQogIDs7IEknZCBwcmVmZXIg Z2Vuc3ltcyBmb3IgdGhpcywgYnV0IHJlYWxpc3RpY2FsbHkgdGhpcyB3aWxsIGRvLgogIChkZWZ2 YXIgb3JnLXRhZy1xdWVyeS9wcml2YXRlLW9wdC1jaC0gbmlsCiAgICAiVGhpcyB2YXJpYWJsZSBz aG91bGQgbm90IGJlIHNldCBieSB0aGUgdXNlciwgZXZlbiBsb2NhbGx5LgpJdCBzaG91bGQgcmVt YWluIG5pbCBvciBjaGFvcyBtYXkgZW5zdWUuIikKCiAgKGRlZnVuIG9yZy1zdHJpbmctYXMtY2hh ci1wIChzKQogICAgIklzIFMgYSBzdHJpbmcgb2YgYSBzaW5nbGUsIHBvc3NpYmx5IGJhY2tzbGFz aC1lc2NhcGVkLCBjaGFyYWN0ZXI/CklmIHNvLCByZXR1cm4gdGhlIGNoYXJhY3RlciB0aGlzIHJl cHJlc2VudHMsIG90aGVyd2lzZSBuaWwuIgogICAgKGlmIChzdHJpbmdwIHMpCiAgICAgICAgKGxl dCAoKGxlbiAobGVuZ3RoIHMpKSkKICAgICAgICAgIChvciAoYW5kICg9IDEgbGVuKSAoc3RyaW5n LXRvLWNoYXIgcykpCiAgICAgICAgICAgICAgKGFuZCAoPSAyIGxlbikgKGNoYXItZXF1YWwgP1xc IChzdHJpbmctdG8tY2hhciBzKSkgKGFyZWYgcyAxKSkpKQogICAgICBuaWwpKQoKICAoZGVmdW4g b3JnLXRhZy1xdWVyeS1tYXRjaGVyPC0gKHBhdHRlcm5zICZvcHRpb25hbCBhdXRvZ3JvdXAgdGVy bWluYWxzIG5leHQtY2gpCiAgICAiQ29udmVydCBhIGxpc3Qgb2YgUEFUVEVSTlMgdG8gYSBgbG9v a2luZy1hdCcgcXVlcnkuIApBVVRPR1JPVVAsIGlmIG5vbi1uaWwsIHR1cm5zIG9uIGF1dG9ncm91 cGluZyBvZiBzaW5nbGV0b25zLgpURVJNSU5BTFMsIGlmIG5vbi1uaWwsIHNob3VsZCBiZSBhIGhh c2ggdGFibGUgZm9yIGF0dGVtcHRlZApzeW1ib2wgbG9va3VwLiBTZWUgYG9yZy1tYXRjaC1jb25k JyBmb3IgbW9yZSBkZXRhaWxzIG9uClBBVFRFUk5TJ3MgZm9ybWF0LiIKICAgIChsZXQqICgoYWxs LXN0cmluZ3MKICAgICAgICAgICAgKGxhbWJkYSAoZWxlbWVudHMpCiAgICAgICAgICAgICAgKGxl dCAoKHB0ciBlbGVtZW50cykpCiAgICAgICAgICAgICAgICAod2hpbGUgKGFuZCBwdHIgKHN0cmlu Z3AgKGNhciBwdHIpKSkKICAgICAgICAgICAgICAgICAgKHNldHEgcHRyIChjZHIgcHRyKSkpCiAg ICAgICAgICAgICAgICAobnVsbCBwdHIpKSkpCiAgICAgICAgICAgKHJlcGxhY2UtdGVybWluYWwK ICAgICAgICAgICAgKGxhbWJkYSAoaXRlbSkKICAgICAgICAgICAgICAoY29uZCAoKG5vdCAoaGFz aC10YWJsZS1wIHRlcm1pbmFscykpIGl0ZW0pCiAgICAgICAgICAgICAgICAgICAgKChzeW1ib2xw IGl0ZW0pICAgIChnZXRoYXNoIGl0ZW0gdGVybWluYWxzIGl0ZW0pKQogICAgICAgICAgICAgICAg ICAgICh0ICAgICAgICAgICAgICAgICBpdGVtKSkpKQogICAgICAgICAgIChwdXNoLWFsbAogICAg ICAgICAgICAobGFtYmRhIChzcmMgZGVzdCkgKGRvbGlzdCAocyBzcmMgZGVzdCkgKHB1c2ggcyBk ZXN0KSkpKQogICAgICAgICAgIChhbHRlcm5hdGl2ZXMKICAgICAgICAgICAgKGxldCAocmhzIGFj YyBub2dyb3VwIG5vY2FwdHVyZSkKICAgICAgICAgICAgICAoZG9saXN0IChwIHBhdHRlcm5zIChw cm9nbiAocHVzaCAobnJldmVyc2UgcmhzKSBhY2MpCiAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgKG5yZXZlcnNlIGFjYykpKQogICAgICAgICAgICAgICAgKGNvbmQgCiAg ICAgICAgICAgICAgICAgKChlcSBwICd8KQogICAgICAgICAgICAgICAgICAoaWYgKG51bGwgcmhz KQogICAgICAgICAgICAgICAgICAgICAgKG9yZy10cXVlcnktZXJyb3IgIm1pc3BsYWNlZCBhbHRl cm5hdGl2ZSBtYXJrZXIiKQogICAgICAgICAgICAgICAgICAgIChwdXNoIChucmV2ZXJzZSByaHMp IGFjYykKICAgICAgICAgICAgICAgICAgICAoc2V0cSByaHMgbmlsKSkpCiAgICAgICAgICAgICAg ICAgKChlcSBwIDpub2dyb3VwKQogICAgICAgICAgICAgICAgICAoc2V0cSBub2dyb3VwIHQpKQog ICAgICAgICAgICAgICAgICgoZXEgcCA6bm9jYXB0dXJlKQogICAgICAgICAgICAgICAgICAoc2V0 cSBub2NhcHR1cmUgdCkpCiAgICAgICAgICAgICAgICAgKChvciAoY29uc3AgcCkgKHZlY3RvcnAg cCkpIDsgY2FwdHVyaW5nL25vbmNhcHR1cmluZyBncm91cCByZXNwLgogICAgICAgICAgICAgICAg ICAodW5sZXNzIG5vZ3JvdXAgOyBhbGxvdyBub2dyb3VwL25vY2FwdHVyZSBoZXJlIGZvciBjb25z aXN0ZW5jeQogICAgICAgICAgICAgICAgICAgIChwdXNoIChpZiAob3Igbm9jYXB0dXJlICh2ZWN0 b3JwIHApKSAiXFwoPzoiICJcXCgiKSByaHMpKQogICAgICAgICAgICAgICAgICAoc2V0cSByaHMg KGZ1bmNhbGwgcHVzaC1hbGwgKG1hcGNhciByZXBsYWNlLXRlcm1pbmFsIHApIHJocykpCiAgICAg ICAgICAgICAgICAgICh1bmxlc3Mgbm9ncm91cAogICAgICAgICAgICAgICAgICAgIChwdXNoICJc XCkiIHJocykpCiAgICAgICAgICAgICAgICAgIChzZXRxIG5vZ3JvdXAgbmlsIG5vY2FwdHVyZSBu aWwpKQogICAgICAgICAgICAgICAgICgoYW5kIGF1dG9ncm91cCAobm90IG5vZ3JvdXApKQogICAg ICAgICAgICAgICAgICAocHVzaCAoaWYgKG9yIG5vY2FwdHVyZSAodmVjdG9ycCBwKSkgIlxcKD86 IiAiXFwoIikgcmhzKQogICAgICAgICAgICAgICAgICAocHVzaCAoZnVuY2FsbCByZXBsYWNlLXRl cm1pbmFsIHApIHJocykKICAgICAgICAgICAgICAgICAgKHB1c2ggIlxcKSIgcmhzKQogICAgICAg ICAgICAgICAgICAoc2V0cSBub2dyb3VwIG5pbCBub2NhcHR1cmUgbmlsKSkKICAgICAgICAgICAg ICAgICAodAogICAgICAgICAgICAgICAgICAocHVzaCAoZnVuY2FsbCByZXBsYWNlLXRlcm1pbmFs IHApIHJocykKICAgICAgICAgICAgICAgICAgKHNldHEgbm9ncm91cCBuaWwgbm9jYXB0dXJlIG5p bCkpKSkpKQogICAgICAgICAgIChtYXRjaGVycwogICAgICAgICAgICAobWFwY2FyIChsYW1iZGEg KHB0ZXJtcykKICAgICAgICAgICAgICAgICAgICAgIChsZXQgKChmc3QgKGNhciBwdGVybXMpKQog ICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNjaCBuaWwpKQogICAgICAgICAgICAgICAgICAg ICAgICAoY29uZAogICAgICAgICAgICAgICAgICAgICAgICAgKChhbmQgKGNkciBwdGVybXMpIChm dW5jYWxsIGFsbC1zdHJpbmdzIHB0ZXJtcykpCiAgICAgICAgICAgICAgICAgICAgICAgICAgYChs b29raW5nLWF0ICwoYXBwbHkgJ2NvbmNhdCBwdGVybXMpKSkKICAgICAgICAgICAgICAgICAgICAg ICAgICgoY2RyIHB0ZXJtcykKICAgICAgICAgICAgICAgICAgICAgICAgICBgKGxvb2tpbmctYXQg KGNvbmNhdCAsQHB0ZXJtcykpKQogICAgICAgICAgICAgICAgICAgICAgICAgKChhbmQgbmV4dC1j aCAoc2V0cSBzY2ggKG9yZy1zdHJpbmctYXMtY2hhci1wIGZzdCkpKQogICAgICAgICAgICAgICAg ICAgICAgICAgIGAoYW5kICxuZXh0LWNoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg KGNoYXItZXF1YWwgLG5leHQtY2ggLHNjaCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAoc2V0cSBvcmctdGFnLXF1ZXJ5L3ByaXZhdGUtb3B0LWNoLSAsc2NoKSkpCiAgICAgICAgICAg ICAgICAgICAgICAgICAodAogICAgICAgICAgICAgICAgICAgICAgICAgIGAobG9va2luZy1hdCAs ZnN0KSkpKSkKICAgICAgICAgICAgICAgICAgICBhbHRlcm5hdGl2ZXMpKSkKICAgICAgKGlmIChj ZHIgbWF0Y2hlcnMpCiAgICAgICAgICBgKG9yICxAbWF0Y2hlcnMpCiAgICAgICAgYCwoY2FyIG1h dGNoZXJzKSkpKSkKCihkZWZtYWNybyBvcmctbWF0Y2gtY29uZCAob3B0aW9ucyAmcmVzdCBjbGF1 c2VzKQogICJMaWtlIGBjb25kJywgYnV0IGFsbG93cyBzcGVjaWFsIGZvcm1zIGluIHRoZSBjbGF1 c2VzIHRoYXQgbG9va2FoZWFkIGluLApleHRyYWN0IGZyb20sIGFuZCBtb3ZlIGluIHRoZSBjdXJy ZW50IGJ1ZmZlci4gVGhlIHNwZWNpYWwgZm9ybXMKYXJlIGRlc2NyaWJlZCBiZWxvdy4gT1BUSU9O UywgaWYgbm9uLW5pbCwgaXMgZWl0aGVyIGEgc3ltYm9sLApTWU1CT0wtVEFCTEUsIGJvdW5kIHRv IGEgaGFzaCB0YWJsZSBmb3Igc3ltYm9sIGxvb2t1cCwgb3IgYSBsaXN0Cm9mIHRoZSBmb3JtIChT WU1CT0wtVEFCTEUgTkVYVC1DSEFSLVNZTSAmcmVzdCBCSU5ESU5HUykuIElmIE5FWFQtQ0hBUi1T WU0KaXMgbm90IG5pbCwgaXQgc2hvdWxkIGJlIGEgc3ltYm9sIHRoYXQgd2lsbCBiZSBib3VuZCB0 byB0aGUgbmV4dCBjaGFyYWN0ZXIKYW5kIHVzZWQgdG8gb3B0aW1pemUgdGhlIG1hdGNoaW5nIG9m IGVzcGVjaWFsbHkgc2ltcGxlIHBhdHRlcm5zLCBhcyBkZXNjcmliZWQKYmVsb3cuIEJJTkRJTkdT IGFyZSBzdGFuZGFyZCBsZXQgYmluZGluZ3Mgd2hpY2ggd2lsbCB2aXNpYmxlIGluIHRoZQpDTEFV U0VTLiBDTEFVU0VTIGFyZSBzdHJ1Y3R1cmVkIGxpa2UgdGhlIGNsYXVzZXMgaW4gYGNvbmQnLgoK ICAgTG9va2FoZWFkOgogICAgICg8LSAgUEFUVEVSTi4uLiBbfCBQQVRURVJOLi4uXSopICAtLSBz eW1ib2wgbG9va3VwIGluIFNZTUJPTC1IQVNICiAgICAgKDw8LSBQQVRURVJOLi4uIFt8IFBBVFRF Uk4uLi5dKikgIC0tIHN5bWJvbCBsb29rdXAgKyBzaW5nbGV0b24gYXV0b2dyb3VwaW5nCiAgICAg KDw8PSBQQVRURVJOLi4uIFt8IFBBVFRFUk4uLi5dKikgIC0tIG5vIHN5bWJvbCBsb29rdXAgb3Ig YXV0b2dyb3VwaW5nCgogICAgIEVhY2ggcGF0dGVybiBpbiB0aGUgbGlzdCBpcyBlaXRoZXIgYSBz dHJpbmcsIGEgc3ltYm9sLCBhCiAgICAgbGlzdCBvZiBzdHJpbmdzIGFuZCBzeW1ib2xzIC0tIHJl cHJlc2VudGluZyBjYXB0dXJpbmcKICAgICBncm91cHMsIG9yIGEgdmVjdG9yIG9mIHN0cmluZ3Mg YW5kIHN5bWJvbHMgLS0gcmVwcmVzZW50aW5nCiAgICAgbm9uLWNhcHR1cmluZyBncm91cHMuIFRo ZSB8J3Mgc2VwYXJhdGUgYWx0ZXJuYXRpdmVzIHRoYXQgYXJlCiAgICAgdGVzdGVkIGxhemlseSAo YSBsYSBgb3InKTsgdGhlIGV2ZW50dWFsIHN0cmluZ3MgY29tcHV0ZWQgZm9yCiAgICAgdGhlIHBh dHRlcm5zIGluIGVhY2ggYWx0ZXJuYXRpdmUgYXJlIGNvbmNhdGVuYXRlZCB0b2dldGhlcgogICAg IHRvIGZvcm0gYSByZWd1bGFyIGV4cHJlc3Npb24gd2hpY2ggaXMgdGVzdGVkIHdpdGgKICAgICBg bG9va2luZy1hdCcuIFdoZW4gc3ltYm9sIGxvb2t1cCBpcyBpbiBlZmZlY3QgKDwtIGFuZCA8PC0K ICAgICBmb3JtcyksIHN5bWJvbHMgaW4gYSBwYXR0ZXJuIGFyZSBmaXJzdCBsb29rZWQgdXAgaW4K ICAgICBTWU1CT0wtVEFCTEUgaWYgaXQgZXhpc3RzLCBhbmQgcmVwbGFjZWQgd2l0aCB0aGUKICAg ICBjb3JyZXNwb25kaW5nIHZhbHVlIGlmIHByZXNlbnQuIElmIGFsbCB0aGUgcGF0dGVybnMncyBp biBhbgogICAgIGFsdGVybmF0aXZlIHJlc29sdmUgdG8gc3RyaW5ncyBhdCBjb21waWxlIHRpbWUs IHRoZSByZWd1bGFyCiAgICAgZXhwcmVzc2lvbiBpcyBjb21wdXRlZCBhdCBjb21waWxlIHRpbWUg YW5kIGFsbCB0aGUgZm9ybXMKICAgICByZWR1Y2UgdG8gYSBzaW5nbGUgY2FsbCB0byBgbG9va2lu Zy1hdCcuIE90aGVyd2lzZSwgdGhlCiAgICAgcmVndWxhciBleHByZXNzaW9uIGlzIGNvbXB1dGVk IGF0IHJ1bnRpbWUuCgogICAgIEluIHRoZSBzcGVjaWFsIGNhc2Ugd2hlcmUgdGhlcmUgYXJlIG5v IGFsdGVybmF0aXZlcywgdGhlCiAgICAgcGF0dGVybiBpcyBhIHN0cmluZyByZXByZXNlbnRpbmcg YSBzaW5nbGUgY2hhcmFjdGVyIGF0CiAgICAgY29tcGlsZSB0aW1lIChvbmUgY2hhcmFjdGVyIG9y IGEgYmFja3NsYXNoLWVzY2FwZWQKICAgICBjaGFyYWN0ZXIpLCBhbmQgTkVYVC1DSEFSLVNZTSBp cyBhIG5vbi1uaWwgc3ltYm9sLCB0aGUgY29uZAogICAgIGNsYXVzZSBpcyBvcHRpbWl6ZWQgdG8g ZG8gYSBjaGFyYWN0ZXIgY29tcGFyaXNvbiByYXRoZXIgdGhhbgogICAgIGEgYGxvb2tpbmctYXQn LiBTcGVjaWZpY2FsbHksIE5FWFQtQ0hBUi1TWU0gaXMgYm91bmQgdG8gdGhlCiAgICAgY2hhcmFj dGVyIGF0IHBvaW50IGJlZm9yZSBhbnkgdGVzdHMgYW5kIHVzZWQgdmlhCiAgICAgYGNoYXItZXF1 YWwnIGZvciB0aGlzIG9wdGltaXplZCBtYXRjaC4gTW92ZW1lbnQgYW5kIHN0cmluZwogICAgIGZv cm1zIHdpdGggZ3JvdXAgMCwgaS5lLiwgKEAgZW5kIDApLCAoJCAwKSwgKCQkIDApLCBzZWUKICAg ICBiZWxvdywgc3RpbGwgd29yayBhcyBleHBlY3RlZCBpbiB0aGlzIGNhc2UuIFRvIHN1cHByZXNz IHRoZQogICAgIGNoYXJhY3RlciBvcHRpbWl6YXRpb24gd2hlbiBORVhULUNIQVItU1lNIGlzIG5v bi1uaWwsIGZvcgogICAgIGluc3RhbmNlIHRvIG1hdGNoIGEgcmVndWxhciBleHByZXNzaW9uIGAu JywgaXQgaXMgc3VmZmljaWVudAogICAgIHRvIGluY2x1ZGUgYW4gZW1wdHkgc3RyaW5nIGluIHRo ZSBwYXR0ZXJuIGxpc3Qgb3IgdG8gcHV0IHRoZQogICAgIHRlcm0gaW4gYSBub24tY2FwdHVyaW5n IGdyb3VwLi4KCiAgICAgSW4gdGhlIDw8LSBmb3JtLCBlYWNoIHNpbmdsZXRvbiBwYXR0ZXJuIChz dHJpbmdzIG9yIHN5bWJvbHMpCiAgICAgaXMgYXV0b21hdGljYWxseSBwdXQgaW4gYSBjYXB0dXJp bmcgZ3JvdXAsIHVubGVzcyBwcmVjZWRlZCBieQogICAgIDpub2dyb3VwIChpbmhpYml0aW5nIGdy b3VwKSBvciA6bm9jYXB0dXJlIChpbmhpYml0aW5nIGNhcHR1cmUpLgoKICAgTW92ZW1lbnQ6CiAg ICAgKEAgRlJPTSBHUk9VUCBbT0ZGU0VUXSkgCiAgICAgICAgTW92ZXMgcG9pbnQgdG8gYSBwb3Np dGlvbiByZWxhdGl2ZSB0byBhIG1hdGNoIEdST1VQLAogICAgICAgIHdoaWNoIHNob3VsZCBiZSBh IG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLiBUaGlzIGhhcyBubwogICAgICAgIGVmZmVjdCBpZiB0aGUg Z3JvdXAgZGlkIG5vdCBtYXRjaCwgZXhjZXB0IGFuIChAIGVuZCAwKQogICAgICAgIGFsd2F5cyBt b3ZlcyB0byB0aGUgZW5kIG9mIHdoYXQgbWF0Y2hlZCBldmVuIGlmIHRoZQogICAgICAgIGNsYXVz ZSB3YXMgb3B0aW1pemVkIGludG8gYSBjaGFyYWN0ZXIgbWF0Y2guIEZST00gY2FuIGJlCiAgICAg ICAgZWl0aGVyIHRoZSBzeW1ib2wgYGVuZCcgb3IgYGJlZ2luJywgd2hpY2ggbWF0Y2hlcyB0aGUg ZW5kCiAgICAgICAgb3IgYmVnaW5uaW5nIG9mIHRoZSBncm91cCwgb3IgYSBmdW5jdGlvbiB3aGlj aCBpcyBjYWxsZWQKICAgICAgICB3aXRoIGdyb3VwIGFzIGFuIGFyZ3VtZW50LiBPcHRpb25hbCBP RkZTRVQsIGlmIG5vbi1uaWwsCiAgICAgICAgaXMgYWRkZWQgdG8gdGhlIHNwZWNpZmllZCBwb3Np dGlvbi4KCiAgIFN0cmluZyBFeHRyYWN0aW9uOgogICAgICgkIEdST1VQKSAgIFRoZSBtYXRjaGVk IHN0cmluZyBmb3IgZ3JvdXAgR1JPVVAsIG9yIG5pbC4KICAgICAgICAgICAgICAgICBBICgkIDAp IGFsd2F5cyB3b3JrcywgZXZlbiB3aXRoIGNoYXJhY3RlciBvcHRpbWl6YXRpb24uCiIKICAoZGVj bGFyZSAoaW5kZW50IDEpKQogIChsZXQqICgob3B0LWxpc3RwIChjb25zcCBvcHRpb25zKSkKICAg ICAgICAgKHN5bS10YWJsZSAoaWYgb3B0LWxpc3RwIChjYXIgb3B0aW9ucykgICAgICBvcHRpb25z KSkKICAgICAgICAgKG5leHQtY2hhciAoaWYgb3B0LWxpc3RwIChjYWRyIG9wdGlvbnMpICAgICBu aWwpKQogICAgICAgICAobmV4dC1zeW0gIChpZiBuZXh0LWNoYXIgYCcsbmV4dC1jaGFyIG5pbCkp CiAgICAgICAgIChiaW5kaW5ncyAgKGlmIG9wdC1saXN0cCAobnRoY2RyIDIgb3B0aW9ucykgbmls KSkpCiAgIGAobWFjcm9sZXQgKCg8LSAoJnJlc3QgcGF0dGVybnMpICAgICA7IGxvb2t1cAogICAg ICAgICAgICAgICAgICAgYCwob3JnLXRhZy1xdWVyeS1tYXRjaGVyPC0gcGF0dGVybnMgbmlsICxz eW0tdGFibGUgLG5leHQtc3ltKSkKICAgICAgICAgICAgICAgKDw8LSAoJnJlc3QgcGF0dGVybnMp ICAgIDsgbG9va3VwICsgYXV0b2dyb3VwaW5nCiAgICAgICAgICAgICAgICAgICAgYCwob3JnLXRh Zy1xdWVyeS1tYXRjaGVyPC0gcGF0dGVybnMgdCAsc3ltLXRhYmxlICxuZXh0LXN5bSkpCiAgICAg ICAgICAgICAgICg8PD0gKCZyZXN0IHBhdHRlcm5zKSAgICA7IG5vIGxvb2t1cCBvciBhdXRvZ3Jv dXBpbmcKICAgICAgICAgICAgICAgICAgICBgLChvcmctdGFnLXF1ZXJ5LW1hdGNoZXI8LSBwYXR0 ZXJucyBuaWwgbmlsICxuZXh0LXN5bSkpCiAgICAgICAgICAgICAgIChAIChmcm9tIGdyb3VwICZv cHRpb25hbCBvZmZzZXQpIDsgbW92ZSBwb2ludCByZWxhdGl2ZSB0byBncm91cAogICAgICAgICAg ICAgICAgICA7OyBIYW5kbGluZyB0aGUgY2hhcmFjdGVyLW1hdGNoIG9wdGltaXphdGlvbiByZXF1 aXJlcwogICAgICAgICAgICAgICAgICA7OyBjaGVja2luZyBpZiBhIGNoYXJhY3RlciBtYXRjaCB3 YXMgbWFkZSBzbyBhbiAoQCBlbmQgMCkKICAgICAgICAgICAgICAgICAgOzsgbW92ZXMgZm9yd2Fy ZCBpbnN0ZWFkIG9mIHJlZmVycmluZyB0byB0aGUgbWF0Y2gKICAgICAgICAgICAgICAgICAgOzsg ZGF0YS4gVGhlIGlkZWEgaGVyZSBpcyB0byBvbmx5IGNoZWNrIHRoYXQgY2FzZSB3aGVuCiAgICAg ICAgICAgICAgICAgIDs7IHRoZSBvcHRpbWl6YXRpb24gd2FzIHJlcXVlc3RlZCBpbiB0aGUgZmly c3QgcGxhY2UKICAgICAgICAgICAgICAgICAgOzsgYW5kIHRoZW4gdG8gZG8gYXMgbXVjaCB3b3Jr IGFzIHBvc3NpYmxlIGF0IGNvbXBpbGUKICAgICAgICAgICAgICAgICAgOzsgdGltZS4gQWRtaXR0 ZWRseSwgdGhpcyBwYXJ0IGhhcyBnb3R0ZW4gYSBiaXQgY3JhenksCiAgICAgICAgICAgICAgICAg IDs7IGJ1dCBpdCBkb2VzIHByb2R1Y2UgZ29vZCBjb2RlLiAtLSBDUkcgMDIgQXVnIDIwMTIKICAg ICAgICAgICAgICAgICAgLChpZiAobm90IG5leHQtY2hhcikKICAgICAgICAgICAgICAgICAgICAg ICBgKGxldCAoKGlwb3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjYXNlIGZyb20K ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVuZCBgKG9yIChtYXRjaC1lbmQgLGdy b3VwKSAocG9pbnQpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGJlZ2luIGAo b3IgKG1hdGNoLWJlZ2lubmluZyAsZ3JvdXApIChwb2ludCkpKQogICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAodCBgKCxmcm9tICxncm91cCkpKSkpCiAgICAgICAgICAgICAgICAgICAg ICAgICAgYChnb3RvLWNoYXIgLChpZiBvZmZzZXQgYCgrICxpcG9zICxvZmZzZXQpIGlwb3MpKSkK ICAgICAgICAgICAgICAgICAgICAgYChsZXQgKChpcG9zIChjYXNlIGZyb20KICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgKGVuZAogICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgYChpZiBvcmctdGFnLXF1ZXJ5L3ByaXZhdGUtb3B0LWNoLQogICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsKGNvbmQKICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAoKGFuZCAoaW50ZWdlcnAgZ3JvdXApICh6ZXJvcCBncm91 cCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcobWluICgx KyAocG9pbnQpKSAocG9pbnQtbWF4KSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgKChpbnRlZ2VycCBncm91cCkKICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgJyhwb2ludCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgKHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgYChtaW4gKCsgKHBvaW50KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAoaWYgKHplcm9wICxncm91cCkgMSAwKSkKICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBvaW50LW1heCkpKSkKICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvciAobWF0Y2gtZW5kICxncm91 cCkgKHBvaW50KSkpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYmVnaW4K ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAob3IgKGFuZAogICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5vdCBvcmctdGFnLXF1ZXJ5L3ByaXZh dGUtb3B0LWNoLSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICht YXRjaC1iZWdpbm5pbmcgLGdyb3VwKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgKHBvaW50KSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0 IGAoLGZyb20gLGdyb3VwKSkpKSkKICAgICAgICAgICAgICAgICAgICAgICAgYChnb3RvLWNoYXIg LChpZiBvZmZzZXQgYCgrICxpcG9zICxvZmZzZXQpIGlwb3MpKSkpKQogICAgICAgICAgICAgICAo JCAoZ3JvdXApICAgICAgICAgIDsgc3RyaW5nIG9yIG5pbCBpZiBubyBtYXRjaCBmb3IgZ3JvdXAK ICAgICAgICAgICAgICAgICAgLChpZiAobm90IG5leHQtY2hhcikKICAgICAgICAgICAgICAgICAg ICAgICBgYChtYXRjaC1zdHJpbmcgLGdyb3VwKQogICAgICAgICAgICAgICAgICAgICBgYChpZiBv cmctdGFnLXF1ZXJ5L3ByaXZhdGUtb3B0LWNoLQogICAgICAgICAgICAgICAgICAgICAgICAgICwo aWYgKGludGVnZXJwIGdyb3VwKSA7OyB3L2xpdGVyYWwgZ3JvdXAsIGp1c3QgZG8gaXQKICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIChpZiAoemVyb3AgZ3JvdXApIDs7ICBsaWtlbHkgdGhl IGNvbW1vbiBjYXNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyhzdHJpbmcg b3JnLXRhZy1xdWVyeS9wcml2YXRlLW9wdC1jaC0pIG5pbCkKICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBgKGlmICh6ZXJvcCAsZ3JvdXApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAoc3RyaW5nIG9yZy10YWctcXVlcnkvcHJpdmF0ZS1vcHQtY2gtKSBuaWwpKQogICAgICAg ICAgICAgICAgICAgICAgICAobWF0Y2gtc3RyaW5nICxncm91cCkpKSkpCiAgICAgIChsZXQgKCxA YmluZGluZ3MKICAgICAgICAgICAgLEAoaWYgbmV4dC1jaGFyIChsaXN0IGAoLG5leHQtY2hhciAo Y2hhci1hZnRlcikpKSBuaWwpCiAgICAgICAgICAgICxAKGlmIG5leHQtY2hhciAobGlzdCAnKG9y Zy10YWctcXVlcnkvcHJpdmF0ZS1vcHQtY2gtIG5pbCkpIG5pbCkpCiAgICAgICAgKGNvbmQKICAg ICAgICAgLEBjbGF1c2VzKSkpKSkKCgo7OzsgVGhlIHRhZyBxdWVyeSBwYXJzZXIgaXRzZWxmCgoo ZGVmdW4gb3JnLXRhZy1xdWVyeS1wYXJzZSAodG9kby1vbmx5KQogIDs7IFdvcmtzIGluIGN1cnJl bnQgYnVmZmVyIHdpdGggc3RyaW5nIHRvIGJlIHBhcnNlZCBzdGFydGluZyBhdCBwb2ludC4KICAo bGV0ICgocGFyc2Utc3RhY2sgbmlsKQogICAgICAgIChwYXJlbi1jb3VudCAwKQogICAgICAgIG5l Zy1zZWxlY3QgZ290LXNlbGVjdAogICAgICAgIHRvZG8tYmFuZyB0b2RvLW1hdGNoKQogICAgKGxh YmVscwogICAgICAgICgoZW1pdCAoJnJlc3QgaXRlbXMpCiAgICAgICAgICAgICAgIChkb2xpc3Qg KGl0ZW0gaXRlbXMpIChwdXNoIGl0ZW0gcGFyc2Utc3RhY2spKSkKICAgICAgICAgKG5vLXRlcm0t cCAoKQogICAgICAgICAgICAgICAgICAgIChzeW1ib2xwIChjYXIgcGFyc2Utc3RhY2spKSkKICAg ICAgICAgKG5lZ2F0ZS1pZiAobmVnYXRlIGl0ZW0pCiAgICAgICAgICAgICAgICAgICAgKGlmIG5l Z2F0ZSBgKG5vdCAsaXRlbSkgaXRlbSkpCiAgICAgICAgICh0aHJlYWQgKCZyZXN0IGl0ZXJhdGlv bnMpCiAgICAgICAgICAgICAgICAgKGRvbGlzdCAoXyBpdGVyYXRpb25zKQogICAgICAgICAgICAg ICAgICAgKGxldCAoZW50cmllcyBuZXctZW50cnkgdHlwZSkKICAgICAgICAgICAgICAgICAgICAg KHdoaWxlIChvciAoZXEgdCAoY2FyIHBhcnNlLXN0YWNrKSkKICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAobm90IChzeW1ib2xwIChjYXIgcGFyc2Utc3RhY2spKSkpCiAgICAgICAgICAg ICAgICAgICAgICAgKHNldHEgZW50cmllcyAoY29ucyAocG9wIHBhcnNlLXN0YWNrKSBlbnRyaWVz KSkpCiAgICAgICAgICAgICAgICAgICAgICh1bmxlc3MgKGFuZCBlbnRyaWVzIHBhcnNlLXN0YWNr KQogICAgICAgICAgICAgICAgICAgICAgIChvcmctdHF1ZXJ5LWVycm9yICJlbXB0eSBzdWJleHBy ZXNzaW9uIikpCiAgICAgICAgICAgICAgICAgICAgIChjYXNlIChzZXRxIHR5cGUgKHBvcCBwYXJz ZS1zdGFjaykpCiAgICAgICAgICAgICAgICAgICAgICAgKChhbmQgb3IpCiAgICAgICAgICAgICAg ICAgICAgICAgIChzZXRxIG5ldy1lbnRyeSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg KGlmIChjZHIgZW50cmllcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb25z IHR5cGUgZW50cmllcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2FyIGVudHJp ZXMpKSkpCiAgICAgICAgICAgICAgICAgICAgICAgKG5vdAogICAgICAgICAgICAgICAgICAgICAg ICAoYXNzZXJ0IChudWxsIChjZHIgZW50cmllcykpIG5pbCAibm90IGlzIHVuYXJ5IikKICAgICAg ICAgICAgICAgICAgICAgICAgKGxldCAoKGFyZyAoY2FyIGVudHJpZXMpKSkKICAgICAgICAgICAg ICAgICAgICAgICAgICAoc2V0cSBuZXctZW50cnkKICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAoaWYgKGFuZCAoY29uc3AgYXJnKSAoZXEgKGNhciBhcmcpICdub3QpKQogICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAoY2FkciBhcmcpCiAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBgKG5vdCAsYXJnKSkpKSkKICAgICAgICAgICAgICAgICAgICAgICAoaWRl bnRpdHkKICAgICAgICAgICAgICAgICAgICAgICAgKGFzc2VydCAobnVsbCAoY2RyIGVudHJpZXMp KSBuaWwgIigpIGlzIG9uZSBleHByZXNzaW9uIikKICAgICAgICAgICAgICAgICAgICAgICAgKHNl dHEgbmV3LWVudHJ5IChjYXIgZW50cmllcykpKQogICAgICAgICAgICAgICAgICAgICAgICh0ICAg ICAgICAgICAgICAgICAgOyB0aGlzIHJlYWxseSBzaG91bGRuJ3QgaGFwcGVuCiAgICAgICAgICAg ICAgICAgICAgICAgIChvcmctdHF1ZXJ5LWVycm9yICJpbnZhbGlkIHN5bWJvbCAlcyBvbiBzdGFj ay4iIHR5cGUpKSkKICAgICAgICAgICAgICAgICAgICAgKGVtaXQgbmV3LWVudHJ5KSkpKQogICAg ICAgICAodGFnLWNoZWNrIChpZCAmb3B0aW9uYWwgbmVnYXRlKQogICAgICAgICAgICAgICAgICAg IChsZXQgKChjaGVjayBgKG1lbWJlciAsaWQgdGFncy1saXN0KSkpCiAgICAgICAgICAgICAgICAg ICAgICAoaWYgbmVnYXRlIGAobm90ICxjaGVjaykgY2hlY2spKSkKICAgICAgICAgKHByb3AtY2hl Y2sgKHByb3AgJm9wdGlvbmFsIG51bWVyaWNwKQogICAgICAgICAgICAgICAgICAgICAoY29uZAog ICAgICAgICAgICAgICAgICAgICAgKChzdHJpbmctZXF1YWwgcHJvcCAiTEVWRUwiKQogICAgICAg ICAgICAgICAgICAgICAgICdsZXZlbCkKICAgICAgICAgICAgICAgICAgICAgICgobWVtYmVyIHBy b3AgJygiVE9ETyIgIkhFQURJTkciICJQUklPUklUWSIpKQogICAgICAgICAgICAgICAgICAgICAg IGAob3IgLChpbnRlcm4gKGRvd25jYXNlIHByb3ApKSAiIikpCiAgICAgICAgICAgICAgICAgICAg ICAoKHN0cmluZy1lcXVhbCBwcm9wICJDQVRFR09SWSIpCiAgICAgICAgICAgICAgICAgICAgICAg JyhvciAoZ2V0LXRleHQtcHJvcGVydHkgKHBvaW50KSAnb3JnLWNhdGVnb3J5KSAiIikpCiAgICAg ICAgICAgICAgICAgICAgICAgKG51bWVyaWNwCiAgICAgICAgICAgICAgICAgICAgICAgIGAoc3Ry aW5nLXRvLW51bWJlcgogICAgICAgICAgICAgICAgICAgICAgICAgIChvciAob3JnLWNhY2hlZC1l bnRyeS1nZXQgbmlsICxwcm9wKSAiIikpKQogICAgICAgICAgICAgICAgICAgICAgICh0CiAgICAg ICAgICAgICAgICAgICAgICAgIGAob3IgKG9yZy1jYWNoZWQtZW50cnktZ2V0IG5pbCAscHJvcCkg IiIpKSkpKQogICAgICA7OyBTZWVkIG91dGVybW9zdCBleHByZXNzaW9uIGluIHBhcnNlIHRyZWUK ICAgICAgKGVtaXQgJ29yICdhbmQpCiAgICAgIChza2lwLWNoYXJzLWZvcndhcmQgKG9yZy1yZSAi WzpibGFuazpdIikpCgogICAgICAod2hpbGUgKG5vdCAoZW9icCkpCiAgICAgICAgOzsgUHJvY2Vz cyBhIHRlcm0KICAgICAgICA7OyAgIExvb2sgZm9yIHRoZSBzZWxlY3RvciBjaGFyIGZpcnN0CiAg ICAgICAgKG9yZy1tYXRjaC1jb25kIG9yZy10YWctcXVlcnktdGVybWluYWxzCiAgICAgICAgICAo KDwtIChTRUxFQ1RPUikgU1BBQ0UqKQogICAgICAgICAgIChAIGVuZCAwKQogICAgICAgICAgIChz ZXRxIGdvdC1zZWxlY3QgdAogICAgICAgICAgICAgICAgIG5lZy1zZWxlY3QgKGNoYXItZXF1YWwg KHN0cmluZy10by1jaGFyICgkIDEpKSA/LSkpKQogICAgICAgICAgKHQKICAgICAgICAgICAoc2V0 cSBnb3Qtc2VsZWN0IG5pbAogICAgICAgICAgICAgICAgIG5lZy1zZWxlY3QgbmlsKSkpCiAgICAg ICAgOzsgICBOb3cgbG9vayBmb3IgdGhlIHJlc3Qgb2YgdGhlIHRlcm0KICAgICAgICAob3JnLW1h dGNoLWNvbmQgKG9yZy10YWctcXVlcnktdGVybWluYWxzIGNoYXItYXQtcG9pbnQpCiAgICAgICAg ICgoPC0gKFBST1AtSURFTlQpIFNQQUNFKiAoQ01QLU9QKSBTUEFDRSogKENNUC1SSFMtQkVHSU4p KQogICAgICAgICAgKEAgYmVnaW4gMykKICAgICAgICAgIChsZXQqICgocHJvcCAoc2F2ZS1tYXRj aC1kYXRhCiAgICAgICAgICAgICAgICAgICAgICAgICAocmVwbGFjZS1yZWdleHAtaW4tc3RyaW5n CiAgICAgICAgICAgICAgICAgICAgICAgICAgIlxcXFwtIiAiLSIgKCQgMSkgdCB0KSkpCiAgICAg ICAgICAgICAgICAgKGNtcCAgKCQgMikpCiAgICAgICAgICAgICAgICAgKGluZHggKGNhc2UgKGNo YXItYWZ0ZXIpCiAgICAgICAgICAgICAgICAgICAgICAgICAoP1x7IDMpCiAgICAgICAgICAgICAg ICAgICAgICAgICAoP1wiIChvcmctbWF0Y2gtY29uZCBvcmctdGFnLXF1ZXJ5LXRlcm1pbmFscwog ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoPC0gREFURS1TVFJJTkcpIDIpCiAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgKHQgMSkpKQogICAgICAgICAgICAgICAgICAgICAg ICAgKHQgMCkpKQogICAgICAgICAgICAgICAgIChvcC1mIChhcmVmIChnZXRoYXNoIGNtcCBvcmct dGFnLXF1ZXJ5LWNtcC1vcHMpIGluZHgpKQogICAgICAgICAgICAgICAgIChyaHMKICAgICAgICAg ICAgICAgICAgKGNhc2UgaW5keAogICAgICAgICAgICAgICAgICAgICgwIChvcmctbWF0Y2gtY29u ZCBvcmctdGFnLXF1ZXJ5LXRlcm1pbmFscwogICAgICAgICAgICAgICAgICAgICAgICAgKCg8LSBO VU1CRVIpIChAIGVuZCAwKSAoc3RyaW5nLXRvLW51bWJlciAoJCAwKSkpCiAgICAgICAgICAgICAg ICAgICAgICAgICAodCAob3JnLXRxdWVyeS1lcnJvcgogICAgICAgICAgICAgICAgICAgICAgICAg ICAgICJpbnZhbGlkIG51bWJlciBvbiByaHMgb2YgcHJvcGVydHkgY29tcGFyaXNvbiIpKSkpCiAg ICAgICAgICAgICAgICAgICAgKDEgKG9yZy1yZWFkLXF1b3RlZC1zdHJpbmctaW4tcXVlcnkpKQog ICAgICAgICAgICAgICAgICAgICgyIChvcmctbWF0Y2hlci10aW1lIChvcmctcmVhZC1xdW90ZWQt c3RyaW5nLWluLXF1ZXJ5KSkpCiAgICAgICAgICAgICAgICAgICAgKDMgKG9yZy1yZWFkLWJhbGFu Y2VkLXN0cmluZyA/XHsgP1x9KSkpKQogICAgICAgICAgICAgICAgIChmb3JtIChsaXN0IG9wLWYg KHByb3AtY2hlY2sgcHJvcCAoemVyb3AgaW5keCkpIHJocykpKQogICAgICAgICAgICAodW5sZXNz IG9wLWYKICAgICAgICAgICAgICAob3JnLXRxdWVyeS1lcnJvciAiaW52YWxpZCBvcGVyYXRvciBm b3IgcHJvcGVydHkgcmVnZXhwIG1hdGNoIikpCiAgICAgICAgICAgIChlbWl0IChuZWdhdGUtaWYg bmVnLXNlbGVjdCBmb3JtKSkpKQogICAgICAgICAoKDwtIFRBRy1JREVOVCkKICAgICAgICAgIChA IGVuZCAwKQogICAgICAgICAgKGVtaXQgKHRhZy1jaGVjayAoJCAwKSBuZWctc2VsZWN0KSkpCiAg ICAgICAgICgoPC0gUkVHRVgtT1BFTikKICAgICAgICAgIChsZXQgKChyZWdleCAob3JnLXJlYWQt YmFsYW5jZWQtc3RyaW5nID9ceyA/XH0pKSkKICAgICAgICAgICAgKGVtaXQgKG5lZ2F0ZS1pZiBu ZWctc2VsZWN0IGAob3JnLW1hdGNoLWFueS1wICxyZWdleCB0YWdzLWxpc3QpKSkpKQogICAgICAg ICAoKDwtIEdST1VQLU9QRU4pCiAgICAgICAgICAoQCBlbmQgMCkKICAgICAgICAgIChlbWl0IChp ZiBuZWctc2VsZWN0ICdub3QgJ2lkZW50aXR5KSAnb3IgJ2FuZCkKICAgICAgICAgIChpbmNmIHBh cmVuLWNvdW50KSkKICAgICAgICAgKGdvdC1zZWxlY3QKICAgICAgICAgIChvcmctdHF1ZXJ5LWVy cm9yICJ0cmFpbGluZyBzZWxlY3RvciB3aXRoIG5vIHRlcm0iKSkKICAgICAgICAgKCg8LSBUT0RP LU1BUktFUiAoVE9ETy1PTkxZLU0pXD8gU1BBQ0UqKQogICAgICAgICAgKHVubGVzcyAoemVyb3Ag cGFyZW4tY291bnQpCiAgICAgICAgICAgIChvcmctdHF1ZXJ5LWVycm9yICJtaXNzaW5nIClzIGlu IHF1ZXJ5IHN0cmluZyIpKQogICAgICAgICAgKEAgZW5kIDApCiAgICAgICAgICAoc2V0cSB0b2Rv LWJhbmcgIChhbmQgKCQgMSkgdCkpCiAgICAgICAgICAod2hlbiAobm8tdGVybS1wKSA7IG5vIHRh ZyBxdWVyeSB0ZXJtcyBiZWZvcmUgdGhpcwogICAgICAgICAgICAoZW1pdCB0KSkKICAgICAgICAg ICh1bmxlc3MgKGVvYnApCiAgICAgICAgICAgIChzZXRxIHRvZG8tbWF0Y2ggKG9yZy10b2RvLXF1 ZXJ5LXBhcnNlKSkpKQogICAgICAgICAoKG5vLXRlcm0tcCkKICAgICAgICAgIChvcmctdHF1ZXJ5 LWVycm9yICJtaXNzaW5nIHRoZSBleHBlY3RlZCB0ZXJtIikpCiAgICAgICAgICgoPC0gR1JPVVAt Q0xPU0UpICAgIDsgZW5kIG9mIHN1YmV4cHJlc3Npb24sIGNsZWFuIHVwCiAgICAgICAgICAoQCBl bmQgMCkKICAgICAgICAgIChkZWNmIHBhcmVuLWNvdW50KQogICAgICAgICAgKHdoZW4gKDwgcGFy ZW4tY291bnQgMCkgKG9yZy10cXVlcnktZXJyb3IgIm1pc21hdGNoZWQgKSdzIikpCiAgICAgICAg ICAodGhyZWFkICdjb25qdW5jdGlvbiAnZGlzanVuY3Rpb24gJ3NlbGVjdG9yKSkKICAgICAgICAg KCg8LSBBTkQtT1ApICAgICAgICAgOyBjb250aW51ZSBjb25qdW5jdGlvbiwgZXhwZWN0IGEgdGVy bQogICAgICAgICAgKEAgZW5kIDApKSAgICAgICAgICAgICAgICAgICAKICAgICAgICAgKCg8LSBP Ui1PUCkgICAgICAgICAgOyBzdGFydCBvciBjb250aW51ZSBhIGRpc2p1bmN0aW9uCiAgICAgICAg ICAoQCBlbmQgMCkKICAgICAgICAgICh0aHJlYWQgJ2Nvbmp1bmN0aW9uKQogICAgICAgICAgKGVt aXQgJ2FuZCkpCiAgICAgICAgICh0CiAgICAgICAgICAob3JnLXRxdWVyeS1lcnJvciAiaW52YWxp ZCB0b2tlbiAlYyBkdXJpbmcgcXVlcnkgcGFyc2UiCiAgICAgICAgICAgICAgICAgICAgICAgICAg ICAoY2hhci1hZnRlcikpKSkKICAgICAgICA7OyBBbGxvdyBzcGFjZXMgYXJvdW5kIHRlcm1zLCBv cGVyYXRvcnMsIGFuZCBwYXJlbnMKICAgICAgICAoc2tpcC1jaGFycy1mb3J3YXJkIChvcmctcmUg Ils6Ymxhbms6XSIpKSkKCiAgICAgICh1bmxlc3MgKHplcm9wIHBhcmVuLWNvdW50KQogICAgICAg IChvcmctdHF1ZXJ5LWVycm9yICJtaXNzaW5nIClzIGluIHF1ZXJ5IHN0cmluZyIpKQoKICAgICAg OzsgQnVpbGQgdGhlIGZpbmFsIHBhcnNlIHRyZWUgYnkgdGhyZWFkaW5nIHRoZSBzdGFjawogICAg ICAod2hpbGUgKGNkciBwYXJzZS1zdGFjaykKICAgICAgICAodGhyZWFkICdhbnkpKQoKICAgICAg OzsgUHV0IHRoZSBwaWVjZXMgdG9nZXRoZXIgKHRvZG8tbWF0Y2ggaXMgd3JhcHBlZCBpbiBhIGxp c3QpCiAgICAgIChsZXQgKCh0YWctbWF0Y2hlcgogICAgICAgICAgICAgKGlmIChlcSAoY2FyIHBh cnNlLXN0YWNrKSB0KQogICAgICAgICAgICAgICAgIHQKICAgICAgICAgICAgICAgYChwcm9nbgog ICAgICAgICAgICAgICAgICAoc2V0cSBvcmctY2FjaGVkLXByb3BzIG5pbCkKICAgICAgICAgICAg ICAgICAgLChjYXIgcGFyc2Utc3RhY2spKSkpCiAgICAgICAgICAgICh0b2RvLXJlc3RyaWN0CiAg ICAgICAgICAgICAoaWYgKG9yIHRvZG8tYmFuZyB0b2RvLW9ubHkpCiAgICAgICAgICAgICAgICAg JygobWVtYmVyIHRvZG8gb3JnLW5vdC1kb25lLWtleXdvcmRzKSkKICAgICAgICAgICAgICAgbmls KSkpCiAgICAgICAgKGlmIChvciB0b2RvLXJlc3RyaWN0IHRvZG8tbWF0Y2gpCiAgICAgICAgICAg IGAoYW5kICxAdG9kby1yZXN0cmljdCAsdGFnLW1hdGNoZXIgLEB0b2RvLW1hdGNoKQogICAgICAg ICAgdGFnLW1hdGNoZXIpKSkpKQoKKGRlZnVuIG9yZy10b2RvLXF1ZXJ5LXBhcnNlICgpCiAgOzsg VG9kbyB0ZXJtcyBtYXRjaCBURVJNIChBTkQtT1A/IFRFUk0pKiBiZXR3ZWVuIE9SLU9QJ3MsCiAg Ozsgd2hlcmUgVEVSTSA9ICJcXChbLSs6XVxcKT9cXCh7W159XSp9XFx8W14tK1wie30mfF0rXFwp IgogIChsZXQgKG9ybGlzdCBhbmRsaXN0IG5lZy1zZWxlY3QgZ290LXNlbGVjdCkKICAgICh3aGls ZSAobm90IChlb2JwKSkKICAgICAgKG9yZy1tYXRjaC1jb25kIG9yZy10YWctcXVlcnktdGVybWlu YWxzCiAgICAgICAgKCg8LSAoU0VMRUNUT1IpIFNQQUNFKikKICAgICAgICAgKEAgZW5kIDApCiAg ICAgICAgIChzZXRxIGdvdC1zZWxlY3QgdAogICAgICAgICAgICAgICBuZWctc2VsZWN0IChjaGFy LWVxdWFsIChzdHJpbmctdG8tY2hhciAoJCAxKSkgPy0pKSkKICAgICAgICAodAogICAgICAgICAo c2V0cSBnb3Qtc2VsZWN0IG5pbAogICAgICAgICAgICAgICBuZWctc2VsZWN0IG5pbCkpKQogICAg ICAob3JnLW1hdGNoLWNvbmQgKG9yZy10YWctcXVlcnktdGVybWluYWxzIGNoYXItYXQtcG9pbnQp CiAgICAgICAgKCg8LSBSRUdFWC1PUEVOKQogICAgICAgICAobGV0KiAoKHJlZ2V4IChvcmctcmVh ZC1iYWxhbmNlZC1zdHJpbmcgP1x7ID9cfSkpKQogICAgICAgICAgICAocHVzaCAoaWYgbmVnLXNl bGVjdAogICAgICAgICAgICAgICAgICAgICAgYChvcmctc3RyaW5nLW1hdGNoPD4gdG9kbyAscmVn ZXgpCiAgICAgICAgICAgICAgICAgICAgYChvcmctc3RyaW5nLW1hdGNoPSB0b2RvICxyZWdleCkp CiAgICAgICAgICAgICAgICAgIGFuZGxpc3QpKSkKICAgICAgICAoKDwtIFRPRE8tS0VZKQogICAg ICAgICAoQCBlbmQgMCkKICAgICAgICAgKGxldCAoKG1hdGNoIGAoZXF1YWwgdG9kbyAsKCQgMCkp KSkKICAgICAgICAgICAocHVzaCAoaWYgbmVnLXNlbGVjdCBgKG5vdCAsbWF0Y2gpIG1hdGNoKSBh bmRsaXN0KSkpCiAgICAgICAgKCg8LSBBTkQtT1ApCiAgICAgICAgIChAIGVuZCAwKQogICAgICAg ICAoY29uZAogICAgICAgICAgKGdvdC1zZWxlY3QKICAgICAgICAgICAob3JnLXRxdWVyeS1lcnJv ciAidHJhaWxpbmcgc2VsZWN0b3Igd2l0aCBubyB0b2RvIHRlcm0iKSkKICAgICAgICAgICgobnVs bCBhbmRsaXN0KQogICAgICAgICAgIChvcmctdHF1ZXJ5LWVycm9yICJtaXNzaW5nIHRvZG8gdGVy bSBiZWZvcmUgJiIpKSkpCiAgICAgICAgKCg8LSBPUi1PUCkKICAgICAgICAgKEAgZW5kIDApCiAg ICAgICAgIChjb25kCiAgICAgICAgICAoZ290LXNlbGVjdAogICAgICAgICAgIChvcmctdHF1ZXJ5 LWVycm9yICJ0cmFpbGluZyBzZWxlY3RvciB3aXRoIG5vIHRvZG8gdGVybSIpKQogICAgICAgICAg KChudWxsIGFuZGxpc3QpCiAgICAgICAgICAgKG9yZy10cXVlcnktZXJyb3IgIm1pc3NpbmcgdG9k byB0ZXJtIGJlZm9yZSB8IikpKQogICAgICAgICAocHVzaCAoaWYgKGNkciBhbmRsaXN0KQogICAg ICAgICAgICAgICAgICAgKGNvbnMgJ2FuZCAobnJldmVyc2UgYW5kbGlzdCkpCiAgICAgICAgICAg ICAgICAgKGNhciBhbmRsaXN0KSkKICAgICAgICAgICAgICAgb3JsaXN0KQogICAgICAgICAoc2V0 cSBhbmRsaXN0IG5pbCkpCiAgICAgICAgKHQKICAgICAgICAgKG9yZy10cXVlcnktZXJyb3IgImlu dmFsaWQgdG9rZW4gJWMgaW4gdG9kbyBleHByZXNzaW9uIgogICAgICAgICAgICAgICAgICAgICAg ICAgICAoY2hhci1hZnRlcikpKSkKICAgICAgKHNraXAtY2hhcnMtZm9yd2FyZCAob3JnLXJlICJb OmJsYW5rOl0iKSkpCiAgICAod2hlbiBhbmRsaXN0CiAgICAgIChwdXNoIChpZiAoY2RyIGFuZGxp c3QpIChjb25zICdhbmQgKG5yZXZlcnNlIGFuZGxpc3QpKSAoY2FyIGFuZGxpc3QpKQogICAgICAg ICAgICBvcmxpc3QpKQogICAgKGxpc3QgOyB3cmFwIGluIGEgbGlzdCBmb3IgbGF0ZXIgc3BsaWNp bmcKICAgICAoaWYgKGNkciBvcmxpc3QpCiAgICAgICAgIChjb25zICdvciAobnJldmVyc2Ugb3Js aXN0KSkKICAgICAgIChjYXIgb3JsaXN0KSkpKSkKCgo7OzsgTW9kaWZpZWQgYG9yZy1tYWtlLXRh Z3MtbWF0Y2hlcicgYW5kIGBvcmctc2Nhbi10YWdzJyB0aGF0IHVzZSB0aGUgbmV3IHBhcnNlcgoK Ozs7IFRoZSBtYWluIGNoYW5nZSB0byBgb3JnLW1ha2UtdGFncy1tYXRjaGVyJyBpcyB0byBpbnNl cnQgdGhlIG5ldyB0YWcKOzs7IHBhcnNlciwgYnV0IHRoaXMgYWxsb3dlZCBtZSB0byBzaG9ydGVu IGFuZCBjbGVhbiB1cCB0aGUgY29kZSwgZml4Cjs7OyBvbmUgdmVyeSBtaW5vciBidWcgKHNlZSBO T1RFIGJlbG93KSwgYW5kIHVwZGF0ZSB0aGUgZG9jc3RyaW5nLgo7OzsgSSd2ZSBhbHNvIHNlcGFy YXRlZCBvdXQgdGhlIHRvZG8gcGFyc2luZyBpbnRvIGEgc2VwYXJhdGUgZnVuY3Rpb24KOzs7IGZv ciBjbGFyaXR5IGFuZCBzeW1tZXRyeSwgdGhvdWdoIEkndmUgbGVmdCB0aGUgbWV0aG9kIGFzIGlz Lgo7OzsgCjs7OyBUaGUgY2hhbmdlcyB0byBgb3JnLXNjYW4tdGFncycgYXJlIG1pbm9yIGFuZCBl c3NlbnRpYWxseSBmcmVlLCBhbmQgCjs7OyBJIGluY2x1ZGUgdGhlIGNvbnRleHQgZGlmZiBpbiBj b21tZW50cyBiZWxvdy4KOzs7Cjs7OyBUaGVzZSBib3RoIGFyZSBkcmF3biBmcm9tIHRoZSA3Ljgu MTEgY29kZS4gVG8gZmFjaWxpdGF0ZSB0ZXN0aW5nLAo7OzsgSSd2ZSBhZGRlZCBhbiAtTkVXIHRv IHRoZSBuYW1lcyBvZiB0aGVzZSBmdW5jdGlvbnMgZm9yIHRoZSBtb21lbnQsCjs7OyBidXQgdGhh dCBzaG91bGQgYmUgY2hhbmdlZCBpZiB0aGV5IGFyZSB1c2VkLiBUaGUgdGVtcG9yYXJ5IGZ1bmN0 aW9uCjs7OyBgb3JnLXRtcC11c2UtdGFnLXBhcnNlcicgYWxsb3dzIHN3aXRjaGluZyBiZXR3ZWVu IG9sZCBhbmQgbmV3IGZvcgo7OzsgdGVzdGluZy4gU2VlIGFsc28gdGhlIGZpbGUgYHRhZy1xdWVy eS10ZXN0cy5lbCcgdGhhdCBydW5zIHNvbWUgYmFzaWMKOzs7IHRlc3RzLgoKOzsgTm90ZTogU3Vj Y2Vzc2l2ZSBtYXRjaGVzIChcRy1zdHlsZSkgaW4gYSBmaXhlZCBzdHJpbmcgYXJlIG5vdCBwb3Nz aWJsZQo7OyBpbiBlbWFjcyAod2l0aG91dCBtYWtpbmcgcmVwZWF0ZWQgY29waWVzIG9mIHN1YnN0 cmluZ3MpIGJlY2F1c2UgdGhlcmUKOzsgaXMgbm8gd2F5IHRvIGFuY2hvciBhIHN0cmluZy1tYXRj aCBhdCB0aGUgc3RhcnQgcG9zaXRpb24gYXJndW1lbnQuCjs7IChJIGhhdmUgc3VnZ2VzdGVkIHVz aW5nIHRoZSB6ZXJvLWxlbmd0aCBhc3NlcnRpb24gXD0gaW4gYSBzdHJpbmcgdG8KOzsgYW5jaG9y IGF0IHRoYXQgcG9zaXRpb24sIGFuYWxvZ291cyB0byBpdHMgdXNlIGluIGJ1ZmZlciBzZWFyY2hl cy4gSWYKOzsgeW91J3JlIHdpdGggbWUsIHNwcmVhZCB0aGUgd29yZC4pCjs7Cjs7IFNvIGluc3Rl YWQgb2YgbWFyY2hpbmcgdGhyb3VnaCB0aGUgc3RyaW5nIGNvcHlpbmcgc3Vic3RyaW5ncywgd2UK OzsgcHJvY2VzcyB0aGUgcXVlcnkgc3RyaW5nIGluIGEgdGVtcG9yYXJ5IGJ1ZmZlci4gVGhpcyBp cyBtb3JlCjs7IGlkaW9tYXRpYyBlbGlzcCBpbiBhbnkgY2FzZSwgYW5kIGlzIHF1aXRlIGZhc3Qg YW5kIGNvbnZlbmllbnQgaXQKOzsgdHVybnMgb3V0LiBEb2luZyBpdCB0aGUgb3RoZXIgd2F5IGlz IHBvc3NpYmxlIGFzIHdlbGwsIGJ5IG1ha2luZwo7OyBjaGFuZ2VzIGluIGEgZmV3IHBsYWNlcywg cGFydGljdWxhcmx5IHRoZSBvcmctbWF0Y2gtY29uZCBtYWNybyBhbmQKOzsgb3JnLXRhZy1xdWVy eS1wYXJzZSBpbiBhIGZldyBwbGFjZXMuIEJ1dCBzbyBmYXIgSSBsaWtlIHRoaXMgYXBwcm9hY2gu CgooZGVmdW4gb3JnLW1ha2UtdGFncy1tYXRjaGVyLU5FVyAobWF0Y2gpCiAgIkNyZWF0ZSB0aGUg VEFHUy9UT0RPIG1hdGNoZXIgZm9ybSBmb3IgdGhlIHNlbGVjdGlvbiBzdHJpbmcgTUFUQ0guCgpU aGUgdmFyaWFibGUgYHRvZG8tb25seScgaXMgc2NvcGVkIGR5bmFtaWNhbGx5IGludG8gdGhpcwpm dW5jdGlvbjsgaXQgd2lsbCBiZSBzZXQgdG8gdCBpZiB0aGUgbWF0Y2hlciByZXN0cmljdHMgbWF0 Y2hpbmcKdG8gVE9ETyBlbnRyaWVzLCBvdGhlcndpc2Ugd2lsbCBub3QgYmUgdG91Y2hlZC4KClJl dHVybnMgYSBjb25zIG9mIHRoZSBzZWxlY3Rpb24gc3RyaW5nIE1BVENIIGFuZCB0aGUgY29uc3Ry dWN0ZWQKbGlzcCBmb3JtIGltcGxlbWVudGluZyB0aGUgbWF0Y2hlci4gVGhlIG1hdGNoZXIgaXMg dG8gYmUKZXZhbHVhdGVkIGF0IGFuIE9yZyBlbnRyeSwgd2l0aCBwb2ludCBvbiB0aGUgaGVhZGxp bmUsIGFuZApyZXR1cm5zIHQgaWYgdGhlIGVudHJ5IG1hdGNoZXMgdGhlIHNlbGVjdGlvbiBzdHJp bmcgTUFUQ0guIFRoZQpyZXR1cm5lZCBsaXNwIGZvcm0gbWF5IHJlZmVyZW5jZSBmb3VyIHZhcmlh YmxlcyB3aXRoIGluZm9ybWF0aW9uCmFib3V0IHRoZSBlbnRyeSwgd2hpY2ggbXVzdCBiZSBib3Vu ZCBhcm91bmQgdGhlIGZvcm0ncwpldmFsdWF0aW9uOiB0b2RvLCB0aGUgVE9ETyBrZXl3b3JkIGF0 IHRoZSBlbnRyeSAob3IgbmlsIG9mIG5vbmUpOwpoZWFkaW5nLCB0aGUgdGV4dCBvZiB0aGUgaGVh ZGluZyBmb3IgdGhlIGVudHJ5OyBwcmlvcml0eSwgdGhlCnByaW9yaXR5IGNvb2tpZSBmb3IgdGhl IGVudHJ5IG9yIG5pbDsgYW5kIHRhZ3MtbGlzdCwgdGhlIGxpc3Qgb2YKYWxsIHRhZ3MgYXQgdGhl IGVudHJ5IGluY2x1ZGluZyBpbmhlcml0ZWQgb25lcy4gQWRkaXRpb25hbGx5LCB0aGUKY2F0ZWdv cnkgb2YgdGhlIGVudHJ5IChpZiBhbnkpIG11c3QgYmUgc3BlY2lmaWVkIGFzIHRoZSB0ZXh0CnBy b3BlcnR5ICdvcmctY2F0ZWdvcnkgb24gdGhlIGhlYWRsaW5lLgoKU2VlIGFsc28gYG9yZy1zY2Fu LXRhZ3MnLgoiCiAgKGRlY2xhcmUgKHNwZWNpYWwgdG9kby1vbmx5KSkKICAodW5sZXNzIChib3Vu ZHAgJ3RvZG8tb25seSkKICAgIChlcnJvciAib3JnLW1ha2UtdGFncy1tYXRjaGVyIGV4cGVjdHMg dG9kby1vbmx5IHRvIGJlIHNjb3BlZCBpbiIpKQogICh1bmxlc3MgbWF0Y2gKICAgIDs7IEdldCBh IG5ldyBtYXRjaCByZXF1ZXN0LCB3aXRoIGNvbXBsZXRpb24KICAgIChsZXQgKChvcmctbGFzdC10 YWdzLWNvbXBsZXRpb24tdGFibGUKCSAgIChvcmctZ2xvYmFsLXRhZ3MtY29tcGxldGlvbi10YWJs ZSkpKQogICAgICAoc2V0cSBtYXRjaCAob3JnLWNvbXBsZXRpbmctcmVhZC1uby1pCgkJICAgIk1h dGNoOiAiICdvcmctdGFncy1jb21wbGV0aW9uLWZ1bmN0aW9uIG5pbCBuaWwgbmlsCgkJICAgJ29y Zy10YWdzLWhpc3RvcnkpKSkpCgogIDs7IFBhcnNlIHRoZSBzdHJpbmcgaW50byBhIG1hdGNoZXIg bGlzcCBmb3JtCiAgKGNvbmQKICAgKChvciAobm90IG1hdGNoKSAobm90IChzdHJpbmctbWF0Y2gt cCAiXFxTLSIgbWF0Y2gpKSkKICAgIChjb25zIG1hdGNoIHQpKQogICAoKHN0cmluZy1tYXRjaCAi Xlxccy0qXFwoW14tK0EtWmEtejAtOV9AJSM6eygvIFx0XVxcKSIgbWF0Y2gpCiAgICAob3JnLXRx dWVyeS1lcnJvciAiaW52YWxpZCBjaGFyYWN0ZXJzIGluIHF1ZXJ5IHN0cmluZyIKICAgICAgICAg ICAgICAgICAgICAgIDpwb3MgKG1hdGNoLWJlZ2lubmluZyAxKSkpCiAgICh0CiAgICAod2l0aC10 ZW1wLWJ1ZmZlcgogICAgICAoaW5zZXJ0IG1hdGNoKQogICAgICAoZ290by1jaGFyIChwb2ludC1t aW4pKQogICAgICAoY29ucyBtYXRjaCAob3JnLXRhZy1xdWVyeS1wYXJzZSB0b2RvLW9ubHkpKSkp KSkKCjs7IFRoZSBjaGFuZ2VzIHRvIG9yZy1zY2FuLXRhZ3MgYXJlIG1pbm9yIGFuZCBlc3NlbnRp YWxseSBmcmVlLgo7OyBBIGRpZmYgLVUgMiBhZ2FpbnN0IG9yZy5lbCBmcm9tIDcuOC4xMSB3aXRo IG9ubHkgdGhpcyBmdW5jdGlvbgo7OyBjaGFuZ2VkIGZvbGxvd3MuCjs7Cjs7IC0tLSBvcmcuZWwg ICAgICAyMDEyLTA3LTMxIDE1OjMyOjE3LjAwMDAwMDAwMCAtMDQwMAo7OyArKysgbW9kaWZpZWQt b3JnLmVsICAgICAyMDEyLTA3LTMxIDE1OjIwOjU2LjAwMDAwMDAwMCAtMDQwMAo7OyBAQCAtMTI4 MzAsNSArMTI4MzAsNSBAQAo7OyAgICAgICAgICAgICAgICAgICAgICAiICpcXChcXDxcXCgiCjs7 ICAgICAgICAgICAgICAgICAgICAgIChtYXBjb25jYXQgJ3JlZ2V4cC1xdW90ZSBvcmctdG9kby1r ZXl3b3Jkcy0xICJcXHwiKQo7OyAtICAgICAgICAgICAgICAgICAgICAob3JnLXJlICJcXClcXD5c XCk/ICpcXCguKj9cXClcXCg6W1s6YWxudW06XV9AIyU6XSs6XFwpP1sgXHRdKiQiKSkpCjs7ICsg ICAgICAgICAgICAgICAgICAgIChvcmctcmUgIlxcKVxcPlxcKT9bIFx0XSpcXCg/OlxcWyNcXCgu XFwpXFxdXFwpP1sgXHRdKlxcKC4qP1xcKVxcKDpbWzphbG51bTpdX0AjJTpdKzpcXCk/WyBcdF0q JCIpKSkKOzsgICAgICAgICAgKHByb3BzIChsaXN0ICdmYWNlICdkZWZhdWx0Cjs7ICAgICAgICAg ICAgICAgICAgICAgICAnZG9uZS1mYWNlICdvcmctYWdlbmRhLWRvbmUKOzsgQEAgLTEyODQ4LDUg KzEyODQ4LDUgQEAKOzsgICAgICAgICAgKHRhZ3MtYWxpc3QgKGxpc3QgKGNvbnMgMCBvcmctZmls ZS10YWdzKSkpCjs7ICAgICAgICAgIChsbGFzdCAwKSBydG4gcnRuMSBsZXZlbCBjYXRlZ29yeSBp IHR4dAo7OyAtICAgICAgICB0b2RvIG1hcmtlciBlbnRyeSBwcmlvcml0eSkKOzsgKyAgICAgICAg dG9kbyBtYXJrZXIgZW50cnkgaGVhZGluZyBwcmlvcml0eSBwcmlvcml0eS1udW0pCjs7ICAgICAg KHdoZW4gKG5vdCAob3IgKG1lbWJlciBhY3Rpb24gJyhhZ2VuZGEgc3BhcnNlLXRyZWUpKSAoZnVu Y3Rpb25wIGFjdGlvbikpKQo7OyAgICAgICAgKHNldHEgYWN0aW9uIChsaXN0ICdsYW1iZGEgbmls IGFjdGlvbikpKQo7OyBAQCAtMTI4NjAsNSArMTI4NjAsNyBAQAo7OyAgICAgICAgIChjYXRjaCA6 c2tpcAo7OyAgICAgICAgICAgKHNldHEgdG9kbyAoaWYgKG1hdGNoLWVuZCAxKSAob3JnLW1hdGNo LXN0cmluZy1uby1wcm9wZXJ0aWVzIDIpKQo7OyAtICAgICAgICAgICAgICAgdGFncyAoaWYgKG1h dGNoLWVuZCA0KSAob3JnLW1hdGNoLXN0cmluZy1uby1wcm9wZXJ0aWVzIDQpKSkKOzsgKyAgICAg ICAgICAgICAgICBwcmlvcml0eSAoaWYgKG1hdGNoLWVuZCAzKSAob3JnLW1hdGNoLXN0cmluZy1u by1wcm9wZXJ0aWVzIDMpKQo7OyArICAgICAgICAgICAgICAgIGhlYWRpbmcgKG9yZy1tYXRjaC1z dHJpbmctbm8tcHJvcGVydGllcyA0KQo7OyArICAgICAgICAgICAgICAgdGFncyAoaWYgKG1hdGNo LWVuZCA1KSAob3JnLW1hdGNoLXN0cmluZy1uby1wcm9wZXJ0aWVzIDUpKSkKOzsgICAgICAgICAg IChnb3RvLWNoYXIgKHNldHEgbHNwb3MgKG1hdGNoLWJlZ2lubmluZyAwKSkpCjs7ICAgICAgICAg ICAoc2V0cSBsZXZlbCAob3JnLXJlZHVjZWQtbGV2ZWwgKGZ1bmNhbGwgb3V0bGluZS1sZXZlbCkp Cjs7IEBAIC0xMjkzOCw1ICsxMjk0MCw1IEBACjs7ICAgICAgICAgICAgICAgICAgICAgICAgICB0 YWdzLWxpc3QKOzsgICAgICAgICAgICAgICAgICAgICAgICAgICkKOzsgLSAgICAgICAgICAgICAg ICAgICBwcmlvcml0eSAob3JnLWdldC1wcmlvcml0eSB0eHQpKQo7OyArICAgICAgICAgICAgICAg ICAgIHByaW9yaXR5LW51bSAob3JnLWdldC1wcmlvcml0eSB0eHQpKQo7OyAgICAgICAgICAgICAg IChnb3RvLWNoYXIgbHNwb3MpCjs7ICAgICAgICAgICAgICAgKHNldHEgbWFya2VyIChvcmctYWdl bmRhLW5ldy1tYXJrZXIpKQo7OyBAQCAtMTI5NDQsNSArMTI5NDYsNSBAQAo7OyAgICAgICAgICAg ICAgICAgJ29yZy1tYXJrZXIgbWFya2VyICdvcmctaGQtbWFya2VyIG1hcmtlciAnb3JnLWNhdGVn b3J5IGNhdGVnb3J5Cjs7ICAgICAgICAgICAgICAgICAndG9kby1zdGF0ZSB0b2RvCjs7IC0gICAg ICAgICAgICAgICAncHJpb3JpdHkgcHJpb3JpdHkgJ3R5cGUgInRhZ3NtYXRjaCIpCjs7ICsgICAg ICAgICAgICAgICAncHJpb3JpdHkgcHJpb3JpdHktbnVtICd0eXBlICJ0YWdzbWF0Y2giKQo7OyAg ICAgICAgICAgICAgIChwdXNoIHR4dCBydG4pKQo7OyAgICAgICAgICAgICAgKChmdW5jdGlvbnAg YWN0aW9uKQo7OyAKCihkZWZ1biBvcmctc2Nhbi10YWdzLU5FVyAoYWN0aW9uIG1hdGNoZXIgdG9k by1vbmx5ICZvcHRpb25hbCBzdGFydC1sZXZlbCkKICAiU2NhbiBoZWFkbGluZSB0YWdzIHdpdGgg aW5oZXJpdGFuY2UgYW5kIHByb2R1Y2Ugb3V0cHV0IEFDVElPTi4KCkFDVElPTiBjYW4gYmUgYHNw YXJzZS10cmVlJyB0byBwcm9kdWNlIGEgc3BhcnNlIHRyZWUgaW4gdGhlIGN1cnJlbnQgYnVmZmVy LApvciBgYWdlbmRhJyB0byBwcm9kdWNlIGFuIGVudHJ5IGxpc3QgZm9yIGFuIGFnZW5kYSB2aWV3 LiAgSXQgY2FuIGFsc28gYmUKYSBMaXNwIGZvcm0gb3IgYSBmdW5jdGlvbiB0aGF0IHNob3VsZCBi ZSBjYWxsZWQgYXQgZWFjaCBtYXRjaGVkIGhlYWRsaW5lLCBpbgp0aGlzIGNhc2UgdGhlIHJldHVy biB2YWx1ZSBpcyBhIGxpc3Qgb2YgYWxsIHJldHVybiB2YWx1ZXMgZnJvbSB0aGVzZSBjYWxscy4K Ck1BVENIRVIgaXMgYSBMaXNwIGZvcm0gdG8gYmUgZXZhbHVhdGVkLCB0ZXN0aW5nIGlmIGEgZ2l2 ZW4gc2V0IG9mIHRhZ3MKcXVhbGlmaWVzIGEgaGVhZGxpbmUgZm9yIGluY2x1c2lvbi4gIFdoZW4g VE9ETy1PTkxZIGlzIG5vbi1uaWwsCm9ubHkgbGluZXMgd2l0aCBhIG5vdC1kb25lIFRPRE8ga2V5 d29yZCBhcmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dC4KVGhpcyBzaG91bGQgYmUgdGhlIHNhbWUg dmFyaWFibGUgdGhhdCB3YXMgc2NvcGVkIGludG8KYW5kIHNldCBieSBgb3JnLW1ha2UtdGFncy1t YXRjaGVyJyB3aGVuIGl0IGNvbnN0cnVjdGVkIE1BVENIRVIuCgpTVEFSVC1MRVZFTCBjYW4gYmUg YSBzdHJpbmcgd2l0aCBhc3Rlcmlza3MsIHJlZHVjaW5nIHRoZSBzY29wZSB0bwpoZWFkbGluZXMg bWF0Y2hpbmcgdGhpcyBzdHJpbmcuIgogIChyZXF1aXJlICdvcmctYWdlbmRhKQogIChsZXQqICgo cmUgKGNvbmNhdCAiXiIKCQkgICAgIChpZiBzdGFydC1sZXZlbAoJCQkgOzsgR2V0IHRoZSBjb3Jy ZWN0IGxldmVsIHRvIG1hdGNoCgkJCSAoY29uY2F0ICJcXCpcXHsiIChudW1iZXItdG8tc3RyaW5n IHN0YXJ0LWxldmVsKSAiXFx9ICIpCgkJICAgICAgIG9yZy1vdXRsaW5lLXJlZ2V4cCkKCQkgICAg ICIgKlxcKFxcPFxcKCIKCQkgICAgIChtYXBjb25jYXQgJ3JlZ2V4cC1xdW90ZSBvcmctdG9kby1r ZXl3b3Jkcy0xICJcXHwiKQoJCSAgICAgKG9yZy1yZSAiXFwpXFw+XFwpP1sgXHRdKlxcKD86XFxb I1xcKC5cXClcXF1cXCk/WyBcdF0qXFwoLio/XFwpXFwoOltbOmFsbnVtOl1fQCMlOl0rOlxcKT9b IFx0XSokIikpKQoJIChwcm9wcyAobGlzdCAnZmFjZSAnZGVmYXVsdAoJCSAgICAgICdkb25lLWZh Y2UgJ29yZy1hZ2VuZGEtZG9uZQoJCSAgICAgICd1bmRvbmUtZmFjZSAnZGVmYXVsdAoJCSAgICAg ICdtb3VzZS1mYWNlICdoaWdobGlnaHQKCQkgICAgICAnb3JnLW5vdC1kb25lLXJlZ2V4cCBvcmct bm90LWRvbmUtcmVnZXhwCgkJICAgICAgJ29yZy10b2RvLXJlZ2V4cCBvcmctdG9kby1yZWdleHAK CQkgICAgICAnb3JnLWNvbXBsZXgtaGVhZGluZy1yZWdleHAgb3JnLWNvbXBsZXgtaGVhZGluZy1y ZWdleHAKCQkgICAgICAnaGVscC1lY2hvCgkJICAgICAgKGZvcm1hdCAibW91c2UtMiBvciBSRVQg anVtcCB0byBvcmcgZmlsZSAlcyIKCQkJICAgICAgKGFiYnJldmlhdGUtZmlsZS1uYW1lCgkJCSAg ICAgICAob3IgKGJ1ZmZlci1maWxlLW5hbWUgKGJ1ZmZlci1iYXNlLWJ1ZmZlcikpCgkJCQkgICAo YnVmZmVyLW5hbWUgKGJ1ZmZlci1iYXNlLWJ1ZmZlcikpKSkpKSkKCSAoY2FzZS1mb2xkLXNlYXJj aCBuaWwpCgkgKG9yZy1tYXAtY29udGludWUtZnJvbSBuaWwpCiAgICAgICAgIGxzcG9zIHRhZ3Mg dGFncy1saXN0CgkgKHRhZ3MtYWxpc3QgKGxpc3QgKGNvbnMgMCBvcmctZmlsZS10YWdzKSkpCgkg KGxsYXN0IDApIHJ0biBydG4xIGxldmVsIGNhdGVnb3J5IGkgdHh0CgkgdG9kbyBtYXJrZXIgZW50 cnkgaGVhZGluZyBwcmlvcml0eSBwcmlvcml0eS1udW0pCiAgICAod2hlbiAobm90IChvciAobWVt YmVyIGFjdGlvbiAnKGFnZW5kYSBzcGFyc2UtdHJlZSkpIChmdW5jdGlvbnAgYWN0aW9uKSkpCiAg ICAgIChzZXRxIGFjdGlvbiAobGlzdCAnbGFtYmRhIG5pbCBhY3Rpb24pKSkKICAgIChzYXZlLWV4 Y3Vyc2lvbgogICAgICAoZ290by1jaGFyIChwb2ludC1taW4pKQogICAgICAod2hlbiAoZXEgYWN0 aW9uICdzcGFyc2UtdHJlZSkKCShvcmctb3ZlcnZpZXcpCgkob3JnLXJlbW92ZS1vY2N1ci1oaWdo bGlnaHRzKSkKICAgICAgKHdoaWxlIChyZS1zZWFyY2gtZm9yd2FyZCByZSBuaWwgdCkKCShzZXRx IG9yZy1tYXAtY29udGludWUtZnJvbSBuaWwpCgkoY2F0Y2ggOnNraXAKCSAgKHNldHEgdG9kbyAo aWYgKG1hdGNoLWVuZCAxKSAob3JnLW1hdGNoLXN0cmluZy1uby1wcm9wZXJ0aWVzIDIpKQogICAg ICAgICAgICAgICAgcHJpb3JpdHkgKGlmIChtYXRjaC1lbmQgMykgKG9yZy1tYXRjaC1zdHJpbmct bm8tcHJvcGVydGllcyAzKSkKICAgICAgICAgICAgICAgIGhlYWRpbmcgKG9yZy1tYXRjaC1zdHJp bmctbm8tcHJvcGVydGllcyA0KQoJCXRhZ3MgKGlmIChtYXRjaC1lbmQgNSkgKG9yZy1tYXRjaC1z dHJpbmctbm8tcHJvcGVydGllcyA1KSkpCgkgIChnb3RvLWNoYXIgKHNldHEgbHNwb3MgKG1hdGNo LWJlZ2lubmluZyAwKSkpCgkgIChzZXRxIGxldmVsIChvcmctcmVkdWNlZC1sZXZlbCAoZnVuY2Fs bCBvdXRsaW5lLWxldmVsKSkKCQljYXRlZ29yeSAob3JnLWdldC1jYXRlZ29yeSkpCgkgIChzZXRx IGkgbGxhc3QgbGxhc3QgbGV2ZWwpCgkgIDs7IHJlbW92ZSB0YWcgbGlzdHMgZnJvbSBzYW1lIGFu ZCBzdWJsZXZlbHMKCSAgKHdoaWxlICg+PSBpIGxldmVsKQoJICAgICh3aGVuIChzZXRxIGVudHJ5 IChhc3NvYyBpIHRhZ3MtYWxpc3QpKQoJICAgICAgKHNldHEgdGFncy1hbGlzdCAoZGVsZXRlIGVu dHJ5IHRhZ3MtYWxpc3QpKSkKCSAgICAoc2V0cSBpICgxLSBpKSkpCgkgIDs7IGFkZCB0aGUgbmV4 dCB0YWdzCgkgICh3aGVuIHRhZ3MKCSAgICAoc2V0cSB0YWdzIChvcmctc3BsaXQtc3RyaW5nIHRh Z3MgIjoiKQoJCSAgdGFncy1hbGlzdAoJCSAgKGNvbnMgKGNvbnMgbGV2ZWwgdGFncykgdGFncy1h bGlzdCkpKQoJICA7OyBjb21waWxlIHRhZ3MgZm9yIGN1cnJlbnQgaGVhZGxpbmUKCSAgKHNldHEg dGFncy1saXN0CgkJKGlmIG9yZy11c2UtdGFnLWluaGVyaXRhbmNlCgkJICAgIChhcHBseSAnYXBw ZW5kIChtYXBjYXIgJ2NkciAocmV2ZXJzZSB0YWdzLWFsaXN0KSkpCgkJICB0YWdzKQoJCW9yZy1z Y2FubmVyLXRhZ3MgdGFncy1saXN0KQoJICAod2hlbiBvcmctdXNlLXRhZy1pbmhlcml0YW5jZQoJ ICAgIChzZXRjZHIgKGNhciB0YWdzLWFsaXN0KQoJCSAgICAobWFwY2FyIChsYW1iZGEgKHgpCgkJ CSAgICAgIChzZXRxIHggKGNvcHktc2VxdWVuY2UgeCkpCgkJCSAgICAgIChvcmctYWRkLXByb3At aW5oZXJpdGVkIHgpKQoJCQkgICAgKGNkYXIgdGFncy1hbGlzdCkpKSkKCSAgKHdoZW4gKGFuZCB0 YWdzIG9yZy11c2UtdGFnLWluaGVyaXRhbmNlCgkJICAgICAob3IgKG5vdCAoZXEgdCBvcmctdXNl LXRhZy1pbmhlcml0YW5jZSkpCgkJCSBvcmctdGFncy1leGNsdWRlLWZyb20taW5oZXJpdGFuY2Up KQoJICAgIDs7IHNlbGVjdGl2ZSBpbmhlcml0YW5jZSwgcmVtb3ZlIHVuaW5oZXJpdGVkIG9uZXMK CSAgICAoc2V0Y2RyIChjYXIgdGFncy1hbGlzdCkKCQkgICAgKG9yZy1yZW1vdmUtdW5pbmhlcml0 ZWQtdGFncyAoY2RhciB0YWdzLWFsaXN0KSkpKQoJICAod2hlbiAoYW5kCgoJCSA7OyBldmFsIG1h dGNoZXIgb25seSB3aGVuIHRoZSB0b2RvIGNvbmRpdGlvbiBpcyBPSwoJCSAoYW5kIChvciAobm90 IHRvZG8tb25seSkgKG1lbWJlciB0b2RvIG9yZy1ub3QtZG9uZS1rZXl3b3JkcykpCgkJICAgICAg KGxldCAoKGNhc2UtZm9sZC1zZWFyY2ggdCkpIChldmFsIG1hdGNoZXIpKSkKCgkJIDs7IENhbGwg dGhlIHNraXBwZXIsIGJ1dCByZXR1cm4gdCBpZiBpdCBkb2VzIG5vdCBza2lwLAoJCSA7OyBzbyB0 aGF0IHRoZSBgYW5kJyBmb3JtIGNvbnRpbnVlcyBldmFsdWF0aW5nCgkJIChwcm9nbgoJCSAgICh1 bmxlc3MgKGVxIGFjdGlvbiAnc3BhcnNlLXRyZWUpIChvcmctYWdlbmRhLXNraXApKQoJCSAgIHQp CgoJCSA7OyBDaGVjayBpZiB0aW1lc3RhbXBzIGFyZSBkZXNlbGVjdGluZyB0aGlzIGVudHJ5CgkJ IChvciAobm90IHRvZG8tb25seSkKCQkgICAgIChhbmQgKG1lbWJlciB0b2RvIG9yZy1ub3QtZG9u ZS1rZXl3b3JkcykKCQkJICAob3IgKG5vdCBvcmctYWdlbmRhLXRhZ3MtdG9kby1ob25vci1pZ25v cmUtb3B0aW9ucykKCQkJICAgICAgKG5vdCAob3JnLWFnZW5kYS1jaGVjay1mb3ItdGltZXN0YW1w LWFzLXJlYXNvbi10by1pZ25vcmUtdG9kby1pdGVtKSkpKSkKCgkJIDs7IEV4dHJhIGNoZWNrIGZv ciB0aGUgYXJjaGl2ZSB0YWcKCQkgOzsgRklYTUU6IERvZXMgdGhlIHNraXBwZXIgYWxyZWFkeSBk byB0aGlzPz8/PwoJCSAob3IKCQkgIChub3QgKG1lbWJlciBvcmctYXJjaGl2ZS10YWcgdGFncy1s aXN0KSkKCQkgIDs7IHdlIGhhdmUgYW4gYXJjaGl2ZSB0YWcsIHNob3VsZCB3ZSB1c2UgdGhpcyBh bnl3YXk/CgkJICAob3IgKG5vdCBvcmctYWdlbmRhLXNraXAtYXJjaGl2ZWQtdHJlZXMpCgkJICAg ICAgKGFuZCAoZXEgYWN0aW9uICdhZ2VuZGEpIG9yZy1hZ2VuZGEtYXJjaGl2ZXMtbW9kZSkpKSkK CgkgICAgOzsgc2VsZWN0IHRoaXMgaGVhZGxpbmUKCgkgICAgKGNvbmQKCSAgICAgKChlcSBhY3Rp b24gJ3NwYXJzZS10cmVlKQoJICAgICAgKGFuZCBvcmctaGlnaGxpZ2h0LXNwYXJzZS10cmVlLW1h dGNoZXMKCQkgICAob3JnLWdldC1oZWFkaW5nKSAobWF0Y2gtZW5kIDApCgkJICAgKG9yZy1oaWdo bGlnaHQtbmV3LW1hdGNoCgkJICAgIChtYXRjaC1iZWdpbm5pbmcgMSkgKG1hdGNoLWVuZCAxKSkp CgkgICAgICAob3JnLXNob3ctY29udGV4dCAndGFncy10cmVlKSkKCSAgICAgKChlcSBhY3Rpb24g J2FnZW5kYSkKCSAgICAgIChzZXRxIHR4dCAob3JnLWFnZW5kYS1mb3JtYXQtaXRlbQoJCQkgIiIK CQkJIChjb25jYXQKCQkJICAoaWYgKGVxIG9yZy10YWdzLW1hdGNoLWxpc3Qtc3VibGV2ZWxzICdp bmRlbnRlZCkKCQkJICAgICAgKG1ha2Utc3RyaW5nICgxLSBsZXZlbCkgPy4pICIiKQoJCQkgIChv cmctZ2V0LWhlYWRpbmcpKQoJCQkgY2F0ZWdvcnkKCQkJIHRhZ3MtbGlzdAoJCQkgKQoJCSAgICBw cmlvcml0eS1udW0gKG9yZy1nZXQtcHJpb3JpdHkgdHh0KSkKCSAgICAgIChnb3RvLWNoYXIgbHNw b3MpCgkgICAgICAoc2V0cSBtYXJrZXIgKG9yZy1hZ2VuZGEtbmV3LW1hcmtlcikpCgkgICAgICAo b3JnLWFkZC1wcm9wcyB0eHQgcHJvcHMKCQknb3JnLW1hcmtlciBtYXJrZXIgJ29yZy1oZC1tYXJr ZXIgbWFya2VyICdvcmctY2F0ZWdvcnkgY2F0ZWdvcnkKCQkndG9kby1zdGF0ZSB0b2RvCgkJJ3By aW9yaXR5IHByaW9yaXR5LW51bSAndHlwZSAidGFnc21hdGNoIikKCSAgICAgIChwdXNoIHR4dCBy dG4pKQoJICAgICAoKGZ1bmN0aW9ucCBhY3Rpb24pCgkgICAgICAoc2V0cSBvcmctbWFwLWNvbnRp bnVlLWZyb20gbmlsKQoJICAgICAgKHNhdmUtZXhjdXJzaW9uCgkJKHNldHEgcnRuMSAoZnVuY2Fs bCBhY3Rpb24pKQoJCShwdXNoIHJ0bjEgcnRuKSkpCgkgICAgICh0IChlcnJvciAiSW52YWxpZCBh Y3Rpb24iKSkpCgoJICAgIDs7IGlmIHdlIGFyZSB0byBza2lwIHN1YmxldmVscywganVtcCB0byBl bmQgb2Ygc3VidHJlZQoJICAgICh1bmxlc3Mgb3JnLXRhZ3MtbWF0Y2gtbGlzdC1zdWJsZXZlbHMK CSAgICAgIChvcmctZW5kLW9mLXN1YnRyZWUgdCkKCSAgICAgIChiYWNrd2FyZC1jaGFyIDEpKSkp Cgk7OyBHZXQgdGhlIGNvcnJlY3QgcG9zaXRpb24gZnJvbSB3aGVyZSB0byBjb250aW51ZQoJKGlm IG9yZy1tYXAtY29udGludWUtZnJvbQoJICAgIChnb3RvLWNoYXIgb3JnLW1hcC1jb250aW51ZS1m cm9tKQoJICAoYW5kICg9IChwb2ludCkgbHNwb3MpIChlbmQtb2YtbGluZSAxKSkpKSkKICAgICh3 aGVuIChhbmQgKGVxIGFjdGlvbiAnc3BhcnNlLXRyZWUpCgkgICAgICAgKG5vdCBvcmctc3BhcnNl LXRyZWUtb3Blbi1hcmNoaXZlZC10cmVlcykpCiAgICAgIChvcmctaGlkZS1hcmNoaXZlZC1zdWJ0 cmVlcyAocG9pbnQtbWluKSAocG9pbnQtbWF4KSkpCiAgICAobnJldmVyc2UgcnRuKSkpCgoKOzsg VGVtcG9yYXJ5IGNvZGUgdG8gaGVscCB3aXRoIGludGVyYWN0aXZlIHRlc3RpbmcKOzsKOzsgIEkn dmUgYWRkZWQgYSBgLU5FVycgdG8gdGhlIG5hbWVzIG9mIHRoZSBtb2RpZmllZCBmdW5jdGlvbnMg YW5kIHNhdmUKOzsgIHRoZSBvcmlnaW5hbHMgYmVsb3dvIHdpdGggYSBgLU9SSUdJTkFMJyBhZGRl ZC4gQWZ0ZXIgbG9hZGluZyB0aGlzCjs7ICBmaWxlLCB5b3UgY2FuIGRvCjs7ICAKOzsgICAgICAo b3JnLXRtcC11c2UtdGFnLXBhcnNlciAnbmV3KQo7OyAgYW5kCjs7ICAgICAgKG9yZy10bXAtdXNl LXRhZy1wYXJzZXIgJ29yaWdpbmFsKQo7OyAgCjs7ICB0d28gc3dpdGNoIGJldHdlZW4gdmVyc2lv bnMgYW5kIHRyeSB0aGVtIG91dC4gT3IganVzdCB1c2UgdGhlCjs7ICBuYW1lcyB3aXRoIHN1ZmZp eGVzIGRpcmVjdGx5LiBTZWUgYWxzbyB0aGUgdGVzdHMgaW4gYHRhZy1xdWVyeS10ZXN0cy5lbCcu CgoKKGZzZXQgJ29yZy1zY2FuLXRhZ3MtT1JJR0lOQUwgKHN5bWJvbC1mdW5jdGlvbiAnb3JnLXNj YW4tdGFncykpCihmc2V0ICdvcmctbWFrZS10YWdzLW1hdGNoZXItT1JJR0lOQUwgKHN5bWJvbC1m dW5jdGlvbiAnb3JnLW1ha2UtdGFncy1tYXRjaGVyKSkKCihkZWZ2YXIgb3JnLXRtcC13aGljaC10 YWctcGFyc2VyICdvcmlnaW5hbCkKKGRlZnVuIG9yZy10bXAtdXNlLXRhZy1wYXJzZXIgKCZvcHRp b25hbCB3aGljaCkKICAiU3dpdGNoIGJldHdlZW4gdGFnIHF1ZXJ5IHBhcnNlcnMuIApJZiBub24t bmlsLCBXSElDSCBtdXN0IGJlIGVpdGhlciAnbmV3IG9yICdvcmlnaW5hbC4gSWYgbmlsLCBpdCB0 b2dnbGVzLiIKICAoc2V0cSBvcmctdG1wLXdoaWNoLXRhZy1wYXJzZXIKICAgICAgICAob3Igd2hp Y2ggKGlmIChlcSBvcmctdG1wLXdoaWNoLXRhZy1wYXJzZXIgJ29yaWdpbmFsKSAnbmV3ICdvcmln aW5hbCkpKQogIChlY2FzZSBvcmctdG1wLXdoaWNoLXRhZy1wYXJzZXIKICAgIChuZXcKICAgICAo ZnNldCAnb3JnLXNjYW4tdGFncyAoc3ltYm9sLWZ1bmN0aW9uICdvcmctc2Nhbi10YWdzLU5FVykp CiAgICAgKGZzZXQgJ29yZy1tYWtlLXRhZ3MtbWF0Y2hlciAoc3ltYm9sLWZ1bmN0aW9uICdvcmct bWFrZS10YWdzLW1hdGNoZXItTkVXKSkpCiAgICAob3JpZ2luYWwKICAgICAoZnNldCAnb3JnLXNj YW4tdGFncyAoc3ltYm9sLWZ1bmN0aW9uICdvcmctc2Nhbi10YWdzLU9SSUdJTkFMKSkKICAgICAo ZnNldCAnb3JnLW1ha2UtdGFncy1tYXRjaGVyIChzeW1ib2wtZnVuY3Rpb24gJ29yZy1tYWtlLXRh Z3MtbWF0Y2hlci1PUklHSU5BTCkpKSkKICBvcmctdG1wLXdoaWNoLXRhZy1wYXJzZXIpCgoKOzs7 IG9yZy10YWctcXVlcnktcGFyc2UuZWwgZW5kcyBoZXJlCg== --047d7b2e4f6e94631804c674df38 Content-Type: application/octet-stream; name="tag-query-tests.el" Content-Disposition: attachment; filename="tag-query-tests.el" Content-Transfer-Encoding: base64 X-Attachment-Id: f_h5h0xuok1 O2ZpcnN0PT47IChsb2FkICJvcmctdGFnLXF1ZXJ5LXBhcnNlLmVsIikKCihldmFsLXdoZW4tY29t cGlsZQogIChyZXF1aXJlICdjbCkpCgo7OyBBIHZlcnkgcnVkaW1lbnRhcnkgdGVzdCBmcmFtZXdv cmsKCjs7OyBDb21wYXJpbmcgb3JnLXRhZy1xdWVyeS1wYXJzZXIgYW5kIG9yZy1tYWtlLXRhZy1t YXRjaGVyIGlzCjs7OyBjb21wbGljYXRlZCBieSB0aGUgZGlmZmVyZW50IG9yZGVyaW5nIG9mIGxl YXZlcyBpbiB0aGUgdHJlZXMuCjs7OyBTcGVjaWZpY2FsbHksIHRoZSBmb3JtZXIgcHV0cyB0aGUg dGVybXMgaW4gdGhlIGdpdmVuIG9yZGVyLAo7OzsgYnV0IHRoZSBsYXR0ZXIgKHRoZSBleGlzdGlu ZyBvcmcgY29kZSkgcmV2ZXJzZXMgdGhlIHRlcm1zLgo7OzsgUGFyc2luZyB0aGUgc3RyaW5nIHRv IHJldmVyc2Ugd291bGQgcmVxdWlyZSB0ZXN0aW5nIHRoZSBzZWNvbmRhcnkKOzs7IHBhcnNlciBh bmQgdHVydGxlcyBhbGwgdGhlIHdheSBkb3duLgo7OzsKOzs7IFR3byBhcHByb2FjaGVzIHRoZW46 IHNwZWNpZnkgdGhlIHN0cmluZ3MgbWFudWFsbHkgaW4gcGFpcnMsIG9yCjs7OyBkZWZpbmUgdHJh bnNmb3JtIHRoYXQgYWNjb3VudHMgZm9yIHRoZSBkaWZmZXJlbmNlcy4gSGVyZQo7OzsgYHRhZy10 ZXN0LXN1aXRlJyBtb3N0bHkgdGFrZXMgdGhlIGZvcm1lciBhcHByb2FjaCwgdW5sZXNzIG9ubHkg b25lCjs7OyBzdHJpbmcgaXMgZ2l2ZW4gaW4gd2hpY2ggY2FzZSBpdCB1c2VzIGB0YWctdGVzdC10 cmFuc2Zvcm0nIHRvIHJlbWFwCjs7OyB0aGUgb3JpZ2luYWwgZm9ybXMuIFRoZSBmdW5jdGlvbiBg dGFnLXRlc3QtdHJhbnNmb3JtJyB0YW5zZm9ybXMgdGhlCjs7OyBleGlzdGluZyBmb3JtcyBpbnRv IG5ldyBmb3JtcyBleGNlcHQgaXQgaWdub3JlcyBQUklPUklUWSBhbmQgSEVBRElORwo7OzsgcXVl cmllcyB3aGljaCBhcmUgdHJlYXRlZCBkaWZmZXJlbnRseSBpbiB0aGUgbmV3IGNvZGUuCgooZGVm dW4gdGFnLXRlc3QtdHJhbnNmb3JtIChtYXRjaGVyKQogIChsZXQgKChzcGVjCiAgICAgICAgIChp ZiAoYW5kIChlcSAoY2FkciBtYXRjaGVyKSAnYW5kKQogICAgICAgICAgICAgICAgICAoZXEgKGNh ciAobGFzdCBtYXRjaGVyKSkgdCkpCiAgICAgICAgICAgICAoY29ucyAoY2FyIG1hdGNoZXIpIChj YXIgKGNkZHIgbWF0Y2hlcikpKQogICAgICAgICAgIG1hdGNoZXIpKSkKICAgIChpZiAobGlzdHAg KGNkciBzcGVjKSkKICAgICAgICAobWFwY2FyICd0YWctdGVzdC10cmFuc2Zvcm0tMSBzcGVjKQog ICAgICBzcGVjKSkpCgooZGVmdW4gdGFnLXRlc3QtdHJhbnNmb3JtLTEgKHNwZWMpCiAgKGlmIChh dG9tIHNwZWMpCiAgICAgIHNwZWMKICAgIChjYXNlIChjYXIgc3BlYykKICAgICAgKGFuZAogICAg ICAgKGNvbnMgJ2FuZCAobnJldmVyc2UgKG1hcGNhciAndGFnLXRlc3QtdHJhbnNmb3JtLTEgKGNk ciBzcGVjKSkpKSkKICAgICAgKG9yCiAgICAgICAoaWYgKGFuZCAobnVsbCAobnRoY2RyIDMgc3Bl YykpCiAgICAgICAgICAgICAgICAoZXF1YWwgKGNhciAoY2RkciBzcGVjKSkgIiIpKQogICAgICAg ICAgIHNwZWMKICAgICAgICAgKGNvbnMgJ29yIChucmV2ZXJzZSAobWFwY2FyICd0YWctdGVzdC10 cmFuc2Zvcm0tMSAoY2RyIHNwZWMpKSkpKSkKICAgICAgKG5vdAogICAgICAgKGlmIChlcSAoY2Fy IChjYWRyIHNwZWMpKSAnc3RyaW5nLW1hdGNoKQogICAgICAgICAgIChsaXN0ICdvcmctc3RyaW5n LW1hdGNoPD4KICAgICAgICAgICAgICAgICAoY2FyIChjZGRyIChjYWRyIHNwZWMpKSkKICAgICAg ICAgICAgICAgICAoY2FkciAoY2FkciBzcGVjKSkpCiAgICAgICAgIHNwZWMpKQogICAgICAoc3Ry aW5nLW1hdGNoCiAgICAgICAobGlzdCAnb3JnLXN0cmluZy1tYXRjaD0gKGNhciAoY2RkciBzcGVj KSkgKGNhZHIgc3BlYykpKQogICAgICAodAogICAgICAgKGNvbnMgKHRhZy10ZXN0LXRyYW5zZm9y bS0xIChjYXIgc3BlYykpCiAgICAgICAgICAgICAobWFwY2FyICd0YWctdGVzdC10cmFuc2Zvcm0t MSAoY2RyIHNwZWMpKSkpKSkpCgooZGVmdW4gdGFnLXRlc3QtZmluZC10b2RvLXF1ZXJ5IChxdWVy eS1zdHJpbmcpCiAgIkRvZXMgcXVlcnkgc3RyaW5nIGNvbnRhaW4gYSB0b2RvIG1hdGNoIGV4cHJl c3Npb24/IApTZWFyY2ggZm9yIHRoZSBmaXJzdCAvIHRoYXQgaXMgbm90IGJldHdlZW4gcXVvdGVz IG9yIGJyYWNlcywgYW5kCnJldHVybiB0aGUgaW5kZXggb2YgdGhhdCBjaGFyYWN0ZXIgaWYgZm91 bmQsIG9yIG5pbC4KU2V0IG1hdGNoIGRhdGEgZm9yIFFVRVJZLVNUUklORyBzbyB0aGF0IGdyb3Vw IDAgc3BhbnMgZnJvbSB0aGUKZm91bmQgLyB0byB0aGUgZW5kIG9mIHRoZSBzdHJpbmcsIGdyb3Vw IDEgbWF0Y2hlcyBcIi8hP1xccy0qXCIgYXQKdGhlIGZvdW5kIC8sIGFuZCBncm91cCAyIG1hdGNo ZXMgdGhlICEgaWYgcHJlc2VudC4iCiAgKHdpdGgtdGVtcC1idWZmZXIKICAgIChpbnNlcnQgcXVl cnktc3RyaW5nKQogICAgKGdvdG8tY2hhciAocG9pbnQtbWluKSkKICAgIDs7IFNlYXJjaCBmb3Ig Zmlyc3QgLyB0aGF0IGlzIG5vdCBiZXR3ZWVuICIiJ3Mgb3Ige30ncwogICAgKGNhdGNoIDpmb3Vu ZC1zbGFzaAogICAgICAod2hpbGUgKHJlLXNlYXJjaC1mb3J3YXJkICJcXCgvXFwoIVxcKT9cXHMt KlxcKVxcfFtcIntdIiBuaWwgdCkKICAgICAgICAod2hlbiAobWF0Y2gtZW5kIDEpCiAgICAgICAg ICAoc2V0LW1hdGNoLWRhdGEgIAogICAgICAgICAgIChtYXBjYXIgJzEtICAgIDsgc2V0IGluZGlj ZXMgdXNpbmcgc3RyaW5nIGNvbnZlbnRpb24KICAgICAgICAgICAgICAgICAgIChuY29uYyAobGlz dCAobWF0Y2gtYmVnaW5uaW5nIDApIChwb2ludC1tYXgpICAgIDswIC8gdG8gZW5kCiAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgKG1hdGNoLWJlZ2lubmluZyAxKSAobWF0Y2gtZW5kIDEp KSA7MSAvIT9cXHMtKgogICAgICAgICAgICAgICAgICAgICAgICAgIChpZiAobWF0Y2gtZW5kIDIp ICAgICAgICAgICAgICAgICAgICAgICAgOzIgIT8KICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgKGxpc3QgKG1hdGNoLWJlZ2lubmluZyAyKSAobWF0Y2gtZW5kIDIpKQogICAgICAgICAgICAg ICAgICAgICAgICAgICAgbmlsKSkpKQogICAgICAgICAgKHRocm93IDpmb3VuZC1zbGFzaCAoMS0g KG1hdGNoLWJlZ2lubmluZyAxKSkpKQogICAgICAgIChnb3RvLWNoYXIgKG1hdGNoLWJlZ2lubmlu ZyAwKSkKICAgICAgICAoY2FzZSAoY2hhci1hZnRlcikKICAgICAgICAgICg/XCIgKG9yZy1yZWFk LXF1b3RlZC1zdHJpbmctaW4tcXVlcnkpKQogICAgICAgICAgKD9ceyAob3JnLXJlYWQtYmFsYW5j ZWQtc3RyaW5nID9ceyA/XH0pKSkpCiAgICAgIG5pbCkpKQoKKGRlZnVuIHRhZy10ZXN0LW0gKHF1 ZXJ5ICZvcHRpb25hbCBvcmlnaW5hbHApCiAgIkNhbGwgYG9yZy1tYWtlLXRhZ3MtbWF0Y2hlcicg b24gUVVFUlkuIApOZXcgdmVyc2lvbiBieSBkZWZhdWx0LCBvcmlnaW5hbCB2ZXJzaW9uIGlmIE9S SUdJTkFMUCBpcyBub24tbmlsLiIKICAobGV0ICgodG9kby1vbmx5IG5pbCkpCiAgICAoZnVuY2Fs bAogICAgIChpZiBvcmlnaW5hbHAKICAgICAgICAgJ29yZy1tYWtlLXRhZ3MtbWF0Y2hlci1PUklH SU5BTAogICAgICAgJ29yZy1tYWtlLXRhZ3MtbWF0Y2hlci1ORVcpCiAgICAgcXVlcnkpKSkKCihk ZWZ1biB0YWctdGVzdC1wYXJzZS10cmVlIChxdWVyeSkKICAiUmV0dXJuIChqdXN0KSB0aGUgcGFy c2UgdHJlZSBmb3IgcXVlcnkgcHJvZHVjZWQgYnkgYG9yZy10YWctcXVlcnktcGFyc2VyJyIKICAo Y2FyIChudGhjZHIgMiAob3JnLXRhZy1xdWVyeS1wYXJzZSBxdWVyeSkpKSkKOzsgdXNlZnVsIGF0 IHJlcGw6IChkZWZ1biB0cSAocXVlcnkpIChjb25zIHF1ZXJ5ICh0YWctdGVzdC1wYXJzZS10cmVl IHF1ZXJ5KSkpCgoKKGRlZnVuIHRhZy10ZXN0LWNvbXBhcmUgKG5ldyBvcmlnaW5hbCkKICAoaWYg KGFuZCAob3IgKGVxIChjZHIgbmV3KSB0KSAoZXEgKGNhZHIgbmV3KSAncHJvZ24pKQogICAgICAg ICAgIChlcSAoY2FkciBvcmlnaW5hbCkgJ2FuZCkKICAgICAgICAgICAoZXEgKGNhciAobGFzdCBv cmlnaW5hbCkpIHQpKQogICAgICAoZXF1YWwgYChhbmQgLChjZHIgbmV3KSB0KSAoY2RyIG9yaWdp bmFsKSkKICAgIChlcXVhbCAoY2RyIG5ldykgKGNkciBvcmlnaW5hbCkpKSkKOzsgZm9ybWVybHkg cmV0dXJuZWQgKGFuZCBfXyAoZm9ybWF0ICIlczw9PT4lcyIgKGNhciBuZXcpIChjYXIgb3JpZ2lu YWwpKSkKCihvcmctZGVmaGFzaC1hdC1jb21waWxlIHRhZy10ZXN0LXN1aXRlLXRhYmxlICgpCiAg Ik1hcHBpbmcgZnJvbSB0ZXN0IG5hbWUgc3ltYm9scyB0byB0YWcgdGVzdCBmdW5jdGlvbnMuIEVh Y2gKZnVuY3Rpb24gdGFrZXMgYW4gb3B0aW9uYWwgYXJndW1lbnQsIHdoaWNoIGlmIG5vbi1uaWws IGNhdXNlcyBhCnNpbXBsZSBib29sZWFuIHN1bW1hcnkgdG8gYmUgcmV0dXJuZWQuIE90aGVyd2lz ZSwgdGhlIGZ1bmN0aW9uCnJldHVybnMgdGhlIGxpc3Qgb2YgcmVzdWx0cyBmb3Jtcy4gQ2FsbCB3 aXRoIGB0YWctdGVzdC1ydW4nCmdpdmluZyBuYW1lIGFuZCBvcHRpb25hbCBzdW1tYXJpemUgYXJn dW1lbnQuIikKCihkZWZtYWNybyB0YWctdGVzdC1zdWl0ZSAobmFtZSAmcmVzdCBib2R5KQogICJS ZWdpc3RlciB0ZXN0IE5BTUUuIElmIE5BTUUgaXMgbmlsLCBkbyBub3Qgc2F2ZSB0aGUgdGVzdCwg cnVuIGl0Cm5vdyB3aXRoIHN1bW1hcml6ZSBhcmd1bWVudCB0LiIKICAoZGVjbGFyZSAoaW5kZW50 IDEpKQogIChmbGV0ICgodGVzdC1pdCAoc3BlYykKICAgICAgICAgICAgICAgICAgKGxldCAoKHF1 ZXJ5IChjYXIgc3BlYykpCiAgICAgICAgICAgICAgICAgICAgICAgIChvYmogICAoY2RyIHNwZWMp KSkKICAgICAgICAgICAgICAgICAgICAoY29uZAogICAgICAgICAgICAgICAgICAgICAoKG51bGwg b2JqKQogICAgICAgICAgICAgICAgICAgICAgYChsZXQgKCh0b2RvLW9ubHkgbmlsKSkgOyBuZWVk cyB0byBiZSBzY29wZWQgaW4KICAgICAgICAgICAgICAgICAgICAgICAgIChjb25kaXRpb24tY2Fz ZSBleGNlcHRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29ucwogICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAoZXF1YWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IChvcmctbWFrZS10YWdzLW1hdGNoZXItTkVXICxxdWVyeSkKICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICh0YWctdGVzdC10cmFuc2Zvcm0KICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAob3JnLW1ha2UtdGFncy1tYXRjaGVyLU9SSUdJTkFMICxxdWVyeSkpKQogICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAscXVlcnkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgIChl cnJvciAoY29ucyBuaWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChm b3JtYXQgIkVSUk9SIG9uIHF1ZXJ5ICVzOiAlcyIKICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgLHF1ZXJ5IChjYWRyIGV4Y2VwdGlvbikpKSkpKSkKICAgICAg ICAgICAgICAgICAgICAgKChzdHJpbmdwIG9iaikKICAgICAgICAgICAgICAgICAgICAgIGAobGV0 ICgodG9kby1vbmx5IG5pbCkpIDsgbmVlZHMgdG8gYmUgc2NvcGVkIGluCiAgICAgICAgICAgICAg ICAgICAgICAgICAoY29uZGl0aW9uLWNhc2UgZXhjZXB0aW9uCiAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgKGNvbnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRhZy10ZXN0LWNv bXBhcmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvcmctbWFrZS10YWdzLW1hdGNo ZXItTkVXICxxdWVyeSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvcmctbWFrZS10 YWdzLW1hdGNoZXItT1JJR0lOQUwgLG9iaikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICxxdWVyeSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yIChjb25zIG5pbAogICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvcm1hdCAiRVJST1Igb24gcXVl cnkgJXM6ICVzIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAscXVlcnkgKGNhZHIgZXhjZXB0aW9uKSkpKSkpKQogICAgICAgICAgICAgICAgICAgICAoKGVx IG9iaiAnZXJyb3IpCiAgICAgICAgICAgICAgICAgICAgICBgKGNvbmRpdGlvbi1jYXNlIGV4Y2Vw dGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAobGV0ICgodG9kby1vbmx5IG5pbCkpIDsg bmVlZHMgdG8gYmUgc2NvcGVkIGluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9yZy1t YWtlLXRhZ3MtbWF0Y2hlci1ORVcgLHF1ZXJ5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAg IChjb25zIG5pbCAscXVlcnkpKQogICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yIChjb25z IChjYWRyIGV4Y2VwdGlvbikgLHF1ZXJ5KSkpKQogICAgICAgICAgICAgICAgICAgICAoKGVxIG9i aiB0KQogICAgICAgICAgICAgICAgICAgICAgYChjb25kaXRpb24tY2FzZSBleGNlcHRpb24KICAg ICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnMKICAgICAgICAgICAgICAgICAgICAgICAgICAg IChlcXVhbCAodGFnLXRlc3QtbSAscXVlcnkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgJygscXVlcnkgLiB0KSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICxxdWVyeSkK ICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciAoY29ucyBuaWwKICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIChmb3JtYXQgIkVSUk9SIG9uIHF1ZXJ5ICVzOiAlcyIK ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLHF1ZXJ5IChj YWRyIGV4Y2VwdGlvbikpKSkpKQogICAgICAgICAgICAgICAgICAgICAoKGFuZCAoY29uc3Agb2Jq KQogICAgICAgICAgICAgICAgICAgICAgICAgICAodGFnLXRlc3QtZmluZC10b2RvLXF1ZXJ5IHF1 ZXJ5KSkKICAgICAgICAgICAgICAgICAgICAgIGAoY29uZGl0aW9uLWNhc2UgZXhjZXB0aW9uCiAg ICAgICAgICAgICAgICAgICAgICAgICAgIChjb25zCiAgICAgICAgICAgICAgICAgICAgICAgICAg ICAoZXF1YWwgKHRhZy10ZXN0LW0gLHF1ZXJ5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICcsKGNvbnMgcXVlcnkgKGNhciBvYmopKSkKICAgICAgICAgICAgICAgICAgICAgICAg ICAgICxxdWVyeSkKICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciAoY29ucyBuaWwKICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb3JtYXQgIkVSUk9SIG9uIHF1 ZXJ5ICVzOiAlcyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgLHF1ZXJ5IChjYWRyIGV4Y2VwdGlvbikpKSkpKQogICAgICAgICAgICAgICAgICAgICAoKGNv bnNwIG9iaikKICAgICAgICAgICAgICAgICAgICAgIGAoY29uZGl0aW9uLWNhc2UgZXhjZXB0aW9u CiAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb25zCiAgICAgICAgICAgICAgICAgICAgICAg ICAgICAoZXF1YWwgKHRhZy10ZXN0LW0gLHF1ZXJ5KQogICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICcoLHF1ZXJ5IHByb2duCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgKHNldHEgb3JnLWNhY2hlZC1wcm9wcyBuaWwpCiAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgLChjYXIgb2JqKSkpCiAgICAgICAgICAgICAgICAg ICAgICAgICAgICAscXVlcnkpCiAgICAgICAgICAgICAgICAgICAgICAgICAoZXJyb3IgKGNvbnMg bmlsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9ybWF0ICJFUlJP UiBvbiBxdWVyeSAlczogJXMiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICxxdWVyeSAoY2FkciBleGNlcHRpb24pKSkpKSkKICAgICAgICAgICAgICAgICAg ICAgKHQgKGVycm9yICJVbnJlY29nbml6ZWQgdGVzdCB0eXBlIikpKSkpKQogICAgKGxldCogKChy ZXN1bHQtZm9ybXMgKG1hcGNhciAndGVzdC1pdCBib2R5KSkKICAgICAgICAgICAodGVzdCBgKGxh bWJkYSAoJm9wdGlvbmFsIHN1bW1hcml6ZT8pCiAgICAgICAgICAgICAgICAgICAgKGxldCAoKHRl c3RzIChsaXN0ICxAcmVzdWx0LWZvcm1zKSkpCiAgICAgICAgICAgICAgICAgICAgICAoaWYgc3Vt bWFyaXplPwogICAgICAgICAgICAgICAgICAgICAgICAgIChsZXQgKChvdXRjb21lIChjYXRjaCA6 ZmFpbHVyZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvbGlz dCAocmVzdWx0IHRlc3RzIHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICh1bmxlc3MgKGNhciByZXN1bHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgKHRocm93IDpmYWlsdXJlIG5pbCkpKSkpKQogICAgICAgICAgICAg ICAgICAgICAgICAgICAgKGlmIG91dGNvbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAobWVzc2FnZSAiQWxsICVzIHRlc3RzIHBhc3NlZC4iICcsbmFtZSkKICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgKG1lc3NhZ2UgIlNvbWUgJXMgdGVzdHMgZmFpbGVkLiIgJyxuYW1lKSkK ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dGNvbWUpCiAgICAgICAgICAgICAgICAgICAg ICAgIChsaXN0ICxAcmVzdWx0LWZvcm1zKSkpKSkpCiAgICAgIChpZiBuYW1lCiAgICAgICAgICBg KHByb2duIChwdXRoYXNoICcsbmFtZSAsdGVzdCB0YWctdGVzdC1zdWl0ZS10YWJsZSkgdCkKICAg ICAgICBgKGZ1bmNhbGwgLHRlc3QgdCkpKSkpCgooZGVmdW4gdGFnLXRlc3QtcnVuIChzdW1tYXJp emU/ICZyZXN0IHN1aXRlLXN5bWJvbHMpCiAgKGxldCAoKHN1bW1hcml6ZSAoYW5kIHN1bW1hcml6 ZT8KICAgICAgICAgICAgICAgICAgICAgICAgKG5vdCAobWVtcSBzdW1tYXJpemU/ICcoOnNob3cg OnJlc3VsdHMgOnJlc3VsdCkpKSkpCiAgICAgICAgKHJlc3VsdHMgbmlsKQogICAgICAgIChzdWl0 ZXMgKGlmIHN1aXRlLXN5bWJvbHMKICAgICAgICAgICAgICAgICAgICBzdWl0ZS1zeW1ib2xzCiAg ICAgICAgICAgICAgICAgIChsb29wIGZvciBrZXkgYmVpbmcgdGhlIGhhc2gta2V5cyBvZiB0YWct dGVzdC1zdWl0ZS10YWJsZQogICAgICAgICAgICAgICAgICAgICAgICBjb2xsZWN0IGtleSkpKSkK ICAgIChkb2xpc3QgKHN1aXRlIHN1aXRlcykKICAgICAgKGNvbmRpdGlvbi1jYXNlIGV4Y2VwdAog ICAgICAgICAgKGxldCAoKHRlc3QgKGdldGhhc2ggc3VpdGUgdGFnLXRlc3Qtc3VpdGUtdGFibGUp KSkKICAgICAgICAgICAgKGlmIChhbmQgdGVzdCAoZnVuY3Rpb25wIHRlc3QpKQogICAgICAgICAg ICAgICAgKHB1c2ggKGNvbnMgc3VpdGUgKGZ1bmNhbGwgdGVzdCBzdW1tYXJpemUpKSByZXN1bHRz KQogICAgICAgICAgICAgIChwdXNoIChjb25zIHN1aXRlCiAgICAgICAgICAgICAgICAgICAgICAg ICAgKGNvbnMgbmlsIChmb3JtYXQgIlRlc3Qgc3VpdGUgJXMgbm90IGZvdW5kIiBzdWl0ZSkpKQog ICAgICAgICAgICAgICAgICAgIHJlc3VsdHMpKSkKICAgICAgICAoZXJyb3IgKHB1c2ggKGZvcm1h dCAiVW5jYXVnaHQgZXJyb3Igb24gc3VpdGUgJXM6ICVzIgogICAgICAgICAgICAgICAgICAgICAg ICAgICAgIHN1aXRlIGV4Y2VwdCkKICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cykpKSkKICAg IChpZiAoY2RyIHJlc3VsdHMpIChucmV2ZXJzZSByZXN1bHRzKSAoY2FyIHJlc3VsdHMpKSkpCgoK OzsKOzsgU29tZSBCYXNpYyBUZXN0cwo7Owo7OyBLZWVwIGluIG1pbmQgdGVybSByZXZlcnNhbCBt ZW50aW9uZWQgYWJvdmUKOzsKCih0YWctdGVzdC1zdWl0ZSBvcmctY29tcGFyaXNvbi0xCiAgKCIi KQogICgiZm9vIikKICAoIi1mb28iKQogICgie15IVStSUkFZfSIpCiAgKCIte15CTypPIX0iKQog ICgiTEVWRUw8MyIpCiAgKCJMRVZFTD4zIikKICAoIkxFVkVMPD0zIikKICAoIkxFVkVMPj0zIikK ICAoIkxFVkVMPTMiKQogICgiTEVWRUw8PjMiKQogICgiVE9ETz1cIldBSVRcIiIpCiAgKCJUT0RP PD5cIldBSVRcIiIpCiAgKCJBX1BST1A8XCJmb29cIiIpCiAgKCJBX1BST1A+XCJmb29cIiIpCiAg KCJBX1BST1A8PVwiZm9vXCIiKQogICgiQV9QUk9QPj1cImZvb1wiIikKICAoIkFfUFJPUDw+XCJm b29cIiIpCiAgKCJBX1BST1A9XCJmb29cIiIpCiAgKCJBX0RBVEU9XCI8MjAwOC0xMi0yNCAxODoz MD5cIiIpCiAgKCJBX0RBVEU8XCI8MjAwOC0xMi0yNCAxODozMD5cIiIpCiAgKCJBX0RBVEU8PVwi PDIwMDgtMTItMjQgMTg6MzA+XCIiKQogICgiQV9EQVRFPj1cIjwyMDA4LTEyLTI0IDE4OjMwPlwi IikKICAoIkFfREFURT5cIjwyMDA4LTEyLTI0IDE4OjMwPlwiIikKICAoIkFfREFURTw+XCI8MjAw OC0xMi0yNCAxODozMD5cIiIpCiAgKCJERUFETElORTw+XCI8LTJkPlwiIikKICAoIkRFQURMSU5F PVwiPCsxdz5cIiIpCiAgKCJERUFETElORT5cIjwrNjBtPlwiIikKICAoIkRFQURMSU5FPFwiPHRv ZGF5PlwiIikKICAoIlNDSEVEVUxFRD49XCI8dG9tb3Jyb3c+XCIiKQogICgiU0NIRURVTEVEPD1c IjwrMnk+XCIiKQogICgiQ0FURUdPUlk9XCJmb29cIiIpCiAgKCJmb28rUFJPUD1cIkFcIitaPXth YmN9LWJhciIpCiAgKCJmb28rYmFyK3phcCIpCiAgKCJmb28tYmFyK3phcCIpCiAgKCItZm9vK2Jh ci16YXAiKQogICgiZm9vfGJhcnwtemFwIikKICAoIi1mb28rYmFyK3phcC17XmEuKn0iKQogICgi LXteYWJjfSt7XmF9IikKICAoIi17WzAtOV19fHphcDlAIyVpdHxMRVZFTD41IikKICAoInteQX18 e14uQn18e15DfSIpCiAgKCJ7XkF9fG9rLXphcHx7XkN9IikKICAoIndvcmsrVE9ETz1cIldBSVRJ TkdcInxob21lK1RPRE89XCJXQUlUSU5HXCIiKQogICgid29yay1UT0RPPVwiV0FJVElOR1wifGhv bWUmVE9ETz1cIldBSVRJTkdcIiIpCiAgKCJ6YXAtYmFyK2ZvbyZMRVZFTD4yIikKICAoIi16YXAr YmFyfExFVkVMPD0yJlRPRE88PlwiV0FJVFwiIikKICAoIit3b3JrLWJvc3MrUFJJT1JDPVwiQVwi K0NvZmZlZT1cInVubGltaXRlZFwiK0VmZm9ydDwyK1dpdGg9e1NhcmFoXFx8RGVubnl9K1NDSEVE VUxFRD49XCI8MjAwOC0xMC0xMT5cIiIpCiAgKQoKOzsgU29tZSBvZiB0aGVzZSBhcmUgdGhlIHNh bWUgYXMgYWJvdmUsIGJ1dCBJJ3ZlIGV4cGxpY2l0bHkgcmV2ZXJzZWQKOzsgdGhlIHRlcm1zIHRv IG1ha2Ugc3VyZSB0aGF0IHRoZSB0cmFuc2Zvcm1lciBpcyBub3QgbWFza2luZyBhbnkgcHJvYmxl bXMuCjs7IFRoaXMgbmVjZXNzYXJpbHkgZXhjbHVkZXMgdGhlIG90aGVyIHRyYW5zZm9ybWF0aW9u cyBzbyBpdCBpcyByZWFsbHkgYSBtZXRhLXRlc3QuCjs7IFRoZSByZXN0IGluY2x1ZGUgdG9kbyBt YXRjaGVycyBpbiB0aGUgY29tcGFyaXNvbi4KKHRhZy10ZXN0LXN1aXRlIG9yZy1jb21wYXJpc29u LTIKICAoImZvbytiYXIremFwIiAuICJ6YXArYmFyK2ZvbyIpCiAgKCJmb28tYmFyK3phcCIgLiAi emFwLWJhcitmb28iKQogICgiLWZvbytiYXItemFwIiAuICItemFwK2Jhci1mb28iKQogICgiZm9v fGJhcnwtemFwIiAuICItemFwfGJhcnxmb28iKQogICgiLWZvbytiYXIremFwLXteYS4qfSIgLiAi LXteYS4qfSt6YXArYmFyLWZvbyIpCiAgKCIte15hYmN9K3teYX0iIC4gInteYX0te15hYmN9IikK ICAoIi17WzAtOV19fHphcDlAIyVpdHxMRVZFTD41IiAuICJMRVZFTD41fHphcDlAIyVpdHwte1sw LTldfSIpCiAgKCJ7XkF9fHteLkJ9fHteQ30iIC4gInteQ318e14uQn18e15BfSIpCiAgKCJ7XkF9 fG9rLXphcHx7XkN9IiAuICJ7XkN9fC16YXArb2t8e15BfSIpCiAgKCJ3b3JrK1RPRE89XCJXQUlU SU5HXCJ8aG9tZStUT0RPPVwiV0FJVElOR1wiIiAuICJUT0RPPVwiV0FJVElOR1wiK2hvbWV8VE9E Tz1cIldBSVRJTkdcIit3b3JrIikKICAoIndvcmstVE9ETz1cIldBSVRJTkdcInxob21lJlRPRE89 XCJXQUlUSU5HXCIiIC4gIlRPRE89XCJXQUlUSU5HXCImaG9tZXwtVE9ETz1cIldBSVRJTkdcIit3 b3JrIikKICAoInphcCAtYmFyICAgK2ZvbyAmIExFVkVMID4gMiIgLiAiTEVWRUw+MiZmb28tYmFy K3phcCIpCiAgKCItemFwK2JhciB8IExFVkVMIDw9IDIgJiBUT0RPIDw+IFwiV0FJVFwiIiAuICJU T0RPPD5cIldBSVRcIiZMRVZFTDw9MnxiYXItemFwIikKICAoImZvbytiYXIvVE9ETytXQUlULURP TkUiIC4gImJhcitmb28vLURPTkUrV0FJVCtUT0RPIikKICAoImZvbytiYXIvVE9ETytXQUlUfFVS R0VOVCIgLiAiYmFyK2Zvby9VUkdFTlR8V0FJVCtUT0RPIikKICAoIi9BIikKICAoIi9BLXtBSVR9 IikKICAoImZvby1iYXIvQStCfEMtRHx7Vyt9IikKICAoIi9BLXtBSVR9IikKICAoImZvby1iYXIv QStCfEMtRHx7Vyt9IikKICAoIi16YXArYmFyfExFVkVMPD0yJlRPRE88PlwiV0FJVFwiL09LLU5P VHxHT09ELUJBRHxIVVJSQVktQk9PIikpCgo7OyBzb21lIG9mIHRoZSAvIHRvZG8gbWF0Y2hlcyBh cmUgcHJhY3RpY2FsbHkgc2lsbHksIGJ1dCB0ZXN0aW5nIHN0cnVjdHVyZSBoZXJlCih0YWctdGVz dC1zdWl0ZSBtYXRjaC1yZXN1bHRzLTEKICAoIiIgLiB0KQogICgiICAgICAgICAgICAvISIgCiAg IChhbmQgKG1lbWJlciB0b2RvIG9yZy1ub3QtZG9uZS1rZXl3b3JkcykgdCkpCiAgKCIgICAgICAg ICAgIC8hICAgICAgICAgICAgICAiIAogICAoYW5kIChtZW1iZXIgdG9kbyBvcmctbm90LWRvbmUt a2V5d29yZHMpIHQpKQogICgiQV9QUk9QPXteMHhbMC05QS1GXSt9IgogICAob3JnLXN0cmluZy1t YXRjaD0KICAgIChvciAob3JnLWNhY2hlZC1lbnRyeS1nZXQgbmlsICJBX1BST1AiKSAiIikgIl4w eFswLTlBLUZdKyIpKQogICgiQV9QUk9QPD57XltBLVpdK30iCiAgIChvcmctc3RyaW5nLW1hdGNo PD4KICAgIChvciAob3JnLWNhY2hlZC1lbnRyeS1nZXQgbmlsICJBX1BST1AiKSAiIikgIl5bQS1a XSsiKSkKICAoIihhK2ItY3xBX1BST1A9PTJ8LShkLWUrZiZMRVZFTD4zKSkiCiAgIChvcgogICAg KGFuZAogICAgIChtZW1iZXIgImEiIHRhZ3MtbGlzdCkKICAgICAobWVtYmVyICJiIiB0YWdzLWxp c3QpCiAgICAgKG5vdCAobWVtYmVyICJjIiB0YWdzLWxpc3QpKSkKICAgICg9IChzdHJpbmctdG8t bnVtYmVyIChvciAob3JnLWNhY2hlZC1lbnRyeS1nZXQgbmlsICJBX1BST1AiKSAiIikpIDIpCiAg ICAobm90IChhbmQKICAgICAgICAgIChtZW1iZXIgImQiIHRhZ3MtbGlzdCkKICAgICAgICAgIChu b3QgKG1lbWJlciAiZSIgdGFncy1saXN0KSkKICAgICAgICAgIChtZW1iZXIgImYiIHRhZ3MtbGlz dCkKICAgICAgICAgICg+IGxldmVsIDMpKSkpKQogICgiKChjKSkiIChtZW1iZXIgImMiIHRhZ3Mt bGlzdCkpCiAgKCIoKC0oKCgtKGMpKSkpKSkiIChtZW1iZXIgImMiIHRhZ3MtbGlzdCkpCiAgKCIo KC0oLSgoLShjKSkpKSkpIiAobm90IChtZW1iZXIgImMiIHRhZ3MtbGlzdCkpKQogICgiLSh6YXAg LWJhciAgICtmb28gJiBMRVZFTCA+IDIgfCBIRUFESU5HID09IHtae3szLDd9fX0pIgogICAobm90 IChvciAoYW5kCiAgICAgICAgICAgICAobWVtYmVyICJ6YXAiIHRhZ3MtbGlzdCkKICAgICAgICAg ICAgIChub3QgKG1lbWJlciAiYmFyIiB0YWdzLWxpc3QpKQogICAgICAgICAgICAgKG1lbWJlciAi Zm9vIiB0YWdzLWxpc3QpCiAgICAgICAgICAgICAoPiBsZXZlbCAyKSkKICAgICAgICAgICAgKG9y Zy1zdHJpbmctbWF0Y2g9IChvciBoZWFkaW5nICIiKSAiWnszLDd9IikpKSkKICAoInphcCAtYmFy ICAgK2ZvbyAmIExFVkVMID4gMiIgCiAgIChhbmQgCiAgICAobWVtYmVyICJ6YXAiIHRhZ3MtbGlz dCkKICAgIChub3QgKG1lbWJlciAiYmFyIiB0YWdzLWxpc3QpKQogICAgKG1lbWJlciAiZm9vIiB0 YWdzLWxpc3QpCiAgICAoPiBsZXZlbCAyKSkpCiAgKCItemFwK2JhciB8IExFVkVMIDw9IDIgJiBU T0RPIDw+IFwiV0FJVFwiIiAKICAgKG9yCiAgICAoYW5kCiAgICAgKG5vdCAobWVtYmVyICJ6YXAi IHRhZ3MtbGlzdCkpCiAgICAgKG1lbWJlciAiYmFyIiB0YWdzLWxpc3QpKQogICAgKGFuZAogICAg ICg8PSBsZXZlbCAyKQogICAgIChvcmctc3RyaW5nPD4gKG9yIHRvZG8gIiIpICAiV0FJVCIpKSkp CiAgKCItKHphcHx7XkF9fExFVkVMPTIpIgogICAobm90IChvcgogICAgICAgICAobWVtYmVyICJ6 YXAiIHRhZ3MtbGlzdCkKICAgICAgICAgKG9yZy1tYXRjaC1hbnktcCAiXkEiIHRhZ3MtbGlzdCkK ICAgICAgICAgKD0gbGV2ZWwgMikpKSkKICAoIi8hVE9ETyIKICAgKGFuZAogICAgKG1lbWJlciB0 b2RvIG9yZy1ub3QtZG9uZS1rZXl3b3JkcykKICAgIHQKICAgIChlcXVhbCB0b2RvICJUT0RPIikp KQogICgiL1RPRE8iCiAgIChhbmQgdCAoZXF1YWwgdG9kbyAiVE9ETyIpKSkKICAoIi8hIgogICAo YW5kIChtZW1iZXIgdG9kbyBvcmctbm90LWRvbmUta2V5d29yZHMpIHQpKQogICgiYWJjLXV2dyt4 eXovIVRPRE8iCiAgIChhbmQKICAgIChtZW1iZXIgdG9kbyBvcmctbm90LWRvbmUta2V5d29yZHMp CiAgICAocHJvZ24KICAgICAgKHNldHEgb3JnLWNhY2hlZC1wcm9wcyBuaWwpCiAgICAgIChhbmQK ICAgICAgIChtZW1iZXIgImFiYyIgdGFncy1saXN0KQogICAgICAgKG5vdCAobWVtYmVyICJ1dnci IHRhZ3MtbGlzdCkpCiAgICAgICAobWVtYmVyICJ4eXoiIHRhZ3MtbGlzdCkpKQogICAgKGVxdWFs IHRvZG8gIlRPRE8iKSkpCiAgKCJhYmMtdXZ3K3h5eitMRVZFTDw9My9UT0RPfEhPTERJTkctV0FJ VElOR3xBVk9JRElORy1SRUFMTFlfQVZPSURJTkciIAogICAoYW5kCiAgICAocHJvZ24KICAgICAg KHNldHEgb3JnLWNhY2hlZC1wcm9wcyBuaWwpCiAgICAgIChhbmQKICAgICAgIChtZW1iZXIgImFi YyIgdGFncy1saXN0KQogICAgICAgKG5vdCAobWVtYmVyICJ1dnciIHRhZ3MtbGlzdCkpCiAgICAg ICAobWVtYmVyICJ4eXoiIHRhZ3MtbGlzdCkKICAgICAgICg8PSBsZXZlbCAzKSkpCiAgICAob3IK ICAgICAoZXF1YWwgdG9kbyAiVE9ETyIpCiAgICAgKGFuZAogICAgICAoZXF1YWwgdG9kbyAiSE9M RElORyIpCiAgICAgIChub3QgKGVxdWFsIHRvZG8gIldBSVRJTkciKSkpCiAgICAgKGFuZAogICAg ICAoZXF1YWwgdG9kbyAiQVZPSURJTkciKQogICAgICAobm90IChlcXVhbCB0b2RvICJSRUFMTFlf QVZPSURJTkciKSkpKSkpCiAgKCJhYmMtdXZ3K3h5eitMRVZFTDw9My8hVE9ET3xIT0xESU5HLVdB SVRJTkd8QVZPSURJTkctUkVBTExZX0FWT0lESU5HIgogICAoYW5kCiAgICAobWVtYmVyIHRvZG8g b3JnLW5vdC1kb25lLWtleXdvcmRzKQogICAgKHByb2duCiAgICAgIChzZXRxIG9yZy1jYWNoZWQt cHJvcHMgbmlsKQogICAgICAoYW5kCiAgICAgICAobWVtYmVyICJhYmMiIHRhZ3MtbGlzdCkKICAg ICAgIChub3QgKG1lbWJlciAidXZ3IiB0YWdzLWxpc3QpKQogICAgICAgKG1lbWJlciAieHl6IiB0 YWdzLWxpc3QpCiAgICAgICAoPD0gbGV2ZWwgMykpKQogICAgKG9yCiAgICAgKGVxdWFsIHRvZG8g IlRPRE8iKQogICAgIChhbmQKICAgICAgKGVxdWFsIHRvZG8gIkhPTERJTkciKQogICAgICAobm90 IChlcXVhbCB0b2RvICJXQUlUSU5HIikpKQogICAgIChhbmQKICAgICAgKGVxdWFsIHRvZG8gIkFW T0lESU5HIikKICAgICAgKG5vdCAoZXF1YWwgdG9kbyAiUkVBTExZX0FWT0lESU5HIikpKSkpKQog ICgiYWJjLXV2dyt4eXorTEVWRUw8PTMvIVRPRE98e1l9LXtafXx7QX0te0J9IgogICAoYW5kCiAg ICAobWVtYmVyIHRvZG8gb3JnLW5vdC1kb25lLWtleXdvcmRzKQogICAgKHByb2duCiAgICAgIChz ZXRxIG9yZy1jYWNoZWQtcHJvcHMgbmlsKQogICAgICAoYW5kCiAgICAgICAobWVtYmVyICJhYmMi IHRhZ3MtbGlzdCkKICAgICAgIChub3QgKG1lbWJlciAidXZ3IiB0YWdzLWxpc3QpKQogICAgICAg KG1lbWJlciAieHl6IiB0YWdzLWxpc3QpCiAgICAgICAoPD0gbGV2ZWwgMykpKQogICAgKG9yCiAg ICAgKGVxdWFsIHRvZG8gIlRPRE8iKQogICAgIChhbmQKICAgICAgKG9yZy1zdHJpbmctbWF0Y2g9 IHRvZG8gIlkiKQogICAgICAob3JnLXN0cmluZy1tYXRjaDw+IHRvZG8gIloiKSkKICAgICAoYW5k CiAgICAgIChvcmctc3RyaW5nLW1hdGNoPSB0b2RvICJBIikKICAgICAgKG9yZy1zdHJpbmctbWF0 Y2g8PiB0b2RvICJCIikpKSkpCiAgKCJQUk9QPXteXFxzLSovLyAuKiR9L0F7fUIiCiAgIChhbmQK ICAgIChwcm9nbgogICAgICAoc2V0cSBvcmctY2FjaGVkLXByb3BzIG5pbCkKICAgICAgKG9yZy1z dHJpbmctbWF0Y2g9IChvciAob3JnLWNhY2hlZC1lbnRyeS1nZXQgbmlsICJQUk9QIikgIiIpCiAg ICAgICAgICAgICAgICAgICAgICAgICAiXlxccy0qLy8gLiokIikpCiAgICAoYW5kCiAgICAgKGVx dWFsIHRvZG8gIkEiKQogICAgIChvcmctc3RyaW5nLW1hdGNoPSB0b2RvICIiKQogICAgIChlcXVh bCB0b2RvICJCIikpKSkgOyBTZWUgTm90ZSBoIGZvciB3aHkgdGhlIGN1cnJlbnQgNy44IGNvZGUg ZG9lcyBub3Qgd29yayBmb3IgdGhpcyBjYXNlCiAgKCJQUk9QPXteXFxzLSovLyAuKiR9L0Ere14u KmFiJH0rQiIgCiAgIChhbmQKICAgIChwcm9nbgogICAgICAoc2V0cSBvcmctY2FjaGVkLXByb3Bz IG5pbCkKICAgICAgKG9yZy1zdHJpbmctbWF0Y2g9IChvciAob3JnLWNhY2hlZC1lbnRyeS1nZXQg bmlsICJQUk9QIikgIiIpCiAgICAgICAgICAgICAgICAgICAgICAgICAiXlxccy0qLy8gLiokIikp CiAgICAoYW5kCiAgICAgKGVxdWFsIHRvZG8gIkEiKQogICAgIChvcmctc3RyaW5nLW1hdGNoPSB0 b2RvICJeLiphYiQiKQogICAgIChlcXVhbCB0b2RvICJCIikpKSkKICAoIlBST1A9e15cXHMtKi8v IC4qJH0vQSt7Xi4qYWJ7ezEsM319JH0rQiIgCiAgIChhbmQKICAgIChwcm9nbgogICAgICAoc2V0 cSBvcmctY2FjaGVkLXByb3BzIG5pbCkKICAgICAgKG9yZy1zdHJpbmctbWF0Y2g9IChvciAob3Jn LWNhY2hlZC1lbnRyeS1nZXQgbmlsICJQUk9QIikgIiIpCiAgICAgICAgICAgICAgICAgICAgICAg ICAiXlxccy0qLy8gLiokIikpCiAgICAoYW5kCiAgICAgKGVxdWFsIHRvZG8gIkEiKQogICAgIChv cmctc3RyaW5nLW1hdGNoPSB0b2RvICJeLiphYnsxLDN9JCIpCiAgICAgKGVxdWFsIHRvZG8gIkIi KSkpKQogICgiUFJPUD17Xlxccy0qLy8gLiokfS9BLXteLiphYiR9LUJ8LUMre15jKiR9IiAKICAg KGFuZAogICAgKHByb2duCiAgICAgIChzZXRxIG9yZy1jYWNoZWQtcHJvcHMgbmlsKQogICAgICAo b3JnLXN0cmluZy1tYXRjaD0gKG9yIChvcmctY2FjaGVkLWVudHJ5LWdldCBuaWwgIlBST1AiKSAi IikgCiAgICAgICAgICAgICAgICAgICAgICAgICAiXlxccy0qLy8gLiokIikpCiAgICAob3IKICAg ICAoYW5kCiAgICAgIChlcXVhbCB0b2RvICJBIikKICAgICAgKG9yZy1zdHJpbmctbWF0Y2g8PiB0 b2RvICJeLiphYiQiKQogICAgICAobm90IChlcXVhbCB0b2RvICJCIikpKQogICAgIChhbmQKICAg ICAgKG5vdCAoZXF1YWwgdG9kbyAiQyIpKQogICAgICAob3JnLXN0cmluZy1tYXRjaD0gdG9kbyAi XmMqJCIpKSkpKQogICgiLyFBIiAKICAgKGFuZAogICAgKG1lbWJlciB0b2RvIG9yZy1ub3QtZG9u ZS1rZXl3b3JkcykKICAgIHQKICAgIChlcXVhbCB0b2RvICJBIikpKQogICgiZm9vK2Jhci8hVE9E TytXQUlULURPTkUiIAogICAoYW5kCiAgICAobWVtYmVyIHRvZG8gb3JnLW5vdC1kb25lLWtleXdv cmRzKQogICAgKHByb2duCiAgICAgIChzZXRxIG9yZy1jYWNoZWQtcHJvcHMgbmlsKQogICAgICAo YW5kCiAgICAgICAobWVtYmVyICJmb28iIHRhZ3MtbGlzdCkKICAgICAgIChtZW1iZXIgImJhciIg dGFncy1saXN0KSkpCiAgICAoYW5kCiAgICAgKGVxdWFsIHRvZG8gIlRPRE8iKQogICAgIChlcXVh bCB0b2RvICJXQUlUIikKICAgICAobm90IChlcXVhbCB0b2RvICJET05FIikpKSkpCiAgKCJmb28r YmFyLyFUT0RPK1dBSVR8VVJHRU5UIgogICAoYW5kCiAgICAobWVtYmVyIHRvZG8gb3JnLW5vdC1k b25lLWtleXdvcmRzKQogICAgKHByb2duCiAgICAgIChzZXRxIG9yZy1jYWNoZWQtcHJvcHMgbmls KQogICAgICAoYW5kCiAgICAgICAobWVtYmVyICJmb28iIHRhZ3MtbGlzdCkKICAgICAgIChtZW1i ZXIgImJhciIgdGFncy1saXN0KSkpCiAgICAob3IKICAgICAoYW5kCiAgICAgIChlcXVhbCB0b2Rv ICJUT0RPIikKICAgICAgKGVxdWFsIHRvZG8gIldBSVQiKSkKICAgICAoZXF1YWwgdG9kbyAiVVJH RU5UIikpKSkKICAoImZvbytiYXIvIVRPRE98V0FJVHxVUkdFTlQiCiAgIChhbmQKICAgIChtZW1i ZXIgdG9kbyBvcmctbm90LWRvbmUta2V5d29yZHMpCiAgICAocHJvZ24KICAgICAgKHNldHEgb3Jn LWNhY2hlZC1wcm9wcyBuaWwpCiAgICAgIChhbmQKICAgICAgIChtZW1iZXIgImZvbyIgdGFncy1s aXN0KQogICAgICAgKG1lbWJlciAiYmFyIiB0YWdzLWxpc3QpKSkKICAgIChvcgogICAgIChlcXVh bCB0b2RvICJUT0RPIikKICAgICAoZXF1YWwgdG9kbyAiV0FJVCIpCiAgICAgKGVxdWFsIHRvZG8g IlVSR0VOVCIpKSkpICAKICAoImZvbytiYXIvIXtUT0RPfS1XQUlUIgogICAoYW5kCiAgICAobWVt YmVyIHRvZG8gb3JnLW5vdC1kb25lLWtleXdvcmRzKQogICAgKHByb2duCiAgICAgIChzZXRxIG9y Zy1jYWNoZWQtcHJvcHMgbmlsKQogICAgICAoYW5kCiAgICAgICAobWVtYmVyICJmb28iIHRhZ3Mt bGlzdCkKICAgICAgIChtZW1iZXIgImJhciIgdGFncy1saXN0KSkpCiAgICAoYW5kCiAgICAgKG9y Zy1zdHJpbmctbWF0Y2g9IHRvZG8gIlRPRE8iKQogICAgIChub3QgKGVxdWFsIHRvZG8gIldBSVQi KSkpKSkpCgoodGFnLXRlc3Qtc3VpdGUgbWF0Y2gtcmVzdWx0cy0yCiAgKCIoKGEgK2IgLWMgJiBM RVZFTCA+IDIgfCBjICYgTEVWRUwgPT0gMSktKEhFQURJTkc9ezxOT1RFUz59fFRPRE89XCJET05F XCIpfHVyZ2VudHxfcXVldWUmREVBRExJTkU+XCI8MjAxMi0wMS0wMSAwNDowMD5cIikiCiAgIChv cgogICAgKGFuZAogICAgIChvciAoYW5kCiAgICAgICAgICAobWVtYmVyICJhIiB0YWdzLWxpc3Qp CiAgICAgICAgICAobWVtYmVyICJiIiB0YWdzLWxpc3QpCiAgICAgICAgICAobm90IChtZW1iZXIg ImMiIHRhZ3MtbGlzdCkpCiAgICAgICAgICAoPiBsZXZlbCAyKSkKICAgICAgICAgKGFuZAogICAg ICAgICAgKG1lbWJlciAiYyIgdGFncy1saXN0KQogICAgICAgICAgKD0gbGV2ZWwgMSkpKQogICAg IChub3QKICAgICAgKG9yIChvcmctc3RyaW5nLW1hdGNoPSAob3IgaGVhZGluZyAiIikgIjxOT1RF Uz4iKQogICAgICAgICAgKHN0cmluZz0gKG9yIHRvZG8gIiIpICJET05FIikpKSkKICAgIChtZW1i ZXIgInVyZ2VudCIgdGFncy1saXN0KQogICAgKGFuZAogICAgIChtZW1iZXIgIl9xdWV1ZSIgdGFn cy1saXN0KQogICAgIChvcmctdGltZT4gKG9yIChvcmctY2FjaGVkLWVudHJ5LWdldCBuaWwgIkRF QURMSU5FIikgIiIpIDEzMjUzOTQwMDAuMCkpKSkKICAoIit5b3UrbWUtdGhlbSZQUklPUklUWT09 XCJBXCIrQ0FURUdPUlk8PlwibWlzc2luZ1wiIgogICAoYW5kCiAgICAobWVtYmVyICJ5b3UiIHRh Z3MtbGlzdCkKICAgIChtZW1iZXIgIm1lIiB0YWdzLWxpc3QpCiAgICAobm90IChtZW1iZXIgInRo ZW0iIHRhZ3MtbGlzdCkpCiAgICAoc3RyaW5nPSAob3IgcHJpb3JpdHkgIiIpICJBIikKICAgIChv cmctc3RyaW5nPD4KICAgICAob3IgKGdldC10ZXh0LXByb3BlcnR5IChwb2ludCkgJ29yZy1jYXRl Z29yeSkgIiIpICJtaXNzaW5nIikpKQogICgiK3lvdSttZS10aGVtICYgUFJJT1JJVFkgPT0gXCJB XCIgKyBDQVRFR09SWSA8PiBcIm1pc3NpbmdcIiIKICAgKGFuZAogICAgKG1lbWJlciAieW91IiB0 YWdzLWxpc3QpCiAgICAobWVtYmVyICJtZSIgdGFncy1saXN0KQogICAgKG5vdCAobWVtYmVyICJ0 aGVtIiB0YWdzLWxpc3QpKQogICAgKHN0cmluZz0gKG9yIHByaW9yaXR5ICIiKSAiQSIpCiAgICAo b3JnLXN0cmluZzw+IChvciAoZ2V0LXRleHQtcHJvcGVydHkgKHBvaW50KSAnb3JnLWNhdGVnb3J5 KSAiIikgIm1pc3NpbmciKSkpCiAgKCIreW91K21lLXRoZW0gJiBQUklPUklUWSA8IFwiQVwiIHwg Q0FURUdPUlkgPD4gXCJtaXNzaW5nXCIgKyB1cyB8IEhFQURJTkc9e1xcKD86W1NzXWVjcmV0XFwp e3sxLDN9fX0iCiAgIChvcgogICAgKGFuZAogICAgIChtZW1iZXIgInlvdSIgdGFncy1saXN0KQog ICAgIChtZW1iZXIgIm1lIiB0YWdzLWxpc3QpCiAgICAgKG5vdCAobWVtYmVyICJ0aGVtIiB0YWdz LWxpc3QpKQogICAgIChzdHJpbmc8IChvciBwcmlvcml0eSAiIikgIkEiKSkKICAgIChhbmQKICAg ICAob3JnLXN0cmluZzw+IChvciAoZ2V0LXRleHQtcHJvcGVydHkgKHBvaW50KSAnb3JnLWNhdGVn b3J5KSAiIikKICAgICAgICAgICAgICAgICAgICJtaXNzaW5nIikKICAgICAobWVtYmVyICJ1cyIg dGFncy1saXN0KSkKICAgIChvcmctc3RyaW5nLW1hdGNoPSAob3IgaGVhZGluZyAiIikgIlxcKD86 W1NzXWVjcmV0XFwpezEsM30iKSkpCiAgKCJQUk9QXFwtV0lUSFxcLUhZUEhFTlM9MiIKICAgKD0K ICAgIChzdHJpbmctdG8tbnVtYmVyCiAgICAgKG9yCiAgICAgIChvcmctY2FjaGVkLWVudHJ5LWdl dCBuaWwgIlBST1AtV0lUSC1IWVBIRU5TIikKICAgICAgIiIpKQogICAgMikpCiAgKCJQUk9QPXte XFxzLSovLyAuKiR9IgogICAob3JnLXN0cmluZy1tYXRjaD0KICAgIChvciAob3JnLWNhY2hlZC1l bnRyeS1nZXQgbmlsICJQUk9QIikgIiIpCiAgICAiXlxccy0qLy8gLiokIikpCiAgKCJ3b3JrLVRP RE89XCJXQUlUSU5HXCJ8aG9tZSZUT0RPPVwiV0FJVElOR1wiLyEiIAogICAoYW5kCiAgICAobWVt YmVyIHRvZG8gb3JnLW5vdC1kb25lLWtleXdvcmRzKQogICAgKHByb2duCiAgICAgIChzZXRxIG9y Zy1jYWNoZWQtcHJvcHMgbmlsKQogICAgICAob3IKICAgICAgIChhbmQKICAgICAgICAobWVtYmVy ICJ3b3JrIiB0YWdzLWxpc3QpCiAgICAgICAgKG5vdCAoc3RyaW5nPSAob3IgdG9kbyAiIikgIldB SVRJTkciKSkpCiAgICAgICAoYW5kCiAgICAgICAgKG1lbWJlciAiaG9tZSIgdGFncy1saXN0KQog ICAgICAgIChzdHJpbmc9IChvciB0b2RvICIiKSAiV0FJVElORyIpKSkpKSkKICApCgoodGFnLXRl c3Qtc3VpdGUgc2hvdWxkLWVycm9yLTEKICAoIigpIiAuIGVycm9yKSA7IHdlIG1pZ2h0IGp1c3Qg ZG8gdCBoZXJlLCBidXQgdGhlIHBhcmVucyBzdWdnZXN0IGFuIGVycm9yCiAgKCIoJmZvbytMRVZF TD0xKSIgLiBlcnJvcikKICAoIihmb28rTEVWRUw9MSIgLiBlcnJvcikKICAoIihmb28rTEVWRUw9 MSkpIiAuIGVycm9yKQogICgiKGFiYyspIiAuIGVycm9yKQogICgiYWJjK3h5eiEiIC4gZXJyb3Ip CiAgKCIobWlzc2luZytwYXJlbiIgLiBlcnJvcikgICAgICAgICAgICAKICAoIlBST1A9ey4qY2xv c2luZyBicmFjZT8iIC4gZXJyb3IpIAogICgiUFJPUD1cImFiYyIgLiBlcnJvcikKICAoIlA8PDIt YmFkK2NtcCtvcCIgLiBlcnJvcikKICAoIlA8PXteZm9vfSIgLiBlcnJvcikKICAoIlBST1A8LS5k eCIgLiBlcnJvcikgICAgICAgICAgIDsgYmFkIG51bWJlcgogICgiIT87IiAuIGVycm9yKQogICgi ICAgW3hdIiAuIGVycm9yKQogICgiKGZvbytiYXIvVE9ETyIgLiBlcnJvcikKICAoIihmb28rYmFy KSsvVE9ETyIgLiBlcnJvcikKICAoImZvbytiYXIvIVRPRE98e0FDIiAuIGVycm9yKQogICgiKCgo Zm9vKSkpKS9UT0RPIiAuIGVycm9yKQogICgiZm9vKyIgLiBlcnJvcikKICAoImZvby9UT0RPLSIg LiBlcnJvcikKICApCgo7OzsgTWlzY2VsbGFuZW91cyBPdGhlciB0ZXN0cyAtLSByZWFsbHkgbmVl ZCBhIGNvbXBsZXRlIGZyYW1ld29yayBoZXJlLgoKKGRlZnVuIHRhZy10ZXN0LWZpbmQtdG9kby1x dWVyeSAocykKICAoaWYgKG9yZy1maW5kLXRvZG8tcXVlcnkgcykKICAgICAgKHZlY3RvciAoc3Vi c3RyaW5nIHMgMCAobWF0Y2gtYmVnaW5uaW5nIDEpKQogICAgICAgICAgICAgIChzdWJzdHJpbmcg cyAobWF0Y2gtZW5kIDEpKQogICAgICAgICAgICAgIChtYXRjaC1lbmQgMikKICAgICAgICAgICAg ICAoPSAobWF0Y2gtZW5kIDApIChtYXRjaC1lbmQgMSkpKQogICAgKHZlY3RvciBzIG5pbCBuaWwg bmlsKSkpCgooZGVmdW4gdGFnLXRlc3QtYXBwcm94aW1hdGUtdG9kby1jaGVjayAocykKICAoaWYg KHN0cmluZy1tYXRjaCAiXFwoL1xcKCFcXCk/XFxzLSpcXClbXnt9XCJdKiQiIHMpCiAgICAgICh2 ZWN0b3IgKHN1YnN0cmluZyBzIDAgKG1hdGNoLWJlZ2lubmluZyAxKSkKICAgICAgICAgICAgICAo c3Vic3RyaW5nIHMgKG1hdGNoLWVuZCAxKSkKICAgICAgICAgICAgICAobWF0Y2gtZW5kIDIpCiAg ICAgICAgICAgICAgKD0gKG1hdGNoLWVuZCAwKSAobWF0Y2gtZW5kIDEpKSkKICAgICh2ZWN0b3Ig cyBuaWwgbmlsIG5pbCkpKQoKKGRlZnVuIHRxcyAocSkKICAobGV0ICgodG9kby1vbmx5IG5pbCkp CiAgICAoY2RyIChvcmctbWFrZS10YWdzLW1hdGNoZXItTkVXIHEpKSkpCgooZGVmdW4gdGFnLXRl c3Qtc2NhbiAocyBwb2ludC1saXN0ICZvcHRpb25hbCBzdGF5LXB1dCkKICAocHJvZzEKICAgICAg KGlmIChhdG9tIHBvaW50LWxpc3QpCiAgICAgICAgICAob3JnLXNjYW4tdGFncy1ORVcgJ3BvaW50 ICh0cXMgcykgbmlsKQogICAgICAgIChjb25zIChlcXVhbCAob3JnLXNjYW4tdGFncy1ORVcgJ3Bv aW50ICh0cXMgcykgbmlsKSBwb2ludC1saXN0KSBzKSkKICAgICh1bmxlc3Mgc3RheS1wdXQKICAg ICAgKGdvdG8tY2hhciAocG9pbnQtbWluKSkpKSkKCihkZWZ1biB0YWctdGVzdC1zY2FuLWRvLXRl c3RzICh0ZXN0cykKICAobGV0ICgoY29udGVudHMKICAgICAgICAgIiogWyNCXSBBIGhlYWRpbmcg T25lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IDp4eXo6CioqIFB1dCBhIE9uZSBoZXJlIHRvbyBhdCBsZXZlbCBUd28KKioqIEFuZCBhIGxldmVs IFRocmVlLCBhbHNvIE9uZSAgIAoqIFsjQ10gQiBoZWFkaW5nIFR3byAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6dXZ3OgoqKiBBbm90aGVyICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICA6YWJjOgoqIFsjQV0gQyBoZWFkaW5nIFRocmVlICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6eHl6OgoqIDxOT1RFUz4gICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6d3Rm OgoqKiBNb3JlIG1vcmUgbW9yZQoqKiogVE9ETyBPbndhcmQKKioqIFRPRE8gVXB3YXJkCioqKiBX QVRUIFdoYXQgY29tZXMgdXAuLi4KKioqIERPTkUgR2xpZGluZyBob21lCioqKiogSnVzdCBhIHRl c3QgICAgCiogWyNBXSBEIGhlYWRpbmcgRm91ciAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIDp1dnc6CiogVE9ETyBFIGhlYWRpbmcgRml2ZSAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6YWJjOnV2dzp4eXo6CiAg U0NIRURVTEVEOiA8MjAxMi0wNy0zMSBUdWU+CioqIEFuc3dlcnMKICAgKyB4eXo6IDEgMzE0IDY3 NgogICArIHh5ei1hYmM6IDEgMzE0ICAKICAgKyBQcmlvcml0eSBBOiAzMTQgNTk1CiAgICsgUHJp b3JpdHkgbm90IGVtcHR5OiAxIDE1MiAzMTQgNTk1CiAgICsgUHJpb3JpdHkgZW1wdHksIExldmVs IDE6IDM5NSA2NzYKICAgKyBTY2hlZHVsZWQgYWZ0ZXIgPDIwMTItMDctMDEgMDA6MDA+OiA2NzYK ICAgKyBUT0RPPVwiVE9ET1wiOiA0OTQgNTEwIDY3NgogICArIFRPRE89XCJUT0RPXCIsIExldmVs PjE6IDQ5NCA1MTAKICAgKyBIRUFESU5HPXs8Lio+fTogMzk1CiAgICsgSEVBRElORz17T25lXFx8 VHdvfSwgTGV2ZWwgPD0gMjogMSA4MiAxNTIKIikpCiAgICAod2l0aC10ZW1wLWJ1ZmZlcgogICAg ICAoc2V0IChtYWtlLWxvY2FsLXZhcmlhYmxlICdvcmctdGFncy1jb2x1bW4pIC04MCkKICAgICAg KG9yZy1tb2RlKQogICAgICAoaW5zZXJ0IGNvbnRlbnRzKQogICAgICAoZ290by1jaGFyIChwb2lu dC1taW4pKQogICAgICAobWFwY2FyCiAgICAgICAobGFtYmRhICh2KSAodGFnLXRlc3Qtc2NhbiAo Y2FyIHYpIChjZHIgdikpKQogICAgICAgdGVzdHMpKSkpCgooZGVmdW4gdGFnLXRlc3Qtb3RoZXIt dGVzdHMgKCkKICAobGlzdAogICA7OyBUZXN0aW5nIHRoZSBvcmctZmluZC10b2RvLXF1ZXJ5IGZ1 bmN0aW9uCiAgIChtYXBjYXIKICAgIChsYW1iZGEgKHMtYSkKICAgICAgKGNvbnMKICAgICAgIChl cXVhbCAodGFnLXRlc3QtZmluZC10b2RvLXF1ZXJ5IChjYXIgcy1hKSkgKGNhZHIgcy1hKSkKICAg ICAgIChjYXIgcy1hKSkpIAogICAgJygoImZvbytiYXIvQS1CK0MiICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBbImZvbytiYXIiICJBLUIrQyIgbmlsIG5pbF0pCiAgICAgICgiZm9vK2Jhci8i ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiZm9vK2JhciIgIiIgbmlsIHRdKQog ICAgICAoImZvbytiYXIvICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICBbImZvbyti YXIiICIiIG5pbCB0XSkKICAgICAgKCJmb28rYmFyLyAgICAgICAgIGEiICAgICAgICAgICAgICAg ICAgICAgICAgWyJmb28rYmFyIiAiYSIgbmlsIG5pbF0pCiAgICAgICgiZm9vK2Jhci8hQS1CK0Mi ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiZm9vK2JhciIgIkEtQitDIiA5IG5pbF0pCiAg ICAgICgiZm9vK2Jhci8hIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiZm9vK2Jh ciIgIiIgOSB0XSkKICAgICAgKCJmb28rYmFyLyEgICAgICAgICAiICAgICAgICAgICAgICAgICAg ICAgICAgWyJmb28rYmFyIiAiIiA5IHRdKQogICAgICAoImZvbytiYXIvISAgICAgICAgIGEiICAg ICAgICAgICAgICAgICAgICAgICBbImZvbytiYXIiICJhIiA5IG5pbF0pCiAgICAgICgiUFJPUD17 Xlxccy0qLy8gLiokfSIgICAgICAgICAgICAgICAgICAgICAgIFsiUFJPUD17Xlxccy0qLy8gLiok fSIgbmlsIG5pbCBuaWxdKQogICAgICAoIlBST1A9e15cXHMtKi8vIC4qJH0rQT1cIi8hQS1CXCIv IUEtQiIgICAgICBbIlBST1A9e15cXHMtKi8vIC4qJH0rQT1cIi8hQS1CXCIiICJBLUIiIDMwIG5p bF0pCiAgICAgICgiUFJPUD17Xlxccy0qLy8gLiokfStBPVwiLyFBLUJcIi8hICAgICAgICAiIFsi UFJPUD17Xlxccy0qLy8gLiokfStBPVwiLyFBLUJcIiIgIiIgMzAgdF0pKSkKICAgOzsgVGVzdGlu ZyB0aGF0IHRoZSB0b2RvIHF1ZXJpZXMgd29yayB3aXRoIHRoZSBleGlzdGluZyBzdHJpbmctbWF0 Y2gKICAgKG1hcGNhcgogICAgKGxhbWJkYSAocy1hKQogICAgICAoY29ucwogICAgICAgKGVxdWFs ICh0YWctdGVzdC1hcHByb3hpbWF0ZS10b2RvLWNoZWNrIChjYXIgcy1hKSkgKGNhZHIgcy1hKSkK ICAgICAgIChjYXIgcy1hKSkpIAogICAgJygoImZvbytiYXIvQS1CK0MiICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBbImZvbytiYXIiICJBLUIrQyIgbmlsIG5pbF0pCiAgICAgICgiZm9vK2Jh ci8iICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiZm9vK2JhciIgIiIgbmlsIHRd KQogICAgICAoImZvbytiYXIvICAgICAgICAgIiAgICAgICAgICAgICAgICAgICAgICAgICBbImZv bytiYXIiICIiIG5pbCB0XSkKICAgICAgKCJmb28rYmFyLyAgICAgICAgIGEiICAgICAgICAgICAg ICAgICAgICAgICAgWyJmb28rYmFyIiAiYSIgbmlsIG5pbF0pCiAgICAgICgiZm9vK2Jhci8hQS1C K0MiICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiZm9vK2JhciIgIkEtQitDIiA5IG5pbF0p CiAgICAgICgiZm9vK2Jhci8hIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiZm9v K2JhciIgIiIgOSB0XSkKICAgICAgKCJmb28rYmFyLyEgICAgICAgICAiICAgICAgICAgICAgICAg ICAgICAgICAgWyJmb28rYmFyIiAiIiA5IHRdKQogICAgICAoImZvbytiYXIvISAgICAgICAgIGEi ICAgICAgICAgICAgICAgICAgICAgICBbImZvbytiYXIiICJhIiA5IG5pbF0pCiAgICAgICgiUFJP UD17Xlxccy0qLy8gLiokfSIgICAgICAgICAgICAgICAgICAgICAgIFsiUFJPUD17Xlxccy0qLy8g LiokfSIgbmlsIG5pbCBuaWxdKQogICAgICAoIlBST1A9e15cXHMtKi8vIC4qJH0rQT1cIi8hQS1C XCIvIUEtQiIgICAgICBbIlBST1A9e15cXHMtKi8vIC4qJH0rQT1cIi8hQS1CXCIiICJBLUIiIDMw IG5pbF0pCiAgICAgICgiUFJPUD17Xlxccy0qLy8gLiokfStBPVwiLyFBLUJcIi8hICAgICAgICAi IFsiUFJPUD17Xlxccy0qLy8gLiokfStBPVwiLyFBLUJcIiIgIiIgMzAgdF0pKSkKICAgOzsgVGVz dGluZyB0aGF0IHRoZSBtYXRjaGVycyB3b3JrIHdpdGggb3JnLXNjYW4tdGFncwogICAobGV0ICgo c2Nhbi10ZXN0cyAnKCgieHl6K0xFVkVMPTEiIDEgMzE0IDY3NikKICAgICAgICAgICAgICAgICAg ICAgICAoInh5ei1hYmMrTEVWRUw9MSIgMSAzMTQpCiAgICAgICAgICAgICAgICAgICAgICAgKCJ4 eXoiIDEgODIgMTE3IDMxNCA2NzYgNzg3KQogICAgICAgICAgICAgICAgICAgICAgICgieHl6LWFi YyIgMSA4MiAxMTcgMzE0KQogICAgICAgICAgICAgICAgICAgICAgICgiSEVBRElORz17PC4qPn0i IDM5NSkKICAgICAgICAgICAgICAgICAgICAgICAoIkhFQURJTkc9e09uZVxcfFR3b30gJiBMRVZF TCA8PSAyIiAxIDgyIDE1MikKICAgICAgICAgICAgICAgICAgICAgICAoIlBSSU9SSVRZPVwiQVwi IiAzMTQgNTk1KQogICAgICAgICAgICAgICAgICAgICAgICgiUFJJT1JJVFk8PlwiXCIiIDEgMTUy IDMxNCA1OTUpCiAgICAgICAgICAgICAgICAgICAgICAgKCJQUklPUklUWT1cIlwiICsgTEVWRUwg PT0gMSIgMzk1IDY3NikKICAgICAgICAgICAgICAgICAgICAgICAoIlNDSEVEVUxFRD49XCI8MjAx Mi0wNy0wMSAwMDowMD5cIiIgNjc2KQogICAgICAgICAgICAgICAgICAgICAgICgiVE9ETz1cIlRP RE9cIiIgNDk0IDUxMCA2NzYpCiAgICAgICAgICAgICAgICAgICAgICAgKCJUT0RPPVwiVE9ET1wi ICAmIExFVkVMID4gMSIgNDk0IDUxMCkpKSkKICAgICAodGFnLXRlc3Qtc2Nhbi1kby10ZXN0cyBz Y2FuLXRlc3RzKSkpKQoK --047d7b2e4f6e94631804c674df38--