<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>75901</bug_id>
          
          <creation_ts>2012-01-09 16:07:48 -0800</creation_ts>
          <short_desc>Improve keyboard navigation in layout test results</short_desc>
          <delta_ts>2012-01-10 14:38:34 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>Tools / Tests</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Simon Fraser (smfr)">simon.fraser</reporter>
          <assigned_to name="Simon Fraser (smfr)">simon.fraser</assigned_to>
          <cc>dglazkov</cc>
    
    <cc>ojan</cc>
    
    <cc>simon.fraser</cc>
    
    <cc>webkit.review.bot</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>532605</commentid>
    <comment_count>0</comment_count>
    <who name="Simon Fraser (smfr)">simon.fraser</who>
    <bug_when>2012-01-09 16:07:48 -0800</bug_when>
    <thetext>results.html needs some key handling to make test navigation more usable. I plan to add:

i/j/k/l for navigating the list
e/c/t for expand/collapse/toggle current test
some key to &quot;flag&quot; the current test
some way to copy out flagged tests</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>532620</commentid>
    <comment_count>1</comment_count>
    <who name="Ojan Vafai">ojan</who>
    <bug_when>2012-01-09 16:19:22 -0800</bug_when>
    <thetext>Sounds great!</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>532749</commentid>
    <comment_count>2</comment_count>
      <attachid>121777</attachid>
    <who name="Simon Fraser (smfr)">simon.fraser</who>
    <bug_when>2012-01-09 18:22:11 -0800</bug_when>
    <thetext>Created attachment 121777
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>532767</commentid>
    <comment_count>3</comment_count>
      <attachid>121777</attachid>
    <who name="WebKit Review Bot">webkit.review.bot</who>
    <bug_when>2012-01-09 19:03:33 -0800</bug_when>
    <thetext>Comment on attachment 121777
Patch

Attachment 121777 did not pass chromium-ews (chromium-xvfb):
Output: http://queues.webkit.org/results/11183730

New failing tests:
fast/harness/results.html</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>532786</commentid>
    <comment_count>4</comment_count>
      <attachid>121777</attachid>
    <who name="Ojan Vafai">ojan</who>
    <bug_when>2012-01-09 20:10:23 -0800</bug_when>
    <thetext>Comment on attachment 121777
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=121777&amp;action=review

This looks great. I have a bunch of cleanup nits. Feel free to not do any that you disagree with.

&gt; LayoutTests/fast/harness/results.html:190
&gt; +#flagged-tests {
&gt; +    padding: 5px;
&gt; +}

Should this be position:fixed to the bottom of the window? I can&apos;t decide if that would be nice or annoying. :)

&gt; LayoutTests/fast/harness/results.html:942
&gt; +TestNavigator.scrollToFirstTest = function()

Can you make all the properties/methods on TestNavigator except handleKeyEvent &quot;private&quot; (i.e. prefix with an underscore)?

&gt; LayoutTests/fast/harness/results.html:945
&gt; +    if (this.setCurrentTest(0))
&gt; +        this.scrollToCurrentTest();

Here and below, I&apos;d s/this/TestNavigator. While this code does work correctly, I find it confusing when &quot;this&quot; doesn&apos;t point to an instance of a class (i.e. something that was new&apos;ed).

This way, TestNavigator essentially just acts as a namespace.

&gt; LayoutTests/fast/harness/results.html:970
&gt; +    var links = visibleExpandLinks();
&gt; +    return links[this.currentTestIndex];

You could implement this as &quot;return document.querySelector(&apos;.current .expand-button-text&apos;)&quot;.

&gt; LayoutTests/fast/harness/results.html:1014
&gt; +        var label = document.createElement(&apos;h2&apos;);
&gt; +        label.innerText = &apos;Flagged Tests&apos;;
&gt; +        flaggedTestContainer.appendChild(label);
&gt; +        
&gt; +        flaggedTestTextbox = document.createElement(&apos;div&apos;);
&gt; +        flaggedTestTextbox.id = &apos;flagged-tests&apos;;
&gt; +        flaggedTestTextbox.setAttribute(&apos;contentEditable&apos;, &apos;&apos;);
&gt; +        
&gt; +        flaggedTestContainer.appendChild(flaggedTestTextbox);

It&apos;s your call, but I would prefer this to just use innerHTML since it&apos;s more concise and readable:
flaggedTestContainer.innerHTML = &apos;&lt;h2&gt;Flagged Tests&lt;/h2&gt;&lt;div id=&quot;flagged-tests&quot; contentEditable&gt;&lt;/div&gt;&apos;;
flaggedTestTextbox = document.getElementById(&apos;flagged-tests&apos;);

&gt; LayoutTests/fast/harness/results.html:1020
&gt; +    var flaggedTests = [];
&gt; +    for (var test in this.flaggedTests)
&gt; +        flaggedTests.push(test);

var flaggedTests = Object.keys(this.flaggedTests);

&gt; LayoutTests/fast/harness/results.html:1026
&gt; +TestNavigator.setCurrentTest = function(testIndex)

May as well call scrollToCurrentTest at the end of setCurrentTest since you always call it if you return true. Also, then setCurrentTest doesn&apos;t need a return value.

&gt; LayoutTests/fast/harness/results.html:1039
&gt; +    var currExpandButton = links[this.currentTestIndex];
&gt; +    if (currExpandButton)
&gt; +        currExpandButton.parentNode.classList.remove(&apos;current&apos;);
&gt; +
&gt; +    this.currentTestIndex = testIndex;
&gt; +
&gt; +    var currExpandButton = links[this.currentTestIndex];
&gt; +    currExpandButton.parentNode.classList.add(&apos;current&apos;);

Nit: s/currExpandButton/currExpandLink/

Feel free to ignore this, but instead of maintaining currentTestIndex manually, you could rely on the fact that you&apos;re already adding/removing the appropriate class.

So, this could be implemented as:
var currExpandButton = document.querySelector(&apos;.current&apos;);
if (currExpandButton)
    currExpandButton.classList.remove(&apos;current&apos;);
links[testIndex].parentNode.classList.add(&apos;current&apos;);

The only place you really need currentTestIndex is when you&apos;re moving to the next/previous test. In that case, you can retrieve the index as:
function currentTestIndex() {
    var current = document.querySelector(&apos;.current&apos;);
    return Array.prototype.indexOf.call(visibleExpandLinks(), current);
}

&gt; LayoutTests/fast/harness/results.html:1046
&gt; +    var failedResultsTable = document.getElementById(&apos;results-table&apos;);

Dead code.

&gt; LayoutTests/fast/harness/results.html:1047
&gt; +    // Use visibleExpandLinks because it&apos;s already smart about expected failures.

In updateExpectedFailures(), we should probably just clear &quot;current&quot; if appropriate. Shouldn&apos;t be too hard:

if (onlyShowUnexpectedFailures() &amp;&amp; parentOfType(TestNavigator.currentTestLink(), &apos;tbody&apos;).classList.contains(&apos;expected&apos;))
  TestNavigator.currentTestLink().classList.remove(&apos;current&apos;);

&gt; LayoutTests/fast/harness/results.html:1053
&gt; +    var links = visibleExpandLinks();
&gt; +    var testIndex = this.currentTestIndex;
&gt; +    if (testIndex &lt; 0 || testIndex &gt;= links.length)
&gt; +        return;
&gt; +    
&gt; +    var targetLink = links[testIndex];

You could implement this as:
var targetLink = this.currentTestLink();
if (!targetLink)
    return;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>533215</commentid>
    <comment_count>5</comment_count>
    <who name="Simon Fraser (smfr)">simon.fraser</who>
    <bug_when>2012-01-10 11:12:17 -0800</bug_when>
    <thetext>(In reply to comment #4)
&gt; (From update of attachment 121777 [details])
&gt; View in context: https://bugs.webkit.org/attachment.cgi?id=121777&amp;action=review
&gt; 
&gt; This looks great. I have a bunch of cleanup nits. Feel free to not do any that you disagree with.
&gt; 
&gt; &gt; LayoutTests/fast/harness/results.html:190
&gt; &gt; +#flagged-tests {
&gt; &gt; +    padding: 5px;
&gt; &gt; +}
&gt; 
&gt; Should this be position:fixed to the bottom of the window? I can&apos;t decide if that would be nice or annoying. :)

Super annoying, it can get big.

&gt; &gt; LayoutTests/fast/harness/results.html:942
&gt; &gt; +TestNavigator.scrollToFirstTest = function()
&gt; 
&gt; Can you make all the properties/methods on TestNavigator except handleKeyEvent &quot;private&quot; (i.e. prefix with an underscore)?

Done.

&gt; &gt; LayoutTests/fast/harness/results.html:945
&gt; &gt; +    if (this.setCurrentTest(0))
&gt; &gt; +        this.scrollToCurrentTest();
&gt; 
&gt; Here and below, I&apos;d s/this/TestNavigator. While this code does work correctly, I find it confusing when &quot;this&quot; doesn&apos;t point to an instance of a class (i.e. something that was new&apos;ed).
&gt; 
&gt; This way, TestNavigator essentially just acts as a namespace.

OK. Not really keen on this because if we ever want &gt; 1 TestNavigator I&apos;d have to change it back. That seems unlikely though.

&gt; &gt; LayoutTests/fast/harness/results.html:970
&gt; &gt; +    var links = visibleExpandLinks();
&gt; &gt; +    return links[this.currentTestIndex];
&gt; 
&gt; You could implement this as &quot;return document.querySelector(&apos;.current .expand-button-text&apos;)&quot;.

I could, but I&apos;d rather use the same source of links everywhere.

&gt; &gt; LayoutTests/fast/harness/results.html:1014
&gt; &gt; +        var label = document.createElement(&apos;h2&apos;);
&gt; &gt; +        label.innerText = &apos;Flagged Tests&apos;;
&gt; &gt; +        flaggedTestContainer.appendChild(label);
&gt; &gt; +        
&gt; &gt; +        flaggedTestTextbox = document.createElement(&apos;div&apos;);
&gt; &gt; +        flaggedTestTextbox.id = &apos;flagged-tests&apos;;
&gt; &gt; +        flaggedTestTextbox.setAttribute(&apos;contentEditable&apos;, &apos;&apos;);
&gt; &gt; +        
&gt; &gt; +        flaggedTestContainer.appendChild(flaggedTestTextbox);
&gt; 
&gt; It&apos;s your call, but I would prefer this to just use innerHTML since it&apos;s more concise and readable:
&gt; flaggedTestContainer.innerHTML = &apos;&lt;h2&gt;Flagged Tests&lt;/h2&gt;&lt;div id=&quot;flagged-tests&quot; contentEditable&gt;&lt;/div&gt;&apos;;
&gt; flaggedTestTextbox = document.getElementById(&apos;flagged-tests&apos;);

Done.

&gt; &gt; LayoutTests/fast/harness/results.html:1020
&gt; &gt; +    var flaggedTests = [];
&gt; &gt; +    for (var test in this.flaggedTests)
&gt; &gt; +        flaggedTests.push(test);
&gt; 
&gt; var flaggedTests = Object.keys(this.flaggedTests);

I was looking for a way to do that!

&gt; &gt; LayoutTests/fast/harness/results.html:1026
&gt; &gt; +TestNavigator.setCurrentTest = function(testIndex)
&gt; 
&gt; May as well call scrollToCurrentTest at the end of setCurrentTest since you always call it if you return true. Also, then setCurrentTest doesn&apos;t need a return value.

I want to keep them separate.

&gt; &gt; LayoutTests/fast/harness/results.html:1039
&gt; &gt; +    var currExpandButton = links[this.currentTestIndex];
&gt; &gt; +    if (currExpandButton)
&gt; &gt; +        currExpandButton.parentNode.classList.remove(&apos;current&apos;);
&gt; &gt; +
&gt; &gt; +    this.currentTestIndex = testIndex;
&gt; &gt; +
&gt; &gt; +    var currExpandButton = links[this.currentTestIndex];
&gt; &gt; +    currExpandButton.parentNode.classList.add(&apos;current&apos;);
&gt; 
&gt; Nit: s/currExpandButton/currExpandLink/
&gt; 
&gt; Feel free to ignore this, but instead of maintaining currentTestIndex manually, you could rely on the fact that you&apos;re already adding/removing the appropriate class.
&gt; 
&gt; So, this could be implemented as:
&gt; var currExpandButton = document.querySelector(&apos;.current&apos;);
&gt; if (currExpandButton)
&gt;     currExpandButton.classList.remove(&apos;current&apos;);
&gt; links[testIndex].parentNode.classList.add(&apos;current&apos;);
&gt; 
&gt; The only place you really need currentTestIndex is when you&apos;re moving to the next/previous test. In that case, you can retrieve the index as:
&gt; function currentTestIndex() {
&gt;     var current = document.querySelector(&apos;.current&apos;);
&gt;     return Array.prototype.indexOf.call(visibleExpandLinks(), current);
&gt; }

I didn&apos;t want to run a querySelector() every time I access currentTestIndex.

&gt; &gt; LayoutTests/fast/harness/results.html:1046
&gt; &gt; +    var failedResultsTable = document.getElementById(&apos;results-table&apos;);
&gt; 
&gt; Dead code.

Removed.

&gt; &gt; LayoutTests/fast/harness/results.html:1047
&gt; &gt; +    // Use visibleExpandLinks because it&apos;s already smart about expected failures.
&gt; 
&gt; In updateExpectedFailures(), we should probably just clear &quot;current&quot; if appropriate. Shouldn&apos;t be too hard:
&gt; 
&gt; if (onlyShowUnexpectedFailures() &amp;&amp; parentOfType(TestNavigator.currentTestLink(), &apos;tbody&apos;).classList.contains(&apos;expected&apos;))
&gt;   TestNavigator.currentTestLink().classList.remove(&apos;current&apos;);

Holy encapsulation violation batman! I fixed this a cleaner way.

&gt; &gt; LayoutTests/fast/harness/results.html:1053
&gt; &gt; +    var links = visibleExpandLinks();
&gt; &gt; +    var testIndex = this.currentTestIndex;
&gt; &gt; +    if (testIndex &lt; 0 || testIndex &gt;= links.length)
&gt; &gt; +        return;
&gt; &gt; +    
&gt; &gt; +    var targetLink = links[testIndex];
&gt; 
&gt; You could implement this as:
&gt; var targetLink = this.currentTestLink();
&gt; if (!targetLink)
&gt;     return;

Fixed.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>533246</commentid>
    <comment_count>6</comment_count>
    <who name="Simon Fraser (smfr)">simon.fraser</who>
    <bug_when>2012-01-10 11:43:50 -0800</bug_when>
    <thetext>http://trac.webkit.org/changeset/104606</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>533280</commentid>
    <comment_count>7</comment_count>
    <who name="Ojan Vafai">ojan</who>
    <bug_when>2012-01-10 12:05:39 -0800</bug_when>
    <thetext>(In reply to comment #5)
&gt; (In reply to comment #4)
&gt; &gt; (From update of attachment 121777 [details] [details])
&gt; &gt; View in context: https://bugs.webkit.org/attachment.cgi?id=121777&amp;action=review
&gt; &gt; 
&gt; &gt; &gt; LayoutTests/fast/harness/results.html:1047
&gt; &gt; &gt; +    // Use visibleExpandLinks because it&apos;s already smart about expected failures.
&gt; &gt; 
&gt; &gt; In updateExpectedFailures(), we should probably just clear &quot;current&quot; if appropriate. Shouldn&apos;t be too hard:
&gt; &gt; 
&gt; &gt; if (onlyShowUnexpectedFailures() &amp;&amp; parentOfType(TestNavigator.currentTestLink(), &apos;tbody&apos;).classList.contains(&apos;expected&apos;))
&gt; &gt;   TestNavigator.currentTestLink().classList.remove(&apos;current&apos;);
&gt; 
&gt; Holy encapsulation violation batman! I fixed this a cleaner way.

Lol. Yeah, I was a bit rushed as I was finishing this review. FYI, you accidentally left in this code commented out in the final checkin.

Thanks for adding all this! I&apos;m eager to try it out.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>533282</commentid>
    <comment_count>8</comment_count>
    <who name="Ojan Vafai">ojan</who>
    <bug_when>2012-01-10 12:08:34 -0800</bug_when>
    <thetext>Also, this just occurred to me, should we add a legend or something so this is a bit more discoverable? I already find myself forgetting the key commands each time.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>533393</commentid>
    <comment_count>9</comment_count>
    <who name="Simon Fraser (smfr)">simon.fraser</who>
    <bug_when>2012-01-10 14:38:34 -0800</bug_when>
    <thetext>There is a legend.</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>121777</attachid>
            <date>2012-01-09 18:22:11 -0800</date>
            <delta_ts>2012-01-09 20:10:23 -0800</delta_ts>
            <desc>Patch</desc>
            <filename>bug-75901-20120109182211.patch</filename>
            <type>text/plain</type>
            <size>15058</size>
            <attacher name="Simon Fraser (smfr)">simon.fraser</attacher>
            
              <data encoding="base64">U3VidmVyc2lvbiBSZXZpc2lvbjogMTA0NDYyCmRpZmYgLS1naXQgYS9MYXlvdXRUZXN0cy9DaGFu
Z2VMb2cgYi9MYXlvdXRUZXN0cy9DaGFuZ2VMb2cKaW5kZXggN2JiNGJhZjAwMWNiNmM4ZDZhYzkz
OTJmOTc0MTc1NTAzYjUwMmRiYy4uYTJkY2I0YzZmYTY1ZDgzYzBhNDA5ZTJhM2UzMjUxNzY3ZjAw
YzM3OSAxMDA2NDQKLS0tIGEvTGF5b3V0VGVzdHMvQ2hhbmdlTG9nCisrKyBiL0xheW91dFRlc3Rz
L0NoYW5nZUxvZwpAQCAtMSwzICsxLDI3IEBACisyMDEyLTAxLTA5ICBTaW1vbiBGcmFzZXIgIDxz
aW1vbi5mcmFzZXJAYXBwbGUuY29tPgorCisgICAgICAgIEltcHJvdmUga2V5Ym9hcmQgbmF2aWdh
dGlvbiBpbiBsYXlvdXQgdGVzdCByZXN1bHRzCisgICAgICAgIGh0dHBzOi8vYnVncy53ZWJraXQu
b3JnL3Nob3dfYnVnLmNnaT9pZD03NTkwMQorCisgICAgICAgIFJldmlld2VkIGJ5IE5PQk9EWSAo
T09QUyEpLgorICAgICAgICAKKyAgICAgICAgQWRkIHN1cHBvcnQgZm9yIGtleWJvYXJkIHNob3J0
Y3V0cyBmb3IgbmF2aWdhdGluZyB0aGUgbGlzdCBvZiB0ZXN0cywKKyAgICAgICAgYW5kIGZvciBm
bGFnZ2luZyB0ZXN0cy4KKyAgICAgICAgCisgICAgICAgICdpJywgJ2snLCAnaycsIGFuZCAnbCcg
Z28gZm93YXJkLCBiYWNrLCB0byBmaXJzdCBhbmQgdG8gbGFzdCwgZGVub3RpbmcKKyAgICAgICAg
dGhlIGN1cnJlbnQgdGVzdCB3aXRoIGEgcmVkIGV4cGFuZCBpbmRpY2F0b3IuCisgICAgICAgIAor
ICAgICAgICAnZScsICdjJyBhbmQgJ3QnIGV4cGFuZCwgY29sbGFwc2UgYW5kIHRvZ2dsZSB0aGUg
Y3VycmVudCB0ZXN0LgorICAgICAgICAKKyAgICAgICAgJ2YnIHRvZ2dsZWQgYSB0ZXN0IGFzICJm
bGFnZ2VkIiwgd2hpY2ggYWRkcyBpdCB0byBhIGNvcHlhYmxlIGxpc3QKKyAgICAgICAgYXQgdGhl
IGJvdHRvbSBvZiB0aGUgZG9jdW1lbnQuIFRoZSB1c2VyIGNhbiB1c2UgZmxhZ2dpbmcgZm9yIHdo
YXRldmVyIHRoZXkgd2FudC4KKworICAgICAgICAqIGZhc3QvaGFybmVzcy9yZXNvdXJjZXMvcmVz
dWx0cy10ZXN0LmpzOgorICAgICAgICAocnVuVGVzdHMpOgorICAgICAgICAocnVuVGVzdHMuaXND
b2xsYXBzZWQpOgorICAgICAgICAoKToKKyAgICAgICAgKiBmYXN0L2hhcm5lc3MvcmVzdWx0cy5o
dG1sOgorCiAyMDEyLTAxLTA5ICBKb2huIEtub3R0ZW5iZWx0ICA8amtub3R0ZW5AY2hyb21pdW0u
b3JnPgogCiAgICAgICAgIFtDaHJvbWl1bV0gVXBkYXRlIHRlc3QgZXhwZWN0YXRpb25zLgpkaWZm
IC0tZ2l0IGEvTGF5b3V0VGVzdHMvZmFzdC9oYXJuZXNzL3Jlc291cmNlcy9yZXN1bHRzLXRlc3Qu
anMgYi9MYXlvdXRUZXN0cy9mYXN0L2hhcm5lc3MvcmVzb3VyY2VzL3Jlc3VsdHMtdGVzdC5qcwpp
bmRleCBmOWJiMjg3YzhiOTZjZjA4ZWRmOWI1ZTQ4ODFiNmM5NzFkOGE5NDJkLi4yOWE1YmI5MTNl
ODc3ZTEzZmJkMTllM2I0ODI5NzNkZjdlMzNhNjA0IDEwMDY0NAotLS0gYS9MYXlvdXRUZXN0cy9m
YXN0L2hhcm5lc3MvcmVzb3VyY2VzL3Jlc3VsdHMtdGVzdC5qcworKysgYi9MYXlvdXRUZXN0cy9m
YXN0L2hhcm5lc3MvcmVzb3VyY2VzL3Jlc3VsdHMtdGVzdC5qcwpAQCAtMTgxLDYgKzE4MSwxNyBA
QCBmdW5jdGlvbiBydW5UZXN0cygpCiAgICAgICAgIGFzc2VydFRydWUoZG9jdW1lbnQuZ2V0RWxl
bWVudEJ5SWQoJ3RpbWVvdXQtdGVzdHMtdGFibGUnKS50ZXh0Q29udGVudC5pbmRleE9mKCdleHBl
Y3RlZCBhY3R1YWwgZGlmZicpICE9IC0xKTsKICAgICB9KTsKIAorICAgIGZ1bmN0aW9uIGlzRXhw
YW5kZWQoZXhwYW5kTGluaykKKyAgICB7CisgICAgICAgIHZhciBlbkRhc2ggPSAnXHUyMDEzJzsK
KyAgICAgICAgcmV0dXJuIGV4cGFuZExpbmsudGV4dENvbnRlbnQgPT0gZW5EYXNoOworICAgIH0K
KworICAgIGZ1bmN0aW9uIGlzQ29sbGFwc2VkKGV4cGFuZExpbmspCisgICAgeworICAgICAgICBy
ZXR1cm4gZXhwYW5kTGluay50ZXh0Q29udGVudCA9PSAnKyc7CisgICAgfQorCiAgICAgcmVzdWx0
cyA9IG1vY2tSZXN1bHRzKCk7CiAgICAgdmFyIHN1YnRyZWUgPSByZXN1bHRzLnRlc3RzWydmb28n
XSA9IHt9CiAgICAgc3VidHJlZVsnYmFyLmh0bWwnXSA9IG1vY2tFeHBlY3RhdGlvbignVEVYVCcs
ICdQQVNTJyk7CkBAIC0xOTQsMjEgKzIwNSwxOSBAQCBmdW5jdGlvbiBydW5UZXN0cygpCiAgICAg
ICAgIGV4cGFuZEFsbEV4cGVjdGF0aW9ucygpOwogICAgICAgICBhc3NlcnRUcnVlKGRvY3VtZW50
LnF1ZXJ5U2VsZWN0b3JBbGwoJ3Rib2R5IHRyJykubGVuZ3RoID09IDgpOwogICAgICAgICB2YXIg
ZXhwYW5kTGlua3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZXhwYW5kLWJ1dHRvbi10
ZXh0Jyk7Ci0gICAgICAgIHZhciBlbkRhc2ggPSAnXHUyMDEzJzsKLSAgICAgICAgZm9yICh2YXIg
aSA9IDA7IGkgPCBleHBhbmRMaW5rcy5sZW5ndGg7IGkrKykgewotICAgICAgICAgICAgYXNzZXJ0
VHJ1ZShleHBhbmRMaW5rc1tpXS50ZXh0Q29udGVudCA9PSBlbkRhc2gpOwotICAgICAgICB9Cisg
ICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXhwYW5kTGlua3MubGVuZ3RoOyBpKyspCisgICAg
ICAgICAgICBhc3NlcnRUcnVlKGlzRXhwYW5kZWQoZXhwYW5kTGlua3NbaV0pKTsKICAgICAgICAg
CiAgICAgICAgIGNvbGxhcHNlQWxsRXhwZWN0YXRpb25zKCk7CiAgICAgICAgIC8vIENvbGxhcHNl
ZCBleHBlY3RhdGlvbnMgc3RheSBpbiB0aGUgZG9tLCBidXQgYXJlIGRpc3BsYXk6bm9uZS4KICAg
ICAgICAgYXNzZXJ0VHJ1ZShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCd0Ym9keSB0cicpLmxl
bmd0aCA9PSA4KTsKICAgICAgICAgdmFyIGV4cGFuZExpbmtzID0gZG9jdW1lbnQucXVlcnlTZWxl
Y3RvckFsbCgnLmV4cGFuZC1idXR0b24tdGV4dCcpOwogICAgICAgICBmb3IgKHZhciBpID0gMDsg
aSA8IGV4cGFuZExpbmtzLmxlbmd0aDsgaSsrKQotICAgICAgICAgICAgYXNzZXJ0VHJ1ZShleHBh
bmRMaW5rc1tpXS50ZXh0Q29udGVudCA9PSAnKycpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShp
c0NvbGxhcHNlZChleHBhbmRMaW5rc1tpXSkpOwogICAgICAgICAgICAgCiAgICAgICAgIGV4cGFu
ZEV4cGVjdGF0aW9ucyhleHBhbmRMaW5rc1sxXSk7Ci0gICAgICAgIGFzc2VydFRydWUoZXhwYW5k
TGlua3NbMF0udGV4dENvbnRlbnQgPT0gJysnKTsKLSAgICAgICAgYXNzZXJ0VHJ1ZShleHBhbmRM
aW5rc1sxXS50ZXh0Q29udGVudCA9PSBlbkRhc2gpOworICAgICAgICBhc3NlcnRUcnVlKGlzQ29s
bGFwc2VkKGV4cGFuZExpbmtzWzBdKSk7CisgICAgICAgIGFzc2VydFRydWUoaXNFeHBhbmRlZChl
eHBhbmRMaW5rc1sxXSkpOwogCiAgICAgICAgIGNvbGxhcHNlRXhwZWN0YXRpb25zKGV4cGFuZExp
bmtzWzFdKTsKICAgICAgICAgYXNzZXJ0VHJ1ZShleHBhbmRMaW5rc1sxXS50ZXh0Q29udGVudCA9
PSAnKycpOwpAQCAtNTQ4LDYgKzU1Nyw1OSBAQCBmdW5jdGlvbiBydW5UZXN0cygpCiAgICAgICAg
IGV4cGFuZEFsbEV4cGVjdGF0aW9ucygpOwogICAgICAgICBhc3NlcnRUcnVlKHZpc2libGVFeHBh
bmRMaW5rcygpLmxlbmd0aCA9PSAyKTsKICAgICB9KTsKKyAgICAKKworICAgIHJlc3VsdHMgPSBt
b2NrUmVzdWx0cygpOworICAgIHZhciBzdWJ0cmVlID0gcmVzdWx0cy50ZXN0c1snZm9vJ10gPSB7
fQorICAgIHN1YnRyZWVbJ2Jhci5odG1sJ10gPSBtb2NrRXhwZWN0YXRpb24oJ1RFWFQnLCAnRkFJ
TCcpOworICAgIHN1YnRyZWVbJ2JhcjEuaHRtbCddID0gbW9ja0V4cGVjdGF0aW9uKCdURVhUJywg
J0ZBSUwnKTsKKyAgICBzdWJ0cmVlWydiYXIyLmh0bWwnXSA9IG1vY2tFeHBlY3RhdGlvbignVEVY
VCcsICdGQUlMJyk7CisgICAgCisgICAgcnVuVGVzdChyZXN1bHRzLCBmdW5jdGlvbigpIHsKKyAg
ICAgICAgYXNzZXJ0VHJ1ZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVzdWx0cy10YWJsZScp
KTsKKyAgICAgICAgYXNzZXJ0VHJ1ZSh2aXNpYmxlRXhwYW5kTGlua3MoKS5sZW5ndGggPT0gMyk7
CisgICAgICAgIAorICAgICAgICBpZiAod2luZG93LmV2ZW50U2VuZGVyKSB7CisgICAgICAgICAg
ICBldmVudFNlbmRlci5rZXlEb3duKCdpJyk7IC8vIGZpcnN0CisgICAgICAgICAgICB2YXIgZXhw
YW5kQnV0dG9ucyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyNyZXN1bHRzLXRhYmxlIHRi
b2R5IC5leHBhbmQtYnV0dG9uJyk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKGV4cGFuZEJ1dHRv
bnNbMF0uY2xhc3NMaXN0LmNvbnRhaW5zKCdjdXJyZW50JykpOworICAgICAgICAgICAgYXNzZXJ0
VHJ1ZSghZXhwYW5kQnV0dG9uc1sxXS5jbGFzc0xpc3QuY29udGFpbnMoJ2N1cnJlbnQnKSk7Cisg
ICAgICAgICAgICBhc3NlcnRUcnVlKCFleHBhbmRCdXR0b25zWzJdLmNsYXNzTGlzdC5jb250YWlu
cygnY3VycmVudCcpKTsKKworICAgICAgICAgICAgZXZlbnRTZW5kZXIua2V5RG93bignaicpOyAv
LyBuZXh0CisgICAgICAgICAgICB2YXIgZXhwYW5kQnV0dG9ucyA9IGRvY3VtZW50LnF1ZXJ5U2Vs
ZWN0b3JBbGwoJyNyZXN1bHRzLXRhYmxlIHRib2R5IC5leHBhbmQtYnV0dG9uJyk7CisgICAgICAg
ICAgICBhc3NlcnRUcnVlKCFleHBhbmRCdXR0b25zWzBdLmNsYXNzTGlzdC5jb250YWlucygnY3Vy
cmVudCcpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZXhwYW5kQnV0dG9uc1sxXS5jbGFzc0xp
c3QuY29udGFpbnMoJ2N1cnJlbnQnKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCFleHBhbmRC
dXR0b25zWzJdLmNsYXNzTGlzdC5jb250YWlucygnY3VycmVudCcpKTsKKworICAgICAgICAgICAg
ZXZlbnRTZW5kZXIua2V5RG93bignaycpOyAvLyBwcmV2aW91cworICAgICAgICAgICAgdmFyIGV4
cGFuZEJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjcmVzdWx0cy10YWJsZSB0
Ym9keSAuZXhwYW5kLWJ1dHRvbicpOworICAgICAgICAgICAgYXNzZXJ0VHJ1ZShleHBhbmRCdXR0
b25zWzBdLmNsYXNzTGlzdC5jb250YWlucygnY3VycmVudCcpKTsKKyAgICAgICAgICAgIGFzc2Vy
dFRydWUoIWV4cGFuZEJ1dHRvbnNbMV0uY2xhc3NMaXN0LmNvbnRhaW5zKCdjdXJyZW50JykpOwor
ICAgICAgICAgICAgYXNzZXJ0VHJ1ZSghZXhwYW5kQnV0dG9uc1syXS5jbGFzc0xpc3QuY29udGFp
bnMoJ2N1cnJlbnQnKSk7CisKKyAgICAgICAgICAgIGV2ZW50U2VuZGVyLmtleURvd24oJ2wnKTsg
Ly8gbGFzdAorICAgICAgICAgICAgdmFyIGV4cGFuZEJ1dHRvbnMgPSBkb2N1bWVudC5xdWVyeVNl
bGVjdG9yQWxsKCcjcmVzdWx0cy10YWJsZSB0Ym9keSAuZXhwYW5kLWJ1dHRvbicpOworICAgICAg
ICAgICAgYXNzZXJ0VHJ1ZSghZXhwYW5kQnV0dG9uc1swXS5jbGFzc0xpc3QuY29udGFpbnMoJ2N1
cnJlbnQnKSk7CisgICAgICAgICAgICBhc3NlcnRUcnVlKCFleHBhbmRCdXR0b25zWzFdLmNsYXNz
TGlzdC5jb250YWlucygnY3VycmVudCcpKTsKKyAgICAgICAgICAgIGFzc2VydFRydWUoZXhwYW5k
QnV0dG9uc1syXS5jbGFzc0xpc3QuY29udGFpbnMoJ2N1cnJlbnQnKSk7CisKKyAgICAgICAgICAg
IGV2ZW50U2VuZGVyLmtleURvd24oJ2knKTsgLy8gZmlyc3QKKyAgICAgICAgICAgIGV2ZW50U2Vu
ZGVyLmtleURvd24oJ2UnKTsgLy8gZXhwYW5kCisgICAgICAgICAgICB2YXIgZXhwYW5kTGlua3Mg
PSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZXhwYW5kLWJ1dHRvbi10ZXh0Jyk7CisgICAg
ICAgICAgICBhc3NlcnRUcnVlKGlzRXhwYW5kZWQoZXhwYW5kTGlua3NbMF0pKTsKKworICAgICAg
ICAgICAgZXZlbnRTZW5kZXIua2V5RG93bignYycpOyAvLyBjb2xsYXBzZQorICAgICAgICAgICAg
YXNzZXJ0VHJ1ZShpc0NvbGxhcHNlZChleHBhbmRMaW5rc1swXSkpOworCisgICAgICAgICAgICBl
dmVudFNlbmRlci5rZXlEb3duKCdmJyk7IC8vIGZsYWcKKyAgICAgICAgICAgIHZhciBmbGFnZ2Vk
VGVzdHNUZXh0Ym94ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZsYWdnZWQtdGVzdHMnKTsK
KyAgICAgICAgICAgIGZsYWdnZWRUZXN0c1RleHRib3guaW5uZXJUZXh0ID09ICdiYXIuaHRtbCc7
CisKKyAgICAgICAgICAgIGV2ZW50U2VuZGVyLmtleURvd24oJ2YnKTsgLy8gdW5mbGFnCisgICAg
ICAgICAgICBmbGFnZ2VkVGVzdHNUZXh0Ym94LmlubmVyVGV4dCA9PSAnJzsKKyAgICAgICAgfQor
ICAgIH0pOwogCiAgICAgZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSAnPHByZT4nICsgZ19sb2cu
am9pbignXG4nKSArICc8L3ByZT4nOwogfQpkaWZmIC0tZ2l0IGEvTGF5b3V0VGVzdHMvZmFzdC9o
YXJuZXNzL3Jlc3VsdHMuaHRtbCBiL0xheW91dFRlc3RzL2Zhc3QvaGFybmVzcy9yZXN1bHRzLmh0
bWwKaW5kZXggYTIyZGE0MTI5NjhhNjM3OTljMjZlOTlhMDQwOTliMzM4YmY2OTdiMS4uOGQ4MTNl
OTIyNWYzZGI0MWM1MmZlNjhjODNlZTg3MjA2MjIxYTlkNyAxMDA2NDQKLS0tIGEvTGF5b3V0VGVz
dHMvZmFzdC9oYXJuZXNzL3Jlc3VsdHMuaHRtbAorKysgYi9MYXlvdXRUZXN0cy9mYXN0L2hhcm5l
c3MvcmVzdWx0cy5odG1sCkBAIC0yLDEyICsyLDE5IEBACiA8c3R5bGU+CiBib2R5IHsKICAgICBt
YXJnaW46IDRweDsKKyAgICBmb250LWZhbWlseTogSGVsdmV0aWNhLCBzYW5zLXNlcmlmOworICAg
IGZvbnQtc2l6ZTogMTFwdDsKIH0KIAogYm9keSA+IHA6Zmlyc3Qtb2YtdHlwZSB7CiAgICAgbWFy
Z2luLXRvcDogMDsKIH0KIAoraDEgeworICAgIGZvbnQtc2l6ZTogMTRwdDsKKyAgICBtYXJnaW4t
dG9wOiAxLjVlbTsKK30KKwogcCB7CiAgICAgbWFyZ2luLWJvdHRvbTogMC4zZW07CiB9CkBAIC0y
NSw3ICszMiw3IEBAIHRkOm5vdCg6Zmlyc3Qtb2YtdHlwZSkgewogfQogCiB0ZCB7Ci0gICAgcGFk
ZGluZzogMCA0cHg7CisgICAgcGFkZGluZzogMXB4IDRweDsKIH0KIAogdGg6ZW1wdHksIHRkOmVt
cHR5IHsKQEAgLTM3LDYgKzQ0LDExIEBAIHRoIHsKICAgICAtbW96LXVzZXItc2VsZWN0OiBub25l
OwogfQogCisubm90ZSB7CisgICAgY29sb3I6IGdyYXk7CisgICAgZm9udC1zaXplOiBzbWFsbGVy
OworfQorCiAucmVzdWx0cy1yb3cgewogICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlOwogfQpA
QCAtNjEsMTMgKzczLDE3IEBAIHRoIHsKIAogLmV4cGFuZC1idXR0b24gewogICAgIGJhY2tncm91
bmQtY29sb3I6IHdoaXRlOwotICAgIGNvbG9yOiBibHVlOwogICAgIHdpZHRoOiAxMXB4OwotICAg
IGhlaWdodDogMTFweDsKLSAgICBib3JkZXI6IDFweCBzb2xpZCBibHVlOworICAgIGhlaWdodDog
MTJweDsKKyAgICBib3JkZXI6IDFweCBzb2xpZCBncmF5OwogICAgIGRpc3BsYXk6IGlubGluZS1i
bG9jazsKICAgICBtYXJnaW46IDAgM3B4IDAgMDsKICAgICBwb3NpdGlvbjogcmVsYXRpdmU7Cisg
ICAgY3Vyc29yOiBkZWZhdWx0OworfQorCisuZXhwYW5kLWJ1dHRvbi5jdXJyZW50IHsKKyAgICBj
b2xvcjogcmVkOwogfQogCiAuZXhwYW5kLWJ1dHRvbi10ZXh0IHsKQEAgLTc2LDYgKzkyLDEwIEBA
IHRoIHsKICAgICBsZWZ0OiAxcHg7CiB9CiAKKy50ZXN0LWxpbmsuZmxhZ2dlZDphZnRlciB7Cisg
ICAgY29udGVudDogJyAoZmxhZ2dlZCknOworfQorCiAuc3RvcHBlZC1ydW5uaW5nLWVhcmx5LW1l
c3NhZ2UgewogICAgIGJvcmRlcjogM3B4IHNvbGlkICNkMDA7CiAgICAgZm9udC13ZWlnaHQ6IGJv
bGQ7CkBAIC0xNjUsNiArMTg1LDkgQEAgdGggewogICAgIGltYWdlLXJlbmRlcmluZzogLXdlYmtp
dC1vcHRpbWl6ZS1jb250cmFzdDsKIH0KIAorI2ZsYWdnZWQtdGVzdHMgeworICAgIHBhZGRpbmc6
IDVweDsKK30KIDwvc3R5bGU+CiA8c3R5bGUgaWQ9InVuZXhwZWN0ZWQtc3R5bGUiPjwvc3R5bGU+
CiAKQEAgLTI2NSw5ICsyODgsOSBAQCBmdW5jdGlvbiB0b2dnbGluZ0ltYWdlKHByZWZpeCkKICAg
ICAgICAgcHJlZml4ICsgJyI+PC9pbWc+PC9kaXY+JzsKIH0KIAotZnVuY3Rpb24gdG9nZ2xlRXhw
ZWN0YXRpb25zKGUpCitmdW5jdGlvbiB0b2dnbGVFeHBlY3RhdGlvbnMoZWxlbWVudCkKIHsKLSAg
ICB2YXIgZXhwYW5kTGluayA9IGUudGFyZ2V0OworICAgIHZhciBleHBhbmRMaW5rID0gZWxlbWVu
dDsKICAgICBpZiAoZXhwYW5kTGluay5jbGFzc05hbWUgIT0gJ2V4cGFuZC1idXR0b24tdGV4dCcp
CiAgICAgICAgIGV4cGFuZExpbmsgPSBleHBhbmRMaW5rLnF1ZXJ5U2VsZWN0b3IoJy5leHBhbmQt
YnV0dG9uLXRleHQnKTsKIApAQCAtNDAxLDcgKzQyNCw3IEBAIGZ1bmN0aW9uIHRlc3RMaW5rKHRl
c3QpCiAKIGZ1bmN0aW9uIHRlc3RMaW5rV2l0aEV4cGFuZEJ1dHRvbih0ZXN0KQogewotICAgIHJl
dHVybiAnPHNwYW4gY2xhc3M9ZXhwYW5kLWJ1dHRvbiBvbmNsaWNrPSJ0b2dnbGVFeHBlY3RhdGlv
bnMoZXZlbnQpIj48c3BhbiBjbGFzcz1leHBhbmQtYnV0dG9uLXRleHQ+Kzwvc3Bhbj48L3NwYW4+
JyArIHRlc3RMaW5rKHRlc3QpOworICAgIHJldHVybiAnPHNwYW4gY2xhc3M9ZXhwYW5kLWJ1dHRv
biBvbmNsaWNrPSJ0b2dnbGVFeHBlY3RhdGlvbnModGhpcykiPjxzcGFuIGNsYXNzPWV4cGFuZC1i
dXR0b24tdGV4dD4rPC9zcGFuPjwvc3Bhbj4nICsgdGVzdExpbmsodGVzdCk7CiB9CiAKIGZ1bmN0
aW9uIHJlc3VsdExpbmsodGVzdFByZWZpeCwgc3VmZml4LCBjb250ZW50cykKQEAgLTYxMyw3ICs2
MzYsNyBAQCBmdW5jdGlvbiB0ZXN0TGlzdCh0ZXN0cywgaGVhZGVyLCB0YWJsZUlkKQogewogICAg
IHRlc3RzLnNvcnQoKTsKIAotICAgIHZhciBodG1sID0gJzxwPicgKyBoZWFkZXIgKyAnOjwvcD48
dGFibGUgaWQ9IicgKyB0YWJsZUlkICsgJyInOworICAgIHZhciBodG1sID0gJzxoMT4nICsgaGVh
ZGVyICsgJzo8L2gxPjx0YWJsZSBpZD0iJyArIHRhYmxlSWQgKyAnIic7CiAgICAgaWYgKCFoYXNV
bmV4cGVjdGVkKHRlc3RzKSkKICAgICAgICAgaHRtbCArPSAnIGNsYXNzPWV4cGVjdGVkJzsKICAg
ICBodG1sICs9ICc+JzsKQEAgLTg4MSw2ICs5MDQsMTYxIEBAIFBpeGVsWm9vbWVyLmhhbmRsZU1v
dXNlTW92ZSA9IGZ1bmN0aW9uKGUpIHsKIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNl
bW92ZScsIFBpeGVsWm9vbWVyLmhhbmRsZU1vdXNlTW92ZSwgZmFsc2UpOwogZG9jdW1lbnQuYWRk
RXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCBQaXhlbFpvb21lci5oYW5kbGVNb3VzZU91dCwgZmFs
c2UpOwogCit2YXIgVGVzdE5hdmlnYXRvciA9IHt9OworCitUZXN0TmF2aWdhdG9yLmN1cnJlbnRU
ZXN0SW5kZXggPSAwOworVGVzdE5hdmlnYXRvci5mbGFnZ2VkVGVzdHMgPSB7fTsKKworVGVzdE5h
dmlnYXRvci5oYW5kbGVLZXlFdmVudCA9IGZ1bmN0aW9uKGV2ZW50KQoreworICAgIHN3aXRjaCAo
U3RyaW5nLmZyb21DaGFyQ29kZShldmVudC5jaGFyQ29kZSkpIHsKKyAgICAgICAgY2FzZSAnaSc6
CisgICAgICAgICAgICBUZXN0TmF2aWdhdG9yLnNjcm9sbFRvRmlyc3RUZXN0KCk7CisgICAgICAg
ICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnaic6CisgICAgICAgICAgICBUZXN0TmF2aWdhdG9y
LnNjcm9sbFRvTmV4dFRlc3QoKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICdr
JzoKKyAgICAgICAgICAgIFRlc3ROYXZpZ2F0b3Iuc2Nyb2xsVG9QcmV2aW91c1Rlc3QoKTsKKyAg
ICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICdsJzoKKyAgICAgICAgICAgIFRlc3ROYXZp
Z2F0b3Iuc2Nyb2xsVG9MYXN0VGVzdCgpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNh
c2UgJ2UnOgorICAgICAgICAgICAgVGVzdE5hdmlnYXRvci5leHBhbmRDdXJyZW50VGVzdCgpOwor
ICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJ2MnOgorICAgICAgICAgICAgVGVzdE5h
dmlnYXRvci5jb2xsYXBzZUN1cnJlbnRUZXN0KCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAg
ICAgY2FzZSAndCc6CisgICAgICAgICAgICBUZXN0TmF2aWdhdG9yLnRvZ2dsZUN1cnJlbnRUZXN0
KCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnZic6CisgICAgICAgICAgICBU
ZXN0TmF2aWdhdG9yLnRvZ2dsZUN1cnJlbnRUZXN0RmxhZ2dlZCgpOworICAgICAgICAgICAgYnJl
YWs7CisgICAgfQorfQorCitUZXN0TmF2aWdhdG9yLnNjcm9sbFRvRmlyc3RUZXN0ID0gZnVuY3Rp
b24oKQoreworICAgIGlmICh0aGlzLnNldEN1cnJlbnRUZXN0KDApKQorICAgICAgICB0aGlzLnNj
cm9sbFRvQ3VycmVudFRlc3QoKTsKK30KKworVGVzdE5hdmlnYXRvci5zY3JvbGxUb0xhc3RUZXN0
ID0gZnVuY3Rpb24oKQoreworICAgIHZhciBsaW5rcyA9IHZpc2libGVFeHBhbmRMaW5rcygpOwor
ICAgIGlmICh0aGlzLnNldEN1cnJlbnRUZXN0KGxpbmtzLmxlbmd0aCAtIDEpKQorICAgICAgICB0
aGlzLnNjcm9sbFRvQ3VycmVudFRlc3QoKTsKK30KKworVGVzdE5hdmlnYXRvci5zY3JvbGxUb05l
eHRUZXN0ID0gZnVuY3Rpb24oKQoreworICAgIGlmICh0aGlzLnNldEN1cnJlbnRUZXN0KHRoaXMu
Y3VycmVudFRlc3RJbmRleCArIDEpKQorICAgICAgICB0aGlzLnNjcm9sbFRvQ3VycmVudFRlc3Qo
KTsKK30KKworVGVzdE5hdmlnYXRvci5zY3JvbGxUb1ByZXZpb3VzVGVzdCA9IGZ1bmN0aW9uKCkK
K3sKKyAgICBpZiAodGhpcy5zZXRDdXJyZW50VGVzdCh0aGlzLmN1cnJlbnRUZXN0SW5kZXggLSAx
KSkKKyAgICAgICAgdGhpcy5zY3JvbGxUb0N1cnJlbnRUZXN0KCk7Cit9CisKK1Rlc3ROYXZpZ2F0
b3IuY3VycmVudFRlc3RMaW5rID0gZnVuY3Rpb24oKQoreworICAgIHZhciBsaW5rcyA9IHZpc2li
bGVFeHBhbmRMaW5rcygpOworICAgIHJldHVybiBsaW5rc1t0aGlzLmN1cnJlbnRUZXN0SW5kZXhd
OworfQorCitUZXN0TmF2aWdhdG9yLmV4cGFuZEN1cnJlbnRUZXN0ID0gZnVuY3Rpb24oKQorewor
ICAgIGV4cGFuZEV4cGVjdGF0aW9ucyh0aGlzLmN1cnJlbnRUZXN0TGluaygpKTsKK30KKworVGVz
dE5hdmlnYXRvci5jb2xsYXBzZUN1cnJlbnRUZXN0ID0gZnVuY3Rpb24oKQoreworICAgIGNvbGxh
cHNlRXhwZWN0YXRpb25zKHRoaXMuY3VycmVudFRlc3RMaW5rKCkpOworfQorCitUZXN0TmF2aWdh
dG9yLnRvZ2dsZUN1cnJlbnRUZXN0ID0gZnVuY3Rpb24oKQoreworICAgIHRvZ2dsZUV4cGVjdGF0
aW9ucyh0aGlzLmN1cnJlbnRUZXN0TGluaygpKTsKK30KKworVGVzdE5hdmlnYXRvci50b2dnbGVD
dXJyZW50VGVzdEZsYWdnZWQgPSBmdW5jdGlvbigpCit7CisgICAgdmFyIHRlc3RMaW5rID0gcGFy
ZW50T2ZUeXBlKHRoaXMuY3VycmVudFRlc3RMaW5rKCksICd0Ym9keScpLnF1ZXJ5U2VsZWN0b3Io
Jy50ZXN0LWxpbmsnKTsKKyAgICB2YXIgdGVzdE5hbWUgPSB0ZXN0TGluay5pbm5lclRleHQ7Cisg
ICAgCisgICAgaWYgKHRlc3RMaW5rLmNsYXNzTGlzdC5jb250YWlucygnZmxhZ2dlZCcpKSB7Cisg
ICAgICAgIHRlc3RMaW5rLmNsYXNzTGlzdC5yZW1vdmUoJ2ZsYWdnZWQnKTsKKyAgICAgICAgZGVs
ZXRlIHRoaXMuZmxhZ2dlZFRlc3RzW3Rlc3ROYW1lXTsKKyAgICB9IGVsc2UgeworICAgICAgICB0
ZXN0TGluay5jbGFzc0xpc3QuYWRkKCdmbGFnZ2VkJyk7CisgICAgICAgIHRoaXMuZmxhZ2dlZFRl
c3RzW3Rlc3ROYW1lXSA9IDE7CisgICAgfQorICAgIAorICAgIHZhciBmbGFnZ2VkVGVzdFRleHRi
b3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmxhZ2dlZC10ZXN0cycpOworICAgIGlmICgh
ZmxhZ2dlZFRlc3RUZXh0Ym94KSB7CisgICAgICAgIHZhciBmbGFnZ2VkVGVzdENvbnRhaW5lciA9
IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOworICAgICAgICBmbGFnZ2VkVGVzdENvbnRh
aW5lci5jbGFzc05hbWUgPSAnZmxhZ2dlZC10ZXN0LWNvbnRhaW5lcic7CisKKyAgICAgICAgdmFy
IGxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaDInKTsKKyAgICAgICAgbGFiZWwuaW5u
ZXJUZXh0ID0gJ0ZsYWdnZWQgVGVzdHMnOworICAgICAgICBmbGFnZ2VkVGVzdENvbnRhaW5lci5h
cHBlbmRDaGlsZChsYWJlbCk7CisgICAgICAgIAorICAgICAgICBmbGFnZ2VkVGVzdFRleHRib3gg
PSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKKyAgICAgICAgZmxhZ2dlZFRlc3RUZXh0
Ym94LmlkID0gJ2ZsYWdnZWQtdGVzdHMnOworICAgICAgICBmbGFnZ2VkVGVzdFRleHRib3guc2V0
QXR0cmlidXRlKCdjb250ZW50RWRpdGFibGUnLCAnJyk7CisgICAgICAgIAorICAgICAgICBmbGFn
Z2VkVGVzdENvbnRhaW5lci5hcHBlbmRDaGlsZChmbGFnZ2VkVGVzdFRleHRib3gpOworICAgICAg
ICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGZsYWdnZWRUZXN0Q29udGFpbmVyKTsKKyAgICB9
CisKKyAgICB2YXIgZmxhZ2dlZFRlc3RzID0gW107CisgICAgZm9yICh2YXIgdGVzdCBpbiB0aGlz
LmZsYWdnZWRUZXN0cykKKyAgICAgICAgZmxhZ2dlZFRlc3RzLnB1c2godGVzdCk7CisKKyAgICBm
bGFnZ2VkVGVzdHMuc29ydCgpOworICAgIGZsYWdnZWRUZXN0VGV4dGJveC5pbm5lckhUTUwgPSBm
bGFnZ2VkVGVzdHMuam9pbignPGJyPicpOworfQorCitUZXN0TmF2aWdhdG9yLnNldEN1cnJlbnRU
ZXN0ID0gZnVuY3Rpb24odGVzdEluZGV4KQoreworICAgIHZhciBsaW5rcyA9IHZpc2libGVFeHBh
bmRMaW5rcygpOworICAgIGlmICh0ZXN0SW5kZXggPCAwIHx8IHRlc3RJbmRleCA+PSBsaW5rcy5s
ZW5ndGgpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgIHZhciBjdXJyRXhwYW5kQnV0dG9u
ID0gbGlua3NbdGhpcy5jdXJyZW50VGVzdEluZGV4XTsKKyAgICBpZiAoY3VyckV4cGFuZEJ1dHRv
bikKKyAgICAgICAgY3VyckV4cGFuZEJ1dHRvbi5wYXJlbnROb2RlLmNsYXNzTGlzdC5yZW1vdmUo
J2N1cnJlbnQnKTsKKworICAgIHRoaXMuY3VycmVudFRlc3RJbmRleCA9IHRlc3RJbmRleDsKKwor
ICAgIHZhciBjdXJyRXhwYW5kQnV0dG9uID0gbGlua3NbdGhpcy5jdXJyZW50VGVzdEluZGV4XTsK
KyAgICBjdXJyRXhwYW5kQnV0dG9uLnBhcmVudE5vZGUuY2xhc3NMaXN0LmFkZCgnY3VycmVudCcp
OworCisgICAgcmV0dXJuIHRydWU7Cit9CisKK1Rlc3ROYXZpZ2F0b3Iuc2Nyb2xsVG9DdXJyZW50
VGVzdCA9IGZ1bmN0aW9uKCkKK3sKKyAgICB2YXIgZmFpbGVkUmVzdWx0c1RhYmxlID0gZG9jdW1l
bnQuZ2V0RWxlbWVudEJ5SWQoJ3Jlc3VsdHMtdGFibGUnKTsKKyAgICAvLyBVc2UgdmlzaWJsZUV4
cGFuZExpbmtzIGJlY2F1c2UgaXQncyBhbHJlYWR5IHNtYXJ0IGFib3V0IGV4cGVjdGVkIGZhaWx1
cmVzLgorICAgIHZhciBsaW5rcyA9IHZpc2libGVFeHBhbmRMaW5rcygpOworICAgIHZhciB0ZXN0
SW5kZXggPSB0aGlzLmN1cnJlbnRUZXN0SW5kZXg7CisgICAgaWYgKHRlc3RJbmRleCA8IDAgfHwg
dGVzdEluZGV4ID49IGxpbmtzLmxlbmd0aCkKKyAgICAgICAgcmV0dXJuOworICAgIAorICAgIHZh
ciB0YXJnZXRMaW5rID0gbGlua3NbdGVzdEluZGV4XTsKKyAgICB2YXIgcm93UmVjdCA9IHRhcmdl
dExpbmsuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CisgICAgLy8gcm93UmVjdCBpcyBpbiBjbGll
bnQgY29vcmRzIChpLmUuIHJlbGF0aXZlIHRvIHZpZXdwb3J0KSwgc28gd2UganVzdCB3YW50IHRv
IGFkZCBpdHMgdG9wIHRvIHRoZSBjdXJyZW50IHNjcm9sbCBwb3NpdGlvbi4KKyAgICB3aW5kb3cu
c2Nyb2xsVG8od2luZG93LnNjcm9sbFgsIHdpbmRvdy5zY3JvbGxZICsgcm93UmVjdC50b3AgLSAy
MCk7Cit9CisKK2RvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXByZXNzJywgVGVzdE5hdmln
YXRvci5oYW5kbGVLZXlFdmVudCwgZmFsc2UpOworCisKIGZ1bmN0aW9uIG9ubHlTaG93VW5leHBl
Y3RlZEZhaWx1cmVzKCkKIHsKICAgICByZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Vu
ZXhwZWN0ZWQtcmVzdWx0cycpLmNoZWNrZWQ7CkBAIC05NzUsNyArMTE1Myw3IEBAIGZ1bmN0aW9u
IGNvbnZlcnRUb1RvZ2dsaW5nSGFuZGxlcih0b2dnbGluZ0ltYWdlRnVuY3Rpb24pCiAgICAgICAg
IGVsc2UgaWYgKHVybC5tYXRjaCgnLWFjdHVhbC5wbmckJykpIHsKICAgICAgICAgICAgIHZhciBu
YW1lID0gcGFyZW50T2ZUeXBlKG5vZGUsICd0Ym9keScpLnF1ZXJ5U2VsZWN0b3IoJy50ZXN0LWxp
bmsnKS50ZXh0Q29udGVudDsKICAgICAgICAgICAgIGdldFJlc3VsdENvbnRhaW5lcihub2RlKS5v
dXRlckhUTUwgPSB0b2dnbGluZ0ltYWdlRnVuY3Rpb24oc3RyaXBFeHRlbnNpb24obmFtZSkpOwot
ICAgICAgICB9ICAgCisgICAgICAgIH0KICAgICB9CiB9CiAKQEAgLTEwMTQsNyArMTE5Miw3IEBA
IGZ1bmN0aW9uIGZhaWxpbmdUZXN0c1RhYmxlKHRlc3RzLCB0aXRsZSwgaWQpCiAgICAgaWYgKCFo
YXNVbmV4cGVjdGVkKHRlc3RzKSkKICAgICAgICAgaGVhZGVyICs9ICcgY2xhc3M9ZXhwZWN0ZWQn
OwogCi0gICAgaGVhZGVyICs9ICc+PHA+JyArIHRpdGxlICsgJzo8L3A+JyArCisgICAgaGVhZGVy
ICs9ICc+PGgxPicgKyB0aXRsZSArICc6PC9oMT4nICsKICAgICAgICAgJzx0YWJsZSBpZD0iJyAr
IGlkICsgJyI+PHRoZWFkPjx0cj4nICsKICAgICAgICAgJzx0aD50ZXN0PC90aD4nICsKICAgICAg
ICAgJzx0aCBpZD0idGV4dC1yZXN1bHRzLWhlYWRlciI+cmVzdWx0czwvdGg+JyArCkBAIC0xMDM4
LDYgKzEyMTYsNyBAQCBmdW5jdGlvbiBnZW5lcmF0ZVBhZ2UoKQogICAgIGZvckVhY2hUZXN0KHBy
b2Nlc3NHbG9iYWxTdGF0ZUZvcik7CiAKICAgICB2YXIgaHRtbCA9ICc8ZGl2IGlkPXRvb2xiYXI+
JyArCisgICAgICAgICc8ZGl2IGNsYXNzPSJub3RlIj5Vc2UgdGhlIGksIGosIGsgYW5kIGwga2V5
cyB0byBuYXZpZ2F0ZSwgZSwgYyB0byBleHBhbmQgYW5kIGNvbGxhcHNlLCBhbmQgZiB0byBmbGFn
PC9kaXY+JyArCiAgICAgICAgICc8YSBocmVmPSJqYXZhc2NyaXB0OnZvaWQoKSIgb25jbGljaz0i
ZXhwYW5kQWxsRXhwZWN0YXRpb25zKCkiPmV4cGFuZCBhbGw8L2E+ICcgKwogICAgICAgICAnPGEg
aHJlZj0iamF2YXNjcmlwdDp2b2lkKCkiIG9uY2xpY2s9ImNvbGxhcHNlQWxsRXhwZWN0YXRpb25z
KCkiPmNvbGxhcHNlIGFsbDwvYT4gJyArCiAgICAgICAgICc8YSBocmVmPSJqYXZhc2NyaXB0OnZv
aWQoKSIgaWQ9b3B0aW9ucy1saW5rIG9uY2xpY2s9InRvZ2dsZU9wdGlvbnNNZW51KCkiPm9wdGlv
bnM8L2E+JyArCg==
</data>
<flag name="review"
          id="122384"
          type_id="1"
          status="+"
          setter="ojan"
    />
    <flag name="commit-queue"
          id="122391"
          type_id="3"
          status="-"
          setter="webkit.review.bot"
    />
          </attachment>
      

    </bug>

</bugzilla>