From 96be3958a091343882684efbdffc1a10b7b68138 Mon Sep 17 00:00:00 2001 From: Ben Bolker Date: Sun, 8 Oct 2023 16:30:43 -0400 Subject: [PATCH] clean up singular fit section --- glmmFAQ.html | 3922 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 2727 insertions(+), 1195 deletions(-) diff --git a/glmmFAQ.html b/glmmFAQ.html index d795b17..cbf6a6c 100644 --- a/glmmFAQ.html +++ b/glmmFAQ.html @@ -11,7 +11,7 @@ - + GLMM FAQ @@ -32,7 +32,7 @@ !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 - +h1.title {font-size: 38px;} +h2 {font-size: 30px;} +h3 {font-size: 24px;} +h4 {font-size: 18px;} +h5 {font-size: 16px;} +h6 {font-size: 12px;} +code {color: inherit; background-color: rgba(0, 0, 0, 0.04);} +pre:not([class]) { background-color: white } +code{white-space: pre-wrap;} +span.smallcaps{font-variant: small-caps;} +span.underline{text-decoration: underline;} +div.column{display: inline-block; vertical-align: top; width: 50%;} +div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} +ul.task-list{list-style: none;} +

Introduction

-

This is an informal FAQ list for the r-sig-mixed-models mailing list.

+

This is an informal FAQ list for the r-sig-mixed-models +mailing list.

The most commonly used functions for mixed modeling in R are

    -
  • linear mixed models: aov(), nlme::lme1, lme4::lmer; brms::brm
  • +
  • linear mixed models: aov(), +nlme::lme1, lme4::lmer; +brms::brm
  • generalized linear mixed models (GLMMs)
      -
    • frequentist: MASS::glmmPQL, lme4::glmer; glmmTMB
    • -
    • Bayesian: MCMCglmm::MCMCglmm; brms::brm
    • +
    • frequentist: MASS::glmmPQL, lme4::glmer; +glmmTMB
    • +
    • Bayesian: MCMCglmm::MCMCglmm; +brms::brm
  • -
  • nonlinear mixed models: nlme::nlme, lme4::nlmer; brms::brm
  • +
  • nonlinear mixed models: nlme::nlme, +lme4::nlmer; brms::brm
  • GNLMMs: brms::brm
-

Another quick-and-dirty way to search for mixed-model related packages on CRAN:

+

Another quick-and-dirty way to search for mixed-model related +packages on CRAN:

grep("l.?m[me][^t]",rownames(available.packages()),value=TRUE)
##  [1] "blmeco"           "buildmer"         "cellVolumeDist"   "climextRemes"    
-##  [5] "curtailment"      "elementR"         "glmertree"        "glmm.hp"         
-##  [9] "glmmEP"           "glmmfields"       "glmmLasso"        "glmmML"          
-## [13] "glmmPen"          "glmmrBase"        "glmmSeq"          "glmmTMB"         
-## [17] "lamme"            "lme4"             "lmeInfo"          "lmeresampler"    
-## [21] "lmerTest"         "lmeSplines"       "lmmot"            "lmmpar"          
-## [25] "lrmest"           "lsmeans"          "mailmerge"        "mlmm.gwas"       
-## [29] "mlmmm"            "mvglmmRank"       "nlmeU"            "nlmeVPC"         
-## [33] "palmerpenguins"   "tglkmeans"        "trouBBlme4SolveR" "vagalumeR"       
-## [37] "vglmer"
-

There are some false positives here (e.g. palmerpenguins); see here if you’re interested in “regex golf”.

+## [5] "curtailment" "glmertree" "glmm.hp" "glmmEP" +## [9] "glmmfields" "glmmLasso" "glmmML" "glmmPen" +## [13] "glmmrBase" "glmmrOptim" "glmmSeq" "glmmTMB" +## [17] "jlmerclusterperm" "lamme" "lme4" "lmeInfo" +## [21] "lmeresampler" "lmerPerm" "lmerTest" "lmeSplines" +## [25] "lmmot" "lmmpar" "lrmest" "lsmeans" +## [29] "mailmerge" "mlmm.gwas" "mvglmmRank" "nlmeU" +## [33] "nlmeVPC" "palmerpenguins" "SherlockHolmes" "tglkmeans" +## [37] "trouBBlme4SolveR" "vagalumeR" "vglmer" +

There are some false positives here +(e.g. palmerpenguins); see here if you’re interested in “regex +golf”.

Other sources of help

    @@ -1088,17 +1320,50 @@

    Other sources of help

    • sign up here
    • archives here
    • -
    • or Google search with the tag site:https://stat.ethz.ch/pipermail/r-sig-mixed-models/
    • +
    • or Google search with the tag +site:https://stat.ethz.ch/pipermail/r-sig-mixed-models/
    -
  • The source code of this document is available on GitHub; the rendered (HTML) version lives on GitHub pages.
  • -
  • Searching on StackOverflow with the [r] [mixed-models] tags, or on CrossValidated with the [mixed-model] tag may be helpful (these sites also have an [lme4] tag).
  • +
  • The source code of this document is available on +GitHub; the rendered (HTML) version lives on GitHub +pages.
  • +
  • Searching on StackOverflow with the [r] +[mixed-models] tags, or on CrossValidated with the [mixed-model] +tag may be helpful (these sites also have an [lme4] +tag).

DISCLAIMERS:

    -
  • (G)LMMs are hard - harder than you may think based on what you may have learned in your second statistics class, which probably focused on picking the appropriate sums of squares terms and degrees of freedom for the numerator and denominator of an \(F\) test. ‘Modern’ mixed model approaches, although more powerful (they can handle more complex designs, lack of balance, crossed random factors, some kinds of non-Normally distributed responses, etc.), also require a new set of conceptual tools. In order to use these tools you should have at least a general acquaintance with classical mixed-model experimental designs but you should also, probably, read something about modern mixed model approaches. Littell et al. (2006) and Pinheiro and Bates (2000) are two places to start, although Pinheiro and Bates is probably more useful if you want to use R. Other useful references include Gelman and Hill (2006) (focused on Bayesian methods) and Zuur et al. (2009b). If you are going to use generalized linear mixed models, you should understand generalized linear models (Dobson and Barnett (2008), Faraway (2006), and McCullagh and Nelder (1989) are standard references; the last is the canonical reference, but also the most challenging).
  • -
  • All of the issues that arise with regular linear or generalized-linear modeling (e.g.: inadequacy of p-values alone for thorough statistical analysis; need to understand how models are parameterized; need to understand the principle of marginality and how interactions can be treated; dangers of overfitting, which are not mitigated by stepwise procedures; the non-existence of free lunches) also apply, and can apply more severely, to mixed models.
  • -
  • When SAS (or Stata, or Genstat/AS-REML or …) and R differ in their answers, R may not be wrong. Both SAS and R may be `right’ but proceeding in a different way/answering different questions/using a different philosophical approach (or both may be wrong …)
  • -
  • The advice in this FAQ comes with absolutely no warranty of any sort.
  • +
  • (G)LMMs are hard - harder than you may think based on what you may +have learned in your second statistics class, which probably focused on +picking the appropriate sums of squares terms and degrees of freedom for +the numerator and denominator of an \(F\) test. ‘Modern’ mixed model approaches, +although more powerful (they can handle more complex designs, lack of +balance, crossed random factors, some kinds of non-Normally distributed +responses, etc.), also require a new set of conceptual tools. In order +to use these tools you should have at least a general acquaintance with +classical mixed-model experimental designs but you should also, +probably, read something about modern mixed model approaches. Littell et al. (2006) and Pinheiro and Bates (2000) are two places to +start, although Pinheiro and Bates is probably more useful if you want +to use R. Other useful references include Gelman +and Hill (2006) (focused on Bayesian methods) and Zuur et al. (2009b). If you are going to use +generalized linear mixed models, you should understand generalized +linear models (Dobson and Barnett (2008), +Faraway (2006), and McCullagh and Nelder (1989) are standard +references; the last is the canonical reference, but also the most +challenging).
  • +
  • All of the issues that arise with regular linear or +generalized-linear modeling (e.g.: inadequacy of p-values alone for +thorough statistical analysis; need to understand how models are +parameterized; need to understand the principle of marginality and how +interactions can be treated; dangers of overfitting, which are not +mitigated by stepwise procedures; the non-existence of free lunches) +also apply, and can apply more severely, to mixed models.
  • +
  • When SAS (or Stata, or Genstat/AS-REML or …) and R differ in their +answers, R may not be wrong. Both SAS and R may be `right’ but +proceeding in a different way/answering different questions/using a +different philosophical approach (or both may be wrong …)
  • +
  • The advice in this FAQ comes with absolutely no warranty of +any sort.
@@ -1109,7 +1374,8 @@

linear mixed models

@@ -1117,8 +1383,10 @@

web/open

books (dead-tree/closed)

  • pinheiro_mixed-effects_2000: LMM only.
  • -
  • Zuur et al. (2009b): Focused on ecology.
  • -
  • Gelman and Hill (2006): LMM and GLMM; Bayesian; examples from social science. Intermediate mathematics.
  • +
  • Zuur et al. (2009b): Focused on +ecology.
  • +
  • Gelman and Hill (2006): LMM and GLMM; +Bayesian; examples from social science. Intermediate mathematics.
  • (Rethinking)
@@ -1128,18 +1396,21 @@

books (dead-tree/closed)

Model definition

Model specification

-

The following formula extensions for specifying random-effects structures in R are used by

+

The following formula extensions for specifying random-effects +structures in R are used by

  • lme4
  • -
  • nlme (nested effects only, although crossed effects can be specified with more work)
  • +
  • nlme (nested effects only, although crossed effects can +be specified with more work)
  • glmmADMB and glmmTMB
-

MCMCglmm uses a different specification, inherited from AS-REML.

+

MCMCglmm uses a different specification, inherited from +AS-REML.

(Modified from Robin Jeffries, UCLA:)

--++ @@ -1153,28 +1424,39 @@

Model specification

- - + + - - + + - + - - + + - + - - + + @@ -1182,19 +1464,22 @@

Model specification

- + - +
random group intercept
(x|group) = (1+x|group)random slope of x within group with correlated intercept(x|group) = +(1+x|group)random slope of x within group with correlated +intercept
(0+x|group) = (-1+x|group)random slope of x within group: no variation in intercept(0+x|group) = +(-1+x|group)random slope of x within group: no variation in +intercept
(1|group) + (0+x|group)uncorrelated random intercept and random slope within groupuncorrelated random intercept and random slope within +group
(1|site/block) = (1|site)+(1|site:block)intercept varying among sites and among blocks within sites (nested random effects)(1|site/block) = +(1|site)+(1|site:block)intercept varying among sites and among blocks within +sites (nested random effects)
site+(1|site:block)fixed effect of sites plus random variation in intercept among blocks within sitesfixed effect of sites plus random variation in +intercept among blocks within sites
(x|site/block) = (x|site)+(x|site:block) = (1 + x|site)+(1+x|site:block)slope and intercept varying among sites and among blocks within sites(x|site/block) = +(x|site)+(x|site:block) = +(1 + x|site)+(1+x|site:block)slope and intercept varying among sites and among +blocks within sites
(x1|site)+(x2|block)
x*site+(x|site:block)fixed effect variation of slope and intercept varying among sites and random variation of slope and intercept among blocks within sitesfixed effect variation of slope and intercept varying +among sites and random variation of slope and intercept among blocks +within sites
(1|group1)+(1|group2)intercept varying among crossed random effects (e.g. site, year)intercept varying among crossed random effects (e.g. +site, year)

Or in a little more detail:

--++ @@ -1204,19 +1489,23 @@

Model specification

- + - + - + - + @@ -1224,26 +1513,33 @@

Model specification

- + - +
\(β_0 + β_{1}X_{i} + e_{si}\)\(β_0 + β_{1}X_{i} + +e_{si}\) n/a (Not a mixed-effects model)
\((β_0 + b_{S,0s}) + β_{1}X_i + e_{si}\)\((β_0 + b_{S,0s}) + β_{1}X_i ++ e_{si}\) ∼ X + (1∣Subject)
\((β_0 + b_{S,0s}) + (β_{1} + b_{S,1s}) X_i + e_{si}\)\((β_0 + b_{S,0s}) + (β_{1} + +b_{S,1s}) X_i + e_{si}\) ~ X + (1 + X∣Subject)
\((β_0 + b_{S,0s} + b_{I,0i}) + (β_{1} + b_{S,1s}) X_i + e_{si}\)\((β_0 + b_{S,0s} + b_{I,0i}) ++ (β_{1} + b_{S,1s}) X_i + e_{si}\) ∼ X + (1 + X∣Subject) + (1∣Item)
∼ X + (1∣Subject) + (0 + X∣ Subject) + (1∣Item)
\((β_0 + b_{S,0s} + b_{I,0i}) + β_{1}X_i + e_{si}\)\((β_0 + b_{S,0s} + b_{I,0i}) ++ β_{1}X_i + e_{si}\) ∼ X + (1∣Subject) + (1∣Item)
\((β_0 + b_{I,0i}) + (β_{1} + b_{S,1s})X_i + e_{si}\)\((β_0 + b_{I,0i}) + (β_{1} + +b_{S,1s})X_i + e_{si}\) ∼ X + (0 + X∣Subject) + (1∣Item)
-

Modified from: http://stats.stackexchange.com/questions/13166/rs-lmer-cheat-sheet?lq=1 (Livius)

-

The magic development version of the equatiomatic package can handle mixed models (remotes::install_github("datalorax/equatiomatic")), e.g.

+

Modified from: http://stats.stackexchange.com/questions/13166/rs-lmer-cheat-sheet?lq=1 +(Livius)

+

The magic development version of the equatiomatic +package can handle mixed models +(remotes::install_github("datalorax/equatiomatic")), +e.g.

library(lme4)
 library(equatiomatic)
 fm1 <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
 equatiomatic::extract_eq(fm1)

\[ \begin{aligned} - \operatorname{Reaction}_{i} &\sim N \left(\alpha_{j[i]} + \beta_{1j[i]}(\operatorname{Days}), \sigma^2 \right) \\ + \operatorname{Reaction}_{i} &\sim N \left(\alpha_{j[i]} + +\beta_{1j[i]}(\operatorname{Days}), \sigma^2 \right) \\ \left( - \begin{array}{c} + \begin{array}{c} \begin{aligned} &\alpha_{j} \\ &\beta_{1j} @@ -1252,68 +1548,196 @@

Model specification

\right) &\sim N \left( \left( - \begin{array}{c} + \begin{array}{c} \begin{aligned} &\mu_{\alpha_{j}} \\ &\mu_{\beta_{1j}} \end{aligned} \end{array} \right) -, +, \left( \begin{array}{cc} - \sigma^2_{\alpha_{j}} & \rho_{\alpha_{j}\beta_{1j}} \\ + \sigma^2_{\alpha_{j}} & \rho_{\alpha_{j}\beta_{1j}} \\ \rho_{\beta_{1j}\alpha_{j}} & \sigma^2_{\beta_{1j}} \end{array} \right) - \right) +\right) \text{, for Subject j = 1,} \dots \text{,J} \end{aligned} \]

-

It doesn’t handle GLMMs (yet), but you could fit two fake models — one LMM like your GLMM but with a Gaussian response, and one GLM with the same family/link function as your GLMM but without the random effects — and put the pieces together.

+

It doesn’t handle GLMMs (yet), but you could fit two fake models — +one LMM like your GLMM but with a Gaussian response, and one GLM with +the same family/link function as your GLMM but without the random +effects — and put the pieces together.

More possibly useful links:

Should I treat factor xxx as fixed or random?

-

This is in general a far more difficult question than it seems on the surface. There are many competing philosophies and definitions. For example, from Gelman (2005):

+

This is in general a far more difficult question than it seems on the +surface. There are many competing philosophies and definitions. For +example, from Gelman (2005):

-

Before discussing the technical issues, we briefly review what is meant by fixed and random effects. It turns out that different—in fact, incompatible—definitions are used in different contexts. [See also Kreft and de Leeuw (1998), Section 1.3.3, for a discussion of the multiplicity of definitions of fixed and random effects and coefficients, and Robinson (1998) for a historical overview.] Here we outline five definitions that we have seen: 1. Fixed effects are constant across individuals, and random effects vary. For example, in a growth study, a model with random intercepts αi and fixed slope β corresponds to parallel lines for different individuals i, or the model yit = αi + βt. Kreft and de Leeuw [(1998), page 12] thus distinguish between fixed and random coefficients. 2. Effects are fixed if they are interesting in themselves or random if there is interest in the underlying population. Searle, Casella and McCulloch [(1992), Section 1.4] explore this distinction in depth. 3. “When a sample exhausts the population, the corresponding variable is fixed; when the sample is a small (i.e., negligible) part of the population the corresponding variable is random” [Green and Tukey (1960)]. 4. “If an effect is assumed to be a realized value of a random variable, it is called a random effect” [LaMotte (1983)]. 5. Fixed effects are estimated using least squares (or, more generally, maximum likelihood) and random effects are estimated with shrinkage [“linear unbiased prediction” in the terminology of Robinson (1991)]. This definition is standard in the multilevel modeling literature [see, e.g., Snijders and Bosker (1999), Section 4.2] and in econometrics.

+

Before discussing the technical issues, we briefly review what is +meant by fixed and random effects. It turns out that different—in fact, +incompatible—definitions are used in different contexts. [See also Kreft +and de Leeuw (1998), Section 1.3.3, for a discussion of the multiplicity +of definitions of fixed and random effects and coefficients, and +Robinson (1998) for a historical overview.] Here we outline five +definitions that we have seen: 1. Fixed effects are constant across +individuals, and random effects vary. For example, in a growth study, a +model with random intercepts αi and fixed slope β corresponds to +parallel lines for different individuals i, or the model yit = αi + βt. +Kreft and de Leeuw [(1998), page 12] thus distinguish between fixed and +random coefficients. 2. Effects are fixed if they are interesting in +themselves or random if there is interest in the underlying population. +Searle, Casella and McCulloch [(1992), Section 1.4] explore this +distinction in depth. 3. “When a sample exhausts the population, the +corresponding variable is fixed; when the sample is a small (i.e., +negligible) part of the population the corresponding variable is random” +[Green and Tukey (1960)]. 4. “If an effect is assumed to be a realized +value of a random variable, it is called a random effect” [LaMotte +(1983)]. 5. Fixed effects are estimated using least squares (or, more +generally, maximum likelihood) and random effects are estimated with +shrinkage [“linear unbiased prediction” in the terminology of Robinson +(1991)]. This definition is standard in the multilevel modeling +literature [see, e.g., Snijders and Bosker (1999), Section 4.2] and in +econometrics.

-

Another useful comment (via Kevin Wright) reinforcing the idea that “random vs. fixed” is not a simple, cut-and-dried decision: from Schabenberger and Pierce (2001), p. 627:

+

Another useful comment (via Kevin Wright) reinforcing the idea that +“random vs. fixed” is not a simple, cut-and-dried decision: from Schabenberger and Pierce (2001), p. 627:

-

Before proceeding further with random field linear models we need to remind the reader of the adage that one modeler’s random effect is another modeler’s fixed effect.

+

Before proceeding further with random field linear models we need to +remind the reader of the adage that one modeler’s random effect is +another modeler’s fixed effect.

-

Clark and Linzer (2015) address this question from a mostly econometric perspective, focusing mostly on practical variance/bias/RMSE criteria.

-

One point of particular relevance to ‘modern’ mixed model estimation (rather than ‘classical’ method-of-moments estimation) is that, for practical purposes, there must be a reasonable number of random-effects levels (e.g. blocks) – more than 5 or 6 at a minimum. This is not surprising if you consider that random effects estimation is trying to estimate an among-block variance. For example, from Crawley (2002) p. 670:

+

Clark and Linzer (2015) address this +question from a mostly econometric perspective, focusing mostly on +practical variance/bias/RMSE criteria.

+

One point of particular relevance to ‘modern’ mixed model estimation +(rather than ‘classical’ method-of-moments estimation) is that, for +practical purposes, there must be a reasonable number of random-effects +levels (e.g. blocks) – more than 5 or 6 at a minimum. This is not +surprising if you consider that random effects estimation is trying to +estimate an among-block variance. For example, from Crawley (2002) p. 670:

-

Are there enough levels of the factor in the data on which to base an estimate of the variance of the population of effects? No, means [you should probably treat the variable as] fixed effects.

+

Are there enough levels of the factor in the data on which to base an +estimate of the variance of the population of effects? No, means [you +should probably treat the variable as] fixed effects.

-

Some researchers (who treat fixed vs random as a philosophical rather than a pragmatic decision) object to this approach.

-

Also see a very thoughtful chapter in Hodges (2016).

-

Treating factors with small numbers of levels as random will in the best case lead to very small and/or imprecise estimates of random effects; in the worst case it will lead to various numerical difficulties such as lack of convergence, zero variance estimates, etc.. (A small simulation exercise shows that at least the estimates of the standard deviation are downwardly biased in this case; it’s not clear whether/how this bias would affect the point estimates of fixed effects or their estimated confidence intervals.) In the classical method-of-moments approach these problems may not arise (because the sums of squares are always well defined as long as there are at least two units), but the underlying problems of lack of power are there nevertheless.

-

Thierry Onkelinx has a blog post with some simulations on the impact of the number of levels and concludes with a few recommendations for the number of levels of the grouping variable \(n_s\): > - get \(n_s > 1000\) levels when an accurate estimate of the random effect variance is crucial. E.g. when a single number will be use for power calculations. > - get \(n_s > 100\) levels when a reasonable estimate of the random effect variance is sufficient. E.g. power calculations with sensitivity analysis of the random effect variance. > - get \(n_s > 20\) levels for an experimental study > - in case \(10 < n_s <20\) you should validate the model very cautious before using the output > - in case \(n_s < 10\) it is safer to use the variable as a fixed effect.

-

Oberpriller, Leite, and Pichler (2021) also performed a simulation study and found that while the estimates are similar for treating a variable with a small number of levels as fixed or random are similar, there was an impact on Type 1 and Type 2 error rates. They also found that the precise random effects structure (e.g., inclusion of random slopes) had a large impact on these properties.

-

Also see this thread on the r-sig-mixed-models mailing list and this question on CrossValidated.

+

Some researchers (who treat fixed vs random as a philosophical rather +than a pragmatic decision) object to this approach.

+

Also see a very thoughtful chapter in Hodges +(2016).

+

Treating factors with small numbers of levels as random will in the +best case lead to very small and/or imprecise estimates of random +effects; in the worst case it will lead to various numerical +difficulties such as lack of convergence, zero variance estimates, etc.. +(A small simulation exercise +shows that at least the estimates of the standard deviation are +downwardly biased in this case; it’s not clear whether/how this bias +would affect the point estimates of fixed effects or their estimated +confidence intervals.) In the classical method-of-moments approach these +problems may not arise (because the sums of squares are always well +defined as long as there are at least two units), but the underlying +problems of lack of power are there nevertheless.

+

Thierry Onkelinx has a +blog post with some simulations on the impact of the number of +levels and concludes with a few recommendations for the number of levels +of the grouping variable \(n_s\): > +- get \(n_s > 1000\) levels when an +accurate estimate of the random effect variance is crucial. E.g. when a +single number will be use for power calculations. > - get \(n_s > 100\) levels when a reasonable +estimate of the random effect variance is sufficient. E.g. power +calculations with sensitivity analysis of the random effect variance. +> - get \(n_s > 20\) levels for +an experimental study > - in case \(10 < +n_s <20\) you should validate the model very cautious before +using the output > - in case \(n_s < +10\) it is safer to use the variable as a fixed effect.

+

Oberpriller, Leite, and Pichler (2021) +also performed a simulation study and found that while the estimates are +similar for treating a variable with a small number of levels as fixed +or random are similar, there was an impact on Type 1 and Type 2 error +rates. They also found that the precise random effects structure (e.g., +inclusion of random slopes) had a large impact on these properties.

+

Also see this +thread on the r-sig-mixed-models mailing list and this +question on CrossValidated.

Nested or crossed?

    -
  • Relatively few mixed effect modeling packages can handle crossed random effects, i.e. those where one level of a random effect can appear in conjunction with more than one level of another effect. (This definition is confusing, and I would happily accept a better one.) A classic example is crossed temporal and spatial effects. If there is random variation among temporal blocks (e.g. years) ‘’and’’ random variation among spatial blocks (e.g. sites), ‘’and’’ if there is a consistent year effect across sites and ‘’vice versa’’, then the random effects should be treated as crossed.
  • +
  • Relatively few mixed effect modeling packages can handle crossed +random effects, i.e. those where one level of a random effect can appear +in conjunction with more than one level of another effect. (This +definition is confusing, and I would happily accept a better one.) A +classic example is crossed temporal and spatial effects. If there is +random variation among temporal blocks (e.g. years) ‘’and’’ random +variation among spatial blocks (e.g. sites), ‘’and’’ if there is a +consistent year effect across sites and ‘’vice versa’’, then the random +effects should be treated as crossed.
  • lme4 does handled crossed effects, efficiently
  • -
  • if you need to deal with crossed REs in conjunction with some of the features that nlme offers (e.g. heteroscedasticity of residuals via weights/varStruct, correlation of residuals via correlation/corStruct, or if you want to used crossed REs with the gamlss package, see p. 163ff of Pinheiro and Bates (2000) (section 4.2.2: Google books link). I give a worked example here. As far as I can tell, a couple of hacks are necessary to get this to work: (1) the data must be expressed as a groupedData object (at least, I haven’t managed to get it to work in any other way); (2) the crossed effects must be nested within another grouping factor - in the example here I define a dummy group, which is awkward (it makes the variance component for this group and the residual variance jointly unidentifiable), but otherwise seems to work OK.
  • -
  • I rarely find it useful to think of fixed effects as “nested” (although others disagree); if for example treatments A and B are only measured in block 1, and treatments C and D are only measured in block 2, one still assumes (because they are fixed effects) that each treatment would have the same effect if applied in the other block. (One might like to estimate treatment-by-block interactions, but in this case the experimental design doesn’t allow it; one would have to have multiple treatments measured within each block, although not necessarily all treatments in every block.) One would code this analysis as response~treatment+(1|block) in lme4. Also, in the case of fixed effects, crossed and nested specifications change the parameterization of the model, but not anything else (e.g. the number of parameters estimated, log-likelihood, model predictions are all identical). That is, in R’s model.matrix function (which implements a version of Wilkinson-Rogers notation) a*b and a/b (which expand to 1+a+b+a:b and 1+a+a:b respectively) give model matrices with the same number of columns.
  • -
  • Whether you explicitly specify a random effect as nested or not depends (in part) on the way the levels of the random effects are coded. If the ‘lower-level’ random effect is coded with unique levels, then the two syntaxes (1|a/b) (or (1|a)+(1|a:b)) and (1|a)+(1|b) are equivalent. If the lower-level random effect has the same labels within each larger group (e.g. blocks 1, 2, 3, 4 within sites A, B, and C) then the explicit nesting (1|a/b) is required. It seems to be considered best practice to code the nested level uniquely (e.g. A1, A2, …, B1, B2, …) so that confusion between nested and crossed effects is less likely.
  • +
  • if you need to deal with crossed REs in conjunction with some of the +features that nlme offers (e.g. heteroscedasticity of +residuals via weights/varStruct, correlation +of residuals via correlation/corStruct, or if +you want to used crossed REs with the gamlss package, see +p. 163ff of Pinheiro and Bates (2000) +(section 4.2.2: Google books +link). I give a worked example here. +As far as I can tell, a couple of hacks are necessary to get this to +work: (1) the data must be expressed as a groupedData +object (at least, I haven’t managed to get it to work in any other way); +(2) the crossed effects must be nested within another grouping +factor - in the example here I define a dummy group, which is +awkward (it makes the variance component for this group and the residual +variance jointly unidentifiable), but otherwise seems to work OK.
  • +
  • I rarely find it useful to think of fixed effects as “nested” +(although others disagree); if for example treatments A and B are only +measured in block 1, and treatments C and D are only measured in block +2, one still assumes (because they are fixed effects) that each +treatment would have the same effect if applied in the other block. (One +might like to estimate treatment-by-block interactions, but in this case +the experimental design doesn’t allow it; one would have to have +multiple treatments measured within each block, although not necessarily +all treatments in every block.) One would code this analysis as +response~treatment+(1|block) in lme4. Also, in +the case of fixed effects, crossed and nested specifications change the +parameterization of the model, but not anything else (e.g. the number of +parameters estimated, log-likelihood, model predictions are all +identical). That is, in R’s model.matrix function (which +implements a version of Wilkinson-Rogers notation) a*b and +a/b (which expand to 1+a+b+a:b and +1+a+a:b respectively) give model matrices with the same +number of columns.
  • +
  • Whether you explicitly specify a random effect as nested or not +depends (in part) on the way the levels of the random effects are coded. +If the ‘lower-level’ random effect is coded with unique levels, then the +two syntaxes (1|a/b) (or (1|a)+(1|a:b)) and +(1|a)+(1|b) are equivalent. If the lower-level random +effect has the same labels within each larger group (e.g. blocks 1, 2, +3, 4 within sites A, B, and C) then the explicit nesting +(1|a/b) is required. It seems to be considered best +practice to code the nested level uniquely (e.g. A1, A2, …, B1, B2, …) +so that confusion between nested and crossed effects is less +likely.

(When) can I include a predictor as both fixed and random?

-

See blog post by Thierry Onkelinx

+

See blog post by +Thierry Onkelinx

@@ -1324,11 +1748,38 @@

Overdispersion

Testing for overdispersion/computing overdispersion factor

    -
  • with the usual caveats, plus a few extras – counting degrees of freedom, etc. – the usual procedure of calculating the sum of squared Pearson residuals and comparing it to the residual degrees of freedom should give at least a crude idea of overdispersion. The following attempt counts each variance or covariance parameter as one model degree of freedom and presents the sum of squared Pearson residuals, the ratio of (SSQ residuals/rdf), the residual df, and the \(p\)-value based on the (approximately!!) appropriate \(\chi^2\) distribution. Do PLEASE note the usual, and extra, caveats noted here: this is an APPROXIMATE estimate of an overdispersion parameter. Even in the GLM case, the expected deviance per point equaling 1 is only true as the distribution of individual deviates approaches normality, i.e. the usual \(\lambda>5\) rules of thumb for Poisson values and \(\textrm{min}(Np, N(1-p)) > 5\) for binomial values (e.g. see Venables and Ripley (2002), p. 208-209). (And that’s without the extra complexities due to GLMM, i.e. the “effective” residual df should be large enough to make the sums of squares converge on a \(\chi^2\) distribution …)
  • -
  • Remember that (1) overdispersion is irrelevant for models that estimate a scale parameter (i.e. almost anything but Poisson or binomial: Gaussian, Gamma, negative binomial …) and (2) overdispersion is not estimable (and hence practically irrelevant) for Bernoulli models (= binary data = binomial with \(N=1\)).
  • -
  • The recipes below may need adjustment for some of the more complex model types allowed by glmmTMB (e.g. zero-inflation/variable dispersion), where it’s less clear what to measure to estimate overdispersion.
  • +
  • with the usual caveats, plus a few extras – counting degrees of +freedom, etc. – the usual procedure of calculating the sum of squared +Pearson residuals and comparing it to the residual degrees of freedom +should give at least a crude idea of overdispersion. The following +attempt counts each variance or covariance parameter as one model degree +of freedom and presents the sum of squared Pearson residuals, the ratio +of (SSQ residuals/rdf), the residual df, and the \(p\)-value based on the (approximately!!) +appropriate \(\chi^2\) distribution. +Do PLEASE note the usual, and extra, caveats noted here: this is +an APPROXIMATE estimate of an overdispersion parameter. Even in +the GLM case, the expected deviance per point equaling 1 is only true as +the distribution of individual deviates approaches normality, i.e. the +usual \(\lambda>5\) rules of thumb +for Poisson values and \(\textrm{min}(Np, +N(1-p)) > 5\) for binomial values (e.g. see Venables and Ripley (2002), p. 208-209). +(And that’s without the extra complexities due to GLMM, i.e. the +“effective” residual df should be large enough to make the sums of +squares converge on a \(\chi^2\) +distribution …)
  • +
  • Remember that (1) overdispersion is irrelevant for models that +estimate a scale parameter (i.e. almost anything but Poisson or +binomial: Gaussian, Gamma, negative binomial …) and (2) overdispersion +is not estimable (and hence practically irrelevant) for Bernoulli models +(= binary data = binomial with \(N=1\)).
  • +
  • The recipes below may need adjustment for some of the more complex +model types allowed by glmmTMB +(e.g. zero-inflation/variable dispersion), where it’s less clear what to +measure to estimate overdispersion.
-

The following function should work for a variety of model types (at least glmmADMB, glmmTMB, lme4, …).

+

The following function should work for a variety of model types (at +least glmmADMB, glmmTMB, lme4, +…).

overdisp_fun <- function(model) {
     rdf <- df.residual(model)
     rp <- residuals(model,type="pearson")
@@ -1354,13 +1805,26 @@ 

Testing for overdispersion/computing overdispersion factor

overdisp_fun(m2)
##        chisq        ratio          rdf            p 
 ## 1035.9961394    1.0391135  997.0000000    0.1902323
-

The gof function in the aods3 provides similar functionality (it reports both deviance- and \(\chi^2\)-based estimates of overdispersion and tests).

+

The gof function in the aods3 provides +similar functionality (it reports both deviance- and \(\chi^2\)-based estimates of overdispersion +and tests).

Fitting models with overdispersion?

    -
  • quasilikelihood estimation: MASS::glmmPQL. Quasi- was deemed unreliable in lme4, and is no longer available. (Part of the problem was questionable numerical results in some cases; the other problem was that DB felt that he did not have a sufficiently good understanding of the theoretical framework that would explain what the algorithm was actually estimating in this case.) geepack::geelgm may be workable (haven’t tried it)

    -

    If you really want quasi-likelihood analysis for glmer fits, you can do it yourself by adjusting the coefficient table - i.e., by multiplying the standard error by the square root of the dispersion factor2 and recomputing the \(Z\)- and \(p\)-values accordingly, as follows:

  • +
  • quasilikelihood estimation: MASS::glmmPQL. +Quasi- was deemed unreliable in lme4, and is no longer +available. (Part of the problem was questionable numerical results in +some cases; the other problem was that DB felt that he did not have a +sufficiently good understanding of the theoretical framework that would +explain what the algorithm was actually estimating in this case.) geepack::geelgm +may be workable (haven’t tried it)

    +

    If you really want quasi-likelihood analysis for glmer +fits, you can do it yourself by adjusting the coefficient table - i.e., +by multiplying the standard error by the square root of the dispersion +factor 2 +and recomputing the \(Z\)- and \(p\)-values accordingly, as +follows:

## extract summary table; you may also be able to do this via
 ##  broom::tidy or broom.mixed::tidy
@@ -1413,118 +1877,283 @@ 

Fitting models with overdispersion?

## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> ## 1 fixed cond (Intercept) 0.228 0.270 0.843 0.399 ## 2 fixed cond x 2.06 0.0528 39.1 0
-

These functions make some simplifying assumptions: (1) this overdispersion computation is approximate

-

In this case using quasi-likelihood doesn’t make much difference, since the data we simulated in the first place were Poisson.) Keep in mind that once you switch to quasi-likelihood you will either have to eschew inferential methods such as the likelihood ratio test, profile confidence intervals, AIC, etc., or make more heroic assumptions to compute “quasi-” analogs of all of the above (such as QAIC).

+

These functions make some simplifying assumptions: (1) this +overdispersion computation is approximate

+

In this case using quasi-likelihood doesn’t make much difference, +since the data we simulated in the first place were Poisson.) Keep in +mind that once you switch to quasi-likelihood you will either have to +eschew inferential methods such as the likelihood ratio test, profile +confidence intervals, AIC, etc., or make more heroic assumptions to +compute “quasi-” analogs of all of the above (such as QAIC).

    -
  • observation-level random effects (OLRE: this approach should work in most packages). If you want to a citation for this approach, try Elston et al. (2001), who cite Lawson et al. (1999); apparently there is also an example in section 10.5 of Maindonald and Braun (2010), and (according to an R-sig-mixed-models post) this is also discussed by Rabe-Hesketh and Skrondal (2008). Also see Browne et al. (2005) for an example in the binomial context (i.e. logit-normal-binomial rather than lognormal-Poisson). Agresti’s excellent (2002) book Agresti (2002) also discusses this (section 13.5), referring back to Breslow (1984) and Hinde (1982). [Notes: (a) I haven’t checked all these references myself, (b) I can’t find the reference any more, but I have seen it stated that observation-level random effect estimation is probably dodgy for PQL approaches as used in Elston et al 2001]
  • +
  • observation-level random effects (OLRE: this approach should work in +most packages). If you want to a citation for this approach, try Elston et al. (2001), who cite Lawson et al. (1999); apparently there is also +an example in section 10.5 of Maindonald and +Braun (2010), and (according to an R-sig-mixed-models post) this +is also discussed by Rabe-Hesketh and Skrondal +(2008). Also see Browne et al. +(2005) for an example in the binomial context +(i.e. logit-normal-binomial rather than lognormal-Poisson). Agresti’s +excellent (2002) book Agresti (2002) also +discusses this (section 13.5), referring back to Breslow (1984) and Hinde +(1982). [Notes: (a) I haven’t checked all these +references myself, (b) I can’t find the reference any more, but I have +seen it stated that observation-level random effect estimation is +probably dodgy for PQL approaches as used in Elston et al 2001]
  • alternative distributions
      -
    • Poisson-lognormal model for counts or binomial-logit-Normal model for proportions (see above, “observation-level random effects”)
    • +
    • Poisson-lognormal model for counts or binomial-logit-Normal model +for proportions (see above, “observation-level random effects”)
    • negative binomial for counts or beta-binomial for proportions
        -
      • lme4::glmer.nb() should fit a negative binomial, although it is somewhat slow and fragile compared to some of the other methods suggested here. lme4 cannot fit beta-binomial models (these cannot be formulated as a part of the exponential family of distributions)
      • -
      • glmmTMB will fit two parameterizations of the negative binomial: family="nbinom2" gives the classic parameterization with \(\sigma^2=\mu(1+\mu/k)\) (“NB2” in Hardin and Hilbe’s terminology) while family="nbinom1" gives a parameterization with \(\sigma^2=\phi \mu\), \(\phi>1\) (“NB1” to Hardin and Hilbe). The latter might also be called a “quasi-Poisson” parameterization because it matches the mean-variance relationship assumed by quasi-Poisson models, i.e. the variance is strictly proportional to the mean (although the proportionality constant must be >1, a limitation that does not apply to quasi-likelihood approaches). (glmmADMB will also fit these models, with family="nbinom" for NB2, but is deprecated in favour of glmmTMB.)
      • -
      • glmmTMB allows beta-binomial models ((Harrison 2015) suggests comparing beta-binomial with OLRE models to assess reliability)
      • -
      • the brms package has a negbinomial family (no beta-binomial, but it does have a wide range of other families)
      • +
      • lme4::glmer.nb() should fit a negative binomial, +although it is somewhat slow and fragile compared to some of the other +methods suggested here. lme4 cannot fit beta-binomial +models (these cannot be formulated as a part of the exponential family +of distributions)
      • +
      • glmmTMB will fit +two parameterizations of the negative binomial: +family="nbinom2" gives the classic parameterization with +\(\sigma^2=\mu(1+\mu/k)\) (“NB2” in +Hardin and Hilbe’s terminology) while family="nbinom1" +gives a parameterization with \(\sigma^2=\phi +\mu\), \(\phi>1\) (“NB1” to +Hardin and Hilbe). The latter might also be called a “quasi-Poisson” +parameterization because it matches the mean-variance relationship +assumed by quasi-Poisson models, i.e. the variance is strictly +proportional to the mean (although the proportionality constant must be +>1, a limitation that does not apply to quasi-likelihood approaches). +(glmmADMB will also +fit these models, with family="nbinom" for NB2, but is +deprecated in favour of glmmTMB.)
      • +
      • glmmTMB allows beta-binomial models ((Harrison 2015) suggests comparing beta-binomial +with OLRE models to assess reliability)
      • +
      • the brms package has a negbinomial family +(no beta-binomial, but it does have a wide range of other families)
  • -
  • other packages/approaches (less widely used, or requiring a bit more effort) +
  • other packages/approaches (less widely used, or requiring a bit more +effort)
    • gamlss.mx:gamlssNP
    • WinBUGS/JAGS (via R2WinBUGS/Rjags)
    • -
    • AD Model Builder (possibly via R2admb package) or TMB
    • +
    • AD Model Builder (possibly via R2admb package) or +TMB
    • gnlmm in the repeated package (off-CRAN)
    • ASREML
-

Negative binomial models in glmmTMB and lognormal-Poisson models in glmer (or MCMCglmm) are probably the best quick alternatives for overdispersed count data. If you need to explore alternatives (different variance-mean relationships, different distributions), then ADMB, TMB, WinBUGS, Stan, NIMBLE are the most flexible alternatives.

+

Negative binomial models in glmmTMB and +lognormal-Poisson models in glmer (or +MCMCglmm) are probably the best quick alternatives for +overdispersed count data. If you need to explore alternatives (different +variance-mean relationships, different distributions), then +ADMB, TMB, WinBUGS, +Stan, NIMBLE are the most flexible +alternatives.

Underdispersion

-

Underdispersion (much less variability than expected) is a less common problem than overdispersion.

+

Underdispersion (much less variability than expected) is a +less common problem than overdispersion.

    -
  • mild underdispersion is sometimes ignored, since it tends in general to lead to conservative rather than anti-conservative results
  • -
  • quasi-likelihood (and the quasi-hack listed above) can handle under- as well as overdispersion
  • +
  • mild underdispersion is sometimes ignored, since it tends in general +to lead to conservative rather than anti-conservative results
  • +
  • quasi-likelihood (and the quasi-hack listed above) can handle under- +as well as overdispersion
  • some other solutions exist, but are less widely implemented
      -
    • for distributions with a small range (e.g. litter sizes of large mammals), one can treat responses as ordinal (e.g. using the ordinal package, or MCMCglmm or brms for Bayesian solutions)
    • -
    • the COM-Poisson distribution and generalized Poisson distributions, implemented in glmmTMB, can handle underdispersion (J. Hilbe recommends the latter in this CrossValidated answer). (VGAM has a generalized Poisson distribution, but doesn’t handle random effects.)
    • +
    • for distributions with a small range (e.g. litter sizes of large +mammals), one can treat responses as ordinal (e.g. using the +ordinal package, or MCMCglmm or +brms for Bayesian solutions)
    • +
    • the COM-Poisson distribution and generalized Poisson distributions, +implemented in glmmTMB, can handle underdispersion (J. +Hilbe recommends the latter in this +CrossValidated answer). (VGAM has a generalized Poisson +distribution, but doesn’t handle random effects.)

Gamma GLMMs

-

While one (well, OK I) would naively think that GLMMs with Gamma distributions would be just as easy (or hard) as any other sort of GLMMs, it seems that they are in fact harder to implement. Basic simulated examples of Gamma GLMMs can fail in lme4 despite analogous problems with Poisson, binomial, etc. distributions. Solutions: - the default inverse link seems particularly problematic; try other links (especially family=Gamma(link="log")) if that is possible/makes sense - consider whether a lognormal model (i.e. a regular LMM on logged data) would work/makes sense. - Lo and Andrews (2015) argue that the Gamma family with an identity link is superior to lognormal models for reaction-time data. I (BMB) don’t find their argument particularly convincing, but lots of people want to do this. Unfortunately this is technically challenging (see here), because it is likely that some “illegal” values (predicted responses \(\le 0\)) will occur while fitting the model, even if the final fitted model makes no impossible predictions. Thus something has to be done to make the model-fitting machinery tolerant of such values (i.e. returning NA for these model evaluations, or clamping illegal values to the constrained space with an appropriate smooth penalty function).

-

Gamma models can be fitted by a wide variety of platforms (lme4::glmer, MASS::glmmPQL, glmmADMB, glmmTMB, MixedModels.jl, MCMCglmm, brms … not sure about others.

+

While one (well, OK I) would naively think that GLMMs with Gamma +distributions would be just as easy (or hard) as any other sort of +GLMMs, it seems that they are in fact harder to implement. Basic +simulated examples of Gamma GLMMs can fail in lme4 despite analogous +problems with Poisson, binomial, etc. distributions. Solutions: - the +default inverse link seems particularly problematic; try other links +(especially family=Gamma(link="log")) if that is +possible/makes sense - consider whether a lognormal model (i.e. a +regular LMM on logged data) would work/makes sense. - Lo and Andrews (2015) argue that the Gamma +family with an identity link is superior to lognormal models +for reaction-time data. I (BMB) don’t find their argument particularly +convincing, but lots of people want to do this. Unfortunately this is +technically challenging (see here), because it is +likely that some “illegal” values (predicted responses \(\le 0\)) will occur while fitting the +model, even if the final fitted model makes no impossible predictions. +Thus something has to be done to make the model-fitting machinery +tolerant of such values (i.e. returning NA for these model +evaluations, or clamping illegal values to the constrained space with an +appropriate smooth penalty function).

+

Gamma models can be fitted by a wide variety of platforms +(lme4::glmer, MASS::glmmPQL, +glmmADMB, glmmTMB, +MixedModels.jl, MCMCglmm, brms … +not sure about others.

Beta GLMMs

-

Proportion data where the denominator (e.g. maximum possible number of successes for a given observation) is not known can be modeled using a Beta distribution. Smithson and Verkuilen (2006) is a good introduction for non-statisticians (not in the mixed-model case), and the betareg package (Cribari-Neto and Zeileis 2009) handles non-mixed Beta regressions. The glmmTMB and brms packages handle Beta mixed models (brms also handles zero-inflated and zero-one inflated models).

+

Proportion data where the denominator (e.g. maximum possible number +of successes for a given observation) is not known can be modeled using +a Beta distribution. Smithson and Verkuilen +(2006) is a good introduction for non-statisticians (not +in the mixed-model case), and the betareg package (Cribari-Neto and Zeileis 2009) handles +non-mixed Beta regressions. The glmmTMB and +brms packages handle Beta mixed models (brms +also handles zero-inflated and zero-one inflated models).

Zero-inflation

-

See e.g. Martin et al. (2005) or Warton (2005) (“many zeros does not mean zero inflation”) or Zuur et al. (2009a) for general information on zero-inflation.

+

See e.g. Martin et al. (2005) or Warton (2005) (“many zeros does not mean zero +inflation”) or Zuur et al. (2009a) for +general information on zero-inflation.

Count data

    -
  • MCMCglmm handles zero-truncated, zero-inflated, and zero-altered models, although specifying the models is a little bit tricky: see Sections 5.3 to 5.5 of the CourseNotes vignette
  • +
  • MCMCglmm handles zero-truncated, zero-inflated, and +zero-altered models, although specifying the models is a little bit +tricky: see Sections 5.3 to 5.5 of the CourseNotes +vignette
  • glmmADMB handles
      -
    • zero-inflated models (with a single zero-inflation parameter – i.e., the level of zero-inflation is assumed constant across the whole data set)
    • -
    • truncated Poisson and negative binomial distributions (which allows two-stage fitting of hurdle models)
    • +
    • zero-inflated models (with a single zero-inflation parameter – i.e., +the level of zero-inflation is assumed constant across the whole data +set)
    • +
    • truncated Poisson and negative binomial distributions (which allows +two-stage fitting of hurdle models)
  • -
  • glmmTMB handles a variety of Z-I and Z-T models (allows covariates, and random effects, in the zero-alteration model)
  • +
  • glmmTMB handles a variety of Z-I and Z-T models (allows +covariates, and random effects, in the zero-alteration model)
  • brms does too
  • so does GLMMadaptive
  • -
  • Gavin Simpson has a detailed writeup showing that mgcv::gam() can do simple mixed models (Poisson, not NB) with zero-inflation, and comparing mgcv with glmmTMB results
  • -
  • gamlssNP in the gamlss.mx package should handle zero-inflation, and the gamlss.tr package should handle truncated (i.e. hurdle) models – but I haven’t tried them
  • +
  • Gavin Simpson has a detailed +writeup showing that mgcv::gam() can do simple mixed +models (Poisson, not NB) with zero-inflation, and comparing +mgcv with glmmTMB results
  • +
  • gamlssNP in the gamlss.mx package should +handle zero-inflation, and the gamlss.tr package should +handle truncated (i.e. hurdle) models – but I haven’t tried them
  • roll-your-own: ADMB/R2admb, WinBUGS/R2WinBUGS, TMB, Stan, …

Continuous data

-

Continuous data are a special case where the mixture model for zero-inflated data is less relevant, because observations that are exactly zero occur with probability (but not probability density) zero. There are two cases of interest:

+

Continuous data are a special case where the mixture model for +zero-inflated data is less relevant, because observations that are +exactly zero occur with probability (but not probability +density) zero. There are two cases of interest:

-

Probability density of \(x\) zero or infinite

-

In this case zero is a problematic observation for the distribution; it’s either impossible or infinitely (locally) likely. Some examples:

+

Probability density of \(x\) zero +or infinite

+

In this case zero is a problematic observation for the distribution; +it’s either impossible or infinitely (locally) likely. Some +examples:

    -
  • Gamma distribution: probability density at zero is infinite (if shape<1) or zero (if shape>1); it’s finite only for an exponential distribution (shape==1)
  • -
  • Lognormal distribution: the probability density at zero is zero.
  • -
  • Beta distribution: the probability densities at 0 and 1 are zero (if the corresponding shape parameter is >1) or infinite (if shape<1)
  • +
  • Gamma distribution: probability density at zero is infinite (if +shape<1) or zero (if shape>1); it’s finite only for an exponential +distribution (shape==1)
  • +
  • Lognormal distribution: the probability density at zero is +zero.
  • +
  • Beta distribution: the probability densities at 0 and 1 are zero (if +the corresponding shape parameter is >1) or infinite (if +shape<1)
-

The best solution depends very much on the data-generating mechanism.

+

The best solution depends very much on the data-generating +mechanism.

    -
  • If the bad (0/1) values are generated by rounding (e.g. proportions that are too close to the boundaries are reported as being on the boundaries), the simplest solution is to “squeeze” these in slightly, e.g. \(y \to (y +a)/2a\) for some sensible value of \(a\) (Smithson and Verkuilen 2006)
  • -
  • If you think that zero values are generated by a separate process, the simplest solution is to fit a Bernoulli model to the zero/non-zero data, then a conditional continuous model for the non-zero values; this is effectively a hurdle model.
  • -
  • you might have censored data where all values below a certain limit (e.g. a detection limit) are recorded as zero. The The lmec package handles linear mixed models; brms and GLMMadaptive both provide support for censored data in mixed models.
  • -
  • The cplm and glmmTMB packages handles ‘Tweedie compound Poisson linear models’, which in a particular range of parameters allows for skewed continuous responses with a spike at zero
  • +
  • If the bad (0/1) values are generated by rounding (e.g. proportions +that are too close to the boundaries are reported as being on the +boundaries), the simplest solution is to “squeeze” these in slightly, +e.g. \(y \to (y +a)/2a\) for some +sensible value of \(a\) (Smithson and Verkuilen 2006)
  • +
  • If you think that zero values are generated by a separate process, +the simplest solution is to fit a Bernoulli model to the zero/non-zero +data, then a conditional continuous model for the non-zero +values; this is effectively a hurdle model.
  • +
  • you might have censored data where all values below a +certain limit (e.g. a detection limit) are recorded as zero. The The lmec package handles +linear mixed models; brms and +GLMMadaptive both provide support for censored data in +mixed models.
  • +
  • The cplm and glmmTMB packages handles +‘Tweedie compound Poisson linear models’, which in a particular range of +parameters allows for skewed continuous responses with a spike at +zero
-

Probability density of \(x\) positive and finite

-

In this case (e.g. a spike of zeros in the center of an otherwise continuous distribution), the hurdle model probably makes the most sense.

+

Probability density of \(x\) +positive and finite

+

In this case (e.g. a spike of zeros in the center of an otherwise +continuous distribution), the hurdle model probably makes the most +sense.

Tests for zero-inflation

    -
  • you can use a likelihood ratio test between the regular and zero-inflated version of the model, but be aware of boundary issues (search “boundary” elsewhere on this page …) – the null value (no zero inflation) is on the boundary of the feasible space
  • +
  • you can use a likelihood ratio test between the regular and +zero-inflated version of the model, but be aware of boundary issues +(search “boundary” elsewhere on this page …) – the null value (no zero +inflation) is on the boundary of the feasible space
  • you can use AIC or variations, with the same caveats
  • -
  • you can use Vuong’s test, which is often recommended for testing zero-inflation in GLMs, because under some circumstances the various model flavors under consideration (hurdle vs zero-inflated vs “vanilla”) are not nested. Vuong’s test is implemented (and referenced) in the pscl package, but not for (G)LMMs. However, the nonnest package provides an example (in conjunction with the merDeriv package) for using its vuongtest function with merMod objects. (May also work with glmmTMB, haven’t tried it …)
  • +
  • you can use Vuong’s test, which is often recommended for testing +zero-inflation in GLMs, because under some circumstances the various +model flavors under consideration (hurdle vs zero-inflated vs “vanilla”) +are not nested. Vuong’s test is implemented (and referenced) in the +pscl package, but not for (G)LMMs. However, the +nonnest package provides an example (in conjunction with +the merDeriv package) for using its vuongtest +function with merMod objects. (May also work with +glmmTMB, haven’t tried it …)
  • two untested but reasonable approaches:
      -
    • use a simulate() method if it exists to construct a simulated distribution of the proportion of zeros expected overall from your model, and compare it to the observed proportion of zeros in the data set
    • -
    • compute the probability of a zero for each observation. On the basis of (conditionally) independent Bernoulli trials, compute the expected number of zeros and the confidence intervals – compare it with the observed number.
    • +
    • use a simulate() method if it exists to construct a +simulated distribution of the proportion of zeros expected overall from +your model, and compare it to the observed proportion of zeros in the +data set
    • +
    • compute the probability of a zero for each observation. On the basis +of (conditionally) independent Bernoulli trials, compute the expected +number of zeros and the confidence intervals – compare it with the +observed number.
-

Spatial and temporal correlation models, heteroscedasticity (“R-side” models)

-

In nlme these so-called R-side (R for “residual”) structures are accessible via the weights/VarStruct (heteroscedasticity) and correlation/corStruct (spatial or temporal correlation) arguments and data structures. This extension is a bit harder than it might seem. In LMMs it is a natural extension to allow the residual error terms to be components of a single multivariate normal draw; if that MVN distribution is uncorrelated and homoscedastic (i.e. proportional to an identity matrix) we get the classic model, but we can in principle allow it to be correlated and/or heteroscedastic.

-

It is not too hard to define marginal correlation structures that don’t make sense. One class of reasonably sensible models is to always assume an observation-level random effect (as MCMCglmm does for computational reasons) and to allow that random effect to be MVN on the link scale (so that the full model is lognormal-Poisson, logit-normal binomial, etc., depending on the link function and family).

-

For example, a relatively simple Poisson model with spatially correlated errors might look like this:

+

Spatial and temporal correlation models, heteroscedasticity +(“R-side” models)

+

In nlme these so-called R-side (R for +“residual”) structures are accessible via the +weights/VarStruct (heteroscedasticity) and +correlation/corStruct (spatial or temporal +correlation) arguments and data structures. This extension is a bit +harder than it might seem. In LMMs it is a natural extension to allow +the residual error terms to be components of a single multivariate +normal draw; if that MVN distribution is uncorrelated and homoscedastic +(i.e. proportional to an identity matrix) we get the classic model, but +we can in principle allow it to be correlated and/or +heteroscedastic.

+

It is not too hard to define marginal correlation structures that +don’t make sense. One class of reasonably sensible models is to always +assume an observation-level random effect (as MCMCglmm does for +computational reasons) and to allow that random effect to be MVN on the +link scale (so that the full model is lognormal-Poisson, logit-normal +binomial, etc., depending on the link function and family).

+

For example, a relatively simple Poisson model with spatially +correlated errors might look like this:

\[ \begin{split} \eta & \sim \textrm{MVN}(a + b x, \Sigma) \\ @@ -1532,36 +2161,82 @@

Spatial and temporal correlation models, heteroscedasticity (“R-side” mo y_i & \sim \textrm{Poisson}(\lambda=\exp(\eta_i)) \end{split} \]

-

That is, the marginal distributions of the response values are Poisson-lognormal, but on the link (log) scale the latent Normal variables underlying the response are multivariate normal, with a variance-covariance matrix described by an exponential spatial correlation function with scale parameter \(s\).

+

That is, the marginal distributions of the response values are +Poisson-lognormal, but on the link (log) scale the latent Normal +variables underlying the response are multivariate normal, with +a variance-covariance matrix described by an exponential spatial +correlation function with scale parameter \(s\).

How can one achieve this?

    -
  • These types of models are not implemented in lme4, for either LMMs or GLMMs; they are fairly low priority, and it is hard to see how they could be implemented for GLMMs (the equivalent for LMMs is tedious but should be straightforward to implement).
  • -
  • For LMMs, you can use the spatial/temporal correlation structures that are built into (n)lme
  • -
  • You can use the spatial/temporal correlation structures available for (n)lme, which include basic geostatistical (space) and ARMA-type (time) models.
  • +
  • These types of models are not implemented in lme4, for +either LMMs or GLMMs; they are fairly low priority, and it is hard to +see how they could be implemented for GLMMs (the equivalent for LMMs is +tedious but should be straightforward to implement).
  • +
  • For LMMs, you can use the spatial/temporal correlation structures +that are built into (n)lme
  • +
  • You can use the spatial/temporal correlation structures available +for (n)lme, which include basic geostatistical (space) and ARMA-type +(time) models.
library(sos)
 findFn("corStruct")
-

finds additional possibilities in the ramps (extended geostatistical) and ape (phylogenetic) packages.

+

finds additional possibilities in the ramps (extended +geostatistical) and ape (phylogenetic) packages.

    -
  • You can use these structures in GLMMs via MASS::glmmPQL (see Dormann et al.)
  • +
  • You can use these structures in GLMMs via MASS::glmmPQL +(see Dormann et al.)
  • geepack::geeglm
  • -
  • geoR, geoRglm (power tools); these are mostly designed for fitting spatial random field GLMMs via MCMC – not sure that they do random effects other than the spatial random effect
  • +
  • geoR, geoRglm (power tools); these are mostly designed for fitting +spatial random field GLMMs via MCMC – not sure that they do random +effects other than the spatial random effect
  • R-INLA (super-power tool)
  • -
  • it is possible to use AD Model Builder to fit spatial GLMMs, as shown in these AD Model Builder examples; this capability is not in the glmmADMB package (and may not be for a while!), but it would be possible to run AD Model Builder via the R2admb package (requires installing – and learning! ADMB)
  • -
  • geoBUGS, the geostatistical/spatial correlation module for WinBUGS, is another alternative (but again requires going outside of R)
  • +
  • it is possible to use AD Model Builder to fit spatial GLMMs, as +shown in these AD Model Builder +examples; this capability is not in the glmmADMB +package (and may not be for a while!), but it would be possible to run +AD Model Builder via the R2admb package (requires installing – and +learning! ADMB)
  • +
  • geoBUGS, +the geostatistical/spatial correlation module for WinBUGS, is another +alternative (but again requires going outside of R)

Penalization/handling complete separation

-

Complete separation occurs in a binary-response model when there is some linear combination of the parameters that perfectly separates failures from successes - for example, when all of the observations are zero for some particular combination of categories. The symptoms of this problem are unrealistically large parameter estimates; ridiculously large Wald standard errors (the Hauck-Donner effect); and various warnings.

-

In particular, binomial glmer() models with complete separation can lead to “Downdated VtV is not positive definite” (e.g. see here) or “PIRLS step-halvings failed to reduce deviance in pwrssUpdate” errors (e.g. see here). Roughly speaking, the complete separation is likely to appear even if one considers only the fixed effects part of the model (counterarguments or counterexamples welcome!), suggesting two quick-and-dirty diagnostic methods. If fixed_form is the formula including only the fixed effects:

+

Complete separation occurs in a binary-response model when +there is some linear combination of the parameters that perfectly +separates failures from successes - for example, when all of the +observations are zero for some particular combination of categories. The +symptoms of this problem are unrealistically large parameter estimates; +ridiculously large Wald standard errors (the Hauck-Donner +effect); and various warnings.

+

In particular, binomial glmer() models with complete +separation can lead to “Downdated VtV is not positive definite” +(e.g. see here) or +“PIRLS step-halvings failed to reduce deviance in pwrssUpdate” errors +(e.g. see here). +Roughly speaking, the complete separation is likely to appear even if +one considers only the fixed effects part of the model (counterarguments +or counterexamples welcome!), suggesting two quick-and-dirty diagnostic +methods. If fixed_form is the formula including only the +fixed effects:

    -
  • summary(g1 <- glm(fixed_form, family=binomial, data=...)) will show one or more of the following symptoms: +
  • summary(g1 <- glm(fixed_form, family=binomial, data=...)) +will show one or more of the following symptoms:
      -
    • warnings that glm.fit: fitted probabilities numerically 0 or 1 occurred
    • -
    • parameter estimates of large magnitude (e.g. any(abs(g1$coefficients)>8), assuming that predictors are either categorical or scaled to have standard deviations of \(\approx 1\))
    • -
    • extremely large Wald standard errors, and large p-values (Hauck-Donner effect)
    • -
    • the detectseparation package has a method for detecting complete separation: library("detectseparation"); update(g1,method="detect_separation"). This should say whether complete separation occurs, and in which (combinations of) variables, e.g.
    • +
    • warnings that +glm.fit: fitted probabilities numerically 0 or 1 occurred
    • +
    • parameter estimates of large magnitude +(e.g. any(abs(g1$coefficients)>8), assuming that +predictors are either categorical or scaled to have standard deviations +of \(\approx 1\))
    • +
    • extremely large Wald standard errors, and large p-values +(Hauck-Donner effect)
    • +
    • the detectseparation package has a method for detecting +complete separation: +library("detectseparation"); update(g1,method="detect_separation"). +This should say whether complete separation occurs, and in which +(combinations of) variables, e.g.
Separation: TRUE 
@@ -1569,14 +2244,43 @@ 

Penalization/handling complete separation

(Intercept) height Inf Inf 0: finite value, Inf: infinity, -Inf: -infinity
-

If complete separation is occurring between categories of a single categorical fixed-effect predictor with a large number of levels, one option would be to treat this fixed effect as a random effect, which will allow some degree of shrinkage to the mean. (It might be reasonable to specify the variance of this term a priori to a large value [minimal shrinkage], rather than trying to estimate it from the data.)

+

If complete separation is occurring between categories of a single +categorical fixed-effect predictor with a large number of levels, one +option would be to treat this fixed effect as a random effect, which +will allow some degree of shrinkage to the mean. (It might be reasonable +to specify the variance of this term a priori to a large value +[minimal shrinkage], rather than trying to estimate it from the +data.)

(TODO: worked example)

-

The general approach to handling complete separation in logistic regression is called penalized regression; it’s available in the brglm, brglm2, logistf, and rms packages. However, these packages don’t handle mixed models, so the best available general approach is to use a Bayesian method that allows you to set a prior on the fixed effects, e.g. a Gaussian with standard deviation of 3; this can be done in any of the Bayesian GLMM packages (e.g. blme, MCMCglmm, brms, …) (See supplementary material for Fox et al. 2016 for a worked example.)

+

The general approach to handling complete separation in logistic +regression is called penalized regression; it’s available in +the brglm, brglm2, logistf, and +rms packages. However, these packages don’t handle mixed +models, so the best available general approach is to use a +Bayesian method that allows you to set a prior on the fixed effects, +e.g. a Gaussian with standard deviation of 3; this can be done in any of +the Bayesian GLMM packages (e.g. blme, +MCMCglmm, brms, …) (See supplementary +material for Fox et al. 2016 for a worked example.)

Non-Gaussian random effects

-

I’m not aware of easy ways to fit mixed models with non-Gaussian random effects distributions in R (i.e., convenient, flexible, well-tested implementations). McCulloch and Neuhaus (2011) discusses when this misspecification may be important. This presentation discusses various approaches to solving the problem (e.g. using a Gamma rather than a Normal distribution of REs in log-link models). The spaMM package implements H-likelihood models (Lee, Nelder, and Pawitan 2017), and claims to allow a range of random-effects distributions (perhaps not well tested though …)

-

In principle you can implement any random-effects distribution you want in a fully capable Bayesian modeling language (e.g. JAGS/Stan/PyMC/etc.); see e.g. this StackOverflow answer, which uses the rethinking package’s interface to Stan.

+

I’m not aware of easy ways to fit mixed models with non-Gaussian +random effects distributions in R (i.e., convenient, flexible, +well-tested implementations). McCulloch and +Neuhaus (2011) discusses when this misspecification may be +important. This +presentation discusses various approaches to solving the problem +(e.g. using a Gamma rather than a Normal distribution of REs in log-link +models). The spaMM package implements H-likelihood models +(Lee, Nelder, and Pawitan 2017), and +claims to allow a range of random-effects distributions (perhaps not +well tested though …)

+

In principle you can implement any random-effects distribution you +want in a fully capable Bayesian modeling language +(e.g. JAGS/Stan/PyMC/etc.); see e.g. this +StackOverflow answer, which uses the rethinking +package’s interface to Stan.

@@ -1586,10 +2290,10 @@

What methods are available to fit (estimate) GLMMs?

(adapted from Bolker et al TREE 2009)

----++++ @@ -1603,26 +2307,34 @@

What methods are available to fit (estimate) GLMMs?

- - + + - + - + - + - +
Penalized quasi-likelihood Flexible, widely implementedLikelihood inference may be inappropriate; biased for large variance or small meansPROC GLIMMIX (SAS), GLMM (GenStat), glmmPQL (R:MASS), ASREML-RLikelihood inference may be inappropriate; biased for +large variance or small meansPROC GLIMMIX (SAS), GLMM (GenStat), glmmPQL (R:MASS), +ASREML-R
Laplace approximation More accurate than PQL Slower and less flexible than PQLglmer (R:lme4,lme4a), glmm.admb (R:glmmADMB), INLA, glmmTMB, AD Model Builder, HLMglmer (R:lme4,lme4a), glmm.admb (R:glmmADMB), INLA, +glmmTMB, AD Model Builder, HLM
Gauss-Hermite quadrature More accurate than Laplace Slower than Laplace; limited to 2‑3 random effectsPROC NLMIXED (SAS), glmer (R:lme4, lme4a), glmmML (R:glmmML), xtlogit (Stata)PROC NLMIXED (SAS), glmer (R:lme4, lme4a), glmmML +(R:glmmML), xtlogit (Stata)
Markov chain Monte CarloHighly flexible, arbitrary number of random effects; accurateHighly flexible, arbitrary number of random effects; +accurate Slow, technically challenging, Bayesian frameworkMCMCglmm (R:MCMCglmm), rstanarm (R), brms (R), MCMCpack (R), WinBUGS/OpenBUGS (R interface: BRugs/R2WinBUGS), JAGS (R interface: rjags/R2jags), AD Model Builder (R interface: R2admb), glmm.admb (post hoc MCMC after Laplace fit) (R:glmmADMB)MCMCglmm (R:MCMCglmm), rstanarm (R), brms (R), MCMCpack +(R), WinBUGS/OpenBUGS (R interface: BRugs/R2WinBUGS), JAGS (R interface: +rjags/R2jags), AD Model Builder (R interface: R2admb), glmm.admb (post +hoc MCMC after Laplace fit) (R:glmmADMB)
@@ -1631,94 +2343,269 @@

What methods are available to fit (estimate) GLMMs?

Troubleshooting

  • double-check the model specification and the data for mistakes
  • -
  • center and scale continuous predictor variables (e.g. with scale())
  • -
  • try all available optimizers (e.g. several different implementations of BOBYQA and Nelder-Mead, L-BFGS-B from optim, nlminb(), …). While this will of course be slow for large fits, we consider it the gold standard; if all optimizers converge to values that are practically equivalent (it’s up to the user to decide what “practically equivalent means for their case”), then we would consider the model fit to be good enough. For example:
  • +
  • center and scale continuous predictor variables (e.g. with +scale())
  • +
  • try all available optimizers (e.g. several different implementations +of BOBYQA and Nelder-Mead, L-BFGS-B from optim, +nlminb(), …). While this will of course be slow for large +fits, we consider it the gold standard; if all optimizers converge to +values that are practically equivalent (it’s up to the user to decide +what “practically equivalent means for their case”), then we would +consider the model fit to be good enough. For example:
modelfit.all <- lme4::allFit(model)
 ss <- summary(modelfit.all)

Convergence warnings

-

Most of the current advice about troubleshooting lme4 convergence problems can be found in the help page ?convergence. That page explains that the convergence tests in the current version of lme4 (1.1-11, February 2016) generate lots of false positives. We are considering raising the gradient warning threshold to 0.01 in future releases of lme4. In addition to the general troubleshooting tips above:

+

Most of the current advice about troubleshooting lme4 +convergence problems can be found in the help page +?convergence. That page explains that the convergence tests +in the current version of lme4 (1.1-11, February 2016) +generate lots of false positives. We are considering raising the +gradient warning threshold to 0.01 in future releases of +lme4. In addition to the general troubleshooting tips +above:

    -
  • double-check the Hessian calculation with the more expensive Richardson extrapolation method (see examples)
  • -
  • restart the fit from the apparent optimum, or from a point perturbed slightly away from the optimum (getME(model,c("theta","beta")) should retrieve the parameters in a form suitable to be used as the start parameter)
  • -
  • a common error is to specify an offset to a log-link model as a raw searching-effort value, i.e. offset(effort) rather than offset(log(effort)). While the intention is to fit a model where \(\textrm{counts} \propto \textrm{effort}\), specifying offset(effort) leads to a model where \(\textrm{counts} \propto \exp(\textrm{effort})\) instead; exp(effort) is often a huge (and model-destabilizing) number.
  • +
  • double-check the Hessian calculation with the more expensive +Richardson extrapolation method (see examples)
  • +
  • restart the fit from the apparent optimum, or from a point perturbed +slightly away from the optimum +(getME(model,c("theta","beta")) should retrieve the +parameters in a form suitable to be used as the start +parameter)
  • +
  • a common error is to specify an offset to a log-link model as a raw +searching-effort value, i.e. offset(effort) rather than +offset(log(effort)). While the intention is to fit a model +where \(\textrm{counts} \propto +\textrm{effort}\), specifying offset(effort) leads +to a model where \(\textrm{counts} \propto +\exp(\textrm{effort})\) instead; exp(effort) is +often a huge (and model-destabilizing) number.

-
-
-

Singular models: random effect variances estimated as zero, or correlations estimated as +/- 1

-

It is very common for overfitted mixed models to result in singular fits. Technically, singularity means that some of the \(\boldsymbol \theta\) (variance-covariance Cholesky decomposition) parameters corresponding to diagonal elements of the Cholesky factor are exactly zero, which is the edge of the feasible space, or equivalently that the variance-covariance matrix has some zero eigenvalues (i.e. is positive semidefinite rather than positive definite), or (almost equivalently) that some of the variances are estimated as zero or some of the correlations are estimated as +/-1. This commonly occurs in two scenarios:

+ +

+
+
+

Singular fits

+

It is very common for overfitted mixed models to result in singular +fits. Technically, singularity means that the random effects +variance-covariance matrix is of less than full rank. There are +various ways to describe this, from more to less technical:

+
    +
  • some of the eigenvalues of the covariance matrix are zero, or +effectively zero;

  • +
  • some combinations of the elements of the random-effects vector +are perfectly multicollinear;

  • +
  • some linear combinations of elements of the random-effects vector +have zero variance;

  • +
  • an \(n \times n\) covariance +matrix corresponds to an \(n\)-dimensional ellipsoid where the lengths +of the major axes are proportional to the eigenvalues; the ellipsoid is +“flat” in some directions, e.g. an ellipse has collapsed to a line +segment

  • +
  • In simple cases where a random effect term is represented by a +single variance (scalar random effects), this is reflected in a +variance estimate that is zero or near zero. Functions such as +nlme::lme() or glmmTMB() that estimate +variances on the log scale will often not report a singular +fit, but will instead return a very small value (1e-6 or less) for the +random-effects variance; on the log scale, this will correspond to a +parameter estimate that is a large negative number — and, usually, +warnings about non-positive-definite Hessians or (in the case of +lme()) ridiculously large Wald confidence intervals +returned by intervals().

  • +
  • In the case of a two-dimensional random effect (such as a +random-slopes model), this typically corresponds to a perfect (+/- 1) +correlation between the slope and intercept

  • +
  • in higher-dimensional random effects (such as the random effect +of a categorical variable with more than two levels, or a random-slopes +model with more than one covariate), it’s pretty much impossible to see +at a glance that the covariance matrix is singular. Extracting the RE +covariance matrix and computing its eigenvalues (this is what +rePCA in the lme4 package does) will tell you. +In the particular case of lme4, singularity is detectable +by seeing if any of the elements of the \(\boldsymbol \theta\) (variance-covariance +Cholesky decomposition) vector corresponding to diagonal elements are +(near) zero; this is what ?isSingular does.

  • +
+

Singular fits commonly occur in two scenarios:

    -
  • small numbers of random-effect levels (e.g. <5), as illustrated in these simulations and discussed (in a somewhat different, Bayesian context) by Gelman (2006).

  • -
  • complex random-effects models, e.g. models of the form (f|g) where f is a categorical variable with a relatively large number of levels, or models with several different random-slopes terms.

  • -
  • When using lme4, singularity is most obviously detectable in the output of summary.merMod() or VarCorr.merMod() when a variance is estimated as 0 (or very small, i.e. orders of magnitude smaller than other variance components) or when a correlation is estimated as exactly \(\pm 1\). However, as pointed out by D. Bates, Kliegl, et al. (2015), singularities in larger variance-covariance matrices can be hard to detect: checking for small values among the diagonal elements of the Cholesky factor is a good start.

  • +
  • small numbers of random-effect levels (e.g. <5), as +illustrated in these +simulations and discussed (in a somewhat different, Bayesian +context) by Gelman (2006).

  • +
  • complex random-effects models, e.g. models of the form +(f|g) where f is a categorical variable with a +relatively large number of levels, or models with several different +random-slopes terms.

  • +
  • In MCMCglmm, singular or near-singular fits will +provoke an error and a requirement to specify a stronger prior.

-
theta <- getME(model,"theta")
-## diagonal elements are identifiable because they are fitted
-##  with a lower bound of zero ...
-diag.element <- getME(model,"lower")==0
-any(theta[diag.element]<1e-5)
-

As of lme4 version 1.1-19, this functionality is available as isSingular(model). - In MCMCglmm, singular or near-singular models will provoke an error and a requirement to specify a stronger prior.

-

At present there are a variety of strong opinions about how to resolve such problems. Briefly:

-
    -
  • Barr et al. (2013) suggest always starting with the maximal model (i.e. the most random-effects component of the model that is theoretically identifiable given the experimental design) and then dropping terms when singularity or non-convergence occurs (please see the paper for detailed recommendations …)
  • -
  • Matuschek et al. (2017) and D. Bates, Kliegl, et al. (2015) strongly disagree, suggesting that models should be simplified a priori whenever possible; they also provide tools for diagnosing and mitigating singularity.
  • -
  • One alternative (suggested by Robert LaBudde) for the small-numbers-of-levels scenario is to “fit the model with the random factor as a fixed effect, get the level coefficients in the sum to zero form, and then compute the standard deviation of the coefficients.” This is appropriate for users who are (a) primarily interested in measuring variation (i.e. the random effects are not just nuisance parameters, and the variability [rather than the estimated values for each level] is of scientific interest), (b) unable or unwilling to use other approaches (e.g. MCMC with half-Cauchy priors in WinBUGS), (c) unable or unwilling to collect more data. For the simplest case (balanced, orthogonal, nested designs with normal errors) these estimates of standard deviations should equal the classical method-of-moments estimates.
  • -
  • Bayesian approaches allow the user to specify a informative prior that avoids singularity. -
      -
    • The blme package (Chung et al. 2013) provides a wrapper for the lme4 machinery that adds a particular form of weak prior to get an approximate a Bayesian maximum a posteriori estimate that avoids singularity.
    • -
    • The MCMCglmm package allows for priors on the variance-covariance matrix
    • -
    • The rstanarm and brms packages provide wrappers for the Stan Hamiltonian MCMC engine that fit GLMMs via lme4 syntax, again allowing a variety of priors to be set.
    • +

      At present there are a variety of strong opinions about how to +resolve such problems, which are sometimes conflated with the general +problem of how to decide on the appropriate complexity of the +random-effects component of a model. Briefly:

      +
        +
      • If a variance component is zero, dropping it from the model will +have no effect on any of the estimated quantities (although it will +affect the AIC, as the variance parameter is counted even though it has +no effect). Pasch, Bolker, and Phelps +(2013) gives one example where random effects were dropped +because the variance components were consistently estimated as zero. +Conversely, if one chooses for philosophical grounds to retain these +parameters, it won’t change any of the answers.
      • +
      • Barr et al. (2013) suggest always +starting with the maximal model (i.e. the most random-effects component +of the model that is theoretically identifiable given the +experimental design) and then dropping terms when singularity or +non-convergence occurs (please see the paper for detailed +recommendations …)
      • +
      • Matuschek et al. (2017) and Bates, Kliegl, et al. (2015) disagree, +suggesting that models should be simplified a priori whenever +possible. In particular, they suggest \(p\)-value-based stepwise reduction of the +random effects model using a loose \(p\)-value criterion (e.g. \(\alpha_{\text LRT} = 0.2\)). They also +provide tools for +diagnosing and mitigating singularity.
      • +
      • One alternative (suggested by Robert LaBudde) for the +small-numbers-of-levels scenario is to “fit the model with the random +factor as a fixed effect, get the level coefficients in the sum to zero +form, and then compute the standard deviation of the coefficients.” This +is appropriate for users who are (a) primarily interested in measuring +variation (i.e. the random effects are not just nuisance parameters, and +the variability [rather than the estimated values for each level] is of +scientific interest), (b) unable or unwilling to use other approaches +(e.g. MCMC with half-Cauchy priors in WinBUGS), (c) unable or unwilling +to collect more data. For the simplest case (balanced, orthogonal, +nested designs with normal errors) these estimates of standard +deviations should equal the classical method-of-moments estimates.
      • +
      • Bayesian approaches allow the user to specify a informative prior +that avoids singularity. +
          +
        • The blme package (Chung et al. +2013) provides a wrapper for the lme4 machinery that +adds a particular form of weak prior to get an approximate a Bayesian +maximum a posteriori estimate that avoids singularity.
        • +
        • The MCMCglmm package allows for priors on the +variance-covariance matrix
        • +
        • The rstanarm and brms packages provide +wrappers for the Stan Hamiltonian MCMC engine that fit GLMMs via +lme4 syntax, again allowing a variety of priors to be +set.
      • -
      • If a variance component is zero, dropping it from the model will have no effect on any of the estimated quantities (although it will affect the AIC, as the variance parameter is counted even though it has no effect). Pasch, Bolker, and Phelps (2013) gives one example where random effects were dropped because the variance components were consistently estimated as zero. Conversely, if one chooses for philosophical grounds to retain these parameters, it won’t change any of the answers.

Setting residual variances to a fixed value (zero or other)

-

For some problems it would be convenient to be able to set the residual variance term to zero, or a fixed value. This is difficult in lme4, because the model is parameterized internally in such a way that the residual variance is profiled out (i.e., calculated directly from a residual deviance term) and the random-effects variances are scaled by the residual variance.

-

Searching the r-sig-mixed-models list for “fix residual variance”

+

For some problems it would be convenient to be able to set the +residual variance term to zero, or a fixed value. This is difficult in +lme4, because the model is parameterized internally in such +a way that the residual variance is profiled out (i.e., calculated +directly from a residual deviance term) and the random-effects variances +are scaled by the residual variance.

+

Searching +the r-sig-mixed-models list for “fix residual variance”

    -
  • This is done in the metafor package, for meta-analytic models
  • -
  • You can use the blme package to fix the residual variance: from Vincent Dorie,
  • +
  • This is done in the metafor package, for meta-analytic +models
  • +
  • You can use the blme package to fix the residual +variance: from Vincent Dorie,
library(blme)
 blmer(formula = y ~ 1 + (1 | group), weights = V,
       resid.prior = point(1.0), cov.prior = NULL)
-

This sets the residual variance to 1.0. You cannot use this to make it exactly zero, but you can make it very small (and experiment with setting it to different small values, e.g. 0.001 vs 0.0001, to see how sensitive the results are). - Similarly, you can fix the residual variance to a small positive value in [n]lme via the control() argument (Heisterkamp et al. 2017):

+

This sets the residual variance to 1.0. You cannot use this +to make it exactly zero, but you can make it very small (and experiment +with setting it to different small values, e.g. 0.001 vs 0.0001, to see +how sensitive the results are). - Similarly, you can fix the residual +variance to a small positive value in [n]lme via the +control() argument (Heisterkamp et +al. 2017):

nlme::lme(Reaction~Days,random=~1|Subject,
           data=lme4::sleepstudy,
           control=list(sigma=1e-8))
    -
  • the glmmTMB package can set the residual variance to zero, by specifying dispformula = ~0
  • -
  • There is an rrBlupMethod6 package on CRAN (“Re-parametrization of mixed model formulation to allow for a fixed residual variance when using RR-BLUP for genom[e]wide estimation of marker effects”), but it seems fairly special-purpose.
  • -
  • it might be possible in principle to adapt lme4’s internal devfun2() function (used in the likelihood profiling computation for LMMs), which uses a specified value of the residual standard deviation in computing likelihood, but as D. Bates, Mächler, et al. (2015) say:
  • +
  • the glmmTMB package can set the residual variance to +(approximately) zero, by specifying dispformula = ~0 (in +fact the value can be set via +glmmTMBControl(zerodisp_val=...); the default value is +log(sqrt(.Machine$double.eps)))
  • +
  • There is an rrBlupMethod6 +package on CRAN (“Re-parametrization of mixed model formulation to +allow for a fixed residual variance when using RR-BLUP for genom[e]wide +estimation of marker effects”), but it seems fairly +special-purpose.
  • +
  • it might be possible in principle to adapt +lme4’s internal devfun2() function (used in +the likelihood profiling computation for LMMs), which uses a specified +value of the residual standard deviation in computing likelihood, but as +Bates, Mächler, et al. (2015) say:
-

The resulting function is not useful for general nonlinear optimization — one can easily wander into parameter regimes corresponding to infeasible (non-positive semidefinite) variance-covariance matrices — but it serves for likelihood profiling, where one focal parameter is varied at a time and the optimization over the other parameters is likely to start close to an optimum.

+

The resulting function is not useful for general nonlinear +optimization — one can easily wander into parameter regimes +corresponding to infeasible (non-positive semidefinite) +variance-covariance matrices — but it serves for likelihood profiling, +where one focal parameter is varied at a time and the optimization over +the other parameters is likely to start close to an optimum.

Other problems/lme4 error messages

-

Most of the following error messages are relatively unusual, and happen mostly with complex/large/unstable models. There is often no simple fix; the standard suggestions for troubleshooting are (1) try rescaling and/or centering predictors; (2) see if a simpler model can be made to work; (3) look for severe lack of balance and/or complete separation in the data set.

+

Most of the following error messages are relatively unusual, and +happen mostly with complex/large/unstable models. There is often no +simple fix; the standard suggestions for troubleshooting are (1) try +rescaling and/or centering predictors; (2) see if a simpler model can be +made to work; (3) look for severe lack of balance and/or complete +separation in the data set.

REML for GLMMs

    -
  • While restricted maximum likelihood (REML) procedures (Wikipedia are well established for linear mixed models, it is less clear how one should define and compute the equivalent criteria (integrating out the effects of fixed parameters) for GLMMs. Millar (2011) and Berger, Liseo, and Wolpert (1999) are possible starting points in the peer-reviewed literature, and there are mailing-list discussions of these issues here and here.
  • -
  • Attempting to use REML=TRUE with glmer will produce the warning extra argument(s) ‘REML’ disregarded
  • -
  • glmmTMB allows REML=TRUE for GLMMs (it uses the Laplace approximation to integrate over the fixed effect parameters), since version 0.2.2
  • +
  • While restricted maximum likelihood (REML) procedures (Wikipedia +are well established for linear mixed models, it is less clear how one +should define and compute the equivalent criteria (integrating out the +effects of fixed parameters) for GLMMs. Millar +(2011) and Berger, Liseo, and Wolpert +(1999) are possible starting points in the peer-reviewed +literature, and there are mailing-list discussions of these issues here +and here.
  • +
  • Attempting to use REML=TRUE with glmer +will produce the warning +extra argument(s) ‘REML’ disregarded
  • +
  • glmmTMB allows REML=TRUE for GLMMs (it +uses the Laplace approximation to integrate over the fixed effect +parameters), since version 0.2.2
@@ -1730,77 +2617,221 @@

Inference and confidence intervals

Testing hypotheses

-

What are the p-values listed by summary(glmerfit) etc.? Are they reliable?

-

By default, in keeping with the tradition in analysis of generalized linear models, lme4 and similar packages display the Wald Z-statistics for each parameter in the model summary. These have one big advantage: they’re convenient to compute. However, they are asymptotic approximations, assuming both that (1) the sampling distributions of the parameters are multivariate normal (or equivalently that the log-likelihood surface is quadratic) and that (2) the sampling distribution of the log-likelihood is (proportional to) \(\chi^2\). The second approximation is discussed further under “Degrees of freedom”. The first assumption usually requires an even greater leap of faith, and is known to cause problems in some contexts (for binomial models failures of this assumption are called the Hauck-Donner effect), especially with extreme-valued parameters.

+

What are the p-values listed by summary(glmerfit) etc.? +Are they reliable?

+

By default, in keeping with the tradition in analysis of generalized +linear models, lme4 and similar packages display the Wald +Z-statistics for each parameter in the model summary. These have one big +advantage: they’re convenient to compute. However, they are asymptotic +approximations, assuming both that (1) the sampling distributions of the +parameters are multivariate normal (or equivalently that the +log-likelihood surface is quadratic) and that (2) the sampling +distribution of the log-likelihood is (proportional to) \(\chi^2\). The second approximation is +discussed further under “Degrees of freedom”. The first assumption +usually requires an even greater leap of faith, and is known to cause +problems in some contexts (for binomial models failures of this +assumption are called the Hauck-Donner effect), especially with +extreme-valued parameters.

Methods for testing single parameters

From worst to best:

  • Wald \(Z\)-tests
  • -
  • For balanced, nested LMMs where degrees of freedom can be computed according to classical rules: Wald \(t\)-tests
  • -
  • Likelihood ratio test, either by setting up the model so that the parameter can be isolated/dropped (via anova or drop1, or via computing likelihood profiles
  • -
  • Markov chain Monte Carlo (MCMC) or parametric bootstrap confidence intervals
  • +
  • For balanced, nested LMMs where degrees of freedom +can be computed according to classical rules: Wald \(t\)-tests
  • +
  • Likelihood ratio test, either by setting up the model so that the +parameter can be isolated/dropped (via anova or +drop1, or via computing likelihood profiles
  • +
  • Markov chain Monte Carlo (MCMC) or parametric bootstrap confidence +intervals
-

Tests of effects (i.e. testing that several parameters are simultaneously zero)

+

Tests of effects (i.e. testing that several parameters are +simultaneously zero)

From worst to best:

  • Wald chi-square tests (e.g. car::Anova)
  • -
  • Likelihood ratio test (via anova or drop1)
  • -
  • For balanced, nested LMMs where df can be computed: conditional F-tests
  • -
  • For LMMs: conditional F-tests with df correction (e.g. Kenward-Roger in pbkrtest package: see notes on K-R etc below.
  • -
  • MCMC or parametric, or nonparametric, bootstrap comparisons (nonparametric bootstrapping must be implemented carefully to account for grouping factors)
  • +
  • Likelihood ratio test (via anova or +drop1)
  • +
  • For balanced, nested LMMs where df can be computed: +conditional F-tests
  • +
  • For LMMs: conditional F-tests with df correction +(e.g. Kenward-Roger in pbkrtest package: see notes on K-R +etc below.
  • +
  • MCMC or parametric, or nonparametric, bootstrap comparisons +(nonparametric bootstrapping must be implemented carefully to account +for grouping factors)

Is the likelihood ratio test reliable for mixed models?

  • It depends.
  • -
  • Not for fixed effects in finite-size cases (see Pinheiro and Bates (2000)): may depend on ‘denominator degrees of freedom’ (number of groups) and/or total number of samples - total number of parameters
  • -
  • Conditional F-tests are preferred for LMMs, if denominator degrees of freedom are known
  • +
  • Not for fixed effects in finite-size cases (see Pinheiro and Bates (2000)): may depend on +‘denominator degrees of freedom’ (number of groups) and/or total number +of samples - total number of parameters
  • +
  • Conditional F-tests are preferred for LMMs, if +denominator degrees of freedom are known

-

Why doesn’t lme4 display denominator degrees of freedom/p values? What other options do I have?

-

There is an R FAQ entry on this topic, which links to a mailing list post by Doug Bates (there is also a voluminous mailing list thread reproduced on the R wiki). The bottom line is

+

Why doesn’t lme4 display denominator degrees of +freedom/p values? What other options do I have?

+

There is an R +FAQ entry on this topic, which links to a mailing +list post by Doug Bates (there is also a voluminous mailing +list thread reproduced on the R wiki). The bottom line is

    -
  • For special cases that correspond to classical experimental designs (i.e. balanced designs that are nested, split-plot, randomized block, etc.) … we can show that the null distributions of particular ratios of sums of squares follow an \(F\) distribution with known numerator and denominator degrees of freedom (and hence the sampling distributions of particular contrasts are t-distributed with known df). In more complicated situations (unbalanced, GLMMs, crossed random effects, models with temporal or spatial correlation, etc.) it is not in general clear that the null distribution of the computed ratio of sums of squares is really an F distribution, for any choice of denominator degrees of freedom.
  • -
  • For each simple degrees-of-freedom recipe that has been suggested (trace of the hat matrix, etc.) there seems to be at least one fairly simple counterexample where the recipe fails badly (e.g. see this r-help thread from September 2006).
  • -
  • When the responses are normally distributed and the design is balanced, nested etc. (i.e. the classical LMM situation), the scaled deviances and differences in deviances are exactly \(F\)-distributed and looking at the experimental design (i.e., which treatments vary/are replicated at which levels) tells us what the relevant degrees of freedom are (see “df alternatives” below)
  • -
  • Two approaches to approximating df (Satterthwaite and Kenward-Roger) have been implemented in R, Satterthwaite in lmerTest and Kenward-Roger in pbkrtest (as KRmodcomp) (various packages such as lmerTest, emmeans, car, etc., import pbkrtest::get_Lb_ddf). +
  • For special cases that correspond to classical experimental designs +(i.e. balanced designs that are nested, split-plot, randomized block, +etc.) … we can show that the null distributions of particular ratios of +sums of squares follow an \(F\) +distribution with known numerator and denominator degrees of freedom +(and hence the sampling distributions of particular contrasts are +t-distributed with known df). In more complicated situations +(unbalanced, GLMMs, crossed random effects, models with temporal or +spatial correlation, etc.) it is not in general clear that the null +distribution of the computed ratio of sums of squares is really an F +distribution, for any choice of denominator degrees of +freedom.
  • +
  • For each simple degrees-of-freedom recipe that has been suggested +(trace of the hat matrix, etc.) there seems to be at least one fairly +simple counterexample where the recipe fails badly (e.g. see this +r-help thread from September 2006).
  • +
  • When the responses are normally distributed and the design is +balanced, nested etc. (i.e. the classical LMM situation), the scaled +deviances and differences in deviances are exactly \(F\)-distributed and looking at the +experimental design (i.e., which treatments vary/are replicated at which +levels) tells us what the relevant degrees of freedom are (see “df +alternatives” below)
  • +
  • Two approaches to approximating df (Satterthwaite and Kenward-Roger) +have been implemented in R, Satterthwaite in lmerTest and +Kenward-Roger in pbkrtest (as KRmodcomp) +(various packages such as lmerTest, emmeans, +car, etc., import pbkrtest::get_Lb_ddf).
      -
    • K-R is probably the most reliable option (Schaalje, McBride, and Fellingham 2002), although it may be prohibitively computationally expensive for large data sets.

    • -
    • K-R was derived for LMMs (and for REML?) in particular, it isn’t clear how it would apply to GLMMs. Stroup (2014) states (referencing Stroup (2013)) that K-R actually works reasonably well for GLMMs (K-R is not implemented in R for GLMMs; Stroup suggests that a pseudo-likelihood (Wolfinger and O’Connell 1993) approach is necessary in order to implement K-R for GLMMs):

      +
    • K-R is probably the most reliable option (Schaalje, McBride, and Fellingham 2002), +although it may be prohibitively computationally expensive for large +data sets.

    • +
    • K-R was derived for LMMs (and for REML?) in particular, it isn’t +clear how it would apply to GLMMs. Walter W. +Stroup (2014) states (referencing W. W. +Stroup (2013)) that K-R actually works reasonably well for GLMMs +(K-R is not implemented in R for GLMMs; Stroup suggests that a +pseudo-likelihood (Wolfinger and O’Connell +1993) approach is necessary in order to implement K-R for +GLMMs):

      -

      Notice the non-integer values of the denominator df. They, and the \(F\) and \(p\) values, reflect the procedure developed by Kenward and Roger (2009) to account for the effect of the covariance structure on degrees of freedom and standard errors. Although the Kenward–Roger adjustment was derived for the LMM with normally distributed data and is an ad hoc procedure for GLMMs with non-normal data, informal simulation studies consistently have suggested that the adjustment is accurate. The Kenward-Roger adjustment requires that the SAS GLIMMIX default computing algorithm, pseudo-likelihood, be used rather than the Laplace algorithm used to obtain AICC statistics. Stroup (2013b) found that for binomial and Poisson GLMMs, pseudo-likelihood with the Kenward–Roger adjustment yields better Type I error control than Laplace while preserving the GLMM’s advantage with respect to power and accuracy in estimating treatment means.

      +

      Notice the non-integer values of the denominator df. They, and the +\(F\) and \(p\) values, reflect the procedure developed +by Kenward and Roger (2009) to account for the effect of the covariance +structure on degrees of freedom and standard errors. Although the +Kenward–Roger adjustment was derived for the LMM with normally +distributed data and is an ad hoc procedure for GLMMs with non-normal +data, informal simulation studies consistently have suggested that the +adjustment is accurate. The Kenward-Roger adjustment requires that the +SAS GLIMMIX default computing algorithm, pseudo-likelihood, be used +rather than the Laplace algorithm used to obtain AICC statistics. Stroup +(2013b) found that for binomial and Poisson GLMMs, pseudo-likelihood +with the Kenward–Roger adjustment yields better Type I error control +than Laplace while preserving the GLMM’s advantage with respect to power +and accuracy in estimating treatment means.

  • -
  • There are several different issues at play in finite-size (small-sample) adjustments, which apply slightly differently to LMMs and GLMMs. +
  • There are several different issues at play in finite-size +(small-sample) adjustments, which apply slightly differently to LMMs and +GLMMs.
      -
    • When the data don’t fit into the classical framework (crossed, unbalanced, R-side effects), we might still guess that the deviances etc. are approximately F-distributed but that we don’t know the real degrees of freedom – this is what the Satterthwaite, Kenward-Roger, Fai-Cornelius, etc. approximations are supposed to do.
    • -
    • When the responses are not normally distributed (as in GLMs and GLMMs), and when the scale parameter is not estimated (as in standard Poisson- and binomial-response models), then the deviance differences are only asymptotically F- or chi-square-distributed (i.e. not for our real, finite-size samples). In standard GLM practice, we usually ignore this problem; there is some literature on finite-size corrections for GLMs under the rubrics of “Bartlett corrections” and “higher order asymptotics” (see McCullagh and Nelder (1989), Cordeiro, Paula, and Botter (1994), Cordeiro and Ferrari (1998) and the cond package (on CRAN) [which works with GLMs, not GLMMs]), but it’s rarely used. (The bias correction/Firth approach implemented in the brglm package attempts to address the problem of finite-size bias, not finite-size non-chi-squaredness of the deviance differences.)
    • -
    • When the scale parameter in a GLM is estimated rather than fixed (as in Gamma or quasi-likelihood models), it is sometimes recommended to use an \(F\) test to account for the uncertainty of the scale parameter (e.g. Venables and Ripley (2002) recommend anova(...,test="F") for quasi-likelihood models)
    • -
    • Combining these issues, one has to look pretty hard for information on small-sample or finite-size corrections for GLMMs: Feng, Braun, and McCulloch (2004) and Bell and Grunwald (2010) look like good starting points, but it’s not at all trivial.
    • +
    • When the data don’t fit into the classical framework (crossed, +unbalanced, R-side effects), we might still guess that the deviances +etc. are approximately F-distributed but that we don’t know the real +degrees of freedom – this is what the Satterthwaite, Kenward-Roger, +Fai-Cornelius, etc. approximations are supposed to do.
    • +
    • When the responses are not normally distributed (as in GLMs and +GLMMs), and when the scale parameter is not estimated (as in standard +Poisson- and binomial-response models), then the deviance differences +are only asymptotically F- or chi-square-distributed (i.e. not for our +real, finite-size samples). In standard GLM practice, we usually ignore +this problem; there is some literature on finite-size corrections for +GLMs under the rubrics of “Bartlett corrections” and “higher order +asymptotics” (see McCullagh and Nelder +(1989), Cordeiro, Paula, and Botter +(1994), Cordeiro and Ferrari (1998) +and the cond package (on CRAN) [which works +with GLMs, not GLMMs]), but it’s rarely used. (The bias correction/Firth +approach implemented in the brglm package attempts to +address the problem of finite-size bias, not finite-size +non-chi-squaredness of the deviance differences.)
    • +
    • When the scale parameter in a GLM is estimated rather than fixed (as +in Gamma or quasi-likelihood models), it is sometimes recommended to use +an \(F\) test to account for the +uncertainty of the scale parameter (e.g. Venables +and Ripley (2002) recommend anova(...,test="F") for +quasi-likelihood models)
    • +
    • Combining these issues, one has to look pretty hard for information +on small-sample or finite-size corrections for GLMMs: Feng, Braun, and McCulloch (2004) and Bell and Grunwald (2010) look like good starting +points, but it’s not at all trivial.

Df alternatives:

    -
  • use MASS::glmmPQL (uses old nlme rules approximately equivalent to SAS ‘inner-outer’/‘within-between’ rules) for GLMMs, or (n)lme for LMMs
  • -
  • Guess the denominator df from standard rules (for standard designs, e.g. see Gotelli and Ellison (2004)) and apply them to \(t\) or \(F\) tests
  • -
  • Run the model in lme (if possible) and use the denominator df reported there (which follow a simple ‘inner-outer’ rule which should correspond to the canonical answer for simple/orthogonal designs), applied to \(t\) or \(F\) tests. For the explicit specification of the rules that lme uses, see page 91 of Pinheiro and Bates (this page was previously available on Google Books, but the link is no longer useful, so here are the relevant paragraphs):
  • +
  • use MASS::glmmPQL (uses old nlme rules approximately +equivalent to SAS ‘inner-outer’/‘within-between’ rules) for GLMMs, or +(n)lme for LMMs
  • +
  • Guess the denominator df from standard rules (for standard designs, +e.g. see Gotelli and Ellison (2004)) and +apply them to \(t\) or \(F\) tests
  • +
  • Run the model in lme (if possible) and use the +denominator df reported there (which follow a simple ‘inner-outer’ rule +which should correspond to the canonical answer for simple/orthogonal +designs), applied to \(t\) or \(F\) tests. For the explicit specification +of the rules that lme uses, see page 91 of Pinheiro and +Bates (this page was previously available on Google Books, but the link is no +longer useful, so here are the relevant paragraphs):
-

These conditional tests for fixed-effects terms require denominator degrees of freedom. In the case of the conditional \(F\)-tests, the numerator degrees of freedom are also required, being determined by the term itself. The denominator degrees of freedom are determined by the grouping level at which the term is estimated. A term is called inner relative to a factor if its value can change within a given level of the grouping factor. A term is outer to a grouping factor if its value does not changes within levels of the grouping factor. A term is said to be estimated at level \(i\), if it is inner to the \(i-1\)st grouping factor and outer to the \(i\)th grouping factor. For example, the term Machine in the fm2Machine model is outer to Machine %in% Worker and inner to Worker, so it is estimated at level 2 (Machine %in% Worker). If a term is inner to all \(Q\) grouping factors in a model, it is estimated at the level of the within-group errors, which we denote as the \(Q+1\)st level.

-

The intercept, which is the parameter corresponding to the column of all 1’s in the model matrices \(X_i\), is treated differently from all the other parameters, when it is present. As a parameter it is regarded as being estimated at level 0 because it is outer to all the grouping factors. However, its denominator degrees of freedom are calculated as if it were estimated at level \(Q+1\). This is because the intercept is the one parameter that pools information from all the observations at a level even when the corresponding column in \(X_i\) doesn’t change with the level.

-

Letting \(m_i\) denote the total number of groups in level \(i\) (with the convention that \(m_0=1\) when the fixed effects model includes an intercept and 0 otherwise, and \(m_{Q+1}=N\)) and \(p_i\) denote the sum of the degrees of freedom corresponding to the terms estimated at level \(i\), the \(i\)th level denominator degrees of freedom is defined as

-

\[ \mathrm{denDF}_i = m_i - (m_{i-1} + p_i), i = 1, \dots, Q \]

-

This definition coincides with the classical decomposition of degrees of freedom in balanced, multilevel ANOVA designs and gives a reasonable approximation for more general mixed-effects models.

+

These conditional tests for fixed-effects terms require denominator +degrees of freedom. In the case of the conditional \(F\)-tests, the numerator degrees of freedom +are also required, being determined by the term itself. The denominator +degrees of freedom are determined by the grouping level at which the +term is estimated. A term is called inner relative to a factor if its +value can change within a given level of the grouping factor. A term is +outer to a grouping factor if its value does not changes within levels +of the grouping factor. A term is said to be estimated at level \(i\), if it is inner to the \(i-1\)st grouping factor and outer to the +\(i\)th grouping factor. For example, +the term Machine in the fm2Machine model is +outer to Machine %in% Worker and inner to +Worker, so it is estimated at level 2 +(Machine %in% Worker). If a term is inner to all \(Q\) grouping factors in a model, it is +estimated at the level of the within-group errors, which we denote as +the \(Q+1\)st level.

+

The intercept, which is the parameter corresponding to the column of +all 1’s in the model matrices \(X_i\), +is treated differently from all the other parameters, when it is +present. As a parameter it is regarded as being estimated at level 0 +because it is outer to all the grouping factors. However, its +denominator degrees of freedom are calculated as if it were estimated at +level \(Q+1\). This is because the +intercept is the one parameter that pools information from all the +observations at a level even when the corresponding column in \(X_i\) doesn’t change with the level.

+

Letting \(m_i\) denote the total +number of groups in level \(i\) (with +the convention that \(m_0=1\) when the +fixed effects model includes an intercept and 0 otherwise, and \(m_{Q+1}=N\)) and \(p_i\) denote the sum of the degrees of +freedom corresponding to the terms estimated at level \(i\), the \(i\)th level denominator degrees of freedom +is defined as

+

\[ \mathrm{denDF}_i = m_i - (m_{i-1} + +p_i), i = 1, \dots, Q \]

+

This definition coincides with the classical decomposition of degrees +of freedom in balanced, multilevel ANOVA designs and gives a reasonable +approximation for more general mixed-effects models.

-

Note that the implementation used in lme gets the wrong answer for random-slopes models:

+

Note that the implementation used in lme gets +the wrong answer for random-slopes models:

library(nlme)
 lmeDF <- function(formula=distance~age,random=~1|Subject) {
      mod <- lme(formula,random,data=Orthodont)
@@ -1813,7 +2844,8 @@ 

Df alternatives:

lmeDF(random=~age|Subject) ## wrong!
## (Intercept)         age 
 ##          80          80
-

I (BB) have re-implemented this algorithm in a way that does slightly better for random-slopes models (but may still get confused!), see here.

+

I (BB) have re-implemented this algorithm in a way that does slightly +better for random-slopes models (but may still get confused!), see here.

source("R/calcDenDF.R")
 calcDenDF(~age,"Subject",nlme::Orthodont)
## (Intercept)         age 
@@ -1826,14 +2858,19 @@ 

Df alternatives:

## 81 25
  • use SAS, Genstat (AS-REML), Stata?
  • -
  • Assume infinite denominator df (i.e. \(Z\)/\(\chi^2\) test rather than \(t\)/\(F\)) if number of groups is large (>45? Various rules of thumb for how large is “approximately infinite” have been posed, including (in Angrist and Pischke 2009), 42 (in homage to Douglas Adams)
  • +
  • Assume infinite denominator df (i.e. \(Z\)/\(\chi^2\) test rather than \(t\)/\(F\)) +if number of groups is large (>45? Various rules of thumb for how +large is “approximately infinite” have been posed, including (in Angrist and Pischke 2009), 42 (in homage to +Douglas Adams)

Testing significance of random effects

    -
  • the most common way to do this is to use a likelihood ratio test, i.e. fit the full and reduced models (the reduced model is the model with the focal variance(s) set to zero). For example:
  • +
  • the most common way to do this is to use a likelihood ratio test, +i.e. fit the full and reduced models (the reduced model is the model +with the focal variance(s) set to zero). For example:
library(lme4)
 m2 <- lmer(Reaction~Days+(1|Subject)+(0+Days|Subject),sleepstudy,REML=FALSE)
@@ -1851,10 +2888,28 @@ 

Testing significance of random effects

## m2 5 1762.0 1778.0 -876.00 1752.0 42.075 1 8.782e-11 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
-

With recent versions of lme4, goodness-of-fit (deviance) can be compared between (g)lmer and (g)lm models, although anova() must be called with the mixed ((g)lmer) model listed first. Keep in mind that LRT-based null hypothesis tests are conservative when the null value (such as \(\sigma^2=0\)) is on the boundary of the feasible space (Self and Liang 1987; Stram and Lee 1994; Goldman and Whelan 2000); in the simplest case (single random effect variance), the p-value is approximately twice as large as it should be (Pinheiro and Bates 2000).

+

With recent versions of lme4, goodness-of-fit (deviance) +can be compared between (g)lmer and (g)lm +models, although anova() must be called with the mixed +((g)lmer) model listed first. Keep in mind that LRT-based +null hypothesis tests are conservative when the null value (such as +\(\sigma^2=0\)) is on the boundary of +the feasible space (Self and Liang 1987; Stram +and Lee 1994; Goldman and Whelan 2000); in the simplest case +(single random effect variance), the p-value is approximately twice as +large as it should be (Pinheiro and Bates +2000).

    -
  • Consider not testing the significance of random effects. If the random effect is part of the experimental design, this procedure may be considered ‘sacrificial pseudoreplication’ (Hurlbert 1984). Using stepwise approaches to eliminate non-significant terms in order to squeeze more significance out of the remaining terms is dangerous in any case.
  • -
  • consider using the RLRsim package, which has a fast implementation of simulation-based tests of null hypotheses about zero variances, for simple tests. (However, it only applies to lmer models, and is a bit tricky to use for more complex models.)
  • +
  • Consider not testing the significance of random effects. If +the random effect is part of the experimental design, this procedure may +be considered ‘sacrificial pseudoreplication’ (Hurlbert 1984). Using stepwise approaches to +eliminate non-significant terms in order to squeeze more significance +out of the remaining terms is dangerous in any case.
  • +
  • consider using the RLRsim package, which has a fast +implementation of simulation-based tests of null hypotheses about zero +variances, for simple tests. (However, it only applies to +lmer models, and is a bit tricky to use for more complex +models.)
library(RLRsim)
 ## compare m0 and m1
@@ -1878,10 +2933,15 @@ 

Testing significance of random effects

## data: ## RLRT = 42.796, p-value < 2.2e-16
    -
  • Parametric bootstrap: fit the reduced model, then repeatedly simulate from it and compute the differences between the deviance of the reduced and the full model for each simulated data set. Compare this null distribution to the observed deviance difference. This procedure is implemented in the pbkrtest package (messages and warnings suppressed).
  • +
  • Parametric bootstrap: fit the reduced model, then repeatedly +simulate from it and compute the differences between the deviance of the +reduced and the full model for each simulated data set. Compare this +null distribution to the observed deviance difference. This procedure is +implemented in the pbkrtest package (messages and warnings +suppressed).
(pb <- pbkrtest::PBmodcomp(m2,m1,seed=101))
-
## Bootstrap test; time: 15.19 sec; samples: 1000; extremes: 0;
+
## Bootstrap test; time: 15.32 sec; samples: 1000; extremes: 0;
 ## Requested samples: 1000 Used samples: 501 Extremes: 0
 ## large : Reaction ~ Days + (1 | Subject) + (0 + Days | Subject)
 ## Reaction ~ Days + (1 | Subject)
@@ -1895,60 +2955,147 @@ 

Testing significance of random effects

Standard errors of variance estimates

    -
  • Paraphrasing Doug Bates: the sampling distribution of variance estimates is in general strongly asymmetric: the standard error may be a poor characterization of the uncertainty.
  • -
  • lme4 allows for computing likelihood profiles of variances and computing confidence intervals on their basis; these likelihood profile confidence intervals are subject to the usual caveats about the LRT with finite sample sizes.
  • -
  • Using an MCMC-based approach (the simplest/most canned is probably to use the MCMCglmm package, although its mode specifications are not identical to those of lme4) will provide posterior distributions of the variance parameters: quantiles or credible intervals (HPDinterval() in the coda package) will characterize the uncertainty.
  • -
  • (don’t say we didn’t warn you …) [n]lme fits contain an element called apVar which contains the approximate variance-covariance matrix (derived from the Hessian, the matrix of (numerically approximated) second derivatives of the likelihood (REML?) at the maximum (restricted?) likelihood values): you can derive the standard errors from this list element via sqrt(diag(lme.obj$apVar)). For whatever it’s worth, though, these estimates might not match the estimates that SAS gives which are supposedly derived in the same way.
  • -
  • it’s not a full solution, but there is some more information here. I have some delta-method computations there that are off by a factor of 2 for the residual standard deviation, as well as some computations based on reparameterizing the deviance function.
  • +
  • Paraphrasing Doug Bates: the sampling distribution of variance +estimates is in general strongly asymmetric: the standard error may be a +poor characterization of the uncertainty.
  • +
  • lme4 allows for computing likelihood profiles of +variances and computing confidence intervals on their basis; these +likelihood profile confidence intervals are subject to the usual caveats +about the LRT with finite sample sizes.
  • +
  • Using an MCMC-based approach (the simplest/most canned is probably +to use the MCMCglmm package, although its mode +specifications are not identical to those of lme4) will provide +posterior distributions of the variance parameters: quantiles or +credible intervals (HPDinterval() in the coda +package) will characterize the uncertainty.
  • +
  • (don’t say we didn’t warn you …) [n]lme fits contain an +element called apVar which contains the approximate +variance-covariance matrix (derived from the Hessian, the matrix of +(numerically approximated) second derivatives of the likelihood (REML?) +at the maximum (restricted?) likelihood values): you can derive the +standard errors from this list element via +sqrt(diag(lme.obj$apVar)). For whatever it’s worth, though, +these +estimates might not match the estimates +that SAS gives which are supposedly derived in the same way.
  • +
  • it’s not a full solution, but there is some more information here. I have some +delta-method computations there that are off by a factor of 2 for the +residual standard deviation, as well as some computations based on +reparameterizing the deviance function.

P-values: MCMC and parametric bootstrap

-

Abandoning the approximate \(F\)/\(t\)-statistic route, one ends up with the more general problem of estimating \(p\)-values. There is a wider range of options here, although many of them are computationally intensive …

+

Abandoning the approximate \(F\)/\(t\)-statistic route, one ends up with the +more general problem of estimating \(p\)-values. There is a wider range of +options here, although many of them are computationally intensive …

Markov chain Monte Carlo sampling:

    -
  • pseudo-Bayesian: post-hoc sampling, typically (1) assuming flat priors and (2) starting from the MLE, possibly using the approximate variance-covariance estimate to choose a candidate distribution +
  • pseudo-Bayesian: post-hoc sampling, typically (1) assuming flat +priors and (2) starting from the MLE, possibly using the approximate +variance-covariance estimate to choose a candidate distribution
      -
    • via mcmcsamp (if available for your problem: i.e. LMMs with simple random effects – not GLMMs or complex random effects)
    • -
    • via pvals.fnc in the languageR package, a wrapper for mcmcsamp)
    • -
    • in AD Model Builder, possibly via the glmmADMB package (use the mcmc=TRUE option) or the R2admb package (write your own model definition in AD Model Builder), or outside of R
    • -
    • via the sim function from the arm package (simulates the posterior only for the beta (fixed-effect) coefficients; not yet working with development lme4; would like a better formal description of the algorithm …?)
    • +
    • via mcmcsamp (if available for your problem: i.e. LMMs +with simple random effects – not GLMMs or complex random effects)
    • +
    • via pvals.fnc in the languageR package, a +wrapper for mcmcsamp)
    • +
    • in AD Model Builder, possibly via the glmmADMB package +(use the mcmc=TRUE option) or the R2admb +package (write your own model definition in AD Model Builder), or +outside of R
    • +
    • via the sim function from the arm package +(simulates the posterior only for the beta (fixed-effect) coefficients; +not yet working with development lme4; would like a better formal +description of the algorithm …?)
  • fully Bayesian approaches
    • via the MCMCglmm package
    • glmmBUGS (a WinBUGS wrapper/R interface)
    • -
    • JAGS/WinBUGS/OpenBUGS etc., via the rjags/r2jags/R2WinBUGS/BRugs packages
    • +
    • JAGS/WinBUGS/OpenBUGS etc., via the +rjags/r2jags/R2WinBUGS/BRugs +packages

Status of mcmcsamp

-

mcmcsamp is a function for lme4 that is supposed to sample from the posterior distribution of the parameters, based on flat/improper priors for the parameters [ed: I believe, but am not sure, that these priors are flat on the scale of the theta (Cholesky-factor) parameters]. At present, in the CRAN version (lme4 0.999999-0) and the R-forge “stable” version (lme4.0 0.999999-1), this covers only linear mixed models with uncorrelated random effects.

-

As has been discussed in a variety of places (e.g. on r-sig-mixed models, and on the r-forge bug tracker, it is challenging to come up with a sampler that accounts properly for the possibility that the posterior distributions for some of the variance components may be mixtures of point masses at zero and continuous distributions. Naive samplers are likely to get stuck at or near zero. Doug Bates has always been a bit unsure that mcmcsamp is really performing as intended, even in the limited cases it now handles.

-

Given this uncertainty about how even the basic version works, the lme4 developers have been reluctant to make the effort to extend it to GLMMs or more complex LMMs, or to implement it for the development version of lme4 … so unless something miraculous happens, it will not be implemented for the new version of lme4. As always, users are encouraged to write and share their own code that implements these capabilities …

+

mcmcsamp is a function for lme4 that is supposed to +sample from the posterior distribution of the parameters, based on +flat/improper priors for the parameters [ed: I believe, but am not sure, +that these priors are flat on the scale of the theta +(Cholesky-factor) parameters]. At present, in the CRAN version +(lme4 0.999999-0) and the R-forge “stable” version (lme4.0 0.999999-1), +this covers only linear mixed models with uncorrelated random +effects.

+

As has been discussed in a variety of places (e.g. on +r-sig-mixed models, and on +the r-forge bug tracker, it is challenging to come up with a sampler +that accounts properly for the possibility that the posterior +distributions for some of the variance components may be mixtures of +point masses at zero and continuous distributions. Naive samplers are +likely to get stuck at or near zero. Doug Bates has always been a bit +unsure that mcmcsamp is really performing as intended, even +in the limited cases it now handles.

+

Given this uncertainty about how even the basic version works, the +lme4 developers have been reluctant to make the effort to +extend it to GLMMs or more complex LMMs, or to implement it for the +development version of lme4 … so unless something miraculous happens, it +will not be implemented for the new version of lme4. As +always, users are encouraged to write and share their own code that +implements these capabilities …

Parametric bootstrap

-

The idea here is that in order to do inference on the effect of (a) predictor(s), you (1) fit the reduced model (without the predictors) to the data; (2) many times, (2a) simulate data from the reduced model; (2b) fit both the reduced and the full model to the simulated (null) data; (2c) compute some statistic(s) [e.g. t-statistic of the focal parameter, or the log-likelihood or deviance difference between the models]; (3) compare the observed values of the statistic from fitting your full model to the data to the null distribution generated in step 2. - PBmodcomp in the pbkrtest package - see the example in help("simulate-mer") in the lme4 package to roll your own, using a combination of simulate() and refit(). - bootMer in lme4 version >1.0.0 - a presentation at UseR! 2009 (abstract, slides) went into detail about a proposed bootMer package and suggested it could work for GLMMs too – but it does not seem to be active.

+

The idea here is that in order to do inference on the effect of (a) +predictor(s), you (1) fit the reduced model (without the predictors) to +the data; (2) many times, (2a) simulate data from the reduced model; +(2b) fit both the reduced and the full model to the simulated (null) +data; (2c) compute some statistic(s) [e.g. t-statistic of the focal +parameter, or the log-likelihood or deviance difference between the +models]; (3) compare the observed values of the statistic from fitting +your full model to the data to the null distribution generated in step +2. - PBmodcomp in the pbkrtest package - see +the example in help("simulate-mer") in the +lme4 package to roll your own, using a combination of +simulate() and refit(). - bootMer +in lme4 version >1.0.0 - a presentation at UseR! 2009 +(abstract, +slides) +went into detail about a proposed bootMer package and +suggested it could work for GLMMs too – but it does not seem to be +active.

-

Predictions and/or confidence (or prediction) intervals on predictions

-

Note that none of the following approaches takes the uncertainty of the random effects parameters into account … if you want to take RE parameter uncertainty into account, a Bayesian approach is probably the easiest way to do it.

-

The general recipe for computing predictions from a linear or generalized linear model is to

+

Predictions and/or confidence (or prediction) intervals on +predictions

+

Note that none of the following approaches takes the uncertainty of +the random effects parameters into account … if you want to take RE +parameter uncertainty into account, a Bayesian approach is probably the +easiest way to do it.

+

The general recipe for computing predictions from a linear or +generalized linear model is to

    -
  • figure out the model matrix \(X\) corresponding to the new data;
  • -
  • matrix-multiply \(X\) by the parameter vector \(\beta\) to get the predictions (or linear predictor in the case of GLM(M)s);
  • +
  • figure out the model matrix \(X\) +corresponding to the new data;
  • +
  • matrix-multiply \(X\) by the +parameter vector \(\beta\) to get the +predictions (or linear predictor in the case of GLM(M)s);
  • extract the variance-covariance matrix of the parameters \(V\)
  • -
  • compute \(X V X^{\prime}\) to get the variance-covariance matrix of the predictions;
  • -
  • extract the diagonal of this matrix to get variances of predictions;
  • -
  • if computing prediction rather than confidence intervals, add the residual variance;
  • -
  • take the square-root of the variances to get the standard deviations (errors) of the predictions;
  • +
  • compute \(X V X^{\prime}\) to get +the variance-covariance matrix of the predictions;
  • +
  • extract the diagonal of this matrix to get variances of +predictions;
  • +
  • if computing prediction rather than confidence intervals, add the +residual variance;
  • +
  • take the square-root of the variances to get the standard deviations +(errors) of the predictions;
  • compute confidence intervals based on a Normal approximation;
  • -
  • for GL(M)Ms, run the confidence interval boundaries (not the standard errors) through the inverse-link function.
  • +
  • for GL(M)Ms, run the confidence interval boundaries (not the +standard errors) through the inverse-link function.

lme

@@ -1956,7 +3103,7 @@

lme

fm1 <- lme(distance ~ age*Sex, random = ~ 1 + age | Subject, data = Orthodont) plot(Orthodont,asp="fill") ## plot responses by individual
-

+

## note that expand.grid() orders factor levels by *order of
 ## appearance* -- must match levels(Orthodont$Sex)
 newdat <- expand.grid(age=c(8,10,12,14), Sex=c("Female","Male")) 
@@ -1978,7 +3125,8 @@ 

lme

## prediction intervals 
 g0 + geom_linerange(aes(ymin=pred-cmult*SE2,ymax=pred+cmult*SE2), position=pd) 

-

A similar answer is laid out in the responses to this StackOverflow question.

+

A similar answer is laid out in the responses to this StackOverflow +question.

lme4

@@ -2026,8 +3174,8 @@

glmmTMB

fm2 <- glmmTMB(distance ~ age*Sex + (age | Subject), data = Orthodont, family="gaussian")
-
## Warning in fitTMB(TMBStruc): Model convergence problem; non-positive-definite
-## Hessian matrix. See vignette('troubleshooting')
+
## Warning in finalizeTMB(TMBStruc, obj, fit, h, data.tmb.old): Model convergence
+## problem; non-positive-definite Hessian matrix. See vignette('troubleshooting')
## make prediction data frame
 newdat <- expand.grid(age=c(8,10,12,14), Sex=c("Female","Male"))
 ## design matrix (fixed effects)
@@ -2054,8 +3202,13 @@ 

glmmTMB

## prediction intervals g2 + geom_linerange(data=newdat, aes(ymin=distance-2*SE2,ymax=distance+2*SE2), position=pd)
+
## Warning: The dot-dot notation (`..n..`) was deprecated in ggplot2 3.4.0.
+## ℹ Please use `after_stat(n)` instead.
+## This warning is displayed once every 8 hours.
+## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.

-

The effects, emmeans, and sjPlot packages are also useful here.

+

The effects, emmeans, and +sjPlot packages are also useful here.

@@ -2063,18 +3216,38 @@

Confidence intervals on conditional means/BLUPs/random effects

lme4

(From Harold Doran, updated by Assaf Oron Nov. 2013:)

-

If you want the standard errors of the conditional means, you can extract them as follows:

+

If you want the standard errors of the conditional means, you can +extract them as follows:

library(lme4)
 fm1 <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
 cV <- ranef(fm1, condVar = TRUE)   
-

cV is a list; each element is a data frame containing the conditional modes for a particular grouping factor. If you use scalar random effects (typically random intercepts), then specifying ranef(...,drop=TRUE) will return the conditional modes as a single named vector instead.

-

The conditional variances are returned as an attribute of the conditional modes. It may be easiest to use as.data.frame(cV), or broom.mixed::tidy(fm1, effects="ran_vals"), to extract all of the conditional means and standard deviations.

+

cV is a list; each element is a data frame containing +the conditional modes for a particular grouping factor. If you use +scalar random effects (typically random intercepts), then specifying +ranef(...,drop=TRUE) will return the conditional modes as a +single named vector instead.

+

The conditional variances are returned as an attribute of the +conditional modes. It may be easiest to use +as.data.frame(cV), or +broom.mixed::tidy(fm1, effects="ran_vals"), to extract all +of the conditional means and standard deviations.

Or, digging in to the data structure by hand: if we set

ranvar <- attr(cV[[1]], "postVar")
-

then ranvar is a 3-D array (the attribute is still called postVar, rather than condVar, for historical reasons/backward compatibility). Individual-level covariance matrices of the conditional modes will sit on the [,,i] faces. For example, ranvar[,,1] is the variance-covariance matrix of the conditional distribution for the first group, so

+

then ranvar is a 3-D array (the attribute is still +called postVar, rather than condVar, for +historical reasons/backward compatibility). Individual-level covariance +matrices of the conditional modes will sit on the [,,i] +faces. For example, ranvar[,,1] is the variance-covariance +matrix of the conditional distribution for the first group, so

sqrt(diag(ranvar[,,1]))
## [1] 12.070857  2.304839
-

will provide the intercept and slope standard standard deviations for the first group’s conditional modes. If you have a scalar random effect and used drop=TRUE in ranef(), then you will (mercifully) receive only a vector of individual variances here (one for each level of the grouping factor). The following incantation will give a matrix of conditional variances with one row for each group and one column for each parameters:

+

will provide the intercept and slope standard standard deviations for +the first group’s conditional modes. If you have a scalar random effect +and used drop=TRUE in ranef(), then you will +(mercifully) receive only a vector of individual variances here (one for +each level of the grouping factor). The following incantation will give +a matrix of conditional variances with one row for each group and one +column for each parameters:

ng <- dim(ranvar)[3]
 np <- dim(ranvar)[2]
 mm <- matrix(ranvar[cbind(rep(seq(np),ng),
@@ -2082,7 +3255,22 @@ 

lme4

rep(ng,each=np))], byrow=TRUE, nrow=ng)
-

Getting the uncertainty of the coefficients (i.e., what’s returned by coef(): the sum of the fixed-effect and random-effect predictions for a particular level) is not (alas) currently easy with lme4. If the fixed and random effects were independent then we could simply add the conditional variance and the variance of the fixed-effect predictions, but they aren’t in general. There is a long r-sig-mixed-models mailing list thread that discusses the issues, focusing on (1) how to extract the covariance between fixed-effect estimate and the random-effect prediction; (2) whether this value (the covariance between an estimated parameter and a predicted mode of a conditional distribution of a random variable) even makes sense in a frequentist framework. If you’re willing to assume independence of the conditional variance and the fixed-effect sampling variance, then (e.g.) the variance of the intercepts for each group would be the sum of the fixed-effect intercept variance and the conditional variance of the intercept for each group:

+

Getting the uncertainty of the coefficients (i.e., what’s returned by +coef(): the sum of the fixed-effect and random-effect +predictions for a particular level) is not (alas) currently easy with +lme4. If the fixed and random effects were independent then +we could simply add the conditional variance and the variance of the +fixed-effect predictions, but they aren’t in general. There is a long r-sig-mixed-models +mailing list thread that discusses the issues, focusing on (1) how +to extract the covariance between fixed-effect estimate and the +random-effect prediction; (2) whether this value (the covariance between +an estimated parameter and a predicted mode of a +conditional distribution of a random variable) even makes sense in a +frequentist framework. If you’re willing to assume independence +of the conditional variance and the fixed-effect sampling variance, then +(e.g.) the variance of the intercepts for each group would be the sum of +the fixed-effect intercept variance and the conditional variance of the +intercept for each group:

vcov(fm1)[1,1]+mm[,1]
##  [1] 192.2807 192.2807 192.2807 192.2807 192.2807 192.2807 192.2807 192.2807
 ##  [9] 192.2807 192.2807 192.2807 192.2807 192.2807 192.2807 192.2807 192.2807
@@ -2091,75 +3279,190 @@ 

lme4

Power analysis

-

Power analysis for (G)LMMs is mostly done by simulation, although there are some closed-form solutions and approximations, e.g. Snijders and Bosker (1993) (Snijders has links to programs and other resources on his web page). There are resources and bits of code examples spread all over the internet. e.g. here.

-

Kain, Bolker, and McCoy (2015) and Johnson et al. (2015) are peer-reviewed papers that discuss power analysis via simulation in more detail.

+

Power analysis for (G)LMMs is mostly done by simulation, although +there are some closed-form solutions and approximations, e.g. Snijders and Bosker (1993) (Snijders has links +to programs and other resources on his web +page). There are resources and bits of code examples spread all over +the internet. e.g. here.

+

Kain, Bolker, and McCoy (2015) and +Johnson et al. (2015) are peer-reviewed +papers that discuss power analysis via simulation in more detail.

library(sos); findFn("{power analysis} mixed simulation")
-

locates the fullfact, pamm, simr, and simglm packages. Depending on the goal, one of these packages may have sufficient flexibility to do what you want.

+

locates the fullfact, pamm, +simr, and simglm packages. Depending on the +goal, one of these packages may have sufficient flexibility to do what +you want.

Model selection and averaging

-

Can I use AIC for mixed models? How do I count the number of degrees of freedom for a random effect?

+

Can I use AIC for mixed models? How do I count the number of degrees +of freedom for a random effect?

  • Yes, with caution.
  • -
  • It depends on the “level of focus” (sensu Spiegelhalter et al. (2002)) whether (e.g.) a single random-effect variance should be counted as 1 degree of freedom (i.e., the variance parameter or as a value between 1 and N-1 (where N is the number of groups): see Vaida and Blanchard (2005) and Greven and Kneib (2010). If you are interested in population-level prediction/inference, then the former (called marginal AIC [mAIC]); if individual-level prediction/inference (i.e., using the BLUPs/conditional modes), then the latter (called conditional AIC [cAIC]). Greven and Kneib present results for linear models, giving a version of cAIC that is both computationally efficient and takes uncertainty in the estimation of the variances into account. (Bob O’Hara has a very nice, illustrative blog post on this topic in the context of DIC …)
  • -
  • in cases when testing a variance parameter, AIC may be subject to the same kinds of boundary effects as likelihood ratio test p-values (i.e., AICs may be conservative/overfit slightly when the nested parameter value is on the boundary of the feasible space). Greven and Kneib (2010) explore the problems with mAIC in this context, but do not suggest a solution (they point out that Hughes and King (2003) present a ‘one-sided’ AIC, but not one that deals with the non-independence of data points. I haven’t read Hughes and King, I should go do that).
  • -
  • AIC also inherits the primary problem of likelihood ratio tests in the GLMM context – that is, that LRTs are asymptotic tests. A finite-size correction for AIC does exist (AICc) – but it was developed in the context of linear models. As far as I know its adequacy in the GLMM case has not been established. See e.g. Richards (2005) for caution about AICc in the GLM (not GLMM) case.
  • +
  • It depends on the “level of focus” (sensu Spiegelhalter et al. (2002)) whether (e.g.) a +single random-effect variance should be counted as 1 degree of freedom +(i.e., the variance parameter or as a value between 1 and N-1 (where N +is the number of groups): see Vaida and Blanchard +(2005) and Greven and Kneib (2010). +If you are interested in population-level prediction/inference, then the +former (called marginal AIC [mAIC]); if individual-level +prediction/inference (i.e., using the BLUPs/conditional modes), then the +latter (called conditional AIC [cAIC]). Greven and Kneib +present results for linear models, giving a version of cAIC that is both +computationally efficient and takes uncertainty in the estimation of the +variances into account. (Bob O’Hara has a very nice, illustrative blog +post on this topic in the context of DIC …)
  • +
  • in cases when testing a variance parameter, AIC may be subject to +the same kinds of boundary effects as likelihood ratio test p-values +(i.e., AICs may be conservative/overfit slightly when the nested +parameter value is on the boundary of the feasible space). Greven and Kneib (2010) explore the problems +with mAIC in this context, but do not suggest a solution (they point out +that Hughes and King (2003) present a +‘one-sided’ AIC, but not one that deals with the non-independence of +data points. I haven’t read Hughes and King, I should go do that).
  • +
  • AIC also inherits the primary problem of likelihood ratio tests in +the GLMM context – that is, that LRTs are asymptotic tests. A +finite-size correction for AIC does exist (AICc) – but it was developed +in the context of linear models. As far as I know its adequacy in the +GLMM case has not been established. See e.g. Richards (2005) for caution about AICc in the +GLM (not GLMM) case.
  • lme4 and nlme count parameters for AIC(c) as follows:
      -
    • the number of fixed-effect parameters is straightforward (the length of the fixed-effect parameter vector beta, i.e. length(fixef(model)))
    • -
    • each random term in the model with \(q\) components counts for \(q(q+1)/2\) parameters – for example, a term of the form (slope|group) has 3 parameters (intercept variance, slope variance, correlation between intercept and slope).
    • -
    • models that use a scale parameter (e.g. the variance parameter of linear mixed models, or the scale parameter of a Gamma GLMM – standard GLMMs such as binomial and Poisson do not) get an extra parameter counted. Whether to add nuisance parameters or not, such as the residual variance parameter (estimated based on the residual variance, rather than an explicit parameter in the optimization) is as far as I know an open question. In the classic AIC context it doesn’t matter as long as one is consistent. In the AICc context, I don’t think anyone really knows the answer … adding +1 for the residual variance parameter (as lme4 does) would make the model selection process slightly more conservative.
    • +
    • the number of fixed-effect parameters is straightforward (the length +of the fixed-effect parameter vector beta, +i.e. length(fixef(model)))
    • +
    • each random term in the model with \(q\) components counts for \(q(q+1)/2\) parameters – for example, a term +of the form (slope|group) has 3 parameters (intercept variance, slope +variance, correlation between intercept and slope).
    • +
    • models that use a scale parameter (e.g. the variance parameter of +linear mixed models, or the scale parameter of a Gamma GLMM – standard +GLMMs such as binomial and Poisson do not) get an extra parameter +counted. Whether to add nuisance parameters or not, such as the residual +variance parameter (estimated based on the residual variance, rather +than an explicit parameter in the optimization) is as far as I know an +open question. In the classic AIC context it doesn’t matter as long as +one is consistent. In the AICc context, I don’t think anyone really +knows the answer … adding +1 for the residual variance parameter (as +lme4 does) would make the model selection process slightly more +conservative.
-

Model summaries (goodness-of-fit, decomposition of variance, etc.)

+

Model summaries (goodness-of-fit, decomposition of variance, +etc.)

How do I compute a coefficient of determination (\(R^2\)), or an analogue, for (G)LMMs?

Problem

-

(This topic applies to both LMMs and GLMMs, perhaps more so to LMMs, because the issues are even harder for GLMMs.)

-

Researchers often want to know if there is a simple (or at least implemented-in-R) way to get an analogue of \(R^2\) or another simple goodness-of-fit metric for LMMs or GLMMs. This is a challenging question in both the GLM and LMM worlds (and therefore doubly so for GLMMs), because it turns out that the wonderful simplicity of \(R^2\) breaks down in the extension to GLMs or LMMs. If you’re trying to quantify “fraction of variance explained” in the GLM context, should you include or exclude sampling variation (e.g., Poisson variation around the expected mean)? [According to an sos::findFn search for “Nagelkerke”, one of the common solutions to this problem, the LogRegR2 function in the descr package computes several different “pseudo-\(R^2\)” measures for logistic regression.] If you’re trying to quantify it in the LMM context, should you include or exclude variation of different random-effects terms?

-

The same questions apply more generally to decomposition of variance (i.e. trying to assess the contribution of various model components to the overall fit, not just trying to assess the overall goodness-of-fit of the model); there is unlikely to be a single recipe that does everything you want.

-

This has been discussed at various times on the mailing lists. This thread and this thread on the r-sig-mixed-models mailing list are good starting points, and this post is useful too.

+

(This topic applies to both LMMs and GLMMs, perhaps more so to +LMMs, because the issues are even harder for GLMMs.)

+

Researchers often want to know if there is a simple (or at least +implemented-in-R) way to get an analogue of \(R^2\) or another simple goodness-of-fit +metric for LMMs or GLMMs. This is a challenging question in both the GLM +and LMM worlds (and therefore doubly so for GLMMs), because it turns out +that the wonderful simplicity of \(R^2\) breaks down in the extension to GLMs +or LMMs. If you’re trying to quantify “fraction of variance explained” +in the GLM context, should you include or exclude sampling variation +(e.g., Poisson variation around the expected mean)? [According to an +sos::findFn search for “Nagelkerke”, one of the common +solutions to this problem, the LogRegR2 function in the +descr package computes several different “pseudo-\(R^2\)” measures for logistic regression.] +If you’re trying to quantify it in the LMM context, should you include +or exclude variation of different random-effects terms?

+

The same questions apply more generally to decomposition of variance +(i.e. trying to assess the contribution of various model components to +the overall fit, not just trying to assess the overall goodness-of-fit +of the model); there is unlikely to be a single recipe that does +everything you want.

+

This has been discussed at various times on the mailing lists. This +thread and this +thread on the r-sig-mixed-models mailing list are good starting +points, and this +post is useful too.

In one of those threads, Doug Bates said:

-

Assuming that one wants to define an R^2 measure, I think an argument could be made for treating the penalized residual sum of squares from a linear mixed model in the same way that we consider the residual sum of squares from a linear model. Or one could use just the residual sum of squares without the penalty or the minimum residual sum of squares obtainable from a given set of terms, which corresponds to an infinite precision matrix. I don’t know, really. It depends on what you are trying to characterize.

+

Assuming that one wants to define an R^2 measure, I think an argument +could be made for treating the penalized residual sum of squares from a +linear mixed model in the same way that we consider the residual sum of +squares from a linear model. Or one could use just the residual sum of +squares without the penalty or the minimum residual sum of squares +obtainable from a given set of terms, which corresponds to an infinite +precision matrix. I don’t know, really. It depends on what you are +trying to characterize.

Simple/crude solutions

-

In one of those threads, Jarrett Byrnes contributed the following code:

+

In one of those threads, Jarrett Byrnes contributed the following +code:

r2.corr.mer <- function(m) {
    lmfit <-  lm(model.response(model.frame(m)) ~ fitted(m))
    summary(lmfit)$r.squared
 }
-

\(\Omega^2_0\) (Xu 2003), which is almost the same, is based on comparing the residual variance of the full model against the residual variance of a (fixed) intercept-only null model:

+

\(\Omega^2_0\) (Xu 2003), which is almost the same, is based on +comparing the residual variance of the full model against the residual +variance of a (fixed) intercept-only null model:

1-var(residuals(m))/var(model.response(model.frame(m)))
-

Another possibility is the squared correlation between the response variable and the predicted values:

+

Another possibility is the squared correlation between the response +variable and the predicted values:

cor(model.response(model.frame(m)),predict(m,type="response"))^2

Sophisticated solutions

-

Gelman and Pardoe (2006) propose/discuss Bayesian measures of \(R^2\) (I don’t know if anyone has created a canned implementation of these measures in R). Nakagawa and Schielzeth (2013) and Johnson (2014) have also proposed a general methodology for computing \(R^2\); J. Lefcheck gives examples here and here, based on his implementation in the piecewiseSEM package (CRAN, Github). See also Jaeger et al. (2017), Rights and Sterba (2018)

-

A related question is how to quantify “repeatability” (i.e., ratios of variance at different levels) in GLMMs, especially how to compute the “residual error” term for GLMMs: see Nakagawa and Schielzeth (2010) and the rptR package.

-

The bottom line is that there are some simple recipes (and some more complex recipes that may or may not have been coded up by someone), but that ’‘’you have to think carefully about what information you want to get out of the coefficient of determination’’’, because no recipe will have all of the properties of \(R^2\) in the simple linear model case.

-

Packages/functions: See performance::r2(), MuMIn::r.squaredGLMM(), the r2glmm package, the standalone r2MLM function, stuff in the piecewiseSEM package, psycho::R2_nakagawa, partR2 package … (try e.g. sos::findFn("Nakagawa Schielzeth") for an up-to-date list …)

+

Gelman and Pardoe (2006) +propose/discuss Bayesian measures of \(R^2\) (I don’t know if anyone has created a +canned implementation of these measures in R). Nakagawa and Schielzeth (2013) and Johnson (2014) have also proposed a general +methodology for computing \(R^2\); J. +Lefcheck gives examples here +and here, +based on his implementation in the piecewiseSEM package (CRAN, +Github). See also +Jaeger et al. (2017), Rights and Sterba (2018)

+

A related question is how to quantify “repeatability” (i.e., ratios +of variance at different levels) in GLMMs, especially how to compute the +“residual error” term for GLMMs: see Nakagawa and +Schielzeth (2010) and the rptR package.

+

The bottom line is that there are some simple recipes (and some more +complex recipes that may or may not have been coded up by someone), but +that ’‘’you have to think carefully about what information you want to +get out of the coefficient of determination’’’, because no recipe will +have all of the properties of \(R^2\) +in the simple linear model case.

+

Packages/functions: See performance::r2(), +MuMIn::r.squaredGLMM(), the r2glmm +package, the standalone r2MLM +function, stuff in the piecewiseSEM package, psycho::R2_nakagawa, +partR2 package … (try +e.g. sos::findFn("Nakagawa Schielzeth") for an up-to-date +list …)

Variable importance

    -
  • The simplest way to get (within-study) measures of variable importance is to standardize the predictor variables (scaling by 1 SD or 2SD: Gelman (2008), Schielzeth (2010))

  • -
  • The r2glmm package computes partial \(R^2\) values for fixed effects (only for lmer, lme, and glmmPQL models)

  • -
  • Henrik Singmann has a detailed answer here on why standardized measures such as partial eta-squared are problematic:

    +
  • The simplest way to get (within-study) measures of variable +importance is to standardize the predictor variables (scaling by 1 SD or +2SD: Gelman (2008), Schielzeth (2010))

  • +
  • The r2glmm package computes partial \(R^2\) values for fixed effects (only for +lmer, lme, and glmmPQL +models)

  • +
  • Henrik Singmann has a detailed answer here +on why standardized measures such as partial eta-squared are +problematic:

    -

    The fact that calculating a global measure of model fit (such as R2) is already riddled with complications and that no simple single number can be found, should be a hint that doing so for a subset of the model parameters (i.e., main-effects or interactions) is even more difficult. Given this, I would not recommend to try finding a measure of standardized effect sizes for mixed models.

    +

    The fact that calculating a global measure of model fit (such as R2) +is already riddled with complications and that no simple single number +can be found, should be a hint that doing so for a subset of the model +parameters (i.e., main-effects or interactions) is even more difficult. +Given this, I would not recommend to try finding a measure of +standardized effect sizes for mixed models.

    -

    He even gives suggested wording for responding to reviewers who want standardized measures!

  • +

    He even gives suggested wording for responding to reviewers who want +standardized measures!

@@ -2172,20 +3475,30 @@

Miscellaneous/procedural

Pronunciation of lmer/glmer/etc.

    -
  • lmer: I have heard “ell emm ee arr” (i.e. pronouncing each letter); “elmer” (probably most common); and “lemur”
  • -
  • glmer: “gee ell emm ee arr”, “gee elmer”, “glimmer”, or “gleamer”
  • -
  • for lme and nlme people just seem to spell out the names (rather than saying e.g. “lemmy” and “nelmy”)
  • +
  • lmer: I have heard “ell emm ee arr” (i.e. pronouncing +each letter); “elmer” (probably most common); and “lemur”
  • +
  • glmer: “gee ell emm ee arr”, “gee elmer”, “glimmer”, or +“gleamer”
  • +
  • for lme and nlme people just seem to spell +out the names (rather than saying e.g. “lemmy” and “nelmy”)

Storing information

-

Recent versions of lme4 output contain an @optinfo slot that stores warnings.

-

Copied from https://stat.ethz.ch/pipermail/r-help/2012-February/302767.html :

+

Recent versions of lme4 output contain an +@optinfo slot that stores warnings.

+

Copied from https://stat.ethz.ch/pipermail/r-help/2012-February/302767.html +:

-

There’s a somewhat hack-ish solution, which is to use options(warn=2) to ‘upgrade’ warnings to errors, and then use try() or tryCatch() to catch them.

+

There’s a somewhat hack-ish solution, which is to use options(warn=2) +to ‘upgrade’ warnings to errors, and then use try() or tryCatch() to +catch them.

-

More fancily, I used code that looked something like this to save warnings as I went along (sorry about the <<- ) in a recent simulation study. You could also check w$message to do different things in the case of different warnings.

+

More fancily, I used code that looked something like this to save +warnings as I went along (sorry about the <<- ) in a recent +simulation study. You could also check w$message to do different things +in the case of different warnings.

## n.b. have to set up a 3D warn array first ...
 withCallingHandlers(tryCatch(fun(n=nvec[j],tau=tauvec[i],...),
@@ -2201,13 +3514,15 @@ 

Storing information

Mixed modeling packages

Which R packages (functions) fit GLMMs?

  • MASS::glmmPQL (penalized quasi-likelihood)
  • -
  • lme4::glmer (Laplace approximation and adaptive Gauss-Hermite quadrature [AGHQ])
  • +
  • lme4::glmer (Laplace approximation and adaptive Gauss-Hermite +quadrature [AGHQ])
  • MCMCglmm (Markov chain Monte Carlo)
  • glmmML (AGHQ)
  • glmmAK (AGHQ?)
  • @@ -2219,43 +3534,55 @@

    Which R packages (functions) fit GLMMs?

-

Should I use aov(), nlme, or lme4, or some other package?

+

Should I use aov(), nlme, or +lme4, or some other package?

    -
  • aov() (in the stats package in base R: balanced, orthogonal designs only (R analogue of SAS PROC GLM)
  • -
  • nlme (analogue of SAS PROC MIXED/NLMIXED) +
  • aov() (in the stats package in base R: +balanced, orthogonal designs only (R analogue of SAS PROC GLM)
  • +
  • nlme (analogue of SAS +PROC MIXED/NLMIXED)
      -
    • allows more complex designs than aov (unbalanced, heteroscedasticity and/or correlation among residual errors)
    • +
    • allows more complex designs than aov (unbalanced, +heteroscedasticity and/or correlation among residual errors)
    • more mature than lme4
    • -
    • well-documented (Pinheiro and Bates 2000)
    • +
    • well-documented (Pinheiro and Bates +2000)
    • implements R-side effects (heteroscedasticity and correlation)
    • estimates “denominator degrees of freedom” for \(F\) statistics, and hence \(p\) values, for LMMs (but see above)
  • -
  • lme4 (also SAS PROC MIXED/NLMIXED): +
  • lme4 (also SAS +PROC MIXED/NLMIXED):
    • fastest
    • -
    • best for crossed designs (although they are possible in lme)
    • +
    • best for crossed designs (although they are possible in +lme)
    • GLMMs
    • cutting-edge (for better or worse!)
    • likelihood profiles
    • -
    • use lme4 for GLMMs, or if you have big data (thousands to tens of thousands of records)
    • +
    • use lme4 for GLMMs, or if you have big data (thousands +to tens of thousands of records)
-

The following is modified from a contribution by Kingsford Jones, found 2010-03-16

+

The following is modified from a contribution by Kingsford Jones, +found 2010-03-16

linear and nonlinear mixed models

    -
  • lme – Linear mixed-effects models using S4 classes
  • +
  • lme – +Linear mixed-effects models using S4 classes
  • lmm – Linear mixed models
  • nlme – Linear and Nonlinear Mixed Effects Models
  • sabreR
  • -
  • regress Linear mixed models
  • +
  • regress +Linear mixed models

GLMMs

  • glmmAK – Generalized Linear Mixed Models
  • -
  • MASS – Main Package of Venables and Ripley’s MASS (see function glmmPQL)
  • +
  • MASS – Main Package of Venables and Ripley’s MASS (see function +glmmPQL)
  • MCMCglmm – MCMC Generalised Linear Mixed Models
  • lme4 (glmer)
  • glmmML
  • @@ -2275,19 +3602,25 @@

    Additive and generalized-additive mixed models

    Hierarchical GLMs

      -
    • hglm – hglm is used to fit hierarchical generalized linear models
    • +
    • hglm – hglm is used to fit hierarchical generalized linear +models
    • HGLMMM – Hierarchical Generalized Linear Models

    diagnostic and modeling frameworks

      -
    • influence.ME – Tools for detecting influential data in mixed effects models
    • -
    • arm – Data Analysis Using Regression and Multilevel/Hierarchical Models
    • +
    • influence.ME – Tools for detecting influential data in mixed effects +models
    • +
    • arm – Data Analysis Using Regression and Multilevel/Hierarchical +Models
    • pamm – Power analysis for random effects in mixed models
    • -
    • RLRsim – Exact (Restricted) Likelihood Ratio tests for mixed and additive models
    • -
    • npde – Normalised prediction distribution errors for nonlinear mixed-effect models
    • -
    • multilevel – Multilevel Functions (psychology-oriented; within-group agreement, random group resampling, etc.)
    • +
    • RLRsim – Exact (Restricted) Likelihood Ratio tests for mixed and +additive models
    • +
    • npde – Normalised prediction distribution errors for nonlinear +mixed-effect models
    • +
    • multilevel – Multilevel Functions (psychology-oriented; within-group +agreement, random group resampling, etc.)
    • languageR
    • pbkrtest – parametric bootstrap and Kenward-Roger tests
    @@ -2305,14 +3638,17 @@

    extensions

    • lmeSplines – lmeSplines
    • lmec – Linear Mixed-Effects Models with Censored Responses
    • -
    • kinship – mixed-effects Cox models, sparse matrices, and modeling data from large pedigrees
    • +
    • kinship – mixed-effects Cox models, sparse matrices, and modeling +data from large pedigrees
    • coxme – Mixed Effects Cox Models
    • ordinal – Regression Models for Ordinal Data
    • phmm – Proportional Hazards Mixed-effects Model (PHMM)
    • pedigreemm – Pedigree-based mixed-effects models
    • (see also MCMCglmm for pedigree-based approaches)
    • -
    • heavy – Estimation in the linear mixed model using heavy-tailed distributions
    • -
    • GLMMarp – Generalized Linear Multilevel Model with AR(p) Errors Package
    • +
    • heavy – Estimation in the linear mixed model using heavy-tailed +distributions
    • +
    • GLMMarp – Generalized Linear Multilevel Model with AR(p) Errors +Package
    • glmmlasso – penalized GLMM fitting
    • spatialCovariance – spatial covariance matrix calculations
    @@ -2320,7 +3656,8 @@

    extensions

    Interfaces to other systems

      -
    • glmmBUGS – Generalised Linear Mixed Models and Spatial Models with BUGS
    • +
    • glmmBUGS – Generalised Linear Mixed Models and Spatial Models with +BUGS
    • Interfaces to WinBUGS/OpenBUGS/JAGS (roll your own model file):
    • R2WinBUGS
    • r2jags
    • @@ -2331,9 +3668,12 @@

      Interfaces to other systems

      modeling based on LMMs

        -
      • nlmeODE – Non-linear mixed-effects modelling in nlme using differential equations
      • -
      • longRPart – Recursive partitioning of longitudinal data using mixed-effects models
      • -
      • PSM – Non-Linear Mixed-Effects modelling using Stochastic Differential Equations
      • +
      • nlmeODE – Non-linear mixed-effects modelling in nlme +using differential equations
      • +
      • longRPart – Recursive partitioning of longitudinal data +using mixed-effects models
      • +
      • PSM – Non-Linear Mixed-Effects modelling using +Stochastic Differential Equations
    @@ -2349,30 +3689,43 @@

    R-forge and Github:

    Other open source:

      -
    • bernor package (logit-normal fitting), by Yun Ju Sung and Charles J. Geyer
    • -
    • glmm (in Jim Lindsey’s repeated package: at Lindsey’s web site
    • +
    • bernor +package (logit-normal fitting), by Yun Ju Sung and Charles J. Geyer
    • +
    • glmm (in Jim Lindsey’s repeated package: +at Lindsey’s web +site

    Commercial:

    • OpenMx – Advanced Structural Equation Modeling
    • -
    • ASReml-R (commercial, but 30 days’ free use/free license for academic or developing-country use available). Very good at complex LMMs (fast, flexible covariance structures, etc.), but only offers PQL for GLMMs, and the manual says: > we cannot recommend the use of this technique for general use. It is included in the current version of asreml() for advanced users. It is highly recommended that its use be accompanied by some form of cross-validatory assessment for the specific dataset concerned." Resources:
    • -
    • short R wiki tutorial
    • -
    • reference manual (PDF)
    • -
    • Luis Apiolaza’s asreml-r cookbook
    • +
    • ASReml-R (commercial, but 30 days’ free use/free +license for academic or developing-country use available). Very good at +complex LMMs (fast, flexible covariance structures, etc.), but only +offers PQL for GLMMs, and the manual says: > we cannot recommend the +use of this technique for general use. It is included in the current +version of asreml() for advanced users. It is highly recommended that +its use be accompanied by some form of cross-validatory assessment for +the specific dataset concerned.” Resources:
    • +
    • short +R wiki tutorial
    • +
    • reference +manual (PDF)
    • +
    • Luis Apiolaza’s asreml-r +cookbook

    Package versions used

    sessionInfo()
    -
    ## R Under development (unstable) (2022-08-25 r82762)
    -## Platform: x86_64-pc-linux-gnu (64-bit)
    +
    ## R Under development (unstable) (2023-09-20 r85179)
    +## Platform: x86_64-pc-linux-gnu
     ## Running under: Pop!_OS 22.04 LTS
     ## 
     ## Matrix products: default
    -## BLAS/LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so
    +## BLAS/LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so;  LAPACK version 3.10.0
     ## 
     ## locale:
     ##  [1] LC_CTYPE=en_CA.UTF-8       LC_NUMERIC=C              
    @@ -2382,288 +3735,467 @@ 

    Package versions used

    ## [9] LC_ADDRESS=C LC_TELEPHONE=C ## [11] LC_MEASUREMENT=en_CA.UTF-8 LC_IDENTIFICATION=C ## +## time zone: America/Toronto +## tzcode source: system (glibc) +## ## attached base packages: ## [1] stats graphics grDevices utils datasets methods base ## ## other attached packages: -## [1] ggplot2_3.3.6 RLRsim_3.1-8 nlme_3.1-159 -## [4] dplyr_1.0.10 broom.mixed_0.2.9.5 glmmTMB_1.1.4 -## [7] equatiomatic_0.3.1 lme4_1.1-31 Matrix_1.5-1 -## [10] Cairo_1.6-0 pander_0.6.5 knitr_1.40 -## [13] rmarkdown_2.16 +## [1] ggplot2_3.4.3 RLRsim_3.1-8 nlme_3.1-163 +## [4] dplyr_1.1.3 broom.mixed_0.2.9.5 glmmTMB_1.1.8-9000 +## [7] equatiomatic_0.3.1 lme4_1.1-34 Matrix_1.6-1.1 +## [10] Cairo_1.6-1 pander_0.6.5 knitr_1.44 ## ## loaded via a namespace (and not attached): -## [1] gtable_0.3.1 TMB_1.9.1 xfun_0.33 -## [4] bslib_0.4.0 lattice_0.20-45 numDeriv_2016.8-1.1 -## [7] vctrs_0.4.2 tools_4.3.0 generics_0.1.3 -## [10] pbkrtest_0.5.1 sandwich_3.0-2 parallel_4.3.0 -## [13] tibble_3.1.8 fansi_1.0.3 highr_0.9 -## [16] pkgconfig_2.0.3 assertthat_0.2.1 lifecycle_1.0.2 -## [19] farver_2.1.1 compiler_4.3.0 stringr_1.4.1 -## [22] munsell_0.5.0 codetools_0.2-18 httpuv_1.6.6 -## [25] htmltools_0.5.3 sass_0.4.2 yaml_2.3.5 -## [28] later_1.3.0 pillar_1.8.1 furrr_0.3.1 -## [31] nloptr_2.0.3 jquerylib_0.1.4 tidyr_1.2.1 -## [34] MASS_7.3-58.1 ellipsis_0.3.2 cachem_1.0.6 -## [37] multcomp_1.4-20 boot_1.3-28 mime_0.12 -## [40] parallelly_1.32.1 tidyselect_1.1.2 digest_0.6.29 -## [43] mvtnorm_1.1-3 stringi_1.7.8 future_1.28.0 -## [46] purrr_0.3.4 listenv_0.8.0 labeling_0.4.2 -## [49] forcats_0.5.2 splines_4.3.0 fastmap_1.1.0 -## [52] grid_4.3.0 colorspace_2.0-3 cli_3.4.1 -## [55] magrittr_2.0.3 survival_3.4-0 utf8_1.2.2 -## [58] TH.data_1.1-1 broom_1.0.1.9000 withr_2.5.0 -## [61] scales_1.2.1 promises_1.2.0.1 backports_1.4.1 -## [64] estimability_1.4.1 emmeans_1.8.1-1 globals_0.16.1 -## [67] zoo_1.8-11 coda_0.19-4 shiny_1.7.2 -## [70] evaluate_0.16 mgcv_1.8-40 rlang_1.0.6 -## [73] Rcpp_1.0.9 xtable_1.8-4 glue_1.6.2 -## [76] DBI_1.1.3 minqa_1.2.4 jsonlite_1.8.0 -## [79] R6_2.5.1
    +## [1] gtable_0.3.4 TMB_1.9.6 xfun_0.40 +## [4] bslib_0.5.1 lattice_0.21-9 numDeriv_2016.8-1.1 +## [7] vctrs_0.6.3 tools_4.4.0 generics_0.1.3 +## [10] parallel_4.4.0 sandwich_3.0-2 tibble_3.2.1 +## [13] fansi_1.0.4 pkgconfig_2.0.3 lifecycle_1.0.3 +## [16] farver_2.1.1 compiler_4.4.0 munsell_0.5.0 +## [19] codetools_0.2-19 httpuv_1.6.11 htmltools_0.5.6 +## [22] sass_0.4.7 yaml_2.3.7 crayon_1.5.2 +## [25] later_1.3.1 pillar_1.9.0 furrr_0.3.1 +## [28] nloptr_2.0.3 jquerylib_0.1.4 tidyr_1.3.0 +## [31] MASS_7.3-60.1 ellipsis_0.3.2 cachem_1.0.8 +## [34] boot_1.3-28.1 multcomp_1.4-25 mime_0.12 +## [37] parallelly_1.36.0 tidyselect_1.2.0 digest_0.6.33 +## [40] mvtnorm_1.2-3 future_1.33.0 purrr_1.0.2 +## [43] listenv_0.9.0 labeling_0.4.3 forcats_1.0.0 +## [46] splines_4.4.0 fastmap_1.1.1 grid_4.4.0 +## [49] colorspace_2.1-0 cli_3.6.1 magrittr_2.0.3 +## [52] survival_3.5-7 utf8_1.2.3 TH.data_1.1-2 +## [55] broom_1.0.5 withr_2.5.1 scales_1.2.1 +## [58] promises_1.2.1 backports_1.4.1 estimability_1.4.1 +## [61] rmarkdown_2.25 emmeans_1.8.8 globals_0.16.2 +## [64] zoo_1.8-12 coda_0.19-4 shiny_1.7.5 +## [67] evaluate_0.22 mgcv_1.9-0 rlang_1.1.1 +## [70] Rcpp_1.0.11 xtable_1.8-4 glue_1.6.2 +## [73] minqa_1.2.6 jsonlite_1.8.7 R6_2.5.1

    To do

      -
    • add links to merDeriv for standard devs of variances, robust estimates. More on Rizopoulos package
    • -
    • update package descriptions; cross-link with Task View ? rethinking, brms, …
    • -
    • more on post-analysis (broom(.mixed), emmeans, multcomp, …)
    • -
    • more on confidence intervals, simulating from conditional distributions, etc.)
    • +
    • add links to merDeriv for standard devs of variances, +robust estimates. More on Rizopoulos package
    • +
    • update package descriptions; cross-link with Task +View ? rethinking, brms, …
    • +
    • more on post-analysis (broom(.mixed), +emmeans, multcomp, …)
    • +
    • more on confidence intervals, simulating from conditional +distributions, etc.)

Bibliography

-
-
-

Agresti, Alan. 2002. Categorical Data Analysis. 2d ed. Hoboken, NJ: Wiley.

-
-
-

Angrist, Joshua D., and Jörn-Steffen Pischke. 2009. Mostly Harmless Econometrics: An Empiricist’s Companion. 1 edition. Princeton: Princeton University Press.

-
-
-

Barr, Dale J. 2020. Learning Statistical Models Through Simulation in R. PsyTeachR Books. https://psyteachr.github.io/ug3-stats/.

-
-
-

Barr, Dale J., Roger Levy, Christoph Scheepers, and Harry J. Tily. 2013. “Random Effects Structure for Confirmatory Hypothesis Testing: Keep It Maximal.” Journal of Memory and Language 68 (3): 255–78. https://doi.org/10.1016/j.jml.2012.11.001.

-
-
-

Bates, Douglas, Reinhold Kliegl, Shravan Vasishth, and Harald Baayen. 2015. “Parsimonious Mixed Models.” arXiv:1506.04967 [Stat], June. http://arxiv.org/abs/1506.04967.

-
-
-

Bates, Douglas, Martin Mächler, Benjamin M. Bolker, and Steven C. Walker. 2015. “Fitting Linear Mixed-Effects Models Using lme4.” Journal of Statistical Software 67 (1): 1–48. https://doi.org/10.18637/jss.v067.i01.

-
-
-

Bell, Melanie L., and Gary K. Grunwald. 2010. “Small Sample Estimation Properties of Longitudinal Count Models.” Journal of Statistical Computation and Simulation 81 (9): 1067–79. https://doi.org/10.1080/00949651003674144.

-
-
-

Berger, J. O., B. Liseo, and R. L. Wolpert. 1999. “Integrated Likelihood Methods for Eliminating Nuisance Parameters.” Statistical Science 14 (1): 1–22. http://projecteuclid.org/download/pdf_1/euclid.ss/1009211804.

-
-
-

Breslow, N. E. 1984. “Extra-Poisson Variation in Log-Linear Models.” Journal of the Royal Statistical Society C 33: 38–44. http://www.jstor.org/stable/234766.

-
-
-

Browne, W. J, S. V. Subramanian, K. Jones, and H. Goldstein. 2005. “Variance Partitioning in Multilevel Logistic Models That Exhibit Overdispersion.” Journal of the Royal Statistical Society A 168 (3): 599–613. https://doi.org/10.1111/j.1467-985X.2004.00365.x.

-
-
-

Chung, Yeojin, Sophia Rabe-Hesketh, Vincent Dorie, Andrew Gelman, and Jingchen Liu. 2013. “A Nondegenerate Penalized Likelihood Estimator for Variance Parameters in Multilevel Models.” Psychometrika, 1–25. https://doi.org/10.1007/s11336-013-9328-2.

-
-
-

Clark, Tom S, and Drew A Linzer. 2015. “Should I Use Fixed or Random Effects?” Political Science Research and Methods 3 (02): 399–408.

-
-
-

Cordeiro, Gauss M., and Silvia L. P. Ferrari. 1998. “A Note on Bartlett-Type Correction for the First Few Moments of Test Statistics.” Journal of Statistical Planning and Inference 71 (1-2): 261–69. https://doi.org/10.1016/S0378-3758(98)00005-6.

-
-
-

Cordeiro, Gauss M., Gilberto A. Paula, and Denise A. Botter. 1994. “Improved Likelihood Ratio Tests for Dispersion Models.” International Statistical Review / Revue Internationale de Statistique 62 (2): 257–74. https://doi.org/10.2307/1403512.

-
-
-

Crawley, Michael J. 2002. Statistical Computing: An Introduction to Data Analysis Using S-PLUS. John Wiley & Sons.

-
-
-

Cribari-Neto, Francisco, and Achim Zeileis. 2009. “Beta Regression in R.” 98. Vienna, Austria: WU Vienna University of Economics; Business. https://cran.r-project.org/web/packages/betareg/index.html.

-
-
-

Dobson, Annette J., and Adrian Barnett. 2008. An Introduction to Generalized Linear Models, Third Edition. 3rd ed. Chapman; Hall/CRC.

-
-
-

Elston, D. A., R. Moss, T. Boulinier, C. Arrowsmith, and X. Lambin. 2001. “Analysis of Aggregation, a Worked Example: Numbers of Ticks on Red Grouse Chicks.” Parasitology 122 (5): 563–69.

-
-
-

Faraway, Julian J. 2006. Extending Linear Models with R: Generalized Linear, Mixed Effects and Nonparametric Regression Models. Chapman & Hall/CRC.

-
-
-

Feng, Ziding, Thomas Braun, and Charles McCulloch. 2004. “Small Sample Inference for Clustered Data.” In Proceedings of the Second Seattle Symposium in Biostatistics, edited by D. Y. Lin and P. J. Heagerty, 179:71–87. New York, NY: Springer. http://www.springerlink.com/content/h2g33m7127790343/.

-
-
-

Gelman, Andrew. 2005. “Analysis of Variance: Why It Is More Important Than Ever.” Annals of Statistics 33 (1): 1–53. https://doi.org/doi:10.1214/009053604000001048.

-
-
-

———. 2006. “Prior Distributions for Variance Parameters in Hierarchical Models.” Bayesian Analysis 1 (3): 515–33. http://ba.stat.cmu.edu/journal/2006/vol01/issue03/gelman.pdf.

-
-
-

———. 2008. “Scaling Regression Inputs by Dividing by Two Standard Deviations.” Statistics in Medicine 27 (15): 2865–73. https://doi.org/10.1002/sim.3107.

-
-
-

Gelman, Andrew, and Jennifer Hill. 2006. Data Analysis Using Regression and Multilevel/Hierarchical Models. Cambridge, England: Cambridge University Press. http://www.stat.columbia.edu/~gelman/arm/.

-
-
-

Gelman, Andrew, and Iain Pardoe. 2006. “Bayesian Measures of Explained Variance and Pooling in Multilevel (Hierarchical) Models.” Technometrics 48 (2): 241–51. http://amstat.tandfonline.com/doi/abs/10.1198/004017005000000517.

-
-
-

Goldman, Nick, and Simon Whelan. 2000. “Statistical Tests of Gamma-Distributed Rate Heterogeneity in Models of Sequence Evolution in Phylogenetics.” Molecular Biology and Evolution 17 (6): 975–78.

-
-
-

Gotelli, Nicholas J., and Aaron M. Ellison. 2004. A Primer of Ecological Statistics. Sunderland, MA: Sinauer.

-
-
-

Greven, Sonja, and Thomas Kneib. 2010. “On the Behaviour of Marginal and Conditional Akaike Information Criteria in Linear Mixed Models.” Biometrika 97 (4): 773–89. http://www.bepress.com/jhubiostat/paper202/.

-
-
-

Harrison, Xavier A. 2015. “A Comparison of Observation-Level Random Effect and Beta-Binomial Models for Modelling Overdispersion in Binomial Data in Ecology and Evolution.” PeerJ 3 (July): e1114. https://doi.org/10.7717/peerj.1114.

-
-
-

Heisterkamp, Simon H., Engelbertus van Willigen, Paul-Matthias Diderichsen, and John Maringwa. 2017. “Update of the Nlme Package to Allow a Fixed Standard Deviation of the Residual Error.” The R Journal 9 (1): 239–51.

-
-
-

Hinde, John. 1982. “Compound Poisson Regression Models.” In GLIM82: Proc. Int. Conf. On Glms, edited by R. Gilchrist, 109–21. Springer.

-
-
-

Hodges, James S. 2016. Richly Parameterized Linear Models: Additive, Time Series, and Spatial Models Using Random Effects. Chapman; Hall/CRC.

-
-
-

Hughes, A., and M. King. 2003. “Model Selection Using AIC in the Presence of One-Sided Information.” Journal of Statistical Planning and Inference 115: 497–11.

-
-
-

Hurlbert, S. 1984. “Pseudoreplication and the Design of Ecological Field Experiments.” Ecological Monographs 54: 187–211.

-
-
-

Jaeger, Byron C., Lloyd J. Edwards, Kalyan Das, and Pranab K. Sen. 2017. “An R2 Statistic for Fixed Effects in the Generalized Linear Mixed Model.” Journal of Applied Statistics 44 (6): 1086–1105. https://doi.org/10.1080/02664763.2016.1193725.

-
-
-

Johnson, Paul C. D. 2014. “Extension of Nakagawa & Schielzeth’s R2GLMM to Random Slopes Models.” Methods in Ecology and Evolution 5 (9): 944–46. https://doi.org/10.1111/2041-210X.12225.

-
-
-

Johnson, Paul C. D., Sarah J. E. Barry, Heather M. Ferguson, and Pie Müller. 2015. “Power Analysis for Generalized Linear Mixed Models in Ecology and Evolution.” Methods in Ecology and Evolution 6 (2): 133–42. https://doi.org/10.1111/2041-210X.12306.

-
-
-

Kain, Morgan P., Ben M. Bolker, and Michael W. McCoy. 2015. “A Practical Guide and Power Analysis for GLMMs: Detecting Among Treatment Variation in Random Effects.” PeerJ 3 (September): e1226. https://doi.org/10.7717/peerj.1226.

-
-
-

Lawson, A., A. Biggeri, D. Bohning, E. LeSaffre, J. F. Viel, and R. Bertollini, eds. 1999. Disease Mapping and Risk Assessment for Public Health. New York: Wiley.

-
-
-

Lee, Youngjo, John A. Nelder, and Yudi Pawitan. 2017. Generalized Linear Models with Random Effects: Unified Analysis via H-Likelihood, Second Edition. 2 edition. Boca Raton, Florida: Chapman; Hall/CRC.

-
-
-

Littell, Ramon C., George A. Milliken, Walter W. Stroup, Russell D. Wolfinger, and Oliver Schabenberger. 2006. SAS for Mixed Models, Second Edition. SAS Publishing.

-
-
-

Lo, Steson, and Sally Andrews. 2015. “To Transform or Not to Transform: Using Generalized Linear Mixed Models to Analyse Reaction Time Data.” Frontiers in Psychology 6. https://doi.org/10.3389/fpsyg.2015.01171.

-
-
-

Maindonald, J., and J. Braun. 2010. Data Analysis and Graphics Using R, an Example-Based Approach. 3rd ed. Cambridge University Press.

-
-
-

Martin, Tara G., Brendan A. Wintle, Jonathan R. Rhodes, Petra M. Kuhnert, Scott A. Field, Samantha J. Low-Choy, Andrew J. Tyre, and Hugh P. Possingham. 2005. “Zero Tolerance Ecology: Improving Ecological Inference by Modelling the Source of Zero Observations: Modelling Excess Zeros in Ecology.” Ecology Letters 8 (11): 1235–46. https://doi.org/10.1111/j.1461-0248.2005.00826.x.

-
-
-

Matuschek, Hannes, Reinhold Kliegl, Shravan Vasishth, Harald Baayen, and Douglas Bates. 2017. “Balancing Type I Error and Power in Linear Mixed Models.” Journal of Memory and Language 94: 305–15. https://doi.org/10.1016/j.jml.2017.01.001.

-
-
-

McCullagh, P., and J. A. Nelder. 1989. Generalized Linear Models. London: Chapman; Hall.

-
-
-

McCulloch, Charles E., and John M. Neuhaus. 2011. “Misspecifying the Shape of a Random Effects Distribution: Why Getting It Wrong May Not Matter.” Statistical Science 26 (3): 388–402. https://doi.org/10.1214/11-STS361.

-
-
-

Millar, Russell B. 2011. Maximum Likelihood Estimation and Inference: With Examples in R, SAS and ADMB. John Wiley & Sons.

-
-
-

Nakagawa, Shinichi, and Holger Schielzeth. 2010. “Repeatability for Gaussian and Non-Gaussian Data: A Practical Guide for Biologists.” Biological Reviews 85 (4): 935–56. https://doi.org/10.1111/j.1469-185X.2010.00141.x.

-
-
-

———. 2013. “A General and Simple Method for Obtaining R2 from Generalized Linear Mixed-Effects Models.” Methods in Ecology and Evolution 4 (2): 133–42. https://doi.org/10.1111/j.2041-210x.2012.00261.x.

-
-
-

Oberpriller, Johannes, Melina de Souza Leite, and Maximilian Pichler. 2021. “Fixed or Random? On the Reliability of Mixed-Effects Models for a Small Number of Levels in Grouping Variables.” bioRxiv, June, 2021.05.03.442487. https://doi.org/10.1101/2021.05.03.442487.

-
-
-

Pasch, Bret, Benjamin M. Bolker, and Steven M. Phelps. 2013. “Interspecific Dominance via Vocal Interactions Mediates Altitudinal Zonation in Neotropical Singing Mice.” The American Naturalist 182 (5): E161–E173. https://doi.org/10.1086/673263.

-
-
-

Pinheiro, José C., and Douglas M. Bates. 2000. Mixed-Effects Models in S and S-PLUS. New York: Springer.

-
-
-

Rabe-Hesketh, Sophia, and Anders Skrondal. 2008. Multilevel and Longitudinal Modeling Using Stata. 2nd ed. Stata Press. http://www.stata-press.com/books/mlmus2.html.

-
-
-

Richards, Shane A. 2005. “Testing Ecological Theory Using the Information-Theoretic Approach: Examples and Cautionary Results.” Ecology 86 (10): 2805–14. https://doi.org/10.1890/05-0074.

-
-
-

Rights, Jason D., and Sonya K. Sterba. 2018. “Quantifying Explained Variance in Multilevel Models: An Integrative Framework for Defining R-Squared Measures.” Psychological Methods. https://doi.org/10.1037%2Fmet0000184.

-
-
-

Schaalje, G., J. McBride, and G. Fellingham. 2002. “Adequacy of Approximations to Distributions of Test Statistics in Complex Mixed Linear Models.” Journal of Agricultural, Biological & Environmental Statistics 7 (14): 512–24. http://www.ingentaconnect.com/content/asa/jabes/2002/00000007/00000004/art00004.

-
-
-

Schabenberger, Oliver, and Francis J. Pierce. 2001. Contemporary Statistical Models for the Plant and Soil Sciences. Boca Raton, FL: CRC Press.

-
-
-

Schielzeth, Holger. 2010. “Simple Means to Improve the Interpretability of Regression Coefficients.” Methods in Ecology and Evolution 1: 103–13. https://doi.org/10.1111/j.2041-210X.2010.00012.x.

-
-
-

Self, Steven G., and Kung-Yee Liang. 1987. “Asymptotic Properties of Maximum Likelihood Estimators and Likelihood Ratio Tests Under Nonstandard Conditions.” Journal of the American Statistical Association 82 (398): 605–10. https://doi.org/10.1080/01621459.1987.10478472.

-
-
-

Smithson, Michael, and Jay Verkuilen. 2006. “A Better Lemon Squeezer? Maximum-Likelihood Regression with Beta-Distributed Dependent Variables.” Psychological Methods 11 (1): 54–71. https://doi.org/10.1037/1082-989X.11.1.54.

-
-
-

Snijders, Tom A. B., and Roel J. Bosker. 1993. “Standard Errors and Sample Sizes for Two-Level Research.” Journal of Educational Statistics 18 (3): 237. https://doi.org/10.2307/1165134.

-
-
-

Spiegelhalter, D. J., N. Best, B. P. Carlin, and A. Van der Linde. 2002. “Bayesian Measures of Model Complexity and Fit.” Journal of the Royal Statistical Society B 64: 583–640.

-
-
-

Stram, Daniel O, and Jae Won Lee. 1994. “Variance Components Testing in the Longitudinal Fixed Effects Model.” Biometrics 50 (4): 1171–7. http://links.jstor.org/sici?sici=0006-341X%28199412%2950%3A4%3C1171%3AVCTITL%3E2.0.CO%3B2-H.

-
-
-

Stroup, Walter W. 2014. “Rethinking the Analysis of Non-Normal Data in Plant and Soil Science.” Agronomy Journal 106: 1–17. https://doi.org/10.2134/agronj2013.0342.

-
-
-

Stroup, W. W. 2013. “Non-Normal Data in Agricultural Experiments.” In. Kansas State University. http://newprairiepress.org/agstatconference/2013/proceedings/8.

-
-
-

Vaida, Florin, and Suzette Blanchard. 2005. “Conditional Akaike Information for Mixed-Effects Models.” Biometrika 92 (2): 351–70. https://doi.org/10.1093/biomet/92.2.351.

-
-
-

Venables, W., and Brian D. Ripley. 2002. Modern Applied Statistics with S. 4th ed. New York: Springer.

-
-
-

Warton, David I. 2005. “Many Zeros Does Not Mean Zero Inflation: Comparing the Goodness-of-Fit of Parametric Models to Multivariate Abundance Data.” Environmetrics 16 (3): 275–89. https://doi.org/10.1002/env.702.

-
-
-

Wolfinger, Russ, and Michael O’Connell. 1993. “Generalized Linear Mixed Models a Pseudo-Likelihood Approach.” Journal of Statistical Computation and Simulation 48 (3-4): 233–43. https://doi.org/10.1080/00949659308811554.

-
-
-

Xu, R. 2003. “Measuring Explained Variation in Linear Mixed Effects Models.” Statist. Med. 22: 3527–41. https://doi.org/10.1002/sim.1572 doi:10.1002/sim.1572.

-
-
-

Zuur, Alain F., Elena N. Ieno, Neil J. Walker, Anatoly A. Saveliev, and Graham M. Smith. 2009a. “Zero-Truncated and Zero-Inflated Models for Count Data.” In Mixed Effects Models and Extensions in Ecology with R, 261–93. New York, NY: Springer New York. http://www.springerlink.com/content/m087275807178771/.

-
-
-

———. 2009b. Mixed Effects Models and Extensions in Ecology with R. Springer.

-
-
-
-
+
+
+Agresti, Alan. 2002. Categorical Data Analysis. 2d ed. Hoboken, +NJ: Wiley. +
+
+Angrist, Joshua D., and Jörn-Steffen Pischke. 2009. Mostly +Harmless Econometrics: An +Empiricist’s Companion. 1 edition. +Princeton: Princeton University Press. +
+
+Barr, Dale J. 2020. Learning Statistical +Models Through Simulation in +R. PsyTeachR Books. https://psyteachr.github.io/ug3-stats/. +
+
+Barr, Dale J., Roger Levy, Christoph Scheepers, and Harry J. Tily. 2013. +“Random Effects Structure for Confirmatory Hypothesis Testing: +Keep It Maximal.” Journal of Memory and Language 68 (3): +255–78. https://doi.org/10.1016/j.jml.2012.11.001. +
+
+Bates, Douglas, Reinhold Kliegl, Shravan Vasishth, and Harald Baayen. +2015. “Parsimonious Mixed +Models.” arXiv:1506.04967 [Stat], June. http://arxiv.org/abs/1506.04967. +
+
+Bates, Douglas, Martin Mächler, Benjamin M. Bolker, and Steven C. +Walker. 2015. “Fitting Linear Mixed-Effects Models Using lme4.” Journal of Statistical +Software 67 (1): 1–48. https://doi.org/10.18637/jss.v067.i01. +
+
+Bell, Melanie L., and Gary K. Grunwald. 2010. “Small Sample +Estimation Properties of Longitudinal Count Models.” Journal +of Statistical Computation and Simulation 81 (9): 1067–79. https://doi.org/10.1080/00949651003674144. +
+
+Berger, J. O., B. Liseo, and R. L. Wolpert. 1999. “Integrated +Likelihood Methods for Eliminating Nuisance Parameters.” +Statistical Science 14 (1): 1–22. http://projecteuclid.org/download/pdf_1/euclid.ss/1009211804. +
+
+Breslow, N. E. 1984. “Extra-Poisson Variation in +Log-Linear Models.” Journal of the Royal Statistical Society +C 33: 38–44. http://www.jstor.org/stable/234766. +
+
+Browne, W. J, S. V. Subramanian, K. Jones, and H. Goldstein. 2005. +“Variance Partitioning in Multilevel Logistic Models That Exhibit +Overdispersion.” Journal of the Royal Statistical Society +A 168 (3): 599–613. https://doi.org/10.1111/j.1467-985X.2004.00365.x. +
+
+Chung, Yeojin, Sophia Rabe-Hesketh, Vincent Dorie, Andrew Gelman, and +Jingchen Liu. 2013. “A Nondegenerate Penalized Likelihood +Estimator for Variance Parameters in Multilevel Models.” +Psychometrika, 1–25. https://doi.org/10.1007/s11336-013-9328-2. +
+
+Clark, Tom S, and Drew A Linzer. 2015. “Should I Use +Fixed or Random Effects?” Political Science Research and +Methods 3 (02): 399–408. +
+
+Cordeiro, Gauss M., and Silvia L. P. Ferrari. 1998. “A Note on +Bartlett-Type Correction for the First Few Moments of Test +Statistics.” Journal of Statistical Planning and +Inference 71 (1-2): 261–69. https://doi.org/10.1016/S0378-3758(98)00005-6. +
+
+Cordeiro, Gauss M., Gilberto A. Paula, and Denise A. Botter. 1994. +“Improved Likelihood Ratio Tests for Dispersion Models.” +International Statistical Review / Revue Internationale de +Statistique 62 (2): 257–74. https://doi.org/10.2307/1403512. +
+
+Crawley, Michael J. 2002. Statistical Computing: An Introduction to +Data Analysis Using S-PLUS. John Wiley & Sons. +
+
+Cribari-Neto, Francisco, and Achim Zeileis. 2009. “Beta +Regression in R.” 98. Vienna, Austria: +WU Vienna University of Economics; Business. https://cran.r-project.org/web/packages/betareg/index.html. +
+
+Dobson, Annette J., and Adrian Barnett. 2008. An Introduction to +Generalized Linear Models, Third Edition. 3rd ed. Chapman; +Hall/CRC. +
+
+Elston, D. A., R. Moss, T. Boulinier, C. Arrowsmith, and X. Lambin. +2001. “Analysis of Aggregation, a Worked Example: Numbers of Ticks +on Red Grouse Chicks.” Parasitology 122 (5): 563–69. +
+
+Faraway, Julian J. 2006. Extending Linear +Models with R: Generalized +Linear, Mixed Effects and +Nonparametric Regression +Models. Chapman & Hall/CRC. +
+
+Feng, Ziding, Thomas Braun, and Charles McCulloch. 2004. “Small +Sample Inference for Clustered Data.” In Proceedings of the +Second Seattle Symposium in Biostatistics, edited by +D. Y. Lin and P. J. Heagerty, 179:71–87. New York, NY: Springer. http://www.springerlink.com/content/h2g33m7127790343/. +
+
+Gelman, Andrew. 2005. “Analysis of Variance: Why It Is More +Important Than Ever.” Annals of Statistics 33 (1): 1–53. +https://doi.org/doi:10.1214/009053604000001048. +
+
+———. 2006. “Prior Distributions for Variance Parameters in +Hierarchical Models.” Bayesian Analysis 1 (3): 515–33. +http://ba.stat.cmu.edu/journal/2006/vol01/issue03/gelman.pdf. +
+
+———. 2008. “Scaling Regression Inputs by Dividing by Two Standard +Deviations.” Statistics in Medicine 27 (15): 2865–73. https://doi.org/10.1002/sim.3107. +
+
+Gelman, Andrew, and Jennifer Hill. 2006. Data Analysis Using +Regression and Multilevel/Hierarchical Models. +Cambridge, England: Cambridge University Press. http://www.stat.columbia.edu/~gelman/arm/. +
+
+Gelman, Andrew, and Iain Pardoe. 2006. “Bayesian Measures of +Explained Variance and Pooling in Multilevel (Hierarchical) +Models.” Technometrics 48 (2): 241–51. http://amstat.tandfonline.com/doi/abs/10.1198/004017005000000517. +
+
+Goldman, Nick, and Simon Whelan. 2000. “Statistical Tests of +Gamma-Distributed Rate Heterogeneity in Models of Sequence Evolution in +Phylogenetics.” Molecular Biology and Evolution 17 (6): +975–78. +
+
+Gotelli, Nicholas J., and Aaron M. Ellison. 2004. A Primer of +Ecological Statistics. Sunderland, MA: Sinauer. +
+
+Greven, Sonja, and Thomas Kneib. 2010. “On the Behaviour of +Marginal and Conditional Akaike Information Criteria in +Linear Mixed Models.” Biometrika 97 (4): 773–89. http://www.bepress.com/jhubiostat/paper202/. +
+
+Harrison, Xavier A. 2015. “A Comparison of Observation-Level +Random Effect and Beta-Binomial Models for +Modelling Overdispersion in Binomial Data in Ecology and +Evolution.” PeerJ 3 (July): e1114. https://doi.org/10.7717/peerj.1114. +
+
+Heisterkamp, Simon H., Engelbertus van Willigen, Paul-Matthias +Diderichsen, and John Maringwa. 2017. “Update of the Nlme +Package to Allow a Fixed +Standard Deviation of the +Residual Error.” The R Journal +9 (1): 239–51. +
+
+Hinde, John. 1982. “Compound Poisson Regression +Models.” In GLIM82: Proc. Int. Conf. On GLMs, edited by +R. Gilchrist, 109–21. Springer. +
+
+Hodges, James S. 2016. Richly Parameterized Linear Models: Additive, +Time Series, and Spatial Models Using Random Effects. Chapman; +Hall/CRC. +
+
+Hughes, A., and M. King. 2003. “Model Selection Using +AIC in the Presence of One-Sided Information.” +Journal of Statistical Planning and Inference 115: 497–11. +
+
+Hurlbert, S. 1984. “Pseudoreplication and the Design of Ecological +Field Experiments.” Ecological Monographs 54: 187–211. +
+
+Jaeger, Byron C., Lloyd J. Edwards, Kalyan Das, and Pranab K. Sen. 2017. +“An R2 Statistic for Fixed Effects in the Generalized +Linear Mixed Model.” Journal of Applied Statistics 44 +(6): 1086–1105. https://doi.org/10.1080/02664763.2016.1193725. +
+
+Johnson, Paul C. D. 2014. “Extension of Nakagawa +& Schielzeth’s R2GLMM to Random Slopes +Models.” Methods in Ecology and Evolution 5 (9): 944–46. +https://doi.org/10.1111/2041-210X.12225. +
+
+Johnson, Paul C. D., Sarah J. E. Barry, Heather M. Ferguson, and Pie +Müller. 2015. “Power Analysis for Generalized Linear Mixed Models +in Ecology and Evolution.” Methods in Ecology and +Evolution 6 (2): 133–42. https://doi.org/10.1111/2041-210X.12306. +
+
+Kain, Morgan P., Ben M. Bolker, and Michael W. McCoy. 2015. “A +Practical Guide and Power Analysis for GLMMs: Detecting +Among Treatment Variation in Random Effects.” PeerJ 3 +(September): e1226. https://doi.org/10.7717/peerj.1226. +
+
+Lawson, A., A. Biggeri, D. Bohning, E. LeSaffre, J. F. Viel, and R. +Bertollini, eds. 1999. Disease Mapping and Risk Assessment for +Public Health. New York: Wiley. +
+
+Lee, Youngjo, John A. Nelder, and Yudi Pawitan. 2017. Generalized +Linear Models with Random +Effects: Unified Analysis via +H-Likelihood, Second +Edition. 2 edition. Boca Raton, Florida: Chapman; +Hall/CRC. +
+
+Littell, Ramon C., George A. Milliken, Walter W. Stroup, Russell D. +Wolfinger, and Oliver Schabenberger. 2006. SAS for +Mixed Models, Second Edition. SAS Publishing. +
+
+Lo, Steson, and Sally Andrews. 2015. “To Transform or Not to +Transform: Using Generalized Linear Mixed Models to Analyse Reaction +Time Data.” Frontiers in Psychology 6. https://doi.org/10.3389/fpsyg.2015.01171. +
+
+Maindonald, J., and J. Braun. 2010. Data Analysis and Graphics Using +r, an Example-Based Approach. 3rd ed. Cambridge University Press. +
+
+Martin, Tara G., Brendan A. Wintle, Jonathan R. Rhodes, Petra M. +Kuhnert, Scott A. Field, Samantha J. Low-Choy, Andrew J. Tyre, and Hugh +P. Possingham. 2005. “Zero Tolerance Ecology: Improving Ecological +Inference by Modelling the Source of Zero Observations: +Modelling Excess Zeros in Ecology.” Ecology +Letters 8 (11): 1235–46. https://doi.org/10.1111/j.1461-0248.2005.00826.x. +
+
+Matuschek, Hannes, Reinhold Kliegl, Shravan Vasishth, Harald Baayen, and +Douglas Bates. 2017. “Balancing Type I Error and +Power in Linear Mixed Models.” Journal of Memory and +Language 94: 305–15. https://doi.org/10.1016/j.jml.2017.01.001. +
+
+McCullagh, P., and J. A. Nelder. 1989. Generalized Linear +Models. London: Chapman; Hall. +
+
+McCulloch, Charles E., and John M. Neuhaus. 2011. “Misspecifying +the Shape of a Random Effects +Distribution: Why Getting +It Wrong May Not +Matter.” Statistical Science 26 (3): +388–402. https://doi.org/10.1214/11-STS361. +
+
+Millar, Russell B. 2011. Maximum Likelihood Estimation and +Inference: With Examples in r, SAS and +ADMB. John Wiley & Sons. +
+
+Nakagawa, Shinichi, and Holger Schielzeth. 2010. “Repeatability +for Gaussian and Non-Gaussian Data: A +Practical Guide for Biologists.” Biological Reviews 85 +(4): 935–56. https://doi.org/10.1111/j.1469-185X.2010.00141.x. +
+
+———. 2013. “A General and Simple Method for Obtaining +R2 from Generalized Linear Mixed-Effects Models.” +Methods in Ecology and Evolution 4 (2): 133–42. https://doi.org/10.1111/j.2041-210x.2012.00261.x. +
+
+Oberpriller, Johannes, Melina de Souza Leite, and Maximilian Pichler. +2021. “Fixed or Random? On the Reliability of +Mixed-Effects Models for a Small Number of Levels in Grouping +Variables.” bioRxiv, June, 2021.05.03.442487. https://doi.org/10.1101/2021.05.03.442487. +
+
+Pasch, Bret, Benjamin M. Bolker, and Steven M. Phelps. 2013. +“Interspecific Dominance via Vocal Interactions Mediates +Altitudinal Zonation in Neotropical Singing Mice.” The +American Naturalist 182 (5): E161–73. https://doi.org/10.1086/673263. +
+
+Pinheiro, José C., and Douglas M. Bates. 2000. Mixed-Effects Models +in S and S-PLUS. New York: Springer. +
+
+Rabe-Hesketh, Sophia, and Anders Skrondal. 2008. Multilevel and +Longitudinal Modeling Using Stata. 2nd ed. Stata Press. http://www.stata-press.com/books/mlmus2.html. +
+
+Richards, Shane A. 2005. “Testing Ecological Theory Using the +Information-Theoretic Approach: Examples and Cautionary Results.” +Ecology 86 (10): 2805–14. https://doi.org/10.1890/05-0074. +
+
+Rights, Jason D., and Sonya K. Sterba. 2018. “Quantifying +Explained Variance in Multilevel Models: An Integrative +Framework for Defining R-Squared Measures.” +Psychological Methods. https://doi.org/10.1037%2Fmet0000184. +
+
+Schaalje, G., J. McBride, and G. Fellingham. 2002. “Adequacy of +Approximations to Distributions of Test Statistics in Complex Mixed +Linear Models.” Journal of Agricultural, Biological & +Environmental Statistics 7 (14): 512–24. http://www.ingentaconnect.com/content/asa/jabes/2002/00000007/00000004/art00004. +
+
+Schabenberger, Oliver, and Francis J. Pierce. 2001. Contemporary +Statistical Models for the Plant and Soil Sciences. Boca Raton, FL: +CRC Press. +
+
+Schielzeth, Holger. 2010. “Simple Means to Improve the +Interpretability of Regression Coefficients.” Methods in +Ecology and Evolution 1: 103–13. https://doi.org/10.1111/j.2041-210X.2010.00012.x. +
+
+Self, Steven G., and Kung-Yee Liang. 1987. “Asymptotic Properties +of Maximum Likelihood Estimators and Likelihood Ratio Tests Under +Nonstandard Conditions.” Journal of the American Statistical +Association 82 (398): 605–10. https://doi.org/10.1080/01621459.1987.10478472. +
+
+Smithson, Michael, and Jay Verkuilen. 2006. “A Better Lemon +Squeezer? Maximum-Likelihood Regression with +Beta-Distributed Dependent Variables.” Psychological +Methods 11 (1): 54–71. https://doi.org/10.1037/1082-989X.11.1.54. +
+
+Snijders, Tom A. B., and Roel J. Bosker. 1993. “Standard +Errors and Sample Sizes for +Two-Level Research.” +Journal of Educational Statistics 18 (3): 237. https://doi.org/10.2307/1165134. +
+
+Spiegelhalter, D. J., N. Best, B. P. Carlin, and A. Van der Linde. 2002. +“Bayesian Measures of Model Complexity and Fit.” +Journal of the Royal Statistical Society B 64: 583–640. +
+
+Stram, Daniel O, and Jae Won Lee. 1994. “Variance Components +Testing in the Longitudinal Fixed Effects Model.” +Biometrics 50 (4): 1171–77. http://links.jstor.org/sici?sici=0006-341X%28199412%2950%3A4%3C1171%3AVCTITL%3E2.0.CO%3B2-H. +
+
+Stroup, W. W. 2013. “Non-Normal Data in Agricultural +Experiments.” In. Kansas State University. http://newprairiepress.org/agstatconference/2013/proceedings/8. +
+
+Stroup, Walter W. 2014. “Rethinking the Analysis of Non-Normal +Data in Plant and Soil Science.” Agronomy Journal 106: +1–17. https://doi.org/10.2134/agronj2013.0342. +
+
+Vaida, Florin, and Suzette Blanchard. 2005. “Conditional +Akaike Information for Mixed-Effects Models.” +Biometrika 92 (2): 351–70. https://doi.org/10.1093/biomet/92.2.351. +
+
+Venables, W., and Brian D. Ripley. 2002. Modern Applied Statistics +with s. 4th ed. New York: Springer. +
+
+Warton, David I. 2005. “Many Zeros Does Not Mean Zero Inflation: +Comparing the Goodness-of-Fit of Parametric Models to Multivariate +Abundance Data.” Environmetrics 16 (3): 275–89. https://doi.org/10.1002/env.702. +
+
+Wolfinger, Russ, and Michael O’Connell. 1993. “Generalized Linear +Mixed Models a Pseudo-Likelihood Approach.” Journal of +Statistical Computation and Simulation 48 (3-4): 233–43. https://doi.org/10.1080/00949659308811554. +
+
+Xu, R. 2003. “Measuring Explained Variation in Linear Mixed +Effects Models.” Statist. Med. 22: 3527–41. https://doi.org/10.1002/sim.1572 +doi:10.1002/sim.1572. +
+
+Zuur, Alain F., Elena N. Ieno, Neil J. Walker, Anatoly A. Saveliev, and +Graham M. Smith. 2009a. “Zero-Truncated and +Zero-Inflated Models for +Count Data.” In Mixed Effects +Models and Extensions in Ecology with R, 261–93. New +York, NY: Springer New York. http://www.springerlink.com/content/m087275807178771/. +
+
+———. 2009b. Mixed Effects Models and Extensions in Ecology with +R. Springer. +
+
+
+

    -
  1. in R, foo::bar (or foo::bar()) denotes “function bar in package foo”).↩︎

  2. -
  3. the dispersion factor is estimated on a variance, so we need to take the square root to apply it to the standard error↩︎

  4. +
  5. in R, foo::bar (or foo::bar()) +denotes “function bar in package foo”).↩︎

  6. +
  7. the dispersion factor is estimated on a variance, so we +need to take the square root to apply it to the standard error↩︎

-
LS0tCmF1dGhvcjogQmVuIEJvbGtlciBhbmQgb3RoZXJzCnRpdGxlOiBHTE1NIEZBUQpiaWJsaW9ncmFwaHk6IGdsbW0uYmliCmRhdGU6ICAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlYiAlWScpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgICB0b2M6IHRydWUKLS0tCgo8IS0tIEdvb2dsZSB0YWcgKGd0YWcuanMpIC0tPgo8c2NyaXB0IGFzeW5jIHNyYz0iaHR0cHM6Ly93d3cuZ29vZ2xldGFnbWFuYWdlci5jb20vZ3RhZy9qcz9pZD1HLUtZMUpZMEM1M1MiPjwvc2NyaXB0Pgo8c2NyaXB0PgogIHdpbmRvdy5kYXRhTGF5ZXIgPSB3aW5kb3cuZGF0YUxheWVyIHx8IFtdOwogIGZ1bmN0aW9uIGd0YWcoKXtkYXRhTGF5ZXIucHVzaChhcmd1bWVudHMpO30KICBndGFnKCdqcycsIG5ldyBEYXRlKCkpOwoKICBndGFnKCdjb25maWcnLCAnRy1LWTFKWTBDNTNTJyk7Cjwvc2NyaXB0PgoKYGBge3Igc2V0dXAsbWVzc2FnZT1GQUxTRSxlY2hvPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQprbml0cjo6b3B0c19jaHVuayRzZXQoZGV2LmFyZ3MgPSBsaXN0KHBuZyA9IGxpc3QodHlwZSA9ICJjYWlybyIpKSkKbGlicmFyeShwYW5kZXIpCmxpYnJhcnkoQ2Fpcm8pCmBgYAoKYGBge3IgcGtncywgZXZhbD1GQUxTRSxlY2hvPUZBTFNFfQpwa2dzIDwtIGMoImxtZTQiLCJnbG1tQURNQiIsInNvcyIsImJsbWUiLCJSTFJzaW0iLCJnZ3Bsb3QyIiwgIk1FTVNTIikKaTEgPC0gaW5zdGFsbGVkLnBhY2thZ2VzKCkKcGtncyA8LSBzZXRkaWZmKHBrZ3MsIHJvd25hbWVzKGkxKSkKcmVwb3MgPC0gYygiaHR0cDovL2dsbW1hZG1iLnItZm9yZ2Uuci1wcm9qZWN0Lm9yZy9yZXBvcyIsCiAgICAgICAgICAgIGdldE9wdGlvbigicmVwb3MiKSkKaWYgKGxlbmd0aChwa2dzKT4wKSAKICAgIGluc3RhbGwucGFja2FnZXMocGtncyxyZXBvcz1yZXBvcywgdHlwZT0ic291cmNlIikKYGBgCgojIEludHJvZHVjdGlvbgoKVGhpcyBpcyBhbiBpbmZvcm1hbCBGQVEgbGlzdCBmb3IgdGhlIGByLXNpZy1taXhlZC1tb2RlbHNgIG1haWxpbmcgbGlzdC4KClRoZSBtb3N0IGNvbW1vbmx5IHVzZWQgZnVuY3Rpb25zIGZvciBtaXhlZCBtb2RlbGluZyBpbiBSIGFyZSAKCi0gKmxpbmVhciBtaXhlZCBtb2RlbHMqOiBgYW92KClgLCBgbmxtZTo6bG1lYFteMV0sIGBsbWU0OjpsbWVyYDsgYGJybXM6OmJybWAKLSAqZ2VuZXJhbGl6ZWQgbGluZWFyIG1peGVkIG1vZGVscyogKEdMTU1zKQogICAgLSBmcmVxdWVudGlzdDogYE1BU1M6OmdsbW1QUUxgLCBgbG1lNDo6Z2xtZXJgOyBgZ2xtbVRNQmAKICAgIC0gQmF5ZXNpYW46IGBNQ01DZ2xtbTo6TUNNQ2dsbW1gOyBgYnJtczo6YnJtYAotICpub25saW5lYXIgbWl4ZWQgbW9kZWxzKjogYG5sbWU6Om5sbWVgLCBgbG1lNDo6bmxtZXJgOyBgYnJtczo6YnJtYAotICpHTkxNTXMqOiBgYnJtczo6YnJtYAkKClteMV06IGluIFIsIGBmb286OmJhcmAgKG9yIGBmb286OmJhcigpYCkgZGVub3RlcyAiZnVuY3Rpb24gYGJhcmAgaW4gcGFja2FnZSBgZm9vYCIpLgoKQW5vdGhlciBxdWljay1hbmQtZGlydHkgd2F5IHRvIHNlYXJjaCBmb3IgbWl4ZWQtbW9kZWwgcmVsYXRlZCBwYWNrYWdlcyBvbiBDUkFOOgoKYGBge3IgYXZhaWwsY2FjaGU9VFJVRX0KZ3JlcCgibC4/bVttZV1bXnRdIixyb3duYW1lcyhhdmFpbGFibGUucGFja2FnZXMoKSksdmFsdWU9VFJVRSkKYGBgCgpUaGVyZSBhcmUgc29tZSBmYWxzZSBwb3NpdGl2ZXMgaGVyZSAoZS5nLiBgcGFsbWVycGVuZ3VpbnNgKTsgc2VlIFtoZXJlXShodHRwczovL3hrY2QuY29tLzEzMTMvKSBpZiB5b3UncmUgaW50ZXJlc3RlZCBpbiAicmVnZXggZ29sZiIuCgojIyBPdGhlciBzb3VyY2VzIG9mIGhlbHAKCi0gdGhlIG1haWxpbmcgbGlzdCBpcyBgci1zaWctbWl4ZWQtbW9kZWxzQHItcHJvamVjdC5vcmdgCiAgICAtIHNpZ24gdXAgW2hlcmVdKGh0dHBzOi8vc3RhdC5ldGh6LmNoL21haWxtYW4vbGlzdGluZm8vci1zaWctbWl4ZWQtbW9kZWxzKQoJLSBhcmNoaXZlcyBbaGVyZV0oaHR0cHM6Ly9zdGF0LmV0aHouY2gvcGlwZXJtYWlsL3Itc2lnLW1peGVkLW1vZGVscy8pCgktIG9yIEdvb2dsZSBzZWFyY2ggd2l0aCB0aGUgdGFnIGBzaXRlOmh0dHBzOi8vc3RhdC5ldGh6LmNoL3BpcGVybWFpbC9yLXNpZy1taXhlZC1tb2RlbHMvYAotIFRoZSBzb3VyY2UgY29kZSBvZiB0aGlzIGRvY3VtZW50IGlzIGF2YWlsYWJsZSBbb24gR2l0SHViXShodHRwczovL2dpdGh1Yi5jb20vYmJvbGtlci9taXhlZG1vZGVscy1taXNjL2Jsb2IvbWFzdGVyL2dsbW1GQVEucm1kKTsgdGhlIHJlbmRlcmVkIChIVE1MKSB2ZXJzaW9uIGxpdmVzIG9uIFtHaXRIdWIgcGFnZXNdKGh0dHA6Ly9iYm9sa2VyLmdpdGh1Yi5pby9taXhlZG1vZGVscy1taXNjL2dsbW1GQVEuaHRtbCkuCi0gU2VhcmNoaW5nIG9uIFN0YWNrT3ZlcmZsb3cgd2l0aCB0aGUgW1tyXSBbbWl4ZWQtbW9kZWxzXSB0YWdzXShodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zL3RhZ2dlZC9yJTIwbWl4ZWQtbW9kZWxzP21vZGU9YWxsKSwgb3Igb24gQ3Jvc3NWYWxpZGF0ZWQgd2l0aCB0aGUgW1ttaXhlZC1tb2RlbF0gdGFnXShodHRwOi8vc3RhdHMuc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zL3RhZ2dlZC9taXhlZC1tb2RlbCkgbWF5IGJlIGhlbHBmdWwgKHRoZXNlIHNpdGVzIGFsc28gaGF2ZSBhbiBgW2xtZTRdYCB0YWcpLgoKCioqRElTQ0xBSU1FUlM6KioKCi0gKEcpTE1NcyBhcmUgaGFyZCAtIGhhcmRlciB0aGFuIHlvdSBtYXkgdGhpbmsgYmFzZWQgb24gd2hhdCB5b3UgbWF5IGhhdmUgbGVhcm5lZCBpbiB5b3VyIHNlY29uZCBzdGF0aXN0aWNzIGNsYXNzLCB3aGljaCBwcm9iYWJseSBmb2N1c2VkIG9uIHBpY2tpbmcgdGhlIGFwcHJvcHJpYXRlIHN1bXMgb2Ygc3F1YXJlcyB0ZXJtcyBhbmQgZGVncmVlcyBvZiBmcmVlZG9tIGZvciB0aGUgbnVtZXJhdG9yIGFuZCBkZW5vbWluYXRvciBvZiBhbiAkRiQgdGVzdC4gJ01vZGVybicgbWl4ZWQgbW9kZWwgYXBwcm9hY2hlcywgYWx0aG91Z2ggbW9yZSBwb3dlcmZ1bCAodGhleSBjYW4gaGFuZGxlIG1vcmUgY29tcGxleCBkZXNpZ25zLCBsYWNrIG9mIGJhbGFuY2UsIGNyb3NzZWQgcmFuZG9tIGZhY3RvcnMsIHNvbWUga2luZHMgb2Ygbm9uLU5vcm1hbGx5IGRpc3RyaWJ1dGVkIHJlc3BvbnNlcywgZXRjLiksIGFsc28gcmVxdWlyZSBhIG5ldyBzZXQgb2YgY29uY2VwdHVhbCB0b29scy4gSW4gb3JkZXIgdG8gdXNlIHRoZXNlIHRvb2xzIHlvdSBzaG91bGQgaGF2ZSBhdCBsZWFzdCBhIGdlbmVyYWwgYWNxdWFpbnRhbmNlIHdpdGggY2xhc3NpY2FsIG1peGVkLW1vZGVsIGV4cGVyaW1lbnRhbCBkZXNpZ25zIGJ1dCB5b3Ugc2hvdWxkIGFsc28sIHByb2JhYmx5LCByZWFkIHNvbWV0aGluZyBhYm91dCBtb2Rlcm4gbWl4ZWQgbW9kZWwgYXBwcm9hY2hlcy4gQGxpdHRlbGxfc2FzXzIwMDYgYW5kIEBwaW5oZWlyb19taXhlZC1lZmZlY3RzXzIwMDAgYXJlIHR3byBwbGFjZXMgdG8gc3RhcnQsIGFsdGhvdWdoIFBpbmhlaXJvIGFuZCBCYXRlcyBpcyBwcm9iYWJseSBtb3JlIHVzZWZ1bCBpZiB5b3Ugd2FudCB0byB1c2UgUi4gT3RoZXIgdXNlZnVsIHJlZmVyZW5jZXMgaW5jbHVkZSBAZ2VsbWFuX2RhdGFfMjAwNiAoZm9jdXNlZCBvbiBCYXllc2lhbiBtZXRob2RzKSBhbmQgQHp1dXJfbWl4ZWRfMjAwOS4gSWYgeW91IGFyZSBnb2luZyB0byB1c2UgZ2VuZXJhbGl6ZWQgbGluZWFyIG1peGVkIG1vZGVscywgeW91IHNob3VsZCB1bmRlcnN0YW5kIGdlbmVyYWxpemVkIGxpbmVhciBtb2RlbHMgKEBkb2Jzb25faW50cm9kdWN0aW9uXzIwMDgsIEBmYXJhd2F5X2V4dGVuZGluZ18yMDA2LCBhbmQgQE1jQ3VsbGFnaE5lbGRlcjE5ODkgYXJlIHN0YW5kYXJkIHJlZmVyZW5jZXM7IHRoZSBsYXN0IGlzIHRoZSBjYW5vbmljYWwgcmVmZXJlbmNlLCBidXQgYWxzbyB0aGUgbW9zdCBjaGFsbGVuZ2luZykuCi0gQWxsIG9mIHRoZSBpc3N1ZXMgdGhhdCBhcmlzZSB3aXRoIHJlZ3VsYXIgbGluZWFyIG9yIGdlbmVyYWxpemVkLWxpbmVhciBtb2RlbGluZyAoZS5nLjogaW5hZGVxdWFjeSBvZiBwLXZhbHVlcyBhbG9uZSBmb3IgdGhvcm91Z2ggc3RhdGlzdGljYWwgYW5hbHlzaXM7IG5lZWQgdG8gIHVuZGVyc3RhbmQgaG93IG1vZGVscyBhcmUgcGFyYW1ldGVyaXplZDsgbmVlZCB0byB1bmRlcnN0YW5kIHRoZSBwcmluY2lwbGUgb2YgbWFyZ2luYWxpdHkgYW5kIGhvdyBpbnRlcmFjdGlvbnMgY2FuIGJlIHRyZWF0ZWQ7IGRhbmdlcnMgb2Ygb3ZlcmZpdHRpbmcsIHdoaWNoIGFyZSBub3QgbWl0aWdhdGVkIGJ5IHN0ZXB3aXNlIHByb2NlZHVyZXM7IHRoZSBub24tZXhpc3RlbmNlIG9mIGZyZWUgbHVuY2hlcykgYWxzbyBhcHBseSwgYW5kIGNhbiBhcHBseSBtb3JlIHNldmVyZWx5LCB0byBtaXhlZCBtb2RlbHMuCiogV2hlbiBTQVMgKG9yIFN0YXRhLCBvciBHZW5zdGF0L0FTLVJFTUwgb3IgLi4uKSBhbmQgUiBkaWZmZXIgaW4gdGhlaXIgYW5zd2VycywgUiBtYXkgbm90IGJlIHdyb25nLiBCb3RoIFNBUyBhbmQgUiBtYXkgYmUgYHJpZ2h0JyBidXQgcHJvY2VlZGluZyBpbiBhIGRpZmZlcmVudCB3YXkvYW5zd2VyaW5nIGRpZmZlcmVudCBxdWVzdGlvbnMvdXNpbmcgYSBkaWZmZXJlbnQgcGhpbG9zb3BoaWNhbCBhcHByb2FjaCAob3IgYm90aCBtYXkgYmUgd3JvbmcgLi4uKQotIFRoZSBhZHZpY2UgaW4gdGhpcyBGQVEgY29tZXMgd2l0aCAqKmFic29sdXRlbHkgbm8gd2FycmFudHkgb2YgYW55IHNvcnQqKi4KCiMgUmVmZXJlbmNlcwoKIyMgbGluZWFyIG1peGVkIG1vZGVscwoKIyMjIHdlYi9vcGVuCgotIFtVQ0xBIElEUkUgc3RhdGlzdGljYWwgY29uc3VsdGluZ10oaHR0cHM6Ly9zdGF0cy5pZHJlLnVjbGEuZWR1L290aGVyL211bHQtcGtnL2ludHJvZHVjdGlvbi10by1saW5lYXItbWl4ZWQtbW9kZWxzLykKLSBAYmFycl9sZWFybmluZ18yMDIwIENoYXB0ZXJzIDUtOAoKIyMjIGJvb2tzIChkZWFkLXRyZWUvY2xvc2VkKQoKLSBwaW5oZWlyb19taXhlZC1lZmZlY3RzXzIwMDA6IExNTSBvbmx5LgotIEB6dXVyX21peGVkXzIwMDk6IEZvY3VzZWQgb24gZWNvbG9neS4KLSBAZ2VsbWFuX2RhdGFfMjAwNjogTE1NIGFuZCBHTE1NOyBCYXllc2lhbjsgZXhhbXBsZXMgZnJvbSBzb2NpYWwgc2NpZW5jZS4gSW50ZXJtZWRpYXRlIG1hdGhlbWF0aWNzLgotIChSZXRoaW5raW5nKQoKIyBNb2RlbCBkZWZpbml0aW9uCgojIyBNb2RlbCBzcGVjaWZpY2F0aW9uCgpUaGUgZm9sbG93aW5nIGZvcm11bGEgZXh0ZW5zaW9ucyBmb3Igc3BlY2lmeWluZyByYW5kb20tZWZmZWN0cyBzdHJ1Y3R1cmVzIGluIFIgYXJlIHVzZWQgYnkgCgotIGBsbWU0YAotIGBubG1lYCAobmVzdGVkIGVmZmVjdHMgb25seSwgYWx0aG91Z2ggY3Jvc3NlZCBlZmZlY3RzIGNhbiBiZSBzcGVjaWZpZWQgd2l0aCBtb3JlIHdvcmspCi0gYGdsbW1BRE1CYCBhbmQgYGdsbW1UTUJgIAoKYE1DTUNnbG1tYCB1c2VzIGEgZGlmZmVyZW50IHNwZWNpZmljYXRpb24sIGluaGVyaXRlZCBmcm9tIEFTLVJFTUwuCgooTW9kaWZpZWQgZnJvbSBSb2JpbiBKZWZmcmllcywgVUNMQTopCgpgYGB7ciBnbG1tX3N5bnRheCxlY2hvPUZBTFNFfQpzcGVjdGFiIDwtIHJlYWQudGFibGUoc2VwPSImIixoZWFkZXI9VFJVRSx0ZXh0PSIKZm9ybXVsYSAgICAgJiBtZWFuaW5nCmAoMXxncm91cClgICYgIHJhbmRvbSBncm91cCBpbnRlcmNlcHQKYCh4fGdyb3VwKWAgPSBgKDEreHxncm91cClgICYgcmFuZG9tIHNsb3BlIG9mIHggd2l0aGluIGdyb3VwIHdpdGggY29ycmVsYXRlZCBpbnRlcmNlcHQKYCgwK3h8Z3JvdXApYCA9IGAoLTEreHxncm91cClgICYgcmFuZG9tIHNsb3BlIG9mIHggd2l0aGluIGdyb3VwOiBubyB2YXJpYXRpb24gaW4gaW50ZXJjZXB0CmAoMXxncm91cCkgKyAoMCt4fGdyb3VwKWAgICYgdW5jb3JyZWxhdGVkIHJhbmRvbSBpbnRlcmNlcHQgYW5kIHJhbmRvbSBzbG9wZSB3aXRoaW4gZ3JvdXAKYCgxfHNpdGUvYmxvY2spYCA9IGAoMXxzaXRlKSsoMXxzaXRlOmJsb2NrKWAgJiBpbnRlcmNlcHQgdmFyeWluZyBhbW9uZyBzaXRlcyBhbmQgYW1vbmcgYmxvY2tzIHdpdGhpbiBzaXRlcyAobmVzdGVkIHJhbmRvbSBlZmZlY3RzKQpgc2l0ZSsoMXxzaXRlOmJsb2NrKWAgJiAqZml4ZWQqIGVmZmVjdCBvZiBzaXRlcyBwbHVzIHJhbmRvbSB2YXJpYXRpb24gaW4gaW50ZXJjZXB0IGFtb25nIGJsb2NrcyB3aXRoaW4gc2l0ZXMKYCh4fHNpdGUvYmxvY2spYCA9IGAoeHxzaXRlKSsoeHxzaXRlOmJsb2NrKWAgPSBgKDEgKyB4fHNpdGUpKygxK3h8c2l0ZTpibG9jaylgICYgc2xvcGUgYW5kIGludGVyY2VwdCB2YXJ5aW5nIGFtb25nIHNpdGVzIGFuZCBhbW9uZyBibG9ja3Mgd2l0aGluIHNpdGVzCmAoeDF8c2l0ZSkrKHgyfGJsb2NrKWAgJiB0d28gZGlmZmVyZW50IGVmZmVjdHMsIHZhcnlpbmcgYXQgZGlmZmVyZW50IGxldmVscwpgeCpzaXRlKyh4fHNpdGU6YmxvY2spYCAmIGZpeGVkIGVmZmVjdCB2YXJpYXRpb24gb2Ygc2xvcGUgYW5kIGludGVyY2VwdCB2YXJ5aW5nIGFtb25nIHNpdGVzIGFuZCByYW5kb20gdmFyaWF0aW9uIG9mIHNsb3BlIGFuZCBpbnRlcmNlcHQgYW1vbmcgYmxvY2tzIHdpdGhpbiBzaXRlcwpgKDF8Z3JvdXAxKSsoMXxncm91cDIpYCAmIGludGVyY2VwdCB2YXJ5aW5nIGFtb25nIGNyb3NzZWQgcmFuZG9tIGVmZmVjdHMgKGUuZy4gc2l0ZSwgeWVhcikiKQpzZXQuYWxpZ25tZW50KGRlZmF1bHQ9YygiY2VudHJlIiwibGVmdCIpKQpwYW5kZXIoc3BlY3RhYikKYGBgCgpPciBpbiBhIGxpdHRsZSBtb3JlIGRldGFpbDoKCmBgYHtyIGZ0YWIsZWNobz1GQUxTRSxyZXN1bHRzPSJhc2lzIn0KZnRhYiA8LSBtYXRyaXgoYygizrJfMCArIM6yX3sxfVhfe2l9ICsgZV97c2l9IiwKICAgICAgICAgICAgICAgICAibi9hIChOb3QgYSBtaXhlZC1lZmZlY3RzIG1vZGVsKSIsCiAgICAgICAgICAgICAgICAgIijOsl8wICsgYl97Uywwc30pICsgzrJfezF9WF9pICsgZV97c2l9IiwKICAgICAgICAgICAgICAgICAi4oi8IFggKyAoMeKIo1N1YmplY3QpIiwKICAgICAgICAgICAgICAgICAiKM6yXzAgKyBiX3tTLDBzfSkgKyAgKM6yX3sxfSArIGJfe1MsMXN9KSBYX2kgKyBlX3tzaX0iLAogICAgICAgICAgICAgICAgICJ+IFggKyAoMSArIFjiiKNTdWJqZWN0KSIsCiAgICAgICAgICAgICAgICAgIijOsl8wICsgYl97Uywwc30gKyBiX3tJLDBpfSkgKyAozrJfezF9ICsgYl97Uywxc30pIFhfaSArIGVfe3NpfSIsCiAgICAgICAgICAgICAgICAgIuKIvCBYICsgKDEgKyBY4oijU3ViamVjdCkgKyAoMeKIo0l0ZW0pIiwKICAgICAgICAgICAgICAgICAiQXMgYWJvdmUsIGJ1dCAkU197MHN9JCwgJFNfezFzfSQgaW5kZXBlbmRlbnQiLAogICAgICAgICAgICAgICAgICLiiLwgWCArICgx4oijU3ViamVjdCkgKyAoMCArIFjiiKMgU3ViamVjdCkgKyAoMeKIo0l0ZW0pIiwgCiAgICAgICAgICAgICAgICAgIijOsl8wICsgYl97Uywwc30gKyBiX3tJLDBpfSkgKyDOsl97MX1YX2kgKyBlX3tzaX0iLAogICAgICAgICAgICAgICAgICLiiLwgWCArICgx4oijU3ViamVjdCkgKyAoMeKIo0l0ZW0pIiwgCiAgICAgICAgICAgICAgICAgIijOsl8wICsgYl97SSwwaX0pICsgICjOsl97MX0gKyBiX3tTLDFzfSlYX2kgKyBlX3tzaX0iLAogICAgICAgICAgICAgICAgICLiiLwgWCArICgwICsgWOKIo1N1YmplY3QpICsgKDHiiKNJdGVtKSIpLAogICAgICAgICAgICAgICBieXJvdz1UUlVFLG5jb2w9MiwKICAgICAgICAgICAgICAgZGltbmFtZXM9bGlzdChOVUxMLGMoImVxdWF0aW9uIiwiZm9ybXVsYSIpKSkKZnRhYiA8LSBkYXRhLmZyYW1lKGZ0YWIsc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkKZmYgPC0gIWdyZXBsKCJBcyBhYm92ZSIsZnRhYiRlcXVhdGlvbikKZnRhYiRlcXVhdGlvbltmZl0gPC0gc3ByaW50ZigiJCVzJCIsZnRhYiRlcXVhdGlvbltmZl0pCmZmIDwtICFncmVwbCgibi9hIixmdGFiJGZvcm11bGEpCmZ0YWIkZm9ybXVsYVtmZl0gPC0gc3ByaW50ZigiYCVzYCIsZnRhYiRmb3JtdWxhW2ZmXSkKcGFuZGVyOjpwYW5kZXIoZnRhYixqdXN0aWZ5PSJsZWZ0IikKYGBgCgpNb2RpZmllZCBmcm9tOiBodHRwOi8vc3RhdHMuc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzEzMTY2L3JzLWxtZXItY2hlYXQtc2hlZXQ/bHE9MSAoTGl2aXVzKQoKClRoZSAqKm1hZ2ljKiogZGV2ZWxvcG1lbnQgdmVyc2lvbiBvZiB0aGUgW2VxdWF0aW9tYXRpYyBwYWNrYWdlXShodHRwczovL2dpdGh1Yi5jb20vZGF0YWxvcmF4L2VxdWF0aW9tYXRpYykgY2FuIGhhbmRsZSBtaXhlZCBtb2RlbHMgKGByZW1vdGVzOjppbnN0YWxsX2dpdGh1YigiZGF0YWxvcmF4L2VxdWF0aW9tYXRpYyIpYCksIGUuZy4KCmBgYHtyIGVxdWF0aW9tYXRpYywgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0iYXNpcyJ9CmxpYnJhcnkobG1lNCkKbGlicmFyeShlcXVhdGlvbWF0aWMpCmZtMSA8LSBsbWVyKFJlYWN0aW9uIH4gRGF5cyArIChEYXlzfFN1YmplY3QpLCBzbGVlcHN0dWR5KQplcXVhdGlvbWF0aWM6OmV4dHJhY3RfZXEoZm0xKQpgYGAKCkl0IGRvZXNuJ3QgaGFuZGxlIEdMTU1zICh5ZXQpLCBidXQgeW91IGNvdWxkIGZpdCB0d28gZmFrZSBtb2RlbHMgJm1kYXNoOyBvbmUgTE1NIGxpa2UgeW91ciBHTE1NIGJ1dCB3aXRoIGEgR2F1c3NpYW4gcmVzcG9uc2UsIGFuZCBvbmUgR0xNIHdpdGggdGhlIHNhbWUgZmFtaWx5L2xpbmsgZnVuY3Rpb24gYXMgeW91ciBHTE1NIGJ1dCB3aXRob3V0IHRoZSByYW5kb20gZWZmZWN0cyAmbWRhc2g7IGFuZCBwdXQgdGhlIHBpZWNlcyB0b2dldGhlci4KCk1vcmUgcG9zc2libHkgdXNlZnVsIGxpbmtzOgoKLSBSZW5zZSBOaWV1d2VuaHVpcydzIFtibG9ncG9zdC9sZXNzb24gb24gbG1lNCBtb2RlbCBzcGVjaWZpY2F0aW9uXShodHRwOi8vd3d3LnJlbnNlbmlldXdlbmh1aXMubmwvci1zZXNzaW9ucy0xNi1tdWx0aWxldmVsLW1vZGVsLXNwZWNpZmljYXRpb24tbG1lNC8pCi0gQ3Jvc3NWYWxpZGF0ZWQncyBbbG1lciBjaGVhdCBzaGVldF0oaHR0cHM6Ly9zdGF0cy5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvMTMxNjYvcnMtbG1lci1jaGVhdC1zaGVldCkKLSBLcmlzdG9mZmVyIE1hZ251c3NvbidzIFtVc2luZyBSIGFuZCBsbWUvbG1lciB0byBmaXQgZGlmZmVyZW50IHR3by0gYW5kIHRocmVlLWxldmVsIGxvbmdpdHVkaW5hbCBtb2RlbHNdKGh0dHBzOi8vcnBzeWNob2xvZ2lzdC5jb20vci1ndWlkZS1sb25naXR1ZGluYWwtbG1lLWxtZXIpCgojIyBTaG91bGQgSSB0cmVhdCBmYWN0b3IgeHh4IGFzIGZpeGVkIG9yIHJhbmRvbT8KClRoaXMgaXMgaW4gZ2VuZXJhbCBhIGZhciBtb3JlIGRpZmZpY3VsdCBxdWVzdGlvbiB0aGFuIGl0IHNlZW1zIG9uIHRoZSBzdXJmYWNlLiBUaGVyZSBhcmUgbWFueSBjb21wZXRpbmcgcGhpbG9zb3BoaWVzIGFuZCBkZWZpbml0aW9ucy4gRm9yIGV4YW1wbGUsIGZyb20gQGdlbG1hbl9hbmFseXNpc18yMDA1OgoKPiBCZWZvcmUgZGlzY3Vzc2luZyB0aGUgdGVjaG5pY2FsIGlzc3Vlcywgd2UgYnJpZWZseSByZXZpZXcgd2hhdCBpcyBtZWFudCBieSBmaXhlZCBhbmQgcmFuZG9tIGVmZmVjdHMuIEl0IHR1cm5zIG91dCB0aGF0IGRpZmZlcmVudOKAlGluIGZhY3QsIGluY29tcGF0aWJsZeKAlGRlZmluaXRpb25zIGFyZSB1c2VkIGluIGRpZmZlcmVudCBjb250ZXh0cy4gW1NlZSBhbHNvIEtyZWZ0IGFuZCBkZSBMZWV1dyAoMTk5OCksIFNlY3Rpb24gMS4zLjMsIGZvciBhIGRpc2N1c3Npb24gb2YgdGhlIG11bHRpcGxpY2l0eSBvZiBkZWZpbml0aW9ucyBvZiBmaXhlZCBhbmQgcmFuZG9tIGVmZmVjdHMgYW5kIGNvZWZmaWNpZW50cywgYW5kIFJvYmluc29uICgxOTk4KSBmb3IgYSBoaXN0b3JpY2FsIG92ZXJ2aWV3Ll0gSGVyZSB3ZSBvdXRsaW5lIGZpdmUgZGVmaW5pdGlvbnMgdGhhdCB3ZSBoYXZlIHNlZW46IDEuIEZpeGVkIGVmZmVjdHMgYXJlIGNvbnN0YW50IGFjcm9zcyBpbmRpdmlkdWFscywgYW5kIHJhbmRvbSBlZmZlY3RzIHZhcnkuIEZvciBleGFtcGxlLCBpbiBhIGdyb3d0aCBzdHVkeSwgYSBtb2RlbCB3aXRoIHJhbmRvbSBpbnRlcmNlcHRzIM6xaSBhbmQgZml4ZWQgc2xvcGUgzrIgY29ycmVzcG9uZHMgdG8gcGFyYWxsZWwgbGluZXMgZm9yIGRpZmZlcmVudCBpbmRpdmlkdWFscyBpLCBvciB0aGUgbW9kZWwgeWl0ID0gzrFpICsgzrJ0LiBLcmVmdCBhbmQgZGUgTGVldXcgWygxOTk4KSwgcGFnZSAxMl0gdGh1cyBkaXN0aW5ndWlzaCBiZXR3ZWVuIGZpeGVkIGFuZCByYW5kb20gY29lZmZpY2llbnRzLiAyLiBFZmZlY3RzIGFyZSBmaXhlZCBpZiB0aGV5IGFyZSBpbnRlcmVzdGluZyBpbiB0aGVtc2VsdmVzIG9yIHJhbmRvbSBpZiB0aGVyZSBpcyBpbnRlcmVzdCBpbiB0aGUgdW5kZXJseWluZyBwb3B1bGF0aW9uLiBTZWFybGUsIENhc2VsbGEgYW5kIE1jQ3VsbG9jaCBbKDE5OTIpLCBTZWN0aW9uIDEuNF0gZXhwbG9yZSB0aGlzIGRpc3RpbmN0aW9uIGluIGRlcHRoLiAzLiDigJxXaGVuIGEgc2FtcGxlIGV4aGF1c3RzIHRoZSBwb3B1bGF0aW9uLCB0aGUgY29ycmVzcG9uZGluZyB2YXJpYWJsZSBpcyBmaXhlZDsgd2hlbiB0aGUgc2FtcGxlIGlzIGEgc21hbGwgKGkuZS4sIG5lZ2xpZ2libGUpIHBhcnQgb2YgdGhlIHBvcHVsYXRpb24gdGhlIGNvcnJlc3BvbmRpbmcgdmFyaWFibGUgaXMgcmFuZG9t4oCdIFtHcmVlbiBhbmQgVHVrZXkgKDE5NjApXS4gNC4g4oCcSWYgYW4gZWZmZWN0IGlzIGFzc3VtZWQgdG8gYmUgYSByZWFsaXplZCB2YWx1ZSBvZiBhIHJhbmRvbSB2YXJpYWJsZSwgaXQgaXMgY2FsbGVkIGEgcmFuZG9tIGVmZmVjdOKAnSBbTGFNb3R0ZSAoMTk4MyldLiA1LiBGaXhlZCBlZmZlY3RzIGFyZSBlc3RpbWF0ZWQgdXNpbmcgbGVhc3Qgc3F1YXJlcyAob3IsIG1vcmUgZ2VuZXJhbGx5LCBtYXhpbXVtIGxpa2VsaWhvb2QpIGFuZCByYW5kb20gZWZmZWN0cyBhcmUgZXN0aW1hdGVkIHdpdGggc2hyaW5rYWdlIFvigJxsaW5lYXIgdW5iaWFzZWQgcHJlZGljdGlvbuKAnSBpbiB0aGUgdGVybWlub2xvZ3kgb2YgUm9iaW5zb24gKDE5OTEpXS4gVGhpcyBkZWZpbml0aW9uIGlzIHN0YW5kYXJkIGluIHRoZSBtdWx0aWxldmVsIG1vZGVsaW5nIGxpdGVyYXR1cmUgW3NlZSwgZS5nLiwgU25pamRlcnMgYW5kIEJvc2tlciAoMTk5OSksIFNlY3Rpb24gNC4yXSBhbmQgaW4gZWNvbm9tZXRyaWNzLgoKQW5vdGhlciB1c2VmdWwgY29tbWVudCAodmlhIEtldmluIFdyaWdodCkgcmVpbmZvcmNpbmcgdGhlIGlkZWEgdGhhdCAicmFuZG9tIHZzLiBmaXhlZCIgaXMgbm90IGEgc2ltcGxlLCBjdXQtYW5kLWRyaWVkIGRlY2lzaW9uOiBmcm9tIEBzY2hhYmVuYmVyZ2VyX2NvbnRlbXBvcmFyeV8yMDAxLCBwLiA2Mjc6Cgo+IEJlZm9yZSBwcm9jZWVkaW5nIGZ1cnRoZXIgd2l0aCByYW5kb20gZmllbGQgbGluZWFyIG1vZGVscyB3ZSBuZWVkIHRvIHJlbWluZCB0aGUgcmVhZGVyIG9mIHRoZSBhZGFnZSB0aGF0IG9uZSBtb2RlbGVyJ3MgcmFuZG9tIGVmZmVjdCBpcyBhbm90aGVyIG1vZGVsZXIncyBmaXhlZCBlZmZlY3QuCgpAY2xhcmsyMDE1c2hvdWxkIGFkZHJlc3MgdGhpcyBxdWVzdGlvbiBmcm9tIGEgbW9zdGx5IGVjb25vbWV0cmljIHBlcnNwZWN0aXZlLCBmb2N1c2luZyBtb3N0bHkgb24gcHJhY3RpY2FsIHZhcmlhbmNlL2JpYXMvUk1TRSBjcml0ZXJpYS4KCk9uZSBwb2ludCBvZiBwYXJ0aWN1bGFyIHJlbGV2YW5jZSB0byAnbW9kZXJuJyBtaXhlZCBtb2RlbCBlc3RpbWF0aW9uIChyYXRoZXIgdGhhbiAnY2xhc3NpY2FsJyBtZXRob2Qtb2YtbW9tZW50cyBlc3RpbWF0aW9uKSBpcyB0aGF0LCBmb3IgcHJhY3RpY2FsIHB1cnBvc2VzLCB0aGVyZSBtdXN0IGJlIGEgcmVhc29uYWJsZSBudW1iZXIgb2YgcmFuZG9tLWVmZmVjdHMgbGV2ZWxzIChlLmcuIGJsb2NrcykgLS0gbW9yZSB0aGFuIDUgb3IgNiBhdCBhIG1pbmltdW0uIFRoaXMgaXMgbm90IHN1cnByaXNpbmcgaWYgeW91IGNvbnNpZGVyIHRoYXQgcmFuZG9tIGVmZmVjdHMgZXN0aW1hdGlvbiBpcyB0cnlpbmcgdG8gZXN0aW1hdGUgYW4gYW1vbmctYmxvY2sgdmFyaWFuY2UuIEZvciBleGFtcGxlLCBmcm9tIEBDcmF3bGV5MjAwMiBwLiA2NzA6IAoKPiBBcmUgdGhlcmUgZW5vdWdoIGxldmVscyBvZiB0aGUgZmFjdG9yIGluIHRoZSBkYXRhIG9uIHdoaWNoIHRvIGJhc2UgYW4gZXN0aW1hdGUgb2YgdGhlIHZhcmlhbmNlIG9mIHRoZSBwb3B1bGF0aW9uIG9mIGVmZmVjdHM/IE5vLCBtZWFucyBbeW91IHNob3VsZCBwcm9iYWJseSB0cmVhdCB0aGUgdmFyaWFibGUgYXNdIGZpeGVkIGVmZmVjdHMuCgpTb21lIHJlc2VhcmNoZXJzICh3aG8gdHJlYXQgZml4ZWQgdnMgcmFuZG9tIGFzIGEgcGhpbG9zb3BoaWNhbCByYXRoZXIgdGhhbiBhIHByYWdtYXRpYyBkZWNpc2lvbikgb2JqZWN0IHRvIHRoaXMgYXBwcm9hY2guCgpBbHNvIHNlZSBhIHZlcnkgdGhvdWdodGZ1bCBjaGFwdGVyIGluIEBob2RnZXNfcmljaGx5XzIwMTYuCgpUcmVhdGluZyBmYWN0b3JzIHdpdGggc21hbGwgbnVtYmVycyBvZiBsZXZlbHMgYXMgcmFuZG9tIHdpbGwgaW4gdGhlIGJlc3QgY2FzZSAgbGVhZCB0byB2ZXJ5IHNtYWxsIGFuZC9vciBpbXByZWNpc2UgZXN0aW1hdGVzIG9mIHJhbmRvbSBlZmZlY3RzOyBpbiB0aGUgd29yc3QgY2FzZSBpdCB3aWxsIGxlYWQgdG8gdmFyaW91cyBudW1lcmljYWwgZGlmZmljdWx0aWVzIHN1Y2ggYXMgbGFjayBvZiBjb252ZXJnZW5jZSwgemVybyB2YXJpYW5jZSBlc3RpbWF0ZXMsIGV0Yy4uIChBIHNtYWxsIFtzaW11bGF0aW9uIGV4ZXJjaXNlXShodHRwczovcnB1YnMuY29tL2Jib2xrZXIvNDE4Nykgc2hvd3MgdGhhdCBhdCBsZWFzdCB0aGUgZXN0aW1hdGVzIG9mIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gYXJlIGRvd253YXJkbHkgYmlhc2VkIGluIHRoaXMgY2FzZTsgaXQncyBub3QgY2xlYXIgd2hldGhlci9ob3cgdGhpcyBiaWFzIHdvdWxkIGFmZmVjdCB0aGUgcG9pbnQgZXN0aW1hdGVzIG9mICBmaXhlZCBlZmZlY3RzIG9yIHRoZWlyIGVzdGltYXRlZCBjb25maWRlbmNlIGludGVydmFscy4pIEluIHRoZSBjbGFzc2ljYWwgbWV0aG9kLW9mLW1vbWVudHMgYXBwcm9hY2ggdGhlc2UgcHJvYmxlbXMgbWF5IG5vdCBhcmlzZSAoYmVjYXVzZSB0aGUgc3VtcyBvZiBzcXVhcmVzIGFyZSBhbHdheXMgd2VsbCBkZWZpbmVkIGFzIGxvbmcgYXMgdGhlcmUgYXJlIGF0IGxlYXN0IHR3byB1bml0cyksIGJ1dCB0aGUgdW5kZXJseWluZyBwcm9ibGVtcyBvZiBsYWNrIG9mIHBvd2VyIGFyZSB0aGVyZSBuZXZlcnRoZWxlc3MuCgoKVGhpZXJyeSBPbmtlbGlueCBoYXMgW2EgYmxvZyBwb3N0XShodHRwczovL3d3dy5tdXNjYXJkaW51cy5iZS8yMDE4LzA5L251bWJlci1yYW5kb20tZWZmZWN0LWxldmVscy8pIHdpdGggc29tZSBzaW11bGF0aW9ucyBvbiB0aGUgaW1wYWN0IG9mIHRoZSBudW1iZXIgb2YgbGV2ZWxzIGFuZCBjb25jbHVkZXMgd2l0aCBhIGZldyByZWNvbW1lbmRhdGlvbnMgZm9yIHRoZSBudW1iZXIgb2YgbGV2ZWxzIG9mIHRoZSBncm91cGluZyB2YXJpYWJsZSAkbl9zJDoKPiAtIGdldCAkbl9zID4gMTAwMCQgbGV2ZWxzIHdoZW4gYW4gYWNjdXJhdGUgZXN0aW1hdGUgb2YgdGhlIHJhbmRvbSBlZmZlY3QgdmFyaWFuY2UgaXMgY3J1Y2lhbC4gRS5nLiB3aGVuIGEgc2luZ2xlIG51bWJlciB3aWxsIGJlIHVzZSBmb3IgcG93ZXIgY2FsY3VsYXRpb25zLgo+IC0gZ2V0ICRuX3MgPiAxMDAkIGxldmVscyB3aGVuIGEgcmVhc29uYWJsZSBlc3RpbWF0ZSBvZiB0aGUgcmFuZG9tIGVmZmVjdCB2YXJpYW5jZSBpcyBzdWZmaWNpZW50LiBFLmcuIHBvd2VyIGNhbGN1bGF0aW9ucyB3aXRoIHNlbnNpdGl2aXR5IGFuYWx5c2lzIG9mIHRoZSByYW5kb20gZWZmZWN0IHZhcmlhbmNlLgo+IC0gZ2V0ICRuX3MgPiAyMCQgbGV2ZWxzIGZvciBhbiBleHBlcmltZW50YWwgc3R1ZHkKPiAtIGluIGNhc2UgJDEwIDwgbl9zIDwyMCQgeW91IHNob3VsZCB2YWxpZGF0ZSB0aGUgbW9kZWwgdmVyeSBjYXV0aW91cyBiZWZvcmUgdXNpbmcgdGhlIG91dHB1dAo+IC0gaW4gY2FzZSAkbl9zIDwgMTAkIGl0IGlzIHNhZmVyIHRvIHVzZSB0aGUgdmFyaWFibGUgYXMgYSBmaXhlZCBlZmZlY3QuCgpAb2JlcnByaWxsZXJfZml4ZWRfMjAyMSBhbHNvIHBlcmZvcm1lZCBhIHNpbXVsYXRpb24gc3R1ZHkgYW5kIGZvdW5kIHRoYXQgd2hpbGUgdGhlIGVzdGltYXRlcyBhcmUgc2ltaWxhciBmb3IgdHJlYXRpbmcgYSB2YXJpYWJsZSB3aXRoIGEgc21hbGwgbnVtYmVyIG9mIGxldmVscyBhcyBmaXhlZCBvciByYW5kb20gYXJlIHNpbWlsYXIsIHRoZXJlIHdhcyBhbiBpbXBhY3Qgb24gVHlwZSAxIGFuZCBUeXBlIDIgZXJyb3IgcmF0ZXMuIFRoZXkgYWxzbyBmb3VuZCB0aGF0IHRoZSBwcmVjaXNlIHJhbmRvbSBlZmZlY3RzIHN0cnVjdHVyZSAoZS5nLiwgaW5jbHVzaW9uIG9mIHJhbmRvbSBzbG9wZXMpIGhhZCBhIGxhcmdlIGltcGFjdCBvbiB0aGVzZSBwcm9wZXJ0aWVzLgoKQWxzbyBzZWUgW3RoaXMgdGhyZWFkXShodHRwczovL3N0YXQuZXRoei5jaC9waXBlcm1haWwvci1zaWctbWl4ZWQtbW9kZWxzLzIwMTBxMi8wMDM3MDkuaHRtbCkgb24gdGhlIHItc2lnLW1peGVkLW1vZGVscyBtYWlsaW5nIGxpc3QgYW5kIFt0aGlzIHF1ZXN0aW9uXShodHRwczovL3N0YXRzLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy8zNzY0Ny93aGF0LWlzLXRoZS1taW5pbXVtLXJlY29tbWVuZGVkLW51bWJlci1vZi1ncm91cHMtZm9yLWEtcmFuZG9tLWVmZmVjdHMtZmFjdG9yKSBvbiBDcm9zc1ZhbGlkYXRlZC4KCiMjIE5lc3RlZCBvciBjcm9zc2VkPwoKPGEgaWQ9Im5lc3RlZF9vcl9jcm9zc2VkIj48L2E+CgotIFJlbGF0aXZlbHkgZmV3IG1peGVkIGVmZmVjdCBtb2RlbGluZyBwYWNrYWdlcyBjYW4gaGFuZGxlIGNyb3NzZWQgcmFuZG9tIGVmZmVjdHMsIGkuZS4gdGhvc2Ugd2hlcmUgb25lIGxldmVsIG9mIGEgcmFuZG9tIGVmZmVjdCBjYW4gYXBwZWFyIGluIGNvbmp1bmN0aW9uIHdpdGggbW9yZSB0aGFuIG9uZSBsZXZlbCBvZiBhbm90aGVyIGVmZmVjdC4gIChUaGlzIGRlZmluaXRpb24gaXMgY29uZnVzaW5nLCBhbmQgSSB3b3VsZCBoYXBwaWx5IGFjY2VwdCBhIGJldHRlciBvbmUuKSAgQSBjbGFzc2ljIGV4YW1wbGUgaXMgY3Jvc3NlZCB0ZW1wb3JhbCBhbmQgc3BhdGlhbCBlZmZlY3RzLiBJZiB0aGVyZSBpcyByYW5kb20gdmFyaWF0aW9uIGFtb25nIHRlbXBvcmFsIGJsb2NrcyAoZS5nLiB5ZWFycykgJydhbmQnJyByYW5kb20gdmFyaWF0aW9uIGFtb25nIHNwYXRpYWwgYmxvY2tzIChlLmcuIHNpdGVzKSwgJydhbmQnJyBpZiB0aGVyZSBpcyBhIGNvbnNpc3RlbnQgeWVhciBlZmZlY3QgYWNyb3NzIHNpdGVzIGFuZCAnJ3ZpY2UgdmVyc2EnJywgdGhlbiB0aGUgcmFuZG9tIGVmZmVjdHMgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgY3Jvc3NlZC4KLSBgbG1lNGAgZG9lcyBoYW5kbGVkIGNyb3NzZWQgZWZmZWN0cywgZWZmaWNpZW50bHkKLSBpZiB5b3UgbmVlZCB0byBkZWFsIHdpdGggY3Jvc3NlZCBSRXMgaW4gY29uanVuY3Rpb24gd2l0aCBzb21lIG9mIHRoZSBmZWF0dXJlcyB0aGF0IGBubG1lYCBvZmZlcnMgKGUuZy4gaGV0ZXJvc2NlZGFzdGljaXR5IG9mIHJlc2lkdWFscyB2aWEgYHdlaWdodHNgL2B2YXJTdHJ1Y3RgLCBjb3JyZWxhdGlvbiBvZiByZXNpZHVhbHMgdmlhIGBjb3JyZWxhdGlvbmAvYGNvclN0cnVjdGAsICBvciBpZiB5b3Ugd2FudCB0byB1c2VkIGNyb3NzZWQgUkVzIHdpdGggdGhlIGBnYW1sc3NgIHBhY2thZ2UsIHNlZSBwLiAxNjNmZiBvZiBAcGluaGVpcm9fbWl4ZWQtZWZmZWN0c18yMDAwIChzZWN0aW9uIDQuMi4yOiAgW0dvb2dsZSBib29rcyBsaW5rXShodHRwOi8vdGlueXVybC5jb20vY3Jvc3NlZFJFKSkuIEkgZ2l2ZSBhIHdvcmtlZCBleGFtcGxlIFtoZXJlXShodHRwczovL2dpc3QuZ2l0aHViLmNvbS9iYm9sa2VyLzgzYzFmZjAzNmQ0ODUwZDdkYzRjYTgzMmUzNTRmNmE4KS4gQXMgZmFyIGFzIEkgY2FuIHRlbGwsIGEgY291cGxlIG9mIGhhY2tzIGFyZSBuZWNlc3NhcnkgdG8gZ2V0IHRoaXMgdG8gd29yazogKDEpIHRoZSBkYXRhIG11c3QgYmUgZXhwcmVzc2VkIGFzIGEgYGdyb3VwZWREYXRhYCBvYmplY3QgKGF0IGxlYXN0LCBJIGhhdmVuJ3QgbWFuYWdlZCB0byBnZXQgaXQgdG8gd29yayBpbiBhbnkgb3RoZXIgd2F5KTsgKDIpIHRoZSBjcm9zc2VkIGVmZmVjdHMgbXVzdCBiZSAqbmVzdGVkIHdpdGhpbiBhbm90aGVyIGdyb3VwaW5nIGZhY3RvciogLSBpbiB0aGUgZXhhbXBsZSBoZXJlIEkgZGVmaW5lIGEgZHVtbXkgZ3JvdXAsIHdoaWNoIGlzIGF3a3dhcmQgKGl0IG1ha2VzIHRoZSB2YXJpYW5jZSBjb21wb25lbnQgZm9yIHRoaXMgZ3JvdXAgYW5kIHRoZSByZXNpZHVhbCB2YXJpYW5jZSBqb2ludGx5IHVuaWRlbnRpZmlhYmxlKSwgYnV0IG90aGVyd2lzZSBzZWVtcyB0byB3b3JrIE9LLgotIEkgcmFyZWx5IGZpbmQgaXQgdXNlZnVsIHRvIHRoaW5rIG9mIGZpeGVkIGVmZmVjdHMgYXMgIm5lc3RlZCIgKGFsdGhvdWdoIG90aGVycyBkaXNhZ3JlZSk7IGlmIGZvciBleGFtcGxlIHRyZWF0bWVudHMgQSBhbmQgQiBhcmUgb25seSBtZWFzdXJlZCBpbiBibG9jayAxLCBhbmQgdHJlYXRtZW50cyBDIGFuZCBEIGFyZSBvbmx5IG1lYXN1cmVkIGluIGJsb2NrIDIsIG9uZSBzdGlsbCBhc3N1bWVzIChiZWNhdXNlIHRoZXkgYXJlIGZpeGVkIGVmZmVjdHMpIHRoYXQgZWFjaCB0cmVhdG1lbnQgd291bGQgaGF2ZSB0aGUgc2FtZSBlZmZlY3QgaWYgYXBwbGllZCBpbiB0aGUgb3RoZXIgYmxvY2suIChPbmUgbWlnaHQgbGlrZSB0byBlc3RpbWF0ZSB0cmVhdG1lbnQtYnktYmxvY2sgaW50ZXJhY3Rpb25zLCBidXQgaW4gdGhpcyBjYXNlIHRoZSBleHBlcmltZW50YWwgZGVzaWduIGRvZXNuJ3QgYWxsb3cgaXQ7IG9uZSB3b3VsZCBoYXZlIHRvIGhhdmUgbXVsdGlwbGUgdHJlYXRtZW50cyBtZWFzdXJlZCB3aXRoaW4gZWFjaCBibG9jaywgYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IGFsbCB0cmVhdG1lbnRzIGluIGV2ZXJ5IGJsb2NrLikgIE9uZSB3b3VsZCBjb2RlIHRoaXMgYW5hbHlzaXMgYXMgYHJlc3BvbnNlfnRyZWF0bWVudCsoMXxibG9jaylgIGluIGBsbWU0YC4gQWxzbywgaW4gdGhlIGNhc2Ugb2YgZml4ZWQgZWZmZWN0cywgY3Jvc3NlZCBhbmQgbmVzdGVkIHNwZWNpZmljYXRpb25zIGNoYW5nZSB0aGUgcGFyYW1ldGVyaXphdGlvbiBvZiB0aGUgbW9kZWwsIGJ1dCBub3QgYW55dGhpbmcgZWxzZSAoZS5nLiB0aGUgbnVtYmVyIG9mIHBhcmFtZXRlcnMgZXN0aW1hdGVkLCBsb2ctbGlrZWxpaG9vZCwgbW9kZWwgcHJlZGljdGlvbnMgYXJlIGFsbCBpZGVudGljYWwpLiAgVGhhdCBpcywgaW4gUidzIGBtb2RlbC5tYXRyaXhgIGZ1bmN0aW9uICh3aGljaCBpbXBsZW1lbnRzIGEgdmVyc2lvbiBvZiBXaWxraW5zb24tUm9nZXJzIG5vdGF0aW9uKSBgYSpiYCBhbmQgYGEvYmAgKHdoaWNoIGV4cGFuZCB0byBgMSthK2IrYTpiYCBhbmQgYDErYSthOmJgIHJlc3BlY3RpdmVseSkgZ2l2ZSBtb2RlbCBtYXRyaWNlcyB3aXRoIHRoZSBzYW1lIG51bWJlciBvZiBjb2x1bW5zLgotIFdoZXRoZXIgeW91IGV4cGxpY2l0bHkgc3BlY2lmeSBhIHJhbmRvbSBlZmZlY3QgYXMgbmVzdGVkIG9yIG5vdCBkZXBlbmRzIChpbiBwYXJ0KSBvbiB0aGUgd2F5IHRoZSBsZXZlbHMgb2YgdGhlIHJhbmRvbSBlZmZlY3RzIGFyZSBjb2RlZC4gSWYgdGhlICdsb3dlci1sZXZlbCcgcmFuZG9tIGVmZmVjdCBpcyBjb2RlZCB3aXRoIHVuaXF1ZSBsZXZlbHMsIHRoZW4gdGhlIHR3byBzeW50YXhlcyBgKDF8YS9iKWAgKG9yIGAoMXxhKSsoMXxhOmIpYCkgYW5kIGAoMXxhKSsoMXxiKWAgYXJlIGVxdWl2YWxlbnQuIElmIHRoZSBsb3dlci1sZXZlbCByYW5kb20gZWZmZWN0IGhhcyB0aGUgc2FtZSBsYWJlbHMgd2l0aGluIGVhY2ggbGFyZ2VyIGdyb3VwIChlLmcuIGJsb2NrcyAxLCAyLCAzLCA0IHdpdGhpbiBzaXRlcyBBLCBCLCBhbmQgQykgdGhlbiB0aGUgZXhwbGljaXQgbmVzdGluZyBgKDF8YS9iKWAgaXMgcmVxdWlyZWQuIEl0IHNlZW1zIHRvIGJlIGNvbnNpZGVyZWQgYmVzdCBwcmFjdGljZSB0byBjb2RlIHRoZSBuZXN0ZWQgbGV2ZWwgdW5pcXVlbHkgKGUuZy4gQTEsIEEyLCAuLi4sIEIxLCBCMiwgLi4uKSBzbyB0aGF0IGNvbmZ1c2lvbiBiZXR3ZWVuIG5lc3RlZCBhbmQgY3Jvc3NlZCBlZmZlY3RzIGlzIGxlc3MgbGlrZWx5LgoKIyMgKFdoZW4pIGNhbiBJIGluY2x1ZGUgYSBwcmVkaWN0b3IgYXMgYm90aCBmaXhlZCBhbmQgcmFuZG9tPwoKU2VlIFtibG9nIHBvc3QgYnkgVGhpZXJyeSBPbmtlbGlueF0oaHR0cHM6Ly93d3cubXVzY2FyZGludXMuYmUvMjAxNy8wOC9maXhlZC1hbmQtcmFuZG9tLykKCiMgTW9kZWwgZXh0ZW5zaW9ucwoKIyMgT3ZlcmRpc3BlcnNpb24KCjxhIGlkPSJvdmVyZGlzcGVyc2lvbiI+PC9hPgoKIyMjIFRlc3RpbmcgZm9yIG92ZXJkaXNwZXJzaW9uL2NvbXB1dGluZyBvdmVyZGlzcGVyc2lvbiBmYWN0b3IKCi0gd2l0aCB0aGUgdXN1YWwgY2F2ZWF0cywgcGx1cyBhIGZldyBleHRyYXMgLS0gY291bnRpbmcgZGVncmVlcyBvZiBmcmVlZG9tLCBldGMuIC0tIHRoZSB1c3VhbCBwcm9jZWR1cmUgb2YgY2FsY3VsYXRpbmcgdGhlIHN1bSBvZiBzcXVhcmVkIFBlYXJzb24gcmVzaWR1YWxzIGFuZCBjb21wYXJpbmcgaXQgdG8gdGhlIHJlc2lkdWFsIGRlZ3JlZXMgb2YgZnJlZWRvbSBzaG91bGQgZ2l2ZSBhdCBsZWFzdCBhIGNydWRlIGlkZWEgb2Ygb3ZlcmRpc3BlcnNpb24uICBUaGUgZm9sbG93aW5nIGF0dGVtcHQgY291bnRzIGVhY2ggdmFyaWFuY2Ugb3IgY292YXJpYW5jZSBwYXJhbWV0ZXIgYXMgb25lIG1vZGVsIGRlZ3JlZSBvZiBmcmVlZG9tIGFuZCBwcmVzZW50cyB0aGUgc3VtIG9mIHNxdWFyZWQgUGVhcnNvbiByZXNpZHVhbHMsIHRoZSByYXRpbyBvZiAoU1NRIHJlc2lkdWFscy9yZGYpLCB0aGUgcmVzaWR1YWwgZGYsIGFuZCB0aGUgJHAkLXZhbHVlIGJhc2VkIG9uIHRoZSAoYXBwcm94aW1hdGVseSEhKSBhcHByb3ByaWF0ZSAkXGNoaV4yJCBkaXN0cmlidXRpb24uICoqRG8gUExFQVNFIG5vdGUgdGhlIHVzdWFsLCBhbmQgZXh0cmEsIGNhdmVhdHMgbm90ZWQgaGVyZTogdGhpcyBpcyBhbiBBUFBST1hJTUFURSBlc3RpbWF0ZSBvZiBhbiBvdmVyZGlzcGVyc2lvbiBwYXJhbWV0ZXIqKi4gRXZlbiBpbiB0aGUgR0xNIGNhc2UsIHRoZSBleHBlY3RlZCBkZXZpYW5jZSBwZXIgcG9pbnQgZXF1YWxpbmcgMSBpcyBvbmx5IHRydWUgYXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiBpbmRpdmlkdWFsIGRldmlhdGVzIGFwcHJvYWNoZXMgbm9ybWFsaXR5LCBpLmUuIHRoZSB1c3VhbCAkXGxhbWJkYT41JCBydWxlcyBvZiB0aHVtYiBmb3IgUG9pc3NvbiB2YWx1ZXMgYW5kICRcdGV4dHJte21pbn0oTnAsIE4oMS1wKSkgPiA1JCBmb3IgYmlub21pYWwgdmFsdWVzIChlLmcuIHNlZSBAdmVuYWJsZXNfbW9kZXJuXzIwMDIsIFtwLiAyMDgtMjA5XShodHRwOi8vYm9va3MuZ29vZ2xlLmNvbS9ib29rcz9pZD05NzRjNHZLdXJOa0MmcGc9UEEyMDkpKS4gKEFuZCB0aGF0J3Mgd2l0aG91dCB0aGUgZXh0cmEgY29tcGxleGl0aWVzIGR1ZSB0byBHTE1NLCBpLmUuIHRoZSAiZWZmZWN0aXZlIiByZXNpZHVhbCBkZiBzaG91bGQgYmUgbGFyZ2UgZW5vdWdoIHRvIG1ha2UgdGhlIHN1bXMgb2Ygc3F1YXJlcyBjb252ZXJnZSBvbiBhICRcY2hpXjIkIGRpc3RyaWJ1dGlvbiAuLi4pCi0gUmVtZW1iZXIgdGhhdCAoMSkgb3ZlcmRpc3BlcnNpb24gaXMgaXJyZWxldmFudCBmb3IgbW9kZWxzIHRoYXQgZXN0aW1hdGUgYSBzY2FsZSBwYXJhbWV0ZXIgKGkuZS4gYWxtb3N0IGFueXRoaW5nIGJ1dCBQb2lzc29uIG9yIGJpbm9taWFsOiBHYXVzc2lhbiwgR2FtbWEsIG5lZ2F0aXZlIGJpbm9taWFsIC4uLikgYW5kICgyKSBvdmVyZGlzcGVyc2lvbiBpcyBub3QgZXN0aW1hYmxlIChhbmQgaGVuY2UgcHJhY3RpY2FsbHkgaXJyZWxldmFudCkgZm9yIEJlcm5vdWxsaSBtb2RlbHMgKD0gYmluYXJ5IGRhdGEgPSBiaW5vbWlhbCB3aXRoICROPTEkKS4KLSBUaGUgcmVjaXBlcyBiZWxvdyBtYXkgbmVlZCBhZGp1c3RtZW50IGZvciBzb21lIG9mIHRoZSBtb3JlIGNvbXBsZXggbW9kZWwgdHlwZXMgYWxsb3dlZCBieSBgZ2xtbVRNQmAgKGUuZy4gemVyby1pbmZsYXRpb24vdmFyaWFibGUgZGlzcGVyc2lvbiksIHdoZXJlIGl0J3MgbGVzcyBjbGVhciB3aGF0IHRvIG1lYXN1cmUgdG8gZXN0aW1hdGUgb3ZlcmRpc3BlcnNpb24uCgpUaGUgZm9sbG93aW5nIGZ1bmN0aW9uIHNob3VsZCB3b3JrIGZvciBhIHZhcmlldHkgb2YgbW9kZWwgdHlwZXMKKGF0IGxlYXN0IGBnbG1tQURNQmAsIGBnbG1tVE1CYCwgYGxtZTRgLCAuLi4pLgoKYGBge3Igb3ZlcmRpc3BfZnVufQpvdmVyZGlzcF9mdW4gPC0gZnVuY3Rpb24obW9kZWwpIHsKICAgIHJkZiA8LSBkZi5yZXNpZHVhbChtb2RlbCkKICAgIHJwIDwtIHJlc2lkdWFscyhtb2RlbCx0eXBlPSJwZWFyc29uIikKICAgIFBlYXJzb24uY2hpc3EgPC0gc3VtKHJwXjIpCiAgICBwcmF0IDwtIFBlYXJzb24uY2hpc3EvcmRmCiAgICBwdmFsIDwtIHBjaGlzcShQZWFyc29uLmNoaXNxLCBkZj1yZGYsIGxvd2VyLnRhaWw9RkFMU0UpCiAgICBjKGNoaXNxPVBlYXJzb24uY2hpc3EscmF0aW89cHJhdCxyZGY9cmRmLHA9cHZhbCkKfQpgYGAKCkV4YW1wbGU6CmBgYHtyIGxtZTQsbWVzc2FnZT1GQUxTRX0KbGlicmFyeShsbWU0KQpsaWJyYXJ5KGdsbW1UTUIpCmBgYAoKYGBge3Igb3ZlcmRpc3BfZXgsY2FjaGU9VFJVRSxtZXNzYWdlPUZBTFNFfQpzZXQuc2VlZCgxMDEpICAKZCA8LSBkYXRhLmZyYW1lKHg9cnVuaWYoMTAwMCksCiAgICAgICAgICAgICAgICBmPWZhY3RvcihzYW1wbGUoMToxMCxzaXplPTEwMDAscmVwbGFjZT1UUlVFKSkpCnN1cHByZXNzTWVzc2FnZXMoZCR5IDwtIHNpbXVsYXRlKH54KygxfGYpLCBmYW1pbHk9cG9pc3NvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdkYXRhPWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3cGFyYW1zPWxpc3QodGhldGE9MSxiZXRhPWMoMCwyKSkpW1sxXV0pCm0xIDwtIGdsbWVyKHl+eCsoMXxmKSxkYXRhPWQsZmFtaWx5PXBvaXNzb24pCm92ZXJkaXNwX2Z1bihtMSkKbTIgPC0gZ2xtbVRNQih5fngrKDF8ZiksZGF0YT1kLGZhbWlseT0icG9pc3NvbiIpCm92ZXJkaXNwX2Z1bihtMikKYGBgCgpUaGUgYGdvZmAgZnVuY3Rpb24gaW4gdGhlIGBhb2RzM2AgcHJvdmlkZXMgc2ltaWxhciBmdW5jdGlvbmFsaXR5CihpdCByZXBvcnRzIGJvdGggZGV2aWFuY2UtIGFuZCAkXGNoaV4yJC1iYXNlZCBlc3RpbWF0ZXMgb2YKb3ZlcmRpc3BlcnNpb24gYW5kIHRlc3RzKS4KCiMjIyBGaXR0aW5nIG1vZGVscyB3aXRoIG92ZXJkaXNwZXJzaW9uPwoKLSBxdWFzaWxpa2VsaWhvb2QgZXN0aW1hdGlvbjogW01BU1M6OmdsbW1QUUxdKGh0dHA6Ly9maW56aS5wc3ljaC51cGVubi5lZHUvUi9saWJyYXJ5L01BU1MvaHRtbC9nbG1tUFFMLmh0bWwpLiBRdWFzaS0gd2FzIGRlZW1lZCB1bnJlbGlhYmxlIGluIGBsbWU0YCwgYW5kIGlzIG5vIGxvbmdlciBhdmFpbGFibGUuIChQYXJ0IG9mIHRoZSBwcm9ibGVtIHdhcyBxdWVzdGlvbmFibGUgbnVtZXJpY2FsIHJlc3VsdHMgaW4gc29tZSBjYXNlczsgdGhlIG90aGVyIHByb2JsZW0gd2FzIHRoYXQgREIgZmVsdCB0aGF0IGhlIGRpZCBub3QgaGF2ZSBhIHN1ZmZpY2llbnRseSBnb29kIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHRoZW9yZXRpY2FsIGZyYW1ld29yayB0aGF0IHdvdWxkIGV4cGxhaW4gd2hhdCB0aGUgYWxnb3JpdGhtIHdhcyBhY3R1YWxseSBlc3RpbWF0aW5nIGluIHRoaXMgY2FzZS4pIFtnZWVwYWNrOjpnZWVsZ21dKGh0dHA6Ly9maW56aS5wc3ljaC51cGVubi5lZHUvUi9saWJyYXJ5L2dlZXBhY2svaHRtbC9nZWVnbG0uaHRtbCkgbWF5IGJlIHdvcmthYmxlIChoYXZlbid0IHRyaWVkIGl0KQoKICAgIElmIHlvdSByZWFsbHkgd2FudCBxdWFzaS1saWtlbGlob29kIGFuYWx5c2lzIGZvciBgZ2xtZXJgIGZpdHMsIHlvdSBjYW4gZG8gaXQgeW91cnNlbGYgYnkgYWRqdXN0aW5nIHRoZQpjb2VmZmljaWVudCB0YWJsZSAtIGkuZS4sIGJ5IG11bHRpcGx5aW5nIHRoZSBzdGFuZGFyZCBlcnJvciBieSB0aGUgc3F1YXJlIHJvb3QKb2YgdGhlIGRpc3BlcnNpb24gZmFjdG9yIFteMl0gYW5kIHJlY29tcHV0aW5nIHRoZSAkWiQtIGFuZCAkcCQtdmFsdWVzCmFjY29yZGluZ2x5LCBhcyBmb2xsb3dzOgoKW14yXTogdGhlIGRpc3BlcnNpb24gZmFjdG9yIGlzIGVzdGltYXRlZCBvbiBhCnZhcmlhbmNlLCBzbyB3ZSBuZWVkIHRvIHRha2UgdGhlIHNxdWFyZSByb290IHRvIGFwcGx5IGl0IHRvIHRoZQpzdGFuZGFyZCBlcnJvcgoKYGBge3IgcXVhc2l9CiMjIGV4dHJhY3Qgc3VtbWFyeSB0YWJsZTsgeW91IG1heSBhbHNvIGJlIGFibGUgdG8gZG8gdGhpcyB2aWEKIyMgIGJyb29tOjp0aWR5IG9yIGJyb29tLm1peGVkOjp0aWR5CnF1YXNpX3RhYmxlIDwtIGZ1bmN0aW9uKG1vZGVsLGN0YWI9Y29lZihzdW1tYXJ5KG1vZGVsKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBoaT1vdmVyZGlzcF9mdW4obW9kZWwpWyJyYXRpbyJdKSB7CiAgICBxY3RhYiA8LSB3aXRoaW4oYXMuZGF0YS5mcmFtZShjdGFiKSwKICAgIHsgICBgU3RkLiBFcnJvcmAgPC0gYFN0ZC4gRXJyb3JgKnNxcnQocGhpKQogICAgICAgIGB6IHZhbHVlYCA8LSBFc3RpbWF0ZS9gU3RkLiBFcnJvcmAKICAgICAgICBgUHIoPnx6fClgIDwtIDIqcG5vcm0oYWJzKGB6IHZhbHVlYCksIGxvd2VyLnRhaWw9RkFMU0UpCiAgICB9KQogICAgcmV0dXJuKHFjdGFiKQp9CnByaW50Q29lZm1hdChxdWFzaV90YWJsZShtMSksZGlnaXRzPTMpCiMjIHRvIHVzZSB0aGlzIHdpdGggZ2xtbVRNQiwgd2UgbmVlZCB0byBzZXBhcmF0ZSBvdXQgdGhlCiMjICBjb25kaXRpb25hbCBjb21wb25lbnQgb2YgdGhlIHN1bW1hcnkKcHJpbnRDb2VmbWF0KHF1YXNpX3RhYmxlKG0yLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RhYj1jb2VmKHN1bW1hcnkobTIpKVtbImNvbmQiXV0pLAogICAgICAgICAgICAgZGlnaXRzPTMpCmBgYAoKQW5vdGhlciB2ZXJzaW9uLCB0aGlzIG9uZSB0aWR5dmVyc2UtY2VudHJpYzoKCmBgYHtyIHRpZHlxdWFzaSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeShicm9vbS5taXhlZCkKbGlicmFyeShkcGx5cikKdGlkeV9xdWFzaSA8LSBmdW5jdGlvbihtb2RlbCwgcGhpPW92ZXJkaXNwX2Z1bihtb2RlbClbInJhdGlvIl0sCiAgICAgICAgICAgICAgICAgICAgICAgY29uZi5sZXZlbD0wLjk1KSB7CiAgICB0dCA8LSAodGlkeShtb2RlbCwgZWZmZWN0cz0iZml4ZWQiKQogICAgICAgICU+JSBtdXRhdGUoc3RkLmVycm9yPXN0ZC5lcnJvcipzcXJ0KHBoaSksCiAgICAgICAgICAgICAgICAgICBzdGF0aXN0aWM9ZXN0aW1hdGUvc3RkLmVycm9yLAogICAgICAgICAgICAgICAgICAgcC52YWx1ZT0yKnBub3JtKGFicyhzdGF0aXN0aWMpLCBsb3dlci50YWlsPUZBTFNFKSkKICAgICkKICAgIHJldHVybih0dCkKfQp0aWR5X3F1YXNpKG0xKQp0aWR5X3F1YXNpKG0yKQpgYGAKClRoZXNlIGZ1bmN0aW9ucyBtYWtlIHNvbWUgc2ltcGxpZnlpbmcgYXNzdW1wdGlvbnM6ICgxKSB0aGlzIG92ZXJkaXNwZXJzaW9uIGNvbXB1dGF0aW9uIGlzIGFwcHJveGltYXRlCgpJbiB0aGlzIGNhc2UgdXNpbmcgcXVhc2ktbGlrZWxpaG9vZCBkb2Vzbid0IG1ha2UgbXVjaCBkaWZmZXJlbmNlLCBzaW5jZSB0aGUgZGF0YSB3ZSBzaW11bGF0ZWQgaW4gdGhlIGZpcnN0IHBsYWNlIHdlcmUgUG9pc3Nvbi4pIEtlZXAgaW4gbWluZCB0aGF0IG9uY2UgeW91IHN3aXRjaCB0byBxdWFzaS1saWtlbGlob29kIHlvdSB3aWxsIGVpdGhlciBoYXZlIHRvIGVzY2hldyBpbmZlcmVudGlhbCBtZXRob2RzIHN1Y2ggYXMgdGhlIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCwgcHJvZmlsZSBjb25maWRlbmNlIGludGVydmFscywgQUlDLCBldGMuLCBvciBtYWtlIG1vcmUgaGVyb2ljIGFzc3VtcHRpb25zIHRvIGNvbXB1dGUgInF1YXNpLSIgYW5hbG9ncyBvZiBhbGwgb2YgdGhlIGFib3ZlIChzdWNoIGFzIFFBSUMpLiAKCi0gb2JzZXJ2YXRpb24tbGV2ZWwgcmFuZG9tIGVmZmVjdHMgKE9MUkU6IHRoaXMgYXBwcm9hY2ggc2hvdWxkIHdvcmsgaW4gbW9zdCBwYWNrYWdlcykuIElmIHlvdSB3YW50IHRvIGEgY2l0YXRpb24gZm9yIHRoaXMgYXBwcm9hY2gsIHRyeSBAZWxzdG9uX2FuYWx5c2lzXzIwMDEsIHdobyBjaXRlIEBsYXdzb25fZGlzZWFzZV8xOTk5OyBhcHBhcmVudGx5IHRoZXJlIGlzIGFsc28gYW4gZXhhbXBsZSBpbiBzZWN0aW9uIDEwLjUgb2YgQG1haW5kb25hbGRfZGF0YV8yMDEwLCBhbmQgKGFjY29yZGluZyB0byBhbiBSLXNpZy1taXhlZC1tb2RlbHMgcG9zdCkgdGhpcyBpcyBhbHNvIGRpc2N1c3NlZCBieSBAcmFiZWhlc2tldGhfbXVsdGlsZXZlbF8yMDA4LiBBbHNvIHNlZSBAYnJvd25lX3ZhcmlhbmNlXzIwMDUgZm9yIGFuIGV4YW1wbGUgaW4gdGhlIGJpbm9taWFsIGNvbnRleHQgKGkuZS4gbG9naXQtbm9ybWFsLWJpbm9taWFsIHJhdGhlciB0aGFuIGxvZ25vcm1hbC1Qb2lzc29uKS4gQWdyZXN0aSdzIGV4Y2VsbGVudCAoMjAwMikgYm9vayBAYWdyZXN0aV9jYXRlZ29yaWNhbF8yMDAyIGFsc28gZGlzY3Vzc2VzIHRoaXMgKHNlY3Rpb24gMTMuNSksIHJlZmVycmluZyBiYWNrIHRvIEBicmVzbG93X2V4dHJhcG9pc3Nvbl8xOTg0IGFuZCBAaGluZGVfY29tcG91bmRfMTk4Mi4gWyoqTm90ZXMqKjogKGEpIEkgaGF2ZW4ndCBjaGVja2VkIGFsbCB0aGVzZSByZWZlcmVuY2VzIG15c2VsZiwgKGIpIEkgY2FuJ3QgZmluZCB0aGUgcmVmZXJlbmNlIGFueSBtb3JlLCBidXQgSSBoYXZlIHNlZW4gaXQgc3RhdGVkIHRoYXQgb2JzZXJ2YXRpb24tbGV2ZWwgcmFuZG9tIGVmZmVjdCBlc3RpbWF0aW9uIGlzIHByb2JhYmx5IGRvZGd5IGZvciBQUUwgYXBwcm9hY2hlcyBhcyB1c2VkIGluIEVsc3RvbiBldCBhbCAyMDAxXSAKLSBhbHRlcm5hdGl2ZSBkaXN0cmlidXRpb25zCiAgICAtIFBvaXNzb24tbG9nbm9ybWFsIG1vZGVsIGZvciBjb3VudHMgb3IgYmlub21pYWwtbG9naXQtTm9ybWFsIG1vZGVsIGZvciBwcm9wb3J0aW9ucyAoc2VlIGFib3ZlLCAib2JzZXJ2YXRpb24tbGV2ZWwgcmFuZG9tIGVmZmVjdHMiKQogICAgLSBuZWdhdGl2ZSBiaW5vbWlhbCBmb3IgY291bnRzIG9yIGJldGEtYmlub21pYWwgZm9yIHByb3BvcnRpb25zCiAgICAgICAgIC0gYGxtZTQ6OmdsbWVyLm5iKClgIHNob3VsZCBmaXQgYSBuZWdhdGl2ZSBiaW5vbWlhbCwgYWx0aG91Z2ggaXQgaXMgc29tZXdoYXQgc2xvdyBhbmQgZnJhZ2lsZSBjb21wYXJlZCB0byBzb21lIG9mIHRoZSBvdGhlciBtZXRob2RzIHN1Z2dlc3RlZCBoZXJlLiBgbG1lNGAgY2Fubm90IGZpdCBiZXRhLWJpbm9taWFsIG1vZGVscyAodGhlc2UgY2Fubm90IGJlIGZvcm11bGF0ZWQgYXMgYSBwYXJ0IG9mIHRoZSBleHBvbmVudGlhbCBmYW1pbHkgb2YgZGlzdHJpYnV0aW9ucykKCSAgICAgLSBbZ2xtbVRNQl0oaHR0cHM6Ly9naXRodWIuY29tL2dsbW10bWIvZ2xtbVRNQi8pIHdpbGwgZml0IHR3byBwYXJhbWV0ZXJpemF0aW9ucyBvZiB0aGUgbmVnYXRpdmUgYmlub21pYWw6IGBmYW1pbHk9Im5iaW5vbTIiYCBnaXZlcyB0aGUgY2xhc3NpYyBwYXJhbWV0ZXJpemF0aW9uIHdpdGggJFxzaWdtYV4yPVxtdSgxK1xtdS9rKSQgKCJOQjIiIGluIEhhcmRpbiBhbmQgSGlsYmUncyB0ZXJtaW5vbG9neSkgd2hpbGUgYGZhbWlseT0ibmJpbm9tMSJgIGdpdmVzIGEgcGFyYW1ldGVyaXphdGlvbiB3aXRoICRcc2lnbWFeMj1ccGhpIFxtdSQsICRccGhpPjEkICgiTkIxIiB0byBIYXJkaW4gYW5kIEhpbGJlKS4gVGhlIGxhdHRlciBtaWdodCBhbHNvIGJlIGNhbGxlZCBhICJxdWFzaS1Qb2lzc29uIiBwYXJhbWV0ZXJpemF0aW9uIGJlY2F1c2UgaXQgbWF0Y2hlcyB0aGUgbWVhbi12YXJpYW5jZSByZWxhdGlvbnNoaXAgYXNzdW1lZCBieSBxdWFzaS1Qb2lzc29uIG1vZGVscywgaS5lLiB0aGUgdmFyaWFuY2UgaXMgc3RyaWN0bHkgcHJvcG9ydGlvbmFsIHRvIHRoZSBtZWFuIChhbHRob3VnaCB0aGUgcHJvcG9ydGlvbmFsaXR5IGNvbnN0YW50IG11c3QgYmUgPjEsIGEgbGltaXRhdGlvbiB0aGF0IGRvZXMgbm90IGFwcGx5IHRvIHF1YXNpLWxpa2VsaWhvb2QgYXBwcm9hY2hlcykuIChbZ2xtbUFETUJdKGh0dHA6Ly9naXRodWIuY29tL2Jib2xrZXIvZ2xtbUFETUIvKSB3aWxsIGFsc28gZml0IHRoZXNlIG1vZGVscywgd2l0aCBgZmFtaWx5PSJuYmlub20iYCBmb3IgTkIyLCBidXQgaXMgZGVwcmVjYXRlZCBpbiBmYXZvdXIgb2YgZ2xtbVRNQi4pCgkgICAtIGBnbG1tVE1CYCBhbGxvd3MgYmV0YS1iaW5vbWlhbCBtb2RlbHMgKFtAaGFycmlzb25fY29tcGFyaXNvbl8yMDE1XSBzdWdnZXN0cyBjb21wYXJpbmcgYmV0YS1iaW5vbWlhbCB3aXRoIE9MUkUgbW9kZWxzIHRvIGFzc2VzcyByZWxpYWJpbGl0eSkKCSAgIC0gdGhlIGBicm1zYCBwYWNrYWdlIGhhcyBhIGBuZWdiaW5vbWlhbGAgZmFtaWx5IChubyBiZXRhLWJpbm9taWFsLCBidXQgaXQgZG9lcyBoYXZlIGEgd2lkZSByYW5nZSBvZiBvdGhlciBmYW1pbGllcykKLSBvdGhlciBwYWNrYWdlcy9hcHByb2FjaGVzIChsZXNzIHdpZGVseSB1c2VkLCBvciByZXF1aXJpbmcgYSBiaXQgbW9yZSBlZmZvcnQpCiAgICAtIGBnYW1sc3MubXg6Z2FtbHNzTlBgCiAgICAtIFdpbkJVR1MvSkFHUyAodmlhIFIyV2luQlVHUy9SamFncykKICAgIC0gQUQgTW9kZWwgQnVpbGRlciAocG9zc2libHkgdmlhIGBSMmFkbWJgIHBhY2thZ2UpIG9yIGBUTUJgCiAgICAtIGBnbmxtbWAgaW4gdGhlIGByZXBlYXRlZGAgcGFja2FnZSAoW29mZi1DUkFOXShodHRwOi8vd3d3LmNvbW1hbnN0ZXIuZXUvcmNvZGUuaHRtbCkpCiAgKiBbQVNSRU1MXShodHRwOi8vd3d3LmFzcmVtbC5jb20vc29mdHdhcmUvZ2Vuc3RhdC9odG1saGVscC9zZXJ2ZXIvR0xNTS5odG0pCgpOZWdhdGl2ZSBiaW5vbWlhbCBtb2RlbHMgaW4gYGdsbW1UTUJgIGFuZCBsb2dub3JtYWwtUG9pc3NvbiBtb2RlbHMgaW4gYGdsbWVyYCAob3IgYE1DTUNnbG1tYCkgYXJlIHByb2JhYmx5IHRoZSBiZXN0IHF1aWNrIGFsdGVybmF0aXZlcyBmb3Igb3ZlcmRpc3BlcnNlZCBjb3VudCBkYXRhLiBJZiB5b3UgbmVlZCB0byBleHBsb3JlIGFsdGVybmF0aXZlcyAoZGlmZmVyZW50IHZhcmlhbmNlLW1lYW4gcmVsYXRpb25zaGlwcywgZGlmZmVyZW50IGRpc3RyaWJ1dGlvbnMpLCB0aGVuIGBBRE1CYCwgYFRNQmAsIGBXaW5CVUdTYCwgYFN0YW5gLCBgTklNQkxFYCBhcmUgdGhlIG1vc3QgZmxleGlibGUgYWx0ZXJuYXRpdmVzLgoKIyMjIFVuZGVyZGlzcGVyc2lvbgoKVW5kZXJkaXNwZXJzaW9uIChtdWNoICpsZXNzKiB2YXJpYWJpbGl0eSB0aGFuIGV4cGVjdGVkKSBpcyBhIGxlc3MgY29tbW9uIHByb2JsZW0gdGhhbiBvdmVyZGlzcGVyc2lvbi4KCi0gbWlsZCB1bmRlcmRpc3BlcnNpb24gaXMgc29tZXRpbWVzIGlnbm9yZWQsIHNpbmNlIGl0IHRlbmRzIGluIGdlbmVyYWwgdG8gbGVhZCB0byBjb25zZXJ2YXRpdmUgcmF0aGVyIHRoYW4gYW50aS1jb25zZXJ2YXRpdmUgcmVzdWx0cwotIHF1YXNpLWxpa2VsaWhvb2QgKGFuZCB0aGUgcXVhc2ktaGFjayBsaXN0ZWQgYWJvdmUpIGNhbiBoYW5kbGUgdW5kZXItIGFzIHdlbGwgYXMgb3ZlcmRpc3BlcnNpb24KLSBzb21lIG90aGVyIHNvbHV0aW9ucyBleGlzdCwgYnV0IGFyZSBsZXNzIHdpZGVseSBpbXBsZW1lbnRlZAogICAgLSBmb3IgZGlzdHJpYnV0aW9ucyB3aXRoIGEgc21hbGwgcmFuZ2UgKGUuZy4gbGl0dGVyIHNpemVzIG9mIGxhcmdlIG1hbW1hbHMpLCBvbmUgY2FuIHRyZWF0IHJlc3BvbnNlcyBhcyBvcmRpbmFsIChlLmcuIHVzaW5nIHRoZSBgb3JkaW5hbGAgcGFja2FnZSwgb3IgYE1DTUNnbG1tYCBvciBgYnJtc2AgZm9yIEJheWVzaWFuIHNvbHV0aW9ucykKICAgIC0gdGhlIENPTS1Qb2lzc29uIGRpc3RyaWJ1dGlvbiBhbmQgZ2VuZXJhbGl6ZWQgUG9pc3NvbiBkaXN0cmlidXRpb25zLCBpbXBsZW1lbnRlZCBpbiBgZ2xtbVRNQmAsIGNhbiBoYW5kbGUgdW5kZXJkaXNwZXJzaW9uIChKLiBIaWxiZSByZWNvbW1lbmRzIHRoZSBsYXR0ZXIgaW4gW3RoaXMgQ3Jvc3NWYWxpZGF0ZWQgYW5zd2VyXShodHRwczovL3N0YXRzLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy82NzM4NS93aGF0LWlzLXRoZS1hcHByb3ByaWF0ZS1tb2RlbC1mb3ItdW5kZXJkaXNwZXJzZWQtY291bnQtZGF0YSkpLiAoYFZHQU1gIGhhcyBhIGdlbmVyYWxpemVkIFBvaXNzb24gZGlzdHJpYnV0aW9uLCBidXQgZG9lc24ndCBoYW5kbGUgcmFuZG9tIGVmZmVjdHMuKQogICAgIAoKCiMjIEdhbW1hIEdMTU1zCgpXaGlsZSBvbmUgKHdlbGwsIE9LIEkpIHdvdWxkIG5haXZlbHkgdGhpbmsgdGhhdCBHTE1NcyB3aXRoIEdhbW1hIGRpc3RyaWJ1dGlvbnMgd291bGQgYmUganVzdCBhcyBlYXN5IChvciBoYXJkKSBhcyBhbnkgb3RoZXIgc29ydCBvZiBHTE1NcywgaXQgc2VlbXMgdGhhdCB0aGV5IGFyZSBpbiBmYWN0IGhhcmRlciB0byBpbXBsZW1lbnQuIEJhc2ljIHNpbXVsYXRlZCBleGFtcGxlcyBvZiBHYW1tYSBHTE1NcyBjYW4gZmFpbCBpbiBsbWU0IGRlc3BpdGUgYW5hbG9nb3VzIHByb2JsZW1zIHdpdGggUG9pc3NvbiwgYmlub21pYWwsIGV0Yy4gZGlzdHJpYnV0aW9ucy4gIFNvbHV0aW9uczoKLSB0aGUgZGVmYXVsdCBpbnZlcnNlIGxpbmsgc2VlbXMgcGFydGljdWxhcmx5IHByb2JsZW1hdGljOyB0cnkgb3RoZXIgbGlua3MgKGVzcGVjaWFsbHkgYGZhbWlseT1HYW1tYShsaW5rPSJsb2ciKWApIGlmIHRoYXQgaXMgcG9zc2libGUvbWFrZXMgc2Vuc2UKLSBjb25zaWRlciB3aGV0aGVyIGEgbG9nbm9ybWFsIG1vZGVsIChpLmUuIGEgcmVndWxhciBMTU0gb24gbG9nZ2VkIGRhdGEpIHdvdWxkIHdvcmsvbWFrZXMgc2Vuc2UuCi0gQGxvX3RyYW5zZm9ybV8yMDE1IGFyZ3VlIHRoYXQgdGhlIEdhbW1hIGZhbWlseSB3aXRoIGFuICppZGVudGl0eSogbGluayBpcyBzdXBlcmlvciB0byBsb2dub3JtYWwgbW9kZWxzIGZvciByZWFjdGlvbi10aW1lIGRhdGEuIEkgKEJNQikgZG9uJ3QgZmluZCB0aGVpciBhcmd1bWVudCBwYXJ0aWN1bGFybHkgY29udmluY2luZywgYnV0IGxvdHMgb2YgcGVvcGxlIHdhbnQgdG8gZG8gdGhpcy4gVW5mb3J0dW5hdGVseSB0aGlzIGlzIHRlY2huaWNhbGx5IGNoYWxsZW5naW5nIChzZWUgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9sbWU0L2xtZTQvaXNzdWVzLzU3MykpLCBiZWNhdXNlIGl0IGlzIGxpa2VseSB0aGF0IHNvbWUgImlsbGVnYWwiIHZhbHVlcyAocHJlZGljdGVkIHJlc3BvbnNlcyAkXGxlIDAkKSB3aWxsIG9jY3VyIHdoaWxlIGZpdHRpbmcgdGhlIG1vZGVsLCBldmVuIGlmIHRoZSBmaW5hbCBmaXR0ZWQgbW9kZWwgbWFrZXMgbm8gaW1wb3NzaWJsZSBwcmVkaWN0aW9ucy4gVGh1cyBzb21ldGhpbmcgaGFzIHRvIGJlIGRvbmUgdG8gbWFrZSB0aGUgbW9kZWwtZml0dGluZyBtYWNoaW5lcnkgdG9sZXJhbnQgb2Ygc3VjaCB2YWx1ZXMgKGkuZS4gcmV0dXJuaW5nIGBOQWAgZm9yIHRoZXNlIG1vZGVsIGV2YWx1YXRpb25zLCBvciBjbGFtcGluZyBpbGxlZ2FsIHZhbHVlcyB0byB0aGUgY29uc3RyYWluZWQgc3BhY2Ugd2l0aCBhbiBhcHByb3ByaWF0ZSBzbW9vdGggcGVuYWx0eSBmdW5jdGlvbikuCgpHYW1tYSBtb2RlbHMgY2FuIGJlIGZpdHRlZCBieSBhIHdpZGUgdmFyaWV0eSBvZiBwbGF0Zm9ybXMgKGBsbWU0OjpnbG1lcmAsIGBNQVNTOjpnbG1tUFFMYCwgYGdsbW1BRE1CYCwgYGdsbW1UTUJgLCBgTWl4ZWRNb2RlbHMuamxgLCBgTUNNQ2dsbW1gLCBgYnJtc2AgLi4uIG5vdCBzdXJlIGFib3V0IG90aGVycy4KCiMjIEJldGEgR0xNTXMKClByb3BvcnRpb24gZGF0YSB3aGVyZSB0aGUgZGVub21pbmF0b3IgKGUuZy4gbWF4aW11bSBwb3NzaWJsZSBudW1iZXIgb2Ygc3VjY2Vzc2VzIGZvciBhIGdpdmVuIG9ic2VydmF0aW9uKSBpcyBub3Qga25vd24gY2FuIGJlIG1vZGVsZWQgdXNpbmcgYSBCZXRhIGRpc3RyaWJ1dGlvbi4gQHNtaXRoc29uX2JldHRlcl8yMDA2IGlzIGEgZ29vZCBpbnRyb2R1Y3Rpb24gZm9yIG5vbi1zdGF0aXN0aWNpYW5zICgqbm90KiBpbiB0aGUgbWl4ZWQtbW9kZWwgY2FzZSksIGFuZCB0aGUgYGJldGFyZWdgIHBhY2thZ2UgW0BjcmliYXJpLW5ldG9fYmV0YV8yMDA5XSBoYW5kbGVzICpub24qLW1peGVkIEJldGEgcmVncmVzc2lvbnMuIFRoZSBgZ2xtbVRNQmAgYW5kIGBicm1zYCBwYWNrYWdlcyBoYW5kbGUgQmV0YSBtaXhlZCBtb2RlbHMgKGBicm1zYCBhbHNvIGhhbmRsZXMgemVyby1pbmZsYXRlZCBhbmQgemVyby1vbmUgaW5mbGF0ZWQgbW9kZWxzKS4KCiMjIFplcm8taW5mbGF0aW9uCgpTZWUgZS5nLiBAbWFydGluX3plcm9fMjAwNSBvciBAd2FydG9uX21hbnlfMjAwNSAoIm1hbnkgemVyb3MgZG9lcyBub3QgbWVhbiB6ZXJvIGluZmxhdGlvbiIpIG9yIEB6dXVyX3plcm8tdHJ1bmNhdGVkXzIwMDkgZm9yIGdlbmVyYWwgaW5mb3JtYXRpb24gb24gemVyby1pbmZsYXRpb24uCgojIyMgQ291bnQgZGF0YQoKLSBgTUNNQ2dsbW1gIGhhbmRsZXMgemVyby10cnVuY2F0ZWQsIHplcm8taW5mbGF0ZWQsIGFuZCB6ZXJvLWFsdGVyZWQgbW9kZWxzLCBhbHRob3VnaCBzcGVjaWZ5aW5nIHRoZSBtb2RlbHMgaXMgYSBsaXR0bGUgYml0IHRyaWNreTogc2VlIFNlY3Rpb25zIDUuMyB0byA1LjUgb2YgdGhlIFtDb3Vyc2VOb3RlcyB2aWduZXR0ZV0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL01DTUNnbG1tL3ZpZ25ldHRlcy9Db3Vyc2VOb3Rlcy5wZGYpCi0gYGdsbW1BRE1CYCBoYW5kbGVzIAogICAgLSB6ZXJvLWluZmxhdGVkIG1vZGVscyAod2l0aCBhIHNpbmdsZSB6ZXJvLWluZmxhdGlvbiBwYXJhbWV0ZXIgLS0gaS5lLiwgdGhlIGxldmVsIG9mIHplcm8taW5mbGF0aW9uIGlzIGFzc3VtZWQgY29uc3RhbnQgYWNyb3NzIHRoZSB3aG9sZSBkYXRhIHNldCkKICAgIC0gdHJ1bmNhdGVkIFBvaXNzb24gYW5kIG5lZ2F0aXZlIGJpbm9taWFsIGRpc3RyaWJ1dGlvbnMgKHdoaWNoIGFsbG93cyB0d28tc3RhZ2UgZml0dGluZyBvZiBodXJkbGUgbW9kZWxzKQotIGBnbG1tVE1CYCBoYW5kbGVzIGEgdmFyaWV0eSBvZiBaLUkgYW5kIFotVCBtb2RlbHMgKGFsbG93cyBjb3ZhcmlhdGVzLCBhbmQgcmFuZG9tIGVmZmVjdHMsIGluIHRoZSB6ZXJvLWFsdGVyYXRpb24gbW9kZWwpCi0gYGJybXNgIGRvZXMgdG9vCi0gc28gZG9lcyBgR0xNTWFkYXB0aXZlYAotIEdhdmluIFNpbXBzb24gaGFzIGEgW2RldGFpbGVkIHdyaXRldXBdKGh0dHA6Ly93d3cuZnJvbXRoZWJvdHRvbW9mdGhlaGVhcC5uZXQvMjAxNy8wNS8wNC9jb21wYXJlLW1nY3Ytd2l0aC1nbG1tVE1CLykgc2hvd2luZyB0aGF0IGBtZ2N2OjpnYW0oKWAgY2FuIGRvIHNpbXBsZSBtaXhlZCBtb2RlbHMgKFBvaXNzb24sIG5vdCBOQikgd2l0aCB6ZXJvLWluZmxhdGlvbiwgYW5kIGNvbXBhcmluZyBgbWdjdmAgd2l0aCBgZ2xtbVRNQmAgcmVzdWx0cwotIGBnYW1sc3NOUGAgaW4gdGhlIGBnYW1sc3MubXhgIHBhY2thZ2Ugc2hvdWxkIGhhbmRsZSB6ZXJvLWluZmxhdGlvbiwgYW5kIHRoZSBgZ2FtbHNzLnRyYCBwYWNrYWdlIHNob3VsZCBoYW5kbGUgdHJ1bmNhdGVkIChpLmUuIGh1cmRsZSkgbW9kZWxzIC0tIGJ1dCBJIGhhdmVuJ3QgdHJpZWQgdGhlbQotIHJvbGwteW91ci1vd246IEFETUIvUjJhZG1iLCBXaW5CVUdTL1IyV2luQlVHUywgVE1CLCBTdGFuLCAuLi4gCgojIyMgQ29udGludW91cyBkYXRhCgpDb250aW51b3VzIGRhdGEgYXJlIGEgc3BlY2lhbCBjYXNlIHdoZXJlIHRoZSBtaXh0dXJlIG1vZGVsIGZvciB6ZXJvLWluZmxhdGVkIGRhdGEgaXMgbGVzcyByZWxldmFudCwgYmVjYXVzZSBvYnNlcnZhdGlvbnMgdGhhdCBhcmUgZXhhY3RseSB6ZXJvIG9jY3VyIHdpdGggKnByb2JhYmlsaXR5KiAoYnV0IG5vdCBwcm9iYWJpbGl0eSBkZW5zaXR5KSB6ZXJvLiBUaGVyZSBhcmUgdHdvIGNhc2VzIG9mIGludGVyZXN0OgoKIyMjIyBQcm9iYWJpbGl0eSBkZW5zaXR5IG9mICR4JCB6ZXJvIG9yIGluZmluaXRlCgpJbiB0aGlzIGNhc2UgemVybyBpcyBhIHByb2JsZW1hdGljIG9ic2VydmF0aW9uIGZvciB0aGUgZGlzdHJpYnV0aW9uOyBpdCdzIGVpdGhlciBpbXBvc3NpYmxlIG9yIGluZmluaXRlbHkgKGxvY2FsbHkpIGxpa2VseS4gU29tZSBleGFtcGxlczoKCi0gR2FtbWEgZGlzdHJpYnV0aW9uOiBwcm9iYWJpbGl0eSBkZW5zaXR5IGF0IHplcm8gaXMgaW5maW5pdGUgKGlmIHNoYXBlPDEpIG9yIHplcm8gKGlmIHNoYXBlPjEpOyBpdCdzIGZpbml0ZSBvbmx5IGZvciBhbiBleHBvbmVudGlhbCBkaXN0cmlidXRpb24gKHNoYXBlPT0xKQotIExvZ25vcm1hbCBkaXN0cmlidXRpb246IHRoZSBwcm9iYWJpbGl0eSBkZW5zaXR5IGF0IHplcm8gaXMgemVyby4KLSBCZXRhIGRpc3RyaWJ1dGlvbjogdGhlIHByb2JhYmlsaXR5IGRlbnNpdGllcyBhdCAwIGFuZCAxIGFyZSB6ZXJvIChpZiB0aGUgY29ycmVzcG9uZGluZyBzaGFwZSBwYXJhbWV0ZXIgaXMgPjEpIG9yIGluZmluaXRlIChpZiBzaGFwZTwxKQoKVGhlIGJlc3Qgc29sdXRpb24gZGVwZW5kcyB2ZXJ5IG11Y2ggb24gdGhlIGRhdGEtZ2VuZXJhdGluZyBtZWNoYW5pc20uCgotIElmIHRoZSBiYWQgKDAvMSkgdmFsdWVzIGFyZSBnZW5lcmF0ZWQgYnkgcm91bmRpbmcgKGUuZy4gcHJvcG9ydGlvbnMgdGhhdCBhcmUgdG9vIGNsb3NlIHRvIHRoZSBib3VuZGFyaWVzIGFyZSByZXBvcnRlZCBhcyBiZWluZyBvbiB0aGUgYm91bmRhcmllcyksIHRoZSBzaW1wbGVzdCBzb2x1dGlvbiBpcyB0byAic3F1ZWV6ZSIgdGhlc2UgaW4gc2xpZ2h0bHksIGUuZy4gJHkgXHRvICh5ICthKS8yYSQgZm9yIHNvbWUgc2Vuc2libGUgdmFsdWUgb2YgJGEkIFtAc21pdGhzb25fYmV0dGVyXzIwMDZdCi0gSWYgeW91IHRoaW5rIHRoYXQgemVybyB2YWx1ZXMgYXJlIGdlbmVyYXRlZCBieSBhIHNlcGFyYXRlIHByb2Nlc3MsIHRoZSBzaW1wbGVzdCBzb2x1dGlvbiBpcyB0byBmaXQgYSBCZXJub3VsbGkgbW9kZWwgdG8gdGhlIHplcm8vbm9uLXplcm8gZGF0YSwgdGhlbiBhICpjb25kaXRpb25hbCogY29udGludW91cyBtb2RlbCBmb3IgdGhlIG5vbi16ZXJvIHZhbHVlczsgdGhpcyBpcyBlZmZlY3RpdmVseSBhICpodXJkbGUgbW9kZWwqLgotIHlvdSBtaWdodCBoYXZlICpjZW5zb3JlZCogZGF0YSB3aGVyZSBhbGwgdmFsdWVzIGJlbG93IGEgY2VydGFpbiBsaW1pdCAoZS5nLiBhIGRldGVjdGlvbiBsaW1pdCkgYXJlIHJlY29yZGVkIGFzIHplcm8uIFRoZSBUaGUgW2xtZWMgcGFja2FnZV0oaHR0cHM6Ly9DUkFOLlItcHJvamVjdC5vcmcvcGFja2FnZT1sbWVjKSBoYW5kbGVzICpsaW5lYXIqIG1peGVkIG1vZGVsczsgYGJybXNgIGFuZCBgR0xNTWFkYXB0aXZlYCBib3RoIHByb3ZpZGUgc3VwcG9ydCBmb3IgY2Vuc29yZWQgZGF0YSBpbiBtaXhlZCBtb2RlbHMuCi0gVGhlIGBjcGxtYCBhbmQgYGdsbW1UTUJgIHBhY2thZ2VzIGhhbmRsZXMgJ1R3ZWVkaWUgY29tcG91bmQgUG9pc3NvbiBsaW5lYXIgbW9kZWxzJywgd2hpY2ggaW4gYSBwYXJ0aWN1bGFyIHJhbmdlIG9mIHBhcmFtZXRlcnMgYWxsb3dzIGZvciBza2V3ZWQgY29udGludW91cyByZXNwb25zZXMgd2l0aCBhIHNwaWtlIGF0IHplcm8KCiMjIyMgUHJvYmFiaWxpdHkgZGVuc2l0eSBvZiAkeCQgcG9zaXRpdmUgYW5kIGZpbml0ZQoKSW4gdGhpcyBjYXNlIChlLmcuIGEgc3Bpa2Ugb2YgemVyb3MgaW4gdGhlIGNlbnRlciBvZiBhbiBvdGhlcndpc2UgY29udGludW91cyBkaXN0cmlidXRpb24pLCB0aGUgaHVyZGxlIG1vZGVsIHByb2JhYmx5IG1ha2VzIHRoZSBtb3N0IHNlbnNlLgoKIyMjIFRlc3RzIGZvciB6ZXJvLWluZmxhdGlvbgoKLSB5b3UgY2FuIHVzZSBhIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCBiZXR3ZWVuIHRoZSByZWd1bGFyIGFuZCB6ZXJvLWluZmxhdGVkIHZlcnNpb24gb2YgdGhlIG1vZGVsLCBidXQgYmUgYXdhcmUgb2YgYm91bmRhcnkgaXNzdWVzIChzZWFyY2ggImJvdW5kYXJ5IiBlbHNld2hlcmUgb24gdGhpcyBwYWdlIC4uLikgLS0gdGhlIG51bGwgdmFsdWUgKG5vIHplcm8gaW5mbGF0aW9uKSBpcyBvbiB0aGUgYm91bmRhcnkgb2YgdGhlIGZlYXNpYmxlIHNwYWNlCi0geW91IGNhbiB1c2UgQUlDIG9yIHZhcmlhdGlvbnMsIHdpdGggdGhlIHNhbWUgY2F2ZWF0cwotIHlvdSBjYW4gdXNlIFZ1b25nJ3MgdGVzdCwgd2hpY2ggaXMgb2Z0ZW4gcmVjb21tZW5kZWQgZm9yIHRlc3RpbmcgemVyby1pbmZsYXRpb24gaW4gR0xNcywgYmVjYXVzZSB1bmRlciBzb21lIGNpcmN1bXN0YW5jZXMgdGhlIHZhcmlvdXMgbW9kZWwgZmxhdm9ycyB1bmRlciBjb25zaWRlcmF0aW9uIChodXJkbGUgdnMgemVyby1pbmZsYXRlZCB2cyAidmFuaWxsYSIpIGFyZSBub3QgbmVzdGVkLiBWdW9uZydzIHRlc3QgaXMgaW1wbGVtZW50ZWQgKGFuZCByZWZlcmVuY2VkKSBpbiB0aGUgYHBzY2xgIHBhY2thZ2UsIGJ1dCBub3QgZm9yIChHKUxNTXMuIEhvd2V2ZXIsIHRoZSBgbm9ubmVzdGAgcGFja2FnZSBwcm92aWRlcyBhbiBleGFtcGxlIChpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSBgbWVyRGVyaXZgIHBhY2thZ2UpIGZvciB1c2luZyBpdHMgYHZ1b25ndGVzdGAgZnVuY3Rpb24gd2l0aCBgbWVyTW9kYCBvYmplY3RzLiAoTWF5IGFsc28gd29yayB3aXRoIGBnbG1tVE1CYCwgaGF2ZW4ndCB0cmllZCBpdCAuLi4pCi0gdHdvIHVudGVzdGVkIGJ1dCByZWFzb25hYmxlIGFwcHJvYWNoZXM6CiAgICAtICB1c2UgYSBgc2ltdWxhdGUoKWAgbWV0aG9kIGlmIGl0IGV4aXN0cyB0byBjb25zdHJ1Y3QgYSBzaW11bGF0ZWQgZGlzdHJpYnV0aW9uIG9mIHRoZSBwcm9wb3J0aW9uIG9mIHplcm9zIGV4cGVjdGVkIG92ZXJhbGwgZnJvbSB5b3VyIG1vZGVsLCBhbmQgY29tcGFyZSBpdCB0byB0aGUgb2JzZXJ2ZWQgcHJvcG9ydGlvbiBvZiB6ZXJvcyBpbiB0aGUgZGF0YSBzZXQKICAgIC0gY29tcHV0ZSB0aGUgcHJvYmFiaWxpdHkgb2YgYSB6ZXJvIGZvciBlYWNoIG9ic2VydmF0aW9uLiAgT24gdGhlIGJhc2lzIG9mIChjb25kaXRpb25hbGx5KSBpbmRlcGVuZGVudCBCZXJub3VsbGkgdHJpYWxzLCBjb21wdXRlIHRoZSBleHBlY3RlZCBudW1iZXIgb2YgemVyb3MgYW5kIHRoZSBjb25maWRlbmNlIGludGVydmFscyAtLSBjb21wYXJlIGl0IHdpdGggdGhlIG9ic2VydmVkIG51bWJlci4KCiMjIFNwYXRpYWwgYW5kIHRlbXBvcmFsIGNvcnJlbGF0aW9uIG1vZGVscywgaGV0ZXJvc2NlZGFzdGljaXR5ICgiUi1zaWRlIiBtb2RlbHMpCgpJbiBgbmxtZWAgdGhlc2Ugc28tY2FsbGVkICoqUi1zaWRlKiogKFIgZm9yICJyZXNpZHVhbCIpIHN0cnVjdHVyZXMgYXJlIGFjY2Vzc2libGUgdmlhIHRoZSBgd2VpZ2h0c2AvYFZhclN0cnVjdGAgKGhldGVyb3NjZWRhc3RpY2l0eSkgYW5kIGBjb3JyZWxhdGlvbmAvYGNvclN0cnVjdGAgKHNwYXRpYWwgb3IgdGVtcG9yYWwgY29ycmVsYXRpb24pIGFyZ3VtZW50cyBhbmQgZGF0YSBzdHJ1Y3R1cmVzLiBUaGlzIGV4dGVuc2lvbiBpcyBhIGJpdCBoYXJkZXIgdGhhbiBpdCBtaWdodCBzZWVtLiBJbiBMTU1zIGl0IGlzIGEgbmF0dXJhbCBleHRlbnNpb24gdG8gYWxsb3cgdGhlIHJlc2lkdWFsIGVycm9yIHRlcm1zIHRvIGJlIGNvbXBvbmVudHMgb2YgYSBzaW5nbGUgbXVsdGl2YXJpYXRlIG5vcm1hbCBkcmF3OyBpZiB0aGF0IE1WTiBkaXN0cmlidXRpb24gaXMgdW5jb3JyZWxhdGVkIGFuZCBob21vc2NlZGFzdGljIChpLmUuIHByb3BvcnRpb25hbCB0byBhbiBpZGVudGl0eSBtYXRyaXgpIHdlIGdldCB0aGUgY2xhc3NpYyBtb2RlbCwgYnV0IHdlIGNhbiBpbiBwcmluY2lwbGUgYWxsb3cgaXQgdG8gYmUgY29ycmVsYXRlZCBhbmQvb3IgaGV0ZXJvc2NlZGFzdGljLgoKSXQgaXMgbm90IHRvbyBoYXJkIHRvIGRlZmluZSBtYXJnaW5hbCBjb3JyZWxhdGlvbiBzdHJ1Y3R1cmVzIHRoYXQgZG9uJ3QgbWFrZSBzZW5zZS4gIE9uZSBjbGFzcyBvZiByZWFzb25hYmx5IHNlbnNpYmxlIG1vZGVscyBpcyB0byBhbHdheXMgYXNzdW1lIGFuIG9ic2VydmF0aW9uLWxldmVsIHJhbmRvbSBlZmZlY3QgKGFzIE1DTUNnbG1tIGRvZXMgZm9yIGNvbXB1dGF0aW9uYWwgcmVhc29ucykgYW5kIHRvIGFsbG93IHRoYXQgcmFuZG9tIGVmZmVjdCB0byBiZSBNVk4gb24gdGhlIGxpbmsgc2NhbGUgKHNvIHRoYXQgdGhlIGZ1bGwgbW9kZWwgaXMgbG9nbm9ybWFsLVBvaXNzb24sIGxvZ2l0LW5vcm1hbCBiaW5vbWlhbCwgZXRjLiwgZGVwZW5kaW5nIG9uIHRoZSBsaW5rIGZ1bmN0aW9uIGFuZCBmYW1pbHkpLgoKRm9yIGV4YW1wbGUsIGEgcmVsYXRpdmVseSBzaW1wbGUgUG9pc3NvbiBtb2RlbCB3aXRoIHNwYXRpYWxseSBjb3JyZWxhdGVkIGVycm9ycyBtaWdodCBsb29rIGxpa2UgdGhpczoKCiQkClxiZWdpbntzcGxpdH0KXGV0YSAmIFxzaW0gXHRleHRybXtNVk59KGEgKyBiIHgsIFxTaWdtYSkgXFwKXFNpZ21hX3tpan0gJiA9IFxzaWdtYV4yIFxleHAoLWRfe2lqfS9zKSBcXAp5X2kgJiBcc2ltIFx0ZXh0cm17UG9pc3Nvbn0oXGxhbWJkYT1cZXhwKFxldGFfaSkpClxlbmR7c3BsaXR9CiQkCgpUaGF0IGlzLCB0aGUgbWFyZ2luYWwgZGlzdHJpYnV0aW9ucyBvZiB0aGUgcmVzcG9uc2UgdmFsdWVzIGFyZSBQb2lzc29uLWxvZ25vcm1hbCwgYnV0IG9uIHRoZSBsaW5rIChsb2cpIHNjYWxlIHRoZSBsYXRlbnQgTm9ybWFsIHZhcmlhYmxlcyB1bmRlcmx5aW5nIHRoZSByZXNwb25zZSBhcmUgKm11bHRpdmFyaWF0ZSogbm9ybWFsLCB3aXRoIGEgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXggZGVzY3JpYmVkIGJ5IGFuIGV4cG9uZW50aWFsIHNwYXRpYWwgY29ycmVsYXRpb24gZnVuY3Rpb24gd2l0aCBzY2FsZSBwYXJhbWV0ZXIgJHMkLgoKSG93IGNhbiBvbmUgYWNoaWV2ZSB0aGlzPwoKLSBUaGVzZSB0eXBlcyBvZiBtb2RlbHMgYXJlIG5vdCBpbXBsZW1lbnRlZCBpbiBgbG1lNGAsIGZvciBlaXRoZXIgTE1NcyBvciBHTE1NczsgdGhleSBhcmUgZmFpcmx5IGxvdyBwcmlvcml0eSwgYW5kIGl0IGlzIGhhcmQgdG8gc2VlIGhvdyB0aGV5IGNvdWxkIGJlIGltcGxlbWVudGVkIGZvciBHTE1NcyAodGhlIGVxdWl2YWxlbnQgZm9yIExNTXMgaXMgdGVkaW91cyBidXQgc2hvdWxkIGJlIHN0cmFpZ2h0Zm9yd2FyZCB0byBpbXBsZW1lbnQpLgotIEZvciBMTU1zLCB5b3UgY2FuIHVzZSB0aGUgc3BhdGlhbC90ZW1wb3JhbCBjb3JyZWxhdGlvbiBzdHJ1Y3R1cmVzIHRoYXQgYXJlIGJ1aWx0IGludG8gKG4pbG1lCi0gWW91IGNhbiB1c2UgdGhlIHNwYXRpYWwvdGVtcG9yYWwgY29ycmVsYXRpb24gc3RydWN0dXJlcyBhdmFpbGFibGUgZm9yIChuKWxtZSwgd2hpY2ggaW5jbHVkZSBiYXNpYyBnZW9zdGF0aXN0aWNhbCAoc3BhY2UpIGFuZCBBUk1BLXR5cGUgKHRpbWUpIG1vZGVscy4gCmBgYHtyIGZpbmRjb3JzLGV2YWw9RkFMU0V9CmxpYnJhcnkoc29zKQpmaW5kRm4oImNvclN0cnVjdCIpCmBgYApmaW5kcyBhZGRpdGlvbmFsIHBvc3NpYmlsaXRpZXMgaW4gdGhlIGByYW1wc2AgKGV4dGVuZGVkIGdlb3N0YXRpc3RpY2FsKSBhbmQgYGFwZWAgKHBoeWxvZ2VuZXRpYykgcGFja2FnZXMuCgotIFlvdSBjYW4gdXNlIHRoZXNlIHN0cnVjdHVyZXMgaW4gR0xNTXMgdmlhIGBNQVNTOjpnbG1tUFFMYCAoc2VlIERvcm1hbm4gZXQgYWwuKQotIGdlZXBhY2s6OmdlZWdsbQotIGdlb1IsIGdlb1JnbG0gKHBvd2VyIHRvb2xzKTsgdGhlc2UgYXJlIG1vc3RseSBkZXNpZ25lZCBmb3IgZml0dGluZyBzcGF0aWFsIHJhbmRvbSBmaWVsZCBHTE1NcyB2aWEgTUNNQyAtLSBub3Qgc3VyZSB0aGF0IHRoZXkgZG8gcmFuZG9tIGVmZmVjdHMgb3RoZXIgdGhhbiB0aGUgc3BhdGlhbCByYW5kb20gZWZmZWN0Ci0gW1ItSU5MQV0oaHR0cDovL3ItaW5sYS5vcmcpIChzdXBlci1wb3dlciB0b29sKQotIGl0IGlzIHBvc3NpYmxlIHRvIHVzZSBBRCBNb2RlbCBCdWlsZGVyIHRvIGZpdCBzcGF0aWFsIEdMTU1zLCBhcyBzaG93biBpbiB0aGVzZSBbQUQgTW9kZWwgQnVpbGRlciBleGFtcGxlc10oaHR0cDovL2FkbWItcHJvamVjdC5vcmcvZXhhbXBsZXMvc3BhdGlhbC1tb2RlbHMpOyB0aGlzIGNhcGFiaWxpdHkgaXMgbm90IGluIHRoZSBgZ2xtbUFETUJgIHBhY2thZ2UgKGFuZCBtYXkgbm90IGJlIGZvciBhIHdoaWxlISksIGJ1dCBpdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBydW4gQUQgTW9kZWwgQnVpbGRlciB2aWEgdGhlIFIyYWRtYiBwYWNrYWdlIChyZXF1aXJlcyBpbnN0YWxsaW5nIC0tIGFuZCBsZWFybmluZyEgQURNQikKLSBbZ2VvQlVHU10oaHR0cDovL21hdGhzdGF0LmhlbHNpbmtpLmZpL29wZW5idWdzL01hbnVhbHMvR2VvQlVHUy9NYW51YWwuaHRtbCksIHRoZSBnZW9zdGF0aXN0aWNhbC9zcGF0aWFsIGNvcnJlbGF0aW9uIG1vZHVsZSBmb3IgV2luQlVHUywgaXMgYW5vdGhlciBhbHRlcm5hdGl2ZSAoYnV0IGFnYWluIHJlcXVpcmVzIGdvaW5nIG91dHNpZGUgb2YgUikKCiMjIFBlbmFsaXphdGlvbi9oYW5kbGluZyBjb21wbGV0ZSBzZXBhcmF0aW9uCgoqQ29tcGxldGUgc2VwYXJhdGlvbiogb2NjdXJzIGluIGEgYmluYXJ5LXJlc3BvbnNlIG1vZGVsIHdoZW4gdGhlcmUgaXMKc29tZSBsaW5lYXIgY29tYmluYXRpb24gb2YgdGhlIHBhcmFtZXRlcnMgdGhhdCBwZXJmZWN0bHkgc2VwYXJhdGVzIGZhaWx1cmVzCmZyb20gc3VjY2Vzc2VzIC0gZm9yIGV4YW1wbGUsIHdoZW4gYWxsIG9mIHRoZSBvYnNlcnZhdGlvbnMgYXJlIHplcm8KZm9yIHNvbWUgcGFydGljdWxhciBjb21iaW5hdGlvbiBvZiBjYXRlZ29yaWVzLiBUaGUgc3ltcHRvbXMgb2YgdGhpcwpwcm9ibGVtIGFyZSB1bnJlYWxpc3RpY2FsbHkgbGFyZ2UgcGFyYW1ldGVyIGVzdGltYXRlczsgcmlkaWN1bG91c2x5CmxhcmdlIFdhbGQgc3RhbmRhcmQgZXJyb3JzICh0aGUgKkhhdWNrLURvbm5lciBlZmZlY3QqKTsgYW5kIHZhcmlvdXMKd2FybmluZ3MuCgpJbiBwYXJ0aWN1bGFyLCBiaW5vbWlhbCBgZ2xtZXIoKWAgbW9kZWxzIHdpdGggY29tcGxldGUgc2VwYXJhdGlvbiBjYW4gbGVhZCB0bwoiRG93bmRhdGVkIFZ0ViBpcyBub3QgcG9zaXRpdmUgZGVmaW5pdGUiIChlLmcuIHNlZSBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL2xtZTQvbG1lNC9pc3N1ZXMvNDgzKSkgb3IgIlBJUkxTIHN0ZXAtaGFsdmluZ3MgZmFpbGVkIHRvIHJlZHVjZSBkZXZpYW5jZSBpbiBwd3Jzc1VwZGF0ZSIgZXJyb3JzIChlLmcuIHNlZSBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL2xtZTQvbG1lNC9pc3N1ZXMvMTc5I2lzc3VlY29tbWVudC00MjQ0NDUxODcpKS4gUm91Z2hseSBzcGVha2luZywgdGhlIGNvbXBsZXRlIHNlcGFyYXRpb24gaXMgbGlrZWx5IHRvIGFwcGVhciBldmVuIGlmIG9uZSBjb25zaWRlcnMgb25seSB0aGUgZml4ZWQgZWZmZWN0cyBwYXJ0IG9mIHRoZSBtb2RlbCAoY291bnRlcmFyZ3VtZW50cyBvciBjb3VudGVyZXhhbXBsZXMgd2VsY29tZSEpLCBzdWdnZXN0aW5nIHR3byBxdWljay1hbmQtZGlydHkgZGlhZ25vc3RpYyBtZXRob2RzLiBJZiBgZml4ZWRfZm9ybWAgaXMgdGhlIGZvcm11bGEgaW5jbHVkaW5nIG9ubHkgdGhlIGZpeGVkIGVmZmVjdHM6CgotIGBzdW1tYXJ5KGcxIDwtIGdsbShmaXhlZF9mb3JtLCBmYW1pbHk9Ymlub21pYWwsIGRhdGE9Li4uKSlgIHdpbGwgc2hvdyBvbmUgb3IgbW9yZSBvZiB0aGUgZm9sbG93aW5nIHN5bXB0b21zOgogICAgIC0gd2FybmluZ3MgdGhhdCBgZ2xtLmZpdDogZml0dGVkIHByb2JhYmlsaXRpZXMgbnVtZXJpY2FsbHkgMCBvciAxIG9jY3VycmVkYAogICAgIC0gcGFyYW1ldGVyIGVzdGltYXRlcyBvZiBsYXJnZSBtYWduaXR1ZGUgKGUuZy4gYGFueShhYnMoZzEkY29lZmZpY2llbnRzKT44KWAsIGFzc3VtaW5nIHRoYXQgcHJlZGljdG9ycyBhcmUgZWl0aGVyIGNhdGVnb3JpY2FsIG9yIHNjYWxlZCB0byBoYXZlIHN0YW5kYXJkIGRldmlhdGlvbnMgb2YgJFxhcHByb3ggMSQpCgkgLSBleHRyZW1lbHkgbGFyZ2UgV2FsZCBzdGFuZGFyZCBlcnJvcnMsIGFuZCBsYXJnZSBwLXZhbHVlcyAoKkhhdWNrLURvbm5lciBlZmZlY3QqKQoJIC0gdGhlIGBkZXRlY3RzZXBhcmF0aW9uYCBwYWNrYWdlIGhhcyBhIG1ldGhvZCBmb3IgZGV0ZWN0aW5nIGNvbXBsZXRlIHNlcGFyYXRpb246IGBsaWJyYXJ5KCJkZXRlY3RzZXBhcmF0aW9uIik7IHVwZGF0ZShnMSxtZXRob2Q9ImRldGVjdF9zZXBhcmF0aW9uIilgLiBUaGlzIHNob3VsZCBzYXkgd2hldGhlciBjb21wbGV0ZSBzZXBhcmF0aW9uIG9jY3VycywgYW5kIGluIHdoaWNoIChjb21iaW5hdGlvbnMgb2YpIHZhcmlhYmxlcywgZS5nLgoKYGBgClNlcGFyYXRpb246IFRSVUUgCkV4aXN0ZW5jZSBvZiBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGVzCihJbnRlcmNlcHQpICAgICAgaGVpZ2h0IAogICAgICAgIEluZiAgICAgICAgIEluZiAKMDogZmluaXRlIHZhbHVlLCBJbmY6IGluZmluaXR5LCAtSW5mOiAtaW5maW5pdHkKYGBgCgpJZiBjb21wbGV0ZSBzZXBhcmF0aW9uIGlzIG9jY3VycmluZyBiZXR3ZWVuIGNhdGVnb3JpZXMgb2YgYSBzaW5nbGUgY2F0ZWdvcmljYWwgZml4ZWQtZWZmZWN0IHByZWRpY3RvciB3aXRoIGEgbGFyZ2UgbnVtYmVyIG9mIGxldmVscywgb25lIG9wdGlvbiB3b3VsZCBiZSB0byB0cmVhdCB0aGlzIGZpeGVkIGVmZmVjdCBhcyBhIHJhbmRvbSBlZmZlY3QsIHdoaWNoIHdpbGwgYWxsb3cgc29tZSBkZWdyZWUgb2Ygc2hyaW5rYWdlIHRvIHRoZSBtZWFuLiAoSXQgbWlnaHQgYmUgcmVhc29uYWJsZSB0byBzcGVjaWZ5IHRoZSB2YXJpYW5jZSBvZiB0aGlzIHRlcm0gKmEgcHJpb3JpKiB0byBhIGxhcmdlIHZhbHVlIFttaW5pbWFsIHNocmlua2FnZV0sIHJhdGhlciB0aGFuIHRyeWluZyB0byBlc3RpbWF0ZSBpdCBmcm9tIHRoZSBkYXRhLikKCigqKlRPRE8qKjogd29ya2VkIGV4YW1wbGUpCgpUaGUgZ2VuZXJhbCBhcHByb2FjaCB0byBoYW5kbGluZyBjb21wbGV0ZSBzZXBhcmF0aW9uIGluIGxvZ2lzdGljIHJlZ3Jlc3Npb24KaXMgY2FsbGVkICpwZW5hbGl6ZWQgcmVncmVzc2lvbio7IGl0J3MgYXZhaWxhYmxlIGluIHRoZSBgYnJnbG1gLApgYnJnbG0yYCwgYGxvZ2lzdGZgLCBhbmQgYHJtc2AgcGFja2FnZXMuIEhvd2V2ZXIsIHRoZXNlIHBhY2thZ2VzCmRvbid0IGhhbmRsZSBtaXhlZCBtb2RlbHMsIHNvIHRoZSBiZXN0IGF2YWlsYWJsZSAqZ2VuZXJhbCogYXBwcm9hY2ggaXMgdG8KdXNlIGEgQmF5ZXNpYW4gbWV0aG9kIHRoYXQgYWxsb3dzIHlvdSB0byBzZXQgYSBwcmlvciBvbiB0aGUgZml4ZWQgZWZmZWN0cywKZS5nLiBhIEdhdXNzaWFuIHdpdGggc3RhbmRhcmQgZGV2aWF0aW9uIG9mIDM7IHRoaXMgY2FuIGJlIGRvbmUKaW4gYW55IG9mIHRoZSBCYXllc2lhbiBHTE1NIHBhY2thZ2VzIChlLmcuIGBibG1lYCwgYE1DTUNnbG1tYCwgYGJybXNgLCAuLi4pCihTZWUgW3N1cHBsZW1lbnRhcnkgbWF0ZXJpYWwgZm9yIEZveCBldCBhbC4gMjAxNl0oaHR0cDovL2Jib2xrZXIuZ2l0aHViLmlvL21peGVkbW9kZWxzLW1pc2MvZWNvc3RhdHNfY2hhcC5odG1sI2RpZ3Jlc3Npb24tY29tcGxldGUtc2VwYXJhdGlvbikgZm9yIGEgd29ya2VkIGV4YW1wbGUuKQoKIyMgTm9uLUdhdXNzaWFuIHJhbmRvbSBlZmZlY3RzCgpJJ20gbm90IGF3YXJlIG9mIGVhc3kgd2F5cyB0byBmaXQgbWl4ZWQgbW9kZWxzIHdpdGggbm9uLUdhdXNzaWFuIHJhbmRvbSBlZmZlY3RzIGRpc3RyaWJ1dGlvbnMgaW4gUiAoaS5lLiwgY29udmVuaWVudCwgZmxleGlibGUsIHdlbGwtdGVzdGVkIGltcGxlbWVudGF0aW9ucykuIEBtY2N1bGxvY2hfbWlzc3BlY2lmeWluZ18yMDExIGRpc2N1c3NlcyB3aGVuIHRoaXMgbWlzc3BlY2lmaWNhdGlvbiBtYXkgYmUgaW1wb3J0YW50LiBbVGhpcyBwcmVzZW50YXRpb25dKGh0dHBzOi8vbmlhc3JhLnVvdy5lZHUuYXUvY29udGVudC9ncm91cHMvcHVibGljL0B3ZWIvQGluZi9AbWF0aC9kb2N1bWVudHMvbW0vdW93MjM2Mjk2LnBkZikgZGlzY3Vzc2VzIHZhcmlvdXMgYXBwcm9hY2hlcyB0byBzb2x2aW5nIHRoZSBwcm9ibGVtIChlLmcuIHVzaW5nIGEgR2FtbWEgcmF0aGVyIHRoYW4gYSBOb3JtYWwgZGlzdHJpYnV0aW9uIG9mIFJFcyBpbiBsb2ctbGluayAgbW9kZWxzKS4gVGhlIGBzcGFNTWAgcGFja2FnZSBpbXBsZW1lbnRzIEgtbGlrZWxpaG9vZCBtb2RlbHMgW0BsZWVfZ2VuZXJhbGl6ZWRfMjAxN10sIGFuZCBjbGFpbXMgdG8gYWxsb3cgYSByYW5nZSBvZiByYW5kb20tZWZmZWN0cyBkaXN0cmlidXRpb25zIChwZXJoYXBzIG5vdCB3ZWxsIHRlc3RlZCB0aG91Z2ggLi4uKQoKSW4gcHJpbmNpcGxlIHlvdSBjYW4gaW1wbGVtZW50IGFueSByYW5kb20tZWZmZWN0cyBkaXN0cmlidXRpb24geW91IHdhbnQgaW4gYSBmdWxseSBjYXBhYmxlIEJheWVzaWFuIG1vZGVsaW5nIGxhbmd1YWdlIChlLmcuIEpBR1MvU3Rhbi9QeU1DL2V0Yy4pOyBzZWUgZS5nLiBbdGhpcyBTdGFja092ZXJmbG93IGFuc3dlcl0oaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDU2NTY3MTQvdXNlci1kZWZpbmVkLXJhbmRvbS1pbnRlcmNlcHQtZGlzdHJpYnV0aW9uLWZvci1nbG1lciksIHdoaWNoIHVzZXMgdGhlIGByZXRoaW5raW5nYCBwYWNrYWdlJ3MgaW50ZXJmYWNlIHRvIFN0YW4uCgojIEVzdGltYXRpb24gCgojIyBXaGF0IG1ldGhvZHMgYXJlIGF2YWlsYWJsZSB0byBmaXQgKGVzdGltYXRlKSBHTE1Ncz8KCihhZGFwdGVkIGZyb20gQm9sa2VyIGV0IGFsIFRSRUUgMjAwOSkKCmBgYHtyIGdsbW10YWIsZWNobz1GQUxTRSxyZXN1bHRzPSJhc2lzIn0KbWV0aHRhYiA8LSByZWFkLnRhYmxlKHNlcD0ifCIsaGVhZGVyPVRSVUUsdGV4dD0iCk1ldGhvZCB8IEFkdmFudGFnZXMgfCBEaXNhZHZhbnRhZ2VzIHwgUGFja2FnZXMKUGVuYWxpemVkIHF1YXNpLWxpa2VsaWhvb2QgfCBGbGV4aWJsZSwgd2lkZWx5IGltcGxlbWVudGVkIHwgTGlrZWxpaG9vZCBpbmZlcmVuY2UgbWF5IGJlIGluYXBwcm9wcmlhdGU7IGJpYXNlZCBmb3IgbGFyZ2UgdmFyaWFuY2Ugb3Igc21hbGwgbWVhbnMgfCBQUk9DIEdMSU1NSVggKFNBUyksIEdMTU0gKEdlblN0YXQpLCBnbG1tUFFMIChSOk1BU1MpLCBBU1JFTUwtUgpMYXBsYWNlIGFwcHJveGltYXRpb24gfCBNb3JlIGFjY3VyYXRlIHRoYW4gUFFMIHwgU2xvd2VyIGFuZCBsZXNzIGZsZXhpYmxlIHRoYW4gUFFMIHwgZ2xtZXIgKFI6bG1lNCxsbWU0YSksIGdsbW0uYWRtYiAoUjpnbG1tQURNQiksIElOTEEsIGdsbW1UTUIsIEFEIE1vZGVsIEJ1aWxkZXIsIEhMTSAKR2F1c3MtSGVybWl0ZSBxdWFkcmF0dXJlIHwgTW9yZSBhY2N1cmF0ZSB0aGFuIExhcGxhY2UgfCBTbG93ZXIgdGhhbiBMYXBsYWNlOyBsaW1pdGVkIHRvIDLigJEzIHJhbmRvbSBlZmZlY3RzIHwgUFJPQyBOTE1JWEVEIChTQVMpLCBnbG1lciAoUjpsbWU0LCBsbWU0YSksIGdsbW1NTCAoUjpnbG1tTUwpLCB4dGxvZ2l0IChTdGF0YSkKTWFya292IGNoYWluIE1vbnRlIENhcmxvIHwgSGlnaGx5IGZsZXhpYmxlLCBhcmJpdHJhcnkgbnVtYmVyIG9mIHJhbmRvbSBlZmZlY3RzOyBhY2N1cmF0ZSB8IFNsb3csIHRlY2huaWNhbGx5IGNoYWxsZW5naW5nLCBCYXllc2lhbiBmcmFtZXdvcmsgfCBNQ01DZ2xtbSAoUjpNQ01DZ2xtbSksIHJzdGFuYXJtIChSKSwgYnJtcyAoUiksIE1DTUNwYWNrIChSKSwgV2luQlVHUy9PcGVuQlVHUyAoUiBpbnRlcmZhY2U6IEJSdWdzL1IyV2luQlVHUyksIEpBR1MgKFIgaW50ZXJmYWNlOiByamFncy9SMmphZ3MpLCBBRCBNb2RlbCBCdWlsZGVyIChSIGludGVyZmFjZTogUjJhZG1iKSwgZ2xtbS5hZG1iIChwb3N0IGhvYyBNQ01DIGFmdGVyIExhcGxhY2UgZml0KSAoUjpnbG1tQURNQikiCikKc2V0LmFsaWdubWVudChkZWZhdWx0PSJsZWZ0IikKcGFuZGVyKG1ldGh0YWIsc3BsaXQudGFibGU9SW5mKQpgYGAKCiMjIFRyb3VibGVzaG9vdGluZwoKLSBkb3VibGUtY2hlY2sgdGhlIG1vZGVsIHNwZWNpZmljYXRpb24gYW5kIHRoZSBkYXRhIGZvciBtaXN0YWtlcwotIGNlbnRlciBhbmQgc2NhbGUgY29udGludW91cyBwcmVkaWN0b3IgdmFyaWFibGVzIChlLmcuIHdpdGggYHNjYWxlKClgKQotIHRyeSBhbGwgYXZhaWxhYmxlIG9wdGltaXplcnMgKGUuZy4gc2V2ZXJhbCBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb25zIG9mIEJPQllRQSBhbmQgTmVsZGVyLU1lYWQsIEwtQkZHUy1CIGZyb20gIGBvcHRpbWAsIGBubG1pbmIoKWAsIC4uLikuICBXaGlsZSB0aGlzIHdpbGwgb2YgY291cnNlIGJlIHNsb3cgZm9yIGxhcmdlIGZpdHMsIHdlIGNvbnNpZGVyIGl0IHRoZSBnb2xkIHN0YW5kYXJkOyBpZiBhbGwgb3B0aW1pemVycyBjb252ZXJnZSB0byB2YWx1ZXMgdGhhdCBhcmUgcHJhY3RpY2FsbHkgZXF1aXZhbGVudCAoaXQncyB1cCB0byB0aGUgdXNlciB0byBkZWNpZGUgd2hhdCAicHJhY3RpY2FsbHkgZXF1aXZhbGVudCBtZWFucyBmb3IgdGhlaXIgY2FzZSIpLCB0aGVuIHdlIHdvdWxkIGNvbnNpZGVyIHRoZSBtb2RlbCBmaXQgdG8gYmUgZ29vZCBlbm91Z2guIEZvciBleGFtcGxlOgpgYGB7ciBhbGxmaXQsZXZhbD1GQUxTRX0KbW9kZWxmaXQuYWxsIDwtIGxtZTQ6OmFsbEZpdChtb2RlbCkKc3MgPC0gc3VtbWFyeShtb2RlbGZpdC5hbGwpCmBgYAoKIyMjIENvbnZlcmdlbmNlIHdhcm5pbmdzCgpNb3N0IG9mIHRoZSBjdXJyZW50IGFkdmljZSBhYm91dCB0cm91Ymxlc2hvb3RpbmcgYGxtZTRgIGNvbnZlcmdlbmNlIHByb2JsZW1zIGNhbiBiZSBmb3VuZCBpbiB0aGUgaGVscCBwYWdlIGA/Y29udmVyZ2VuY2VgLiBUaGF0IHBhZ2UgZXhwbGFpbnMgdGhhdCB0aGUgY29udmVyZ2VuY2UgdGVzdHMgaW4gdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBgbG1lNGAgKDEuMS0xMSwgRmVicnVhcnkgMjAxNikgZ2VuZXJhdGUgbG90cyBvZiBmYWxzZSBwb3NpdGl2ZXMuIFdlIGFyZSBjb25zaWRlcmluZyByYWlzaW5nIHRoZSBncmFkaWVudCB3YXJuaW5nIHRocmVzaG9sZCB0byAwLjAxIGluIGZ1dHVyZSByZWxlYXNlcyBvZiBgbG1lNGAuIEluIGFkZGl0aW9uIHRvIHRoZSBnZW5lcmFsIHRyb3VibGVzaG9vdGluZyB0aXBzIGFib3ZlOgoKLSBkb3VibGUtY2hlY2sgdGhlIEhlc3NpYW4gY2FsY3VsYXRpb24gd2l0aCB0aGUgbW9yZSBleHBlbnNpdmUgUmljaGFyZHNvbiBleHRyYXBvbGF0aW9uIG1ldGhvZCAoc2VlIGV4YW1wbGVzKQotIHJlc3RhcnQgdGhlIGZpdCBmcm9tIHRoZSBhcHBhcmVudCBvcHRpbXVtLCBvciBmcm9tIGEgcG9pbnQgcGVydHVyYmVkIHNsaWdodGx5IGF3YXkgZnJvbSB0aGUgb3B0aW11bSAoYGdldE1FKG1vZGVsLGMoInRoZXRhIiwiYmV0YSIpKWAgc2hvdWxkIHJldHJpZXZlIHRoZSBwYXJhbWV0ZXJzIGluIGEgZm9ybSBzdWl0YWJsZSB0byBiZSB1c2VkIGFzIHRoZSBgc3RhcnRgIHBhcmFtZXRlcikKLSBhIGNvbW1vbiBlcnJvciBpcyB0byBzcGVjaWZ5IGFuIG9mZnNldCB0byBhIGxvZy1saW5rIG1vZGVsIGFzIGEgcmF3IHNlYXJjaGluZy1lZmZvcnQgdmFsdWUsIGkuZS4gYG9mZnNldChlZmZvcnQpYCByYXRoZXIgdGhhbiBgb2Zmc2V0KGxvZyhlZmZvcnQpKWAuIFdoaWxlIHRoZSBpbnRlbnRpb24gaXMgdG8gZml0IGEgbW9kZWwgd2hlcmUgJFx0ZXh0cm17Y291bnRzfSBccHJvcHRvIFx0ZXh0cm17ZWZmb3J0fSQsIHNwZWNpZnlpbmcgYG9mZnNldChlZmZvcnQpYCBsZWFkcyB0byBhIG1vZGVsIHdoZXJlICRcdGV4dHJte2NvdW50c30gXHByb3B0byBcZXhwKFx0ZXh0cm17ZWZmb3J0fSkkIGluc3RlYWQ7IGBleHAoZWZmb3J0KWAgaXMgb2Z0ZW4gYSBodWdlIChhbmQgbW9kZWwtZGVzdGFiaWxpemluZykgbnVtYmVyLgoKPGEgaWQ9InNpbmd1bGFyLWZpdCI+PC9hPgo8YSBpZD0iemVyby12YXJpYW5jZSI+PC9hPgoKIyMjIFNpbmd1bGFyIG1vZGVsczogcmFuZG9tIGVmZmVjdCB2YXJpYW5jZXMgZXN0aW1hdGVkIGFzIHplcm8sIG9yIGNvcnJlbGF0aW9ucyBlc3RpbWF0ZWQgYXMgKy8tIDEKCkl0IGlzIHZlcnkgY29tbW9uIGZvciBvdmVyZml0dGVkIG1peGVkIG1vZGVscyB0byByZXN1bHQgaW4gc2luZ3VsYXIgZml0cy4gVGVjaG5pY2FsbHksIHNpbmd1bGFyaXR5IG1lYW5zIHRoYXQgc29tZSBvZiB0aGUgJFxib2xkc3ltYm9sIFx0aGV0YSQgKHZhcmlhbmNlLWNvdmFyaWFuY2UgQ2hvbGVza3kgZGVjb21wb3NpdGlvbikgcGFyYW1ldGVycyBjb3JyZXNwb25kaW5nIHRvIGRpYWdvbmFsIGVsZW1lbnRzIG9mIHRoZSBDaG9sZXNreSBmYWN0b3IgYXJlIGV4YWN0bHkgemVybywgd2hpY2ggaXMgdGhlIGVkZ2Ugb2YgdGhlIGZlYXNpYmxlIHNwYWNlLCBvciBlcXVpdmFsZW50bHkgdGhhdCB0aGUgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXggaGFzIHNvbWUgemVybyBlaWdlbnZhbHVlcyAoaS5lLiBpcyBwb3NpdGl2ZSBzZW1pZGVmaW5pdGUgcmF0aGVyIHRoYW4gcG9zaXRpdmUgZGVmaW5pdGUpLCBvciAoKmFsbW9zdCogZXF1aXZhbGVudGx5KSB0aGF0IHNvbWUgb2YgdGhlIHZhcmlhbmNlcyBhcmUgZXN0aW1hdGVkIGFzIHplcm8gb3Igc29tZSBvZiB0aGUgY29ycmVsYXRpb25zIGFyZSBlc3RpbWF0ZWQgYXMgKy8tMS4gVGhpcyBjb21tb25seSBvY2N1cnMgaW4gdHdvIHNjZW5hcmlvczoKCi0gc21hbGwgbnVtYmVycyBvZiByYW5kb20tZWZmZWN0IGxldmVscyAoZS5nLiA8NSksIGFzIGlsbHVzdHJhdGVkIGluIFt0aGVzZSBzaW11bGF0aW9uc10oaHR0cDovL3JwdWJzLmNvbS9iYm9sa2VyLzQxODcpIGFuZCBkaXNjdXNzZWQgKGluIGEgc29tZXdoYXQgZGlmZmVyZW50LCBCYXllc2lhbiBjb250ZXh0KSBieSBAZ2VsbWFuX3ByaW9yXzIwMDYuCi0gY29tcGxleCByYW5kb20tZWZmZWN0cyBtb2RlbHMsIGUuZy4gbW9kZWxzIG9mIHRoZSBmb3JtIGAoZnxnKWAgd2hlcmUgYGZgIGlzIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUgd2l0aCBhIHJlbGF0aXZlbHkgbGFyZ2UgbnVtYmVyIG9mIGxldmVscywgb3IgbW9kZWxzIHdpdGggc2V2ZXJhbCBkaWZmZXJlbnQgcmFuZG9tLXNsb3BlcyB0ZXJtcy4KCi0gV2hlbiB1c2luZyBgbG1lNGAsIHNpbmd1bGFyaXR5IGlzIG1vc3Qgb2J2aW91c2x5IGRldGVjdGFibGUgaW4gdGhlIG91dHB1dCBvZiBgc3VtbWFyeS5tZXJNb2QoKWAgb3IgYFZhckNvcnIubWVyTW9kKClgIHdoZW4gYSB2YXJpYW5jZSBpcyBlc3RpbWF0ZWQgYXMgMCAob3IgdmVyeSBzbWFsbCwgaS5lLiBvcmRlcnMgb2YgbWFnbml0dWRlIHNtYWxsZXIgdGhhbiBvdGhlciB2YXJpYW5jZSBjb21wb25lbnRzKSBvciB3aGVuIGEgY29ycmVsYXRpb24gaXMgZXN0aW1hdGVkIGFzIGV4YWN0bHkgJFxwbSAxJC4gSG93ZXZlciwgYXMgcG9pbnRlZCBvdXQgYnkgQGJhdGVzX3BhcnNpbW9uaW91c18yMDE1LCBzaW5ndWxhcml0aWVzIGluIGxhcmdlciB2YXJpYW5jZS1jb3ZhcmlhbmNlIG1hdHJpY2VzIGNhbiBiZSBoYXJkIHRvIGRldGVjdDogY2hlY2tpbmcgZm9yIHNtYWxsIHZhbHVlcyBhbW9uZyB0aGUgZGlhZ29uYWwgZWxlbWVudHMgb2YgdGhlIENob2xlc2t5IGZhY3RvciBpcyBhIGdvb2Qgc3RhcnQuCmBgYHtyIHNpbmcsZXZhbD1GQUxTRX0KdGhldGEgPC0gZ2V0TUUobW9kZWwsInRoZXRhIikKIyMgZGlhZ29uYWwgZWxlbWVudHMgYXJlIGlkZW50aWZpYWJsZSBiZWNhdXNlIHRoZXkgYXJlIGZpdHRlZAojIyAgd2l0aCBhIGxvd2VyIGJvdW5kIG9mIHplcm8gLi4uCmRpYWcuZWxlbWVudCA8LSBnZXRNRShtb2RlbCwibG93ZXIiKT09MAphbnkodGhldGFbZGlhZy5lbGVtZW50XTwxZS01KQpgYGAKQXMgb2YgYGxtZTRgIHZlcnNpb24gMS4xLTE5LCB0aGlzIGZ1bmN0aW9uYWxpdHkgaXMgYXZhaWxhYmxlIGFzIGBpc1Npbmd1bGFyKG1vZGVsKWAuCi0gSW4gYE1DTUNnbG1tYCwgc2luZ3VsYXIgb3IgbmVhci1zaW5ndWxhciBtb2RlbHMgd2lsbCBwcm92b2tlIGFuIGVycm9yIGFuZCBhIHJlcXVpcmVtZW50IHRvIHNwZWNpZnkgYSBzdHJvbmdlciBwcmlvci4KCkF0IHByZXNlbnQgdGhlcmUgYXJlIGEgdmFyaWV0eSBvZiBzdHJvbmcgb3BpbmlvbnMgYWJvdXQgaG93IHRvIHJlc29sdmUgc3VjaCBwcm9ibGVtcy4gQnJpZWZseToKCi0gQGJhcnJfcmFuZG9tXzIwMTMgc3VnZ2VzdCBhbHdheXMgc3RhcnRpbmcgd2l0aCB0aGUgbWF4aW1hbCBtb2RlbCAoaS5lLiB0aGUgbW9zdCByYW5kb20tZWZmZWN0cyBjb21wb25lbnQgb2YgdGhlIG1vZGVsIHRoYXQgaXMgKnRoZW9yZXRpY2FsbHkqIGlkZW50aWZpYWJsZSBnaXZlbiB0aGUgZXhwZXJpbWVudGFsIGRlc2lnbikgYW5kIHRoZW4gZHJvcHBpbmcgdGVybXMgd2hlbiBzaW5ndWxhcml0eSBvciBub24tY29udmVyZ2VuY2Ugb2NjdXJzIChwbGVhc2Ugc2VlIHRoZSBwYXBlciBmb3IgZGV0YWlsZWQgcmVjb21tZW5kYXRpb25zIC4uLikKLSBAbWF0dXNjaGVrX2JhbGFuY2luZ18yMDE3IGFuZCBAYmF0ZXNfcGFyc2ltb25pb3VzXzIwMTUgc3Ryb25nbHkgZGlzYWdyZWUsIHN1Z2dlc3RpbmcgdGhhdCBtb2RlbHMgc2hvdWxkIGJlIHNpbXBsaWZpZWQgKmEgcHJpb3JpKiB3aGVuZXZlciBwb3NzaWJsZTsgdGhleSBhbHNvIHByb3ZpZGUgW3Rvb2xzXShodHRwczovL2dpdGh1Yi5jb20vZG1iYXRlcy9SZVBzeWNoTGluZykgZm9yIGRpYWdub3NpbmcgYW5kIG1pdGlnYXRpbmcgc2luZ3VsYXJpdHkuCi0gT25lIGFsdGVybmF0aXZlIChzdWdnZXN0ZWQgYnkgUm9iZXJ0IExhQnVkZGUpIGZvciB0aGUgc21hbGwtbnVtYmVycy1vZi1sZXZlbHMgc2NlbmFyaW8gaXMgdG8gImZpdCB0aGUgbW9kZWwgd2l0aCB0aGUgcmFuZG9tIGZhY3RvciBhcyBhIGZpeGVkIGVmZmVjdCwgZ2V0IHRoZSBsZXZlbCBjb2VmZmljaWVudHMgaW4gdGhlIHN1bSB0byB6ZXJvIGZvcm0sIGFuZCB0aGVuIGNvbXB1dGUgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgY29lZmZpY2llbnRzLiIgVGhpcyBpcyBhcHByb3ByaWF0ZSBmb3IgdXNlcnMgd2hvIGFyZSAoYSkgcHJpbWFyaWx5IGludGVyZXN0ZWQgaW4gbWVhc3VyaW5nIHZhcmlhdGlvbiAoaS5lLiB0aGUgcmFuZG9tIGVmZmVjdHMgYXJlIG5vdCBqdXN0IG51aXNhbmNlIHBhcmFtZXRlcnMsIGFuZCB0aGUgdmFyaWFiaWxpdHkgW3JhdGhlciB0aGFuIHRoZSBlc3RpbWF0ZWQgdmFsdWVzIGZvciBlYWNoIGxldmVsXSBpcyBvZiBzY2llbnRpZmljIGludGVyZXN0KSwgKGIpIHVuYWJsZSBvciB1bndpbGxpbmcgdG8gdXNlIG90aGVyIGFwcHJvYWNoZXMgKGUuZy4gTUNNQyB3aXRoIGhhbGYtQ2F1Y2h5IHByaW9ycyBpbiBXaW5CVUdTKSwgKGMpIHVuYWJsZSBvciB1bndpbGxpbmcgdG8gY29sbGVjdCBtb3JlIGRhdGEuIEZvciB0aGUgc2ltcGxlc3QgY2FzZSAoYmFsYW5jZWQsIG9ydGhvZ29uYWwsIG5lc3RlZCBkZXNpZ25zIHdpdGggbm9ybWFsIGVycm9ycykgdGhlc2UgZXN0aW1hdGVzIG9mIHN0YW5kYXJkIGRldmlhdGlvbnMgc2hvdWxkIGVxdWFsIHRoZSBjbGFzc2ljYWwgbWV0aG9kLW9mLW1vbWVudHMgZXN0aW1hdGVzLgotIEJheWVzaWFuIGFwcHJvYWNoZXMgYWxsb3cgdGhlIHVzZXIgdG8gc3BlY2lmeSBhIGluZm9ybWF0aXZlIHByaW9yIHRoYXQgYXZvaWRzIHNpbmd1bGFyaXR5LgogICAgLSBUaGUgYGJsbWVgIHBhY2thZ2UgW0BjaHVuZ19ub25kZWdlbmVyYXRlXzIwMTNdIHByb3ZpZGVzIGEgd3JhcHBlciBmb3IgdGhlIGBsbWU0YCBtYWNoaW5lcnkgdGhhdCBhZGRzIGEgcGFydGljdWxhciBmb3JtIG9mIHdlYWsgcHJpb3IgdG8gZ2V0IGFuIGFwcHJveGltYXRlIGEgQmF5ZXNpYW4gbWF4aW11bSAqYSBwb3N0ZXJpb3JpKiBlc3RpbWF0ZSB0aGF0IGF2b2lkcyBzaW5ndWxhcml0eS4KICAgIC0gVGhlIGBNQ01DZ2xtbWAgcGFja2FnZSBhbGxvd3MgZm9yIHByaW9ycyBvbiB0aGUgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXgKCS0gVGhlIGByc3RhbmFybWAgYW5kIGBicm1zYCBwYWNrYWdlcyBwcm92aWRlIHdyYXBwZXJzIGZvciB0aGUgU3RhbiBIYW1pbHRvbmlhbiBNQ01DIGVuZ2luZSB0aGF0IGZpdCBHTE1NcyB2aWEgYGxtZTRgIHN5bnRheCwgYWdhaW4gYWxsb3dpbmcgYSB2YXJpZXR5IG9mIHByaW9ycyB0byBiZSBzZXQuCi0gSWYgYSB2YXJpYW5jZSBjb21wb25lbnQgaXMgemVybywgZHJvcHBpbmcgaXQgZnJvbSB0aGUgbW9kZWwgd2lsbCBoYXZlIG5vIGVmZmVjdCBvbiBhbnkgb2YgdGhlIGVzdGltYXRlZCBxdWFudGl0aWVzIChhbHRob3VnaCBpdCB3aWxsIGFmZmVjdCB0aGUgQUlDLCBhcyB0aGUgdmFyaWFuY2UgcGFyYW1ldGVyIGlzIGNvdW50ZWQgZXZlbiB0aG91Z2ggaXQgaGFzIG5vIGVmZmVjdCkuIEBwYXNjaF9pbnRlcnNwZWNpZmljXzIwMTMgZ2l2ZXMgb25lIGV4YW1wbGUgd2hlcmUgcmFuZG9tIGVmZmVjdHMgd2VyZSBkcm9wcGVkIGJlY2F1c2UgdGhlIHZhcmlhbmNlIGNvbXBvbmVudHMgd2VyZSBjb25zaXN0ZW50bHkgZXN0aW1hdGVkIGFzIHplcm8uIENvbnZlcnNlbHksIGlmIG9uZSBjaG9vc2VzIGZvciBwaGlsb3NvcGhpY2FsIGdyb3VuZHMgdG8gcmV0YWluIHRoZXNlIHBhcmFtZXRlcnMsIGl0IHdvbid0IGNoYW5nZSBhbnkgb2YgdGhlIGFuc3dlcnMuCgojIyMgU2V0dGluZyByZXNpZHVhbCB2YXJpYW5jZXMgdG8gYSBmaXhlZCB2YWx1ZSAoemVybyBvciBvdGhlcikKCkZvciBzb21lIHByb2JsZW1zIGl0IHdvdWxkIGJlIGNvbnZlbmllbnQgdG8gYmUgYWJsZSB0byBzZXQgdGhlIHJlc2lkdWFsIHZhcmlhbmNlIHRlcm0gdG8gemVybywgb3IgYSBmaXhlZCB2YWx1ZS4gVGhpcyBpcyBkaWZmaWN1bHQgaW4gYGxtZTRgLCBiZWNhdXNlIHRoZSBtb2RlbCBpcyBwYXJhbWV0ZXJpemVkIGludGVybmFsbHkgaW4gc3VjaCBhIHdheSB0aGF0IHRoZSByZXNpZHVhbCB2YXJpYW5jZSBpcyBwcm9maWxlZCBvdXQgKGkuZS4sIGNhbGN1bGF0ZWQgZGlyZWN0bHkgZnJvbSBhIHJlc2lkdWFsIGRldmlhbmNlIHRlcm0pIGFuZCB0aGUgcmFuZG9tLWVmZmVjdHMgdmFyaWFuY2VzIGFyZSBzY2FsZWQgYnkgdGhlIHJlc2lkdWFsIHZhcmlhbmNlLgoKW1NlYXJjaGluZyB0aGUgci1zaWctbWl4ZWQtbW9kZWxzIGxpc3QgZm9yICJmaXggcmVzaWR1YWwgdmFyaWFuY2UiXShodHRwczovL3d3dy5nb29nbGUuY2Evc2VhcmNoP3E9c2l0ZSUzQSUyRiUyRnN0YXQuZXRoei5jaCUyRnBpcGVybWFpbCUyRnItc2lnLW1peGVkLW1vZGVscyUyRitmaXgrcmVzaWR1YWwrdmFyaWFuY2UpCgotIFRoaXMgaXMgZG9uZSBpbiB0aGUgYG1ldGFmb3JgIHBhY2thZ2UsIGZvciBtZXRhLWFuYWx5dGljIG1vZGVscwotIFlvdSBjYW4gdXNlIHRoZSBgYmxtZWAgcGFja2FnZSB0byBmaXggdGhlIHJlc2lkdWFsIHZhcmlhbmNlOiBmcm9tIFZpbmNlbnQgRG9yaWUsCmBgYApsaWJyYXJ5KGJsbWUpCmJsbWVyKGZvcm11bGEgPSB5IH4gMSArICgxIHwgZ3JvdXApLCB3ZWlnaHRzID0gViwKICAgICAgcmVzaWQucHJpb3IgPSBwb2ludCgxLjApLCBjb3YucHJpb3IgPSBOVUxMKQpgYGAKVGhpcyBzZXRzIHRoZSByZXNpZHVhbCB2YXJpYW5jZSB0byAxLjAuICBZb3UgKmNhbm5vdCogdXNlIHRoaXMgdG8gbWFrZSBpdApleGFjdGx5IHplcm8sIGJ1dCB5b3UgY2FuIG1ha2UgaXQgdmVyeSBzbWFsbCAoYW5kIGV4cGVyaW1lbnQgd2l0aCBzZXR0aW5nCml0IHRvIGRpZmZlcmVudCBzbWFsbCB2YWx1ZXMsIGUuZy4gMC4wMDEgdnMgMC4wMDAxLCB0byBzZWUgaG93IHNlbnNpdGl2ZQp0aGUgcmVzdWx0cyBhcmUpLgotIFNpbWlsYXJseSwgeW91IGNhbiBmaXggdGhlIHJlc2lkdWFsIHZhcmlhbmNlIHRvIGEgc21hbGwgcG9zaXRpdmUgdmFsdWUgaW4gYFtuXWxtZWAgdmlhIHRoZSBgY29udHJvbCgpYCBhcmd1bWVudCBbQGhlaXN0ZXJrYW1wX3VwZGF0ZV8yMDE3XToKYGBge3IgbG1lX3p2YXIscmVzdWx0cz0iaGlkZSJ9Cm5sbWU6OmxtZShSZWFjdGlvbn5EYXlzLHJhbmRvbT1+MXxTdWJqZWN0LAogICAgICAgICAgZGF0YT1sbWU0OjpzbGVlcHN0dWR5LAogICAgICAgICAgY29udHJvbD1saXN0KHNpZ21hPTFlLTgpKQpgYGAKLSB0aGUgYGdsbW1UTUJgIHBhY2thZ2UgY2FuIHNldCB0aGUgcmVzaWR1YWwgdmFyaWFuY2UgdG8gemVybywgYnkgc3BlY2lmeWluZyBgZGlzcGZvcm11bGEgPSB+MGAKLSBUaGVyZSBpcyBhbiBbcnJCbHVwTWV0aG9kNiBwYWNrYWdlXShodHRwczovL0NSQU4uUi1wcm9qZWN0Lm9yZy9wYWNrYWdlPXJyQmx1cE1ldGhvZDYpIG9uIENSQU4gKCJSZS1wYXJhbWV0cml6YXRpb24gb2YgbWl4ZWQgbW9kZWwgZm9ybXVsYXRpb24gdG8gYWxsb3cgZm9yIGEgZml4ZWQgcmVzaWR1YWwgdmFyaWFuY2Ugd2hlbiB1c2luZyBSUi1CTFVQIGZvciBnZW5vbVtlXXdpZGUgZXN0aW1hdGlvbiBvZiBtYXJrZXIgZWZmZWN0cyIpLCBidXQgaXQgc2VlbXMgZmFpcmx5IHNwZWNpYWwtcHVycG9zZS4KLSBpdCBtaWdodCBiZSBwb3NzaWJsZSAqaW4gcHJpbmNpcGxlKiB0byBhZGFwdCBgbG1lNGAncyBpbnRlcm5hbCBgZGV2ZnVuMigpYCBmdW5jdGlvbiAodXNlZCBpbiB0aGUgbGlrZWxpaG9vZCBwcm9maWxpbmcgY29tcHV0YXRpb24gZm9yIExNTXMpLCB3aGljaCB1c2VzIGEgc3BlY2lmaWVkIHZhbHVlIG9mIHRoZSByZXNpZHVhbCBzdGFuZGFyZCBkZXZpYXRpb24gaW4gY29tcHV0aW5nIGxpa2VsaWhvb2QsIGJ1dCBhcyBAYmF0ZXNfZml0dGluZ18yMDE1IHNheToKCj4gVGhlIHJlc3VsdGluZyBmdW5jdGlvbiBpcyBub3QgdXNlZnVsIGZvciBnZW5lcmFsIG5vbmxpbmVhciBvcHRpbWl6YXRpb24g4oCUIG9uZSBjYW4gZWFzaWx5IHdhbmRlciBpbnRvIHBhcmFtZXRlciByZWdpbWVzIGNvcnJlc3BvbmRpbmcgdG8gaW5mZWFzaWJsZSAobm9uLXBvc2l0aXZlIHNlbWlkZWZpbml0ZSkgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaWNlcyDigJQgYnV0IGl0IHNlcnZlcyBmb3IgbGlrZWxpaG9vZCBwcm9maWxpbmcsIHdoZXJlIG9uZSBmb2NhbCBwYXJhbWV0ZXIgaXMgdmFyaWVkIGF0IGEgdGltZSBhbmQgdGhlIG9wdGltaXphdGlvbiBvdmVyIHRoZSBvdGhlciBwYXJhbWV0ZXJzIGlzIGxpa2VseSB0byBzdGFydCBjbG9zZSB0byBhbiBvcHRpbXVtLgoKIyMjIE90aGVyIHByb2JsZW1zL2BsbWU0YCBlcnJvciBtZXNzYWdlcwoKTW9zdCBvZiB0aGUgZm9sbG93aW5nIGVycm9yIG1lc3NhZ2VzIGFyZSByZWxhdGl2ZWx5IHVudXN1YWwsIGFuZCBoYXBwZW4gbW9zdGx5IHdpdGggY29tcGxleC9sYXJnZS91bnN0YWJsZSBtb2RlbHMuIFRoZXJlIGlzIG9mdGVuIG5vIHNpbXBsZSBmaXg7IHRoZSBzdGFuZGFyZCBzdWdnZXN0aW9ucyBmb3IgdHJvdWJsZXNob290aW5nIGFyZSAoMSkgdHJ5IHJlc2NhbGluZyBhbmQvb3IgY2VudGVyaW5nIHByZWRpY3RvcnM7ICgyKSBzZWUgaWYgYSBzaW1wbGVyIG1vZGVsIGNhbiBiZSBtYWRlIHRvIHdvcms7ICgzKSBsb29rIGZvciBzZXZlcmUgbGFjayBvZiBiYWxhbmNlIGFuZC9vciBjb21wbGV0ZSBzZXBhcmF0aW9uIGluIHRoZSBkYXRhIHNldC4KCi0gYFBJUkxTIHN0ZXAtaGFsdmluZ3MgZmFpbGVkIHRvIHJlZHVjZSBkZXZpYW5jZSBpbiBwd3Jzc1VwZGF0ZWAKCS0gdGhpcyBjYW4gYWxzbyBvY2N1ciBkdWUgdG8gY29tcGxldGUgb3IgcXVhc2ktY29tcGxldGUgc2VwYXJhdGlvbiAoc2VlIFtQZW5hbGl6YXRpb24vaGFuZGxpbmcgY29tcGxldGUgc2VwYXJhdGlvbl0oI3BlbmFsaXphdGlvbmhhbmRsaW5nLWNvbXBsZXRlLXNlcGFyYXRpb24pCiAgICAtIFdoZW4gdXNpbmcgYGxtZTRgIHRvIGZpdCBHTE1NcyB3aXRoIGxpbmsgZnVuY3Rpb25zIHRoYXQgZG8gbm90IGF1dG9tYXRpY2FsbHkgY29uc3RyYWluIHRoZSByZXNwb25zZSB0byB0aGUgYWxsb3dhYmxlIHJhbmdlIG9mIHRoZSBkaXN0cmlidXRpb25hbCBmYW1pbHkgKGUuZy4gYmlub21pYWwgbW9kZWxzIHdpdGggYSBsb2cgbGluaywgd2hlcmUgdGhlIGVzdGltYXRlZCBwcm9iYWJpbGl0eSBjYW4gYmUgPjEsIG9yIGludmVyc2UtR2FtbWEgbW9kZWxzLCB3aGVyZSB0aGUgZXN0aW1hdGVkIG1lYW4gY2FuIGJlIG5lZ2F0aXZlKSwgaXQgaXMgbm90IHVudXN1YWwgdG8gZ2V0IHRoaXMgZXJyb3IuICBUaGlzIG9jY3VycyBiZWNhdXNlIGBsbWU0YCBkb2Vzbid0IGRvIGFueXRoaW5nIHRvIGNvbnN0cmFpbiB0aGUgcHJlZGljdGVkIHZhbHVlcywgc28gYE5hTmAgdmFsdWVzIHBvcCB1cCwgd2hpY2ggYXJlbid0IGhhbmRsZWQgZ3JhY2VmdWxseS4gSWYgcG9zc2libGUsIHN3aXRjaCB0byBhIGxpbmsgZnVuY3Rpb24gdG8gb25lIHRoYXQgY29uc3RyYWlucyB0aGUgcmVzcG9uc2UgKGUuZy4gbG9naXQgbGluayBmb3IgYmlub21pYWwgb3IgbG9nIGxpbmsgZm9yIEdhbW1hKS4KCS0gb3RoZXJ3aXNlIHRoaXMgbWVzc2FnZSBvZnRlbiBvY2N1cnMgd2hlbiB0aGVyZSBpcyBzb21ldGhpbmcgZWxzZSB3cm9uZyB3aXRoIHRoZSBtb2RlbCBvciBkYXRhLCBlLmcuIAoJICAgICAgLSBbYSBtb2RlbCBmaXR0ZWQgdG8gdW5kZXJkaXNwZXJzZWQgZGF0YSBpbmNsdWRlcyBib3RoIGEgbmVnYXRpdmUgYmlub21pYWwgcmVzcG9uc2UgYW5kIG9ic2VydmF0aW9uLWxldmVsIHJhbmRvbSBlZmZlY3RzXShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yODAzNjMzNC91c2luZy1nbG1lci1uYi10aGUtZXJyb3ItbWVzc2FnZW1heHN0ZXBoYWxmaXQtcGlybHMtc3RlcC1oYWx2aW5ncy1mYWlsZWQtdCkKCQkgIC0gW25lZ2F0aXZlIHJlc3BvbnNlIHZhbHVlcyBmb3IgYSBsaW5rIGZ1bmN0aW9uIHRoYXQgZG9lc24ndCBhbGxvdyB0aGVtXShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zNzUzMzgyNS9lcnJvci1tYXhzdGVwaGFsZml0LXBpcmxzLXN0ZXAtaGFsdmluZ3MtZmFpbGVkLXRvLXJlZHVjZS1kZXZpYW5jZS1pbi1wd3Jzc3VwZCkKLSBgRG93bmRhdGVkIFZ0ViBpcyBub3QgcG9zaXRpdmUgZGVmaW5pdGVgOiBubyBzcGVjaWZpYyBhZHZpY2UsIHNlZSBnZW5lcmFsIHN1Z2dlc3Rpb25zIGFib3ZlCi0gYGNvbnZlcmdlbmNlIGNvZGUgMyBmcm9tIGJvYnlxYTogYm9ieXFhIC0tIGEgdHJ1c3QgcmVnaW9uIHN0ZXAgZmFpbGVkIHRvIHJlZHVjZSBxYDogYWdhaW4gbm8gc3BlY2lmaWMgYWR2aWNlIGFib3V0IGZpeGluZyB0aGlzLCBhbHRob3VnaCB0aGVyZSBpcyBhIFt1c2VmdWwgZGlzY3Vzc2lvbiBvZiB0aGUgbWVhbmluZyBvZiB0aGUgZXJyb3IgbWVzc2FnZSBvbiBDcm9zc1ZhbGlkYXRlZF0oaHR0cHM6Ly9zdGF0cy5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvODk5NDUvbWVhbmluZy1vZi1hLWNvbnZlcmdlbmNlLXdhcm5pbmctaW4tZ2xtZXIpCgojIyBSRU1MIGZvciBHTE1NcwoKLSBXaGlsZSByZXN0cmljdGVkIG1heGltdW0gbGlrZWxpaG9vZCAoUkVNTCkgcHJvY2VkdXJlcyAoW1dpa2lwZWRpYV0oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9SZXN0cmljdGVkX21heGltdW1fbGlrZWxpaG9vZCkgYXJlIHdlbGwgZXN0YWJsaXNoZWQgZm9yIGxpbmVhciBtaXhlZCBtb2RlbHMsIGl0IGlzIGxlc3MgY2xlYXIgaG93IG9uZSBzaG91bGQgZGVmaW5lIGFuZCBjb21wdXRlIHRoZSBlcXVpdmFsZW50IGNyaXRlcmlhIChpbnRlZ3JhdGluZyBvdXQgdGhlIGVmZmVjdHMgb2YgZml4ZWQgcGFyYW1ldGVycykgZm9yIEdMTU1zLiBAbWlsbGFyX21heGltdW1fMjAxMSBhbmQgQGJlcmdlcl9pbnRlZ3JhdGVkXzE5OTkgYXJlIHBvc3NpYmxlIHN0YXJ0aW5nIHBvaW50cyBpbiB0aGUgcGVlci1yZXZpZXdlZCBsaXRlcmF0dXJlLCBhbmQgdGhlcmUgYXJlIG1haWxpbmctbGlzdCBkaXNjdXNzaW9ucyBvZiB0aGVzZSBpc3N1ZXMgW2hlcmVdKGh0dHBzOi8vc3RhdC5ldGh6LmNoL3BpcGVybWFpbC9yLXNpZy1taXhlZC1tb2RlbHMvMjAwOXExLzAwMjEwNC5odG1sKSBhbmQgW2hlcmVdKGh0dHA6Ly9saXN0cy5hZG1iLXByb2plY3Qub3JnL3BpcGVybWFpbC91c2Vycy8yMDExLUp1bmUvMDAxMjI0Lmh0bWwpLgotIEF0dGVtcHRpbmcgdG8gdXNlIGBSRU1MPVRSVUVgIHdpdGggYGdsbWVyYCB3aWxsIHByb2R1Y2UgdGhlIHdhcm5pbmcgYGV4dHJhIGFyZ3VtZW50KHMpIOKAmFJFTUzigJkgZGlzcmVnYXJkZWRgCi0gYGdsbW1UTUJgIGFsbG93cyBgUkVNTD1UUlVFYCBmb3IgR0xNTXMgKGl0IHVzZXMgdGhlIExhcGxhY2UgYXBwcm94aW1hdGlvbiB0byBpbnRlZ3JhdGUgb3ZlciB0aGUgZml4ZWQgZWZmZWN0IHBhcmFtZXRlcnMpLCBzaW5jZSB2ZXJzaW9uIDAuMi4yIAoKIyBNb2RlbCBkaWFnbm9zdGljcwoKIyBJbmZlcmVuY2UgYW5kIGNvbmZpZGVuY2UgaW50ZXJ2YWxzCgojIyBUZXN0aW5nIGh5cG90aGVzZXMKCiMjIyBXaGF0IGFyZSB0aGUgcC12YWx1ZXMgbGlzdGVkIGJ5IGBzdW1tYXJ5KGdsbWVyZml0KWAgZXRjLj8gIEFyZSB0aGV5IHJlbGlhYmxlPwoKQnkgZGVmYXVsdCwgaW4ga2VlcGluZyB3aXRoIHRoZSB0cmFkaXRpb24gaW4gYW5hbHlzaXMgb2YgZ2VuZXJhbGl6ZWQgbGluZWFyIG1vZGVscywgYGxtZTRgIGFuZCBzaW1pbGFyIHBhY2thZ2VzIGRpc3BsYXkgdGhlIFdhbGQgWi1zdGF0aXN0aWNzIGZvciBlYWNoIHBhcmFtZXRlciBpbiB0aGUgbW9kZWwgc3VtbWFyeS4gVGhlc2UgaGF2ZSBvbmUgYmlnIGFkdmFudGFnZTogdGhleSdyZSBjb252ZW5pZW50IHRvIGNvbXB1dGUuICBIb3dldmVyLCB0aGV5IGFyZSBhc3ltcHRvdGljIGFwcHJveGltYXRpb25zLCBhc3N1bWluZyBib3RoIHRoYXQgKDEpIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb25zIG9mIHRoZSBwYXJhbWV0ZXJzIGFyZSBtdWx0aXZhcmlhdGUgbm9ybWFsIChvciBlcXVpdmFsZW50bHkgdGhhdCB0aGUgbG9nLWxpa2VsaWhvb2Qgc3VyZmFjZSBpcyBxdWFkcmF0aWMpIGFuZCB0aGF0ICgyKSB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBsb2ctbGlrZWxpaG9vZCBpcyAocHJvcG9ydGlvbmFsIHRvKSAkXGNoaV4yJC4gIFRoZSBzZWNvbmQgYXBwcm94aW1hdGlvbiBpcyBkaXNjdXNzZWQgZnVydGhlciB1bmRlciAiRGVncmVlcyBvZiBmcmVlZG9tIi4gIFRoZSBmaXJzdCBhc3N1bXB0aW9uIHVzdWFsbHkgcmVxdWlyZXMgYW4gZXZlbiBncmVhdGVyIGxlYXAgb2YgZmFpdGgsIGFuZCBpcyBrbm93biB0byBjYXVzZSBwcm9ibGVtcyBpbiBzb21lIGNvbnRleHRzIChmb3IgYmlub21pYWwgbW9kZWxzIGZhaWx1cmVzIG9mIHRoaXMgYXNzdW1wdGlvbiBhcmUgY2FsbGVkIHRoZSAqSGF1Y2stRG9ubmVyIGVmZmVjdCopLCBlc3BlY2lhbGx5IHdpdGggZXh0cmVtZS12YWx1ZWQgcGFyYW1ldGVycy4KCiMjIyBNZXRob2RzIGZvciB0ZXN0aW5nIHNpbmdsZSBwYXJhbWV0ZXJzCgpGcm9tIHdvcnN0IHRvIGJlc3Q6CgotIFdhbGQgJFokLXRlc3RzCi0gKipGb3IgYmFsYW5jZWQsIG5lc3RlZCBMTU1zKiogd2hlcmUgZGVncmVlcyBvZiBmcmVlZG9tIGNhbiBiZSBjb21wdXRlZCBhY2NvcmRpbmcgdG8gY2xhc3NpY2FsIHJ1bGVzOiBXYWxkICR0JC10ZXN0cyAKLSBMaWtlbGlob29kIHJhdGlvIHRlc3QsIGVpdGhlciBieSBzZXR0aW5nIHVwIHRoZSBtb2RlbCBzbyB0aGF0IHRoZSBwYXJhbWV0ZXIgY2FuIGJlIGlzb2xhdGVkL2Ryb3BwZWQgKHZpYSBgYW5vdmFgIG9yIGBkcm9wMWAsIG9yIHZpYSBjb21wdXRpbmcgbGlrZWxpaG9vZCBwcm9maWxlcwotIE1hcmtvdiBjaGFpbiBNb250ZSBDYXJsbyAoTUNNQykgb3IgcGFyYW1ldHJpYyBib290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbHMKCiMjIyBUZXN0cyBvZiBlZmZlY3RzIChpLmUuIHRlc3RpbmcgdGhhdCBzZXZlcmFsIHBhcmFtZXRlcnMgYXJlIHNpbXVsdGFuZW91c2x5IHplcm8pCgpGcm9tIHdvcnN0IHRvIGJlc3Q6CgotIFdhbGQgY2hpLXNxdWFyZSB0ZXN0cyAoZS5nLiBgY2FyOjpBbm92YWApCi0gTGlrZWxpaG9vZCByYXRpbyB0ZXN0ICh2aWEgYGFub3ZhYCBvciBgZHJvcDFgKQotICoqRm9yIGJhbGFuY2VkLCBuZXN0ZWQgTE1NcyoqIHdoZXJlIGRmIGNhbiBiZSBjb21wdXRlZDogY29uZGl0aW9uYWwgRi10ZXN0cyAKLSAqKkZvciBMTU1zKio6IGNvbmRpdGlvbmFsIEYtdGVzdHMgd2l0aCBkZiBjb3JyZWN0aW9uIChlLmcuIEtlbndhcmQtUm9nZXIgaW4gYHBia3J0ZXN0YCBwYWNrYWdlOiBzZWUgbm90ZXMgb24gSy1SIGV0YyBbYmVsb3ddKCNkZGYpLiAKLSBNQ01DIG9yIHBhcmFtZXRyaWMsIG9yIG5vbnBhcmFtZXRyaWMsIGJvb3RzdHJhcCBjb21wYXJpc29ucyAobm9ucGFyYW1ldHJpYyBib290c3RyYXBwaW5nIG11c3QgYmUgaW1wbGVtZW50ZWQgY2FyZWZ1bGx5IHRvIGFjY291bnQgZm9yIGdyb3VwaW5nIGZhY3RvcnMpCgojIyMgSXMgdGhlIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCByZWxpYWJsZSBmb3IgbWl4ZWQgbW9kZWxzPwoKLSBJdCBkZXBlbmRzLgotIE5vdCBmb3IgZml4ZWQgZWZmZWN0cyBpbiBmaW5pdGUtc2l6ZSBjYXNlcyAoc2VlIEBwaW5oZWlyb19taXhlZC1lZmZlY3RzXzIwMDApOiBtYXkgZGVwZW5kIG9uICdkZW5vbWluYXRvciBkZWdyZWVzIG9mIGZyZWVkb20nIChudW1iZXIgb2YgZ3JvdXBzKSBhbmQvb3IgdG90YWwgbnVtYmVyIG9mIHNhbXBsZXMgLSB0b3RhbCBudW1iZXIgb2YgcGFyYW1ldGVycwotIENvbmRpdGlvbmFsIEYtdGVzdHMgYXJlIHByZWZlcnJlZCBmb3IgTE1NcywgKippZioqIGRlbm9taW5hdG9yIGRlZ3JlZXMgb2YgZnJlZWRvbSBhcmUga25vd24KCjxhIGlkPSJkZGYiPjwvYT4KCiMjIyBXaHkgZG9lc24ndCBgbG1lNGAgZGlzcGxheSBkZW5vbWluYXRvciBkZWdyZWVzIG9mIGZyZWVkb20vcCB2YWx1ZXM/ICBXaGF0IG90aGVyIG9wdGlvbnMgZG8gSSBoYXZlPwoKVGhlcmUgaXMgYW4gW1IgRkFRIGVudHJ5XShodHRwOi8vY3Jhbi5yLXByb2plY3Qub3JnL2RvYy9GQVEvUi1GQVEuaHRtbCNXaHktYXJlLXBfMDAyZHZhbHVlcy1ub3QtZGlzcGxheWVkLXdoZW4tdXNpbmctbG1lcl8wMDI4XzAwMjlfMDAzZikgb24gdGhpcyB0b3BpYywgd2hpY2ggbGlua3MgdG8gYSBbbWFpbGluZyBsaXN0IHBvc3RdKGh0dHBzOi8vc3RhdC5ldGh6LmNoL3BpcGVybWFpbC9yLWhlbHAvMjAwNi1NYXkvMDk0NzY1Lmh0bWwpIGJ5IERvdWcgQmF0ZXMgKHRoZXJlIGlzIGFsc28gYSB2b2x1bWlub3VzIFttYWlsaW5nIGxpc3QgdGhyZWFkXShodHRwOi8vcndpa2kuc2Npdmlld3Mub3JnL2Rva3UucGhwP2lkPWd1aWRlczpsbWVyLXRlc3RzKSByZXByb2R1Y2VkIG9uIHRoZSBSIHdpa2kpLiBUaGUgYm90dG9tIGxpbmUgaXMgCgotIEZvciBzcGVjaWFsIGNhc2VzIHRoYXQgY29ycmVzcG9uZCB0byBjbGFzc2ljYWwgZXhwZXJpbWVudGFsIGRlc2lnbnMgKGkuZS4gYmFsYW5jZWQgZGVzaWducyB0aGF0IGFyZSBuZXN0ZWQsIHNwbGl0LXBsb3QsIHJhbmRvbWl6ZWQgYmxvY2ssIGV0Yy4pIC4uLiB3ZSBjYW4gc2hvdyB0aGF0IHRoZSBudWxsIGRpc3RyaWJ1dGlvbnMgb2YgcGFydGljdWxhciByYXRpb3Mgb2Ygc3VtcyBvZiBzcXVhcmVzIGZvbGxvdyBhbiAkRiQgZGlzdHJpYnV0aW9uIHdpdGgga25vd24gbnVtZXJhdG9yIGFuZCBkZW5vbWluYXRvciBkZWdyZWVzIG9mIGZyZWVkb20gKGFuZCBoZW5jZSB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBvZiBwYXJ0aWN1bGFyIGNvbnRyYXN0cyBhcmUgdC1kaXN0cmlidXRlZCB3aXRoIGtub3duIGRmKS4gSW4gbW9yZSBjb21wbGljYXRlZCBzaXR1YXRpb25zICh1bmJhbGFuY2VkLCBHTE1NcywgY3Jvc3NlZCByYW5kb20gZWZmZWN0cywgbW9kZWxzIHdpdGggdGVtcG9yYWwgb3Igc3BhdGlhbCBjb3JyZWxhdGlvbiwgZXRjLikgaXQgaXMgbm90IGluIGdlbmVyYWwgY2xlYXIgdGhhdCB0aGUgbnVsbCBkaXN0cmlidXRpb24gb2YgdGhlIGNvbXB1dGVkIHJhdGlvIG9mIHN1bXMgb2Ygc3F1YXJlcyBpcyByZWFsbHkgYW4gRiBkaXN0cmlidXRpb24sIGZvciAqYW55KiBjaG9pY2Ugb2YgZGVub21pbmF0b3IgZGVncmVlcyBvZiBmcmVlZG9tLgotIEZvciBlYWNoIHNpbXBsZSBkZWdyZWVzLW9mLWZyZWVkb20gcmVjaXBlIHRoYXQgaGFzIGJlZW4gc3VnZ2VzdGVkICh0cmFjZSBvZiB0aGUgaGF0IG1hdHJpeCwgZXRjLikgdGhlcmUgc2VlbXMgdG8gYmUgYXQgbGVhc3Qgb25lIGZhaXJseSBzaW1wbGUgY291bnRlcmV4YW1wbGUgd2hlcmUgdGhlIHJlY2lwZSBmYWlscyBiYWRseSAoZS5nLiBzZWUgW3RoaXMgci1oZWxwIHRocmVhZCBmcm9tIFNlcHRlbWJlciAyMDA2XShodHRwczovL3N0YXQuZXRoei5jaC9waXBlcm1haWwvci1oZWxwLzIwMDYtU2VwdGVtYmVyLzExMjQ5NS5odG1sKSkuCi0gV2hlbiB0aGUgcmVzcG9uc2VzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZCBhbmQgdGhlIGRlc2lnbiBpcyBiYWxhbmNlZCwgbmVzdGVkIGV0Yy4gKGkuZS4gdGhlIGNsYXNzaWNhbCBMTU0gc2l0dWF0aW9uKSwgdGhlIHNjYWxlZCBkZXZpYW5jZXMgYW5kIGRpZmZlcmVuY2VzIGluIGRldmlhbmNlcyBhcmUgZXhhY3RseSAkRiQtZGlzdHJpYnV0ZWQgYW5kIGxvb2tpbmcgYXQgdGhlIGV4cGVyaW1lbnRhbCBkZXNpZ24gKGkuZS4sIHdoaWNoIHRyZWF0bWVudHMgdmFyeS9hcmUgcmVwbGljYXRlZCBhdCB3aGljaCBsZXZlbHMpIHRlbGxzIHVzIHdoYXQgdGhlIHJlbGV2YW50IGRlZ3JlZXMgb2YgZnJlZWRvbSBhcmUgKHNlZSAiZGYgYWx0ZXJuYXRpdmVzIiBiZWxvdykKLSBUd28gYXBwcm9hY2hlcyB0byBhcHByb3hpbWF0aW5nIGRmIChTYXR0ZXJ0aHdhaXRlIGFuZCBLZW53YXJkLVJvZ2VyKSBoYXZlIGJlZW4gaW1wbGVtZW50ZWQgaW4gUiwgU2F0dGVydGh3YWl0ZSBpbiBgbG1lclRlc3RgIGFuZCBLZW53YXJkLVJvZ2VyIGluIGBwYmtydGVzdGAgKGFzIGBLUm1vZGNvbXBgKSAodmFyaW91cyBwYWNrYWdlcyBzdWNoIGFzIGBsbWVyVGVzdGAsIGBlbW1lYW5zYCwgYGNhcmAsIGV0Yy4sIGltcG9ydCBgcGJrcnRlc3Q6OmdldF9MYl9kZGZgKS4KICAgIC0gSy1SIGlzIHByb2JhYmx5IHRoZSBtb3N0IHJlbGlhYmxlIG9wdGlvbiBbQHNjaGFhbGplX2FkZXF1YWN5XzIwMDJdLCBhbHRob3VnaCBpdCBtYXkgYmUgcHJvaGliaXRpdmVseSBjb21wdXRhdGlvbmFsbHkgZXhwZW5zaXZlIGZvciBsYXJnZSBkYXRhIHNldHMuCiAgICAtIEstUiB3YXMgZGVyaXZlZCBmb3IgTE1NcyAoYW5kIGZvciBSRU1MPykgaW4gcGFydGljdWxhciwgaXQgaXNuJ3QgY2xlYXIgaG93IGl0IHdvdWxkIGFwcGx5IHRvIEdMTU1zLiBAc3Ryb3VwX3JldGhpbmtpbmdfMjAxNCBzdGF0ZXMgKHJlZmVyZW5jaW5nIEBzdHJvdXBfbm9uLW5vcm1hbF8yMDEzKSB0aGF0IEstUiBhY3R1YWxseSB3b3JrcyByZWFzb25hYmx5IHdlbGwgZm9yIEdMTU1zIChLLVIgaXMgbm90IGltcGxlbWVudGVkIGluIFIgZm9yIEdMTU1zOyBTdHJvdXAgc3VnZ2VzdHMgdGhhdCBhIHBzZXVkby1saWtlbGlob29kIFtAd29sZmluZ2VyX2dlbmVyYWxpemVkXzE5OTNdIGFwcHJvYWNoIGlzIG5lY2Vzc2FyeSBpbiBvcmRlciB0byBpbXBsZW1lbnQgSy1SIGZvciBHTE1Ncyk6CgogICAgICAgID4gTm90aWNlIHRoZSBub24taW50ZWdlciB2YWx1ZXMgb2YgdGhlIGRlbm9taW5hdG9yIGRmLiBUaGV5LCBhbmQgdGhlICRGJCBhbmQgJHAkIHZhbHVlcywgcmVmbGVjdCB0aGUgcHJvY2VkdXJlIGRldmVsb3BlZCBieSBLZW53YXJkIGFuZCBSb2dlciAoMjAwOSkgdG8gYWNjb3VudCBmb3IgdGhlIGVmZmVjdCBvZiB0aGUgY292YXJpYW5jZSAgc3RydWN0dXJlIG9uIGRlZ3JlZXMgb2YgZnJlZWRvbSBhbmQgc3RhbmRhcmQgZXJyb3JzLiBBbHRob3VnaCB0aGUgS2Vud2FyZOKAk1JvZ2VyIGFkanVzdG1lbnQgd2FzIGRlcml2ZWQgZm9yIHRoZSBMTU0gd2l0aCBub3JtYWxseSBkaXN0cmlidXRlZCBkYXRhIGFuZCBpcyBhbiBhZCBob2MgcHJvY2VkdXJlIGZvciBHTE1NcyB3aXRoIG5vbi1ub3JtYWwgZGF0YSwgaW5mb3JtYWwgc2ltdWxhdGlvbiBzdHVkaWVzIGNvbnNpc3RlbnRseSBoYXZlIHN1Z2dlc3RlZCB0aGF0IHRoZSBhZGp1c3RtZW50IGlzIGFjY3VyYXRlLiBUaGUgS2Vud2FyZC1Sb2dlciBhZGp1c3RtZW50IHJlcXVpcmVzIHRoYXQgdGhlIFNBUyBHTElNTUlYIGRlZmF1bHQgY29tcHV0aW5nIGFsZ29yaXRobSwgcHNldWRvLWxpa2VsaWhvb2QsIGJlIHVzZWQgcmF0aGVyIHRoYW4gdGhlIExhcGxhY2UgYWxnb3JpdGhtIHVzZWQgdG8gb2J0YWluIEFJQ0Mgc3RhdGlzdGljcy4gU3Ryb3VwICgyMDEzYikgZm91bmQgdGhhdCBmb3IgYmlub21pYWwgYW5kIFBvaXNzb24gR0xNTXMsIHBzZXVkby1saWtlbGlob29kIHdpdGggdGhlIEtlbndhcmTigJNSb2dlciBhZGp1c3RtZW50IHlpZWxkcyBiZXR0ZXIgVHlwZSBJIGVycm9yIGNvbnRyb2wgdGhhbiBMYXBsYWNlIHdoaWxlIHByZXNlcnZpbmcgdGhlIEdMTU3igJlzIGFkdmFudGFnZSB3aXRoIHJlc3BlY3QgdG8gcG93ZXIgYW5kIGFjY3VyYWN5IGluIGVzdGltYXRpbmcgdHJlYXRtZW50IG1lYW5zLgoJCi0gVGhlcmUgYXJlIHNldmVyYWwgZGlmZmVyZW50IGlzc3VlcyBhdCBwbGF5IGluIGZpbml0ZS1zaXplIChzbWFsbC1zYW1wbGUpIGFkanVzdG1lbnRzLCB3aGljaCBhcHBseSBzbGlnaHRseSBkaWZmZXJlbnRseSB0byBMTU1zIGFuZCBHTE1Ncy4KICAgICAtICBXaGVuIHRoZSBkYXRhIGRvbid0IGZpdCBpbnRvIHRoZSBjbGFzc2ljYWwgZnJhbWV3b3JrIChjcm9zc2VkLCB1bmJhbGFuY2VkLCBSLXNpZGUgZWZmZWN0cyksIHdlIG1pZ2h0IHN0aWxsIGd1ZXNzIHRoYXQgdGhlIGRldmlhbmNlcyBldGMuIGFyZSBhcHByb3hpbWF0ZWx5IEYtZGlzdHJpYnV0ZWQgYnV0IHRoYXQgd2UgZG9uJ3Qga25vdyB0aGUgcmVhbCBkZWdyZWVzIG9mIGZyZWVkb20gLS0gdGhpcyBpcyB3aGF0IHRoZSBTYXR0ZXJ0aHdhaXRlLCBLZW53YXJkLVJvZ2VyLCBGYWktQ29ybmVsaXVzLCBldGMuIGFwcHJveGltYXRpb25zIGFyZSBzdXBwb3NlZCB0byBkby4KICAgICAtIFdoZW4gdGhlIHJlc3BvbnNlcyBhcmUgbm90IG5vcm1hbGx5IGRpc3RyaWJ1dGVkIChhcyBpbiBHTE1zIGFuZCBHTE1NcyksIGFuZCB3aGVuIHRoZSBzY2FsZSBwYXJhbWV0ZXIgaXMgbm90IGVzdGltYXRlZCAoYXMgaW4gc3RhbmRhcmQgUG9pc3Nvbi0gYW5kIGJpbm9taWFsLXJlc3BvbnNlIG1vZGVscyksIHRoZW4gdGhlIGRldmlhbmNlIGRpZmZlcmVuY2VzIGFyZSBvbmx5IGFzeW1wdG90aWNhbGx5IEYtIG9yIGNoaS1zcXVhcmUtZGlzdHJpYnV0ZWQgKGkuZS4gbm90IGZvciBvdXIgcmVhbCwgZmluaXRlLXNpemUgc2FtcGxlcykuICBJbiBzdGFuZGFyZCBHTE0gcHJhY3RpY2UsIHdlIHVzdWFsbHkgaWdub3JlIHRoaXMgcHJvYmxlbTsgdGhlcmUgaXMgc29tZSBsaXRlcmF0dXJlIG9uIGZpbml0ZS1zaXplIGNvcnJlY3Rpb25zIGZvciBHTE1zIHVuZGVyIHRoZSBydWJyaWNzIG9mICJCYXJ0bGV0dCBjb3JyZWN0aW9ucyIgYW5kICJoaWdoZXIgb3JkZXIgYXN5bXB0b3RpY3MiIChzZWUgQE1jQ3VsbGFnaE5lbGRlcjE5ODksIEBjb3JkZWlyb19pbXByb3ZlZF8xOTk0LCBAY29yZGVpcm9fbm90ZV8xOTk4IGFuZCB0aGUgYGNvbmRgIHBhY2thZ2UgKFtvbiBDUkFOXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy9wYWNrYWdlPWNvbmQpKSBbd2hpY2ggd29ya3Mgd2l0aCBHTE1zLCBub3QgR0xNTXNdKSwgYnV0IGl0J3MgcmFyZWx5IHVzZWQuICAoVGhlIGJpYXMgY29ycmVjdGlvbi9GaXJ0aCBhcHByb2FjaCBpbXBsZW1lbnRlZCBpbiB0aGUgYGJyZ2xtYCBwYWNrYWdlIGF0dGVtcHRzIHRvIGFkZHJlc3MgdGhlIHByb2JsZW0gb2YgZmluaXRlLXNpemUgYmlhcywgbm90IGZpbml0ZS1zaXplIG5vbi1jaGktc3F1YXJlZG5lc3Mgb2YgdGhlIGRldmlhbmNlIGRpZmZlcmVuY2VzLikKICAgIC0gV2hlbiB0aGUgc2NhbGUgcGFyYW1ldGVyIGluIGEgR0xNIGlzIGVzdGltYXRlZCByYXRoZXIgdGhhbiBmaXhlZCAoYXMgaW4gR2FtbWEgb3IgcXVhc2ktbGlrZWxpaG9vZCBtb2RlbHMpLCBpdCBpcyBzb21ldGltZXMgcmVjb21tZW5kZWQgdG8gdXNlIGFuICRGJCB0ZXN0IHRvIGFjY291bnQgZm9yIHRoZSB1bmNlcnRhaW50eSBvZiB0aGUgc2NhbGUgcGFyYW1ldGVyIChlLmcuIEB2ZW5hYmxlc19tb2Rlcm5fMjAwMiByZWNvbW1lbmQgYGFub3ZhKC4uLix0ZXN0PSJGIilgIGZvciBxdWFzaS1saWtlbGlob29kIG1vZGVscykKICAgIC0gQ29tYmluaW5nIHRoZXNlIGlzc3Vlcywgb25lIGhhcyB0byBsb29rIHByZXR0eSBoYXJkIGZvciBpbmZvcm1hdGlvbiBvbiBzbWFsbC1zYW1wbGUgb3IgZmluaXRlLXNpemUgY29ycmVjdGlvbnMgZm9yIEdMTU1zOiBAZmVuZ19zbWFsbF8yMDA0IGFuZCBAYmVsbF9zbWFsbF8yMDEwIGxvb2sgbGlrZSBnb29kIHN0YXJ0aW5nIHBvaW50cywgYnV0IGl0J3Mgbm90IGF0IGFsbCB0cml2aWFsLgoKIyMjIyBEZiBhbHRlcm5hdGl2ZXM6CgotIHVzZSBNQVNTOjpnbG1tUFFMICh1c2VzIG9sZCBgbmxtZWAgcnVsZXMgYXBwcm94aW1hdGVseSBlcXVpdmFsZW50IHRvIFNBUyAnaW5uZXItb3V0ZXInLyd3aXRoaW4tYmV0d2VlbicgcnVsZXMpIGZvciBHTE1Ncywgb3IgYChuKWxtZWAgZm9yIExNTXMKLSBHdWVzcyB0aGUgZGVub21pbmF0b3IgZGYgZnJvbSBzdGFuZGFyZCBydWxlcyAoZm9yIHN0YW5kYXJkIGRlc2lnbnMsIGUuZy4gc2VlIEBHb3RlbGxpRWxsaXNvbjIwMDQpIGFuZCBhcHBseSB0aGVtIHRvICR0JCBvciAkRiQgdGVzdHMKLSBSdW4gdGhlIG1vZGVsIGluIGBsbWVgIChpZiBwb3NzaWJsZSkgYW5kIHVzZSB0aGUgZGVub21pbmF0b3IgZGYgcmVwb3J0ZWQgdGhlcmUgKHdoaWNoIGZvbGxvdyBhIHNpbXBsZSAnaW5uZXItb3V0ZXInIHJ1bGUgd2hpY2ggc2hvdWxkIGNvcnJlc3BvbmQgdG8gdGhlIGNhbm9uaWNhbCBhbnN3ZXIgZm9yIHNpbXBsZS9vcnRob2dvbmFsIGRlc2lnbnMpLCBhcHBsaWVkIHRvICR0JCBvciAkRiQgdGVzdHMuICBGb3IgdGhlIGV4cGxpY2l0IHNwZWNpZmljYXRpb24gb2YgdGhlIHJ1bGVzIHRoYXQgYGxtZWAgdXNlcywgc2VlIHBhZ2UgOTEgb2YgUGluaGVpcm8gYW5kIEJhdGVzICgqdGhpcyBwYWdlIHdhcyBwcmV2aW91c2x5IGF2YWlsYWJsZSBvbiBbR29vZ2xlIEJvb2tzXShodHRwOi8vdGlueXVybC5jb20vbnR5Z3EzKSwgYnV0IHRoZSBsaW5rIGlzIG5vIGxvbmdlciB1c2VmdWwsIHNvIGhlcmUgYXJlIHRoZSByZWxldmFudCBwYXJhZ3JhcGhzKik6Cgo+IFRoZXNlIGNvbmRpdGlvbmFsIHRlc3RzIGZvciBmaXhlZC1lZmZlY3RzIHRlcm1zIHJlcXVpcmUgZGVub21pbmF0b3IgZGVncmVlcyBvZiBmcmVlZG9tLiBJbiB0aGUgY2FzZSBvZiB0aGUgY29uZGl0aW9uYWwgJEYkLXRlc3RzLCB0aGUgbnVtZXJhdG9yIGRlZ3JlZXMgb2YgZnJlZWRvbSBhcmUgYWxzbyByZXF1aXJlZCwgYmVpbmcgZGV0ZXJtaW5lZCBieSB0aGUgdGVybSBpdHNlbGYuIFRoZSBkZW5vbWluYXRvciBkZWdyZWVzIG9mIGZyZWVkb20gYXJlIGRldGVybWluZWQgYnkgdGhlIGdyb3VwaW5nIGxldmVsIGF0IHdoaWNoIHRoZSB0ZXJtIGlzIGVzdGltYXRlZC4gQSB0ZXJtIGlzIGNhbGxlZCBpbm5lciByZWxhdGl2ZSB0byBhIGZhY3RvciBpZiBpdHMgdmFsdWUgY2FuIGNoYW5nZSB3aXRoaW4gYSBnaXZlbiBsZXZlbCBvZiB0aGUgZ3JvdXBpbmcgZmFjdG9yLiBBIHRlcm0gaXMgb3V0ZXIgdG8gYSBncm91cGluZyBmYWN0b3IgaWYgaXRzIHZhbHVlIGRvZXMgbm90IGNoYW5nZXMgd2l0aGluIGxldmVscyBvZiB0aGUgZ3JvdXBpbmcgZmFjdG9yLiBBIHRlcm0gaXMgc2FpZCB0byBiZSBlc3RpbWF0ZWQgYXQgbGV2ZWwgJGkkLCBpZiBpdCBpcyBpbm5lciB0byB0aGUgJGktMSRzdCBncm91cGluZyBmYWN0b3IgYW5kIG91dGVyIHRvIHRoZSAkaSR0aCBncm91cGluZyBmYWN0b3IuIEZvciBleGFtcGxlLCB0aGUgdGVybSBgTWFjaGluZWAgaW4gdGhlIGBmbTJNYWNoaW5lYCBtb2RlbCBpcyBvdXRlciB0byBgTWFjaGluZSAlaW4lIFdvcmtlcmAgYW5kIGlubmVyIHRvIGBXb3JrZXJgLCBzbyBpdCBpcyBlc3RpbWF0ZWQgYXQgbGV2ZWwgMiAoYE1hY2hpbmUgJWluJSBXb3JrZXJgKS4gSWYgYSB0ZXJtIGlzIGlubmVyIHRvIGFsbCAkUSQgZ3JvdXBpbmcgZmFjdG9ycyBpbiBhIG1vZGVsLCBpdCBpcyBlc3RpbWF0ZWQgYXQgdGhlIGxldmVsIG9mIHRoZSB3aXRoaW4tZ3JvdXAgZXJyb3JzLCB3aGljaCB3ZSBkZW5vdGUgYXMgdGhlICRRKzEkc3QgbGV2ZWwuCj4KPiAgVGhlIGludGVyY2VwdCwgd2hpY2ggaXMgdGhlIHBhcmFtZXRlciBjb3JyZXNwb25kaW5nIHRvIHRoZSBjb2x1bW4gb2YgYWxsIDEncyBpbiB0aGUgbW9kZWwgbWF0cmljZXMgJFhfaSQsIGlzIHRyZWF0ZWQgZGlmZmVyZW50bHkgZnJvbSBhbGwgdGhlIG90aGVyIHBhcmFtZXRlcnMsIHdoZW4gaXQgaXMgcHJlc2VudC4gQXMgYSBwYXJhbWV0ZXIgaXQgaXMgcmVnYXJkZWQgYXMgYmVpbmcgZXN0aW1hdGVkIGF0IGxldmVsIDAgYmVjYXVzZSBpdCBpcyBvdXRlciB0byBhbGwgdGhlIGdyb3VwaW5nIGZhY3RvcnMuIEhvd2V2ZXIsIGl0cyBkZW5vbWluYXRvciBkZWdyZWVzIG9mIGZyZWVkb20gYXJlIGNhbGN1bGF0ZWQgYXMgaWYgaXQgd2VyZSBlc3RpbWF0ZWQgYXQgbGV2ZWwgJFErMSQuIFRoaXMgaXMgYmVjYXVzZSB0aGUgaW50ZXJjZXB0IGlzIHRoZSBvbmUgcGFyYW1ldGVyIHRoYXQgcG9vbHMgaW5mb3JtYXRpb24gZnJvbSBhbGwgdGhlIG9ic2VydmF0aW9ucyBhdCBhIGxldmVsIGV2ZW4gd2hlbiB0aGUgY29ycmVzcG9uZGluZyBjb2x1bW4gaW4gJFhfaSQgZG9lc24ndCBjaGFuZ2Ugd2l0aCB0aGUgbGV2ZWwuCj4KPiAgICBMZXR0aW5nICRtX2kkIGRlbm90ZSB0aGUgdG90YWwgbnVtYmVyIG9mIGdyb3VwcyBpbiBsZXZlbCAkaSQgKHdpdGggdGhlIGNvbnZlbnRpb24gdGhhdCAkbV8wPTEkIHdoZW4gdGhlIGZpeGVkIGVmZmVjdHMgbW9kZWwgaW5jbHVkZXMgYW4gaW50ZXJjZXB0IGFuZCAwIG90aGVyd2lzZSwgYW5kICRtX3tRKzF9PU4kKSBhbmQgJHBfaSQgZGVub3RlIHRoZSBzdW0gb2YgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBjb3JyZXNwb25kaW5nIHRvIHRoZSB0ZXJtcyBlc3RpbWF0ZWQgYXQgbGV2ZWwgJGkkLCB0aGUgJGkkdGggbGV2ZWwgZGVub21pbmF0b3IgZGVncmVlcyBvZiBmcmVlZG9tIGlzIGRlZmluZWQgYXMKPgo+ICQkIFxtYXRocm17ZGVuREZ9X2kgPSBtX2kgLSAobV97aS0xfSArIHBfaSksIGkgPSAxLCBcZG90cywgUSAkJAo+IAo+IFRoaXMgZGVmaW5pdGlvbiBjb2luY2lkZXMgd2l0aCB0aGUgY2xhc3NpY2FsIGRlY29tcG9zaXRpb24gb2YgZGVncmVlcyBvZiBmcmVlZG9tIGluIGJhbGFuY2VkLCBtdWx0aWxldmVsIEFOT1ZBIGRlc2lnbnMgYW5kIGdpdmVzIGEgcmVhc29uYWJsZSBhcHByb3hpbWF0aW9uIGZvciBtb3JlIGdlbmVyYWwgbWl4ZWQtZWZmZWN0cyBtb2RlbHMuCgpOb3RlIHRoYXQgdGhlIGltcGxlbWVudGF0aW9uIHVzZWQgaW4gYGxtZWAgKipnZXRzIHRoZSB3cm9uZyBhbnN3ZXIgZm9yIHJhbmRvbS1zbG9wZXMgbW9kZWxzKio6CmBgYHtyIGxtZURGLG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkobmxtZSkKbG1lREYgPC0gZnVuY3Rpb24oZm9ybXVsYT1kaXN0YW5jZX5hZ2UscmFuZG9tPX4xfFN1YmplY3QpIHsKICAgICBtb2QgPC0gbG1lKGZvcm11bGEscmFuZG9tLGRhdGE9T3J0aG9kb250KQogICAgIGFhIDwtIGFub3ZhKG1vZCkKICAgIHJldHVybihzZXROYW1lcyhhYVssImRlbkRGIl0scm93bmFtZXMoYWEpKSkKfQpsbWVERigpCmxtZURGKHJhbmRvbT1+YWdlfFN1YmplY3QpICMjIHdyb25nIQpgYGAKSSAoQkIpIGhhdmUgcmUtaW1wbGVtZW50ZWQgdGhpcyBhbGdvcml0aG0gaW4gYSB3YXkgdGhhdCBkb2VzIHNsaWdodGx5IGJldHRlciBmb3IgcmFuZG9tLXNsb3BlcyBtb2RlbHMgKGJ1dCBtYXkgc3RpbGwgZ2V0IGNvbmZ1c2VkISksIHNlZSBbaGVyZV0oUi9jYWxjRGVuREYuUikuCgpgYGB7ciBjYWxjRGVuREZ9CnNvdXJjZSgiUi9jYWxjRGVuREYuUiIpCmNhbGNEZW5ERih+YWdlLCJTdWJqZWN0IixubG1lOjpPcnRob2RvbnQpCmNhbGNEZW5ERih+YWdlLGRhdGE9bmxtZTo6T3J0aG9kb250LHJhbmRvbT1+MXxTdWJqZWN0KQpjYWxjRGVuREYofmFnZSxkYXRhPW5sbWU6Ok9ydGhvZG9udCxyYW5kb209fmFnZXxTdWJqZWN0KSAjIyBvZmYgYnkgMQpgYGAKCi0gdXNlIFNBUywgR2Vuc3RhdCAoQVMtUkVNTCksIFN0YXRhPwotIEFzc3VtZSBpbmZpbml0ZSBkZW5vbWluYXRvciBkZiAoaS5lLiAkWiQvJFxjaGleMiQgdGVzdCByYXRoZXIgdGhhbiAkdCQvJEYkKSBpZiBudW1iZXIgb2YgZ3JvdXBzIGlzIGxhcmdlICg+NDU/IFZhcmlvdXMgcnVsZXMgb2YgdGh1bWIgZm9yIGhvdyBsYXJnZSBpcyAiYXBwcm94aW1hdGVseSBpbmZpbml0ZSIgaGF2ZSBiZWVuIHBvc2VkLCBpbmNsdWRpbmcgW2luIEBhbmdyaXN0X21vc3RseV8yMDA5XSwgNDIgKGluIGhvbWFnZSB0byBEb3VnbGFzIEFkYW1zKQoKIyMjIFRlc3Rpbmcgc2lnbmlmaWNhbmNlIG9mIHJhbmRvbSBlZmZlY3RzCgotIHRoZSBtb3N0IGNvbW1vbiB3YXkgdG8gZG8gdGhpcyBpcyB0byB1c2UgYSBsaWtlbGlob29kIHJhdGlvIHRlc3QsIGkuZS4gZml0IHRoZSBmdWxsIGFuZCByZWR1Y2VkIG1vZGVscyAodGhlIHJlZHVjZWQgbW9kZWwgaXMgdGhlIG1vZGVsIHdpdGggdGhlIGZvY2FsIHZhcmlhbmNlKHMpIHNldCB0byB6ZXJvKS4gRm9yIGV4YW1wbGU6CmBgYHtyIHJhbmVmZl90ZXN0LG1lc3NhZ2U9RkFMU0UsY2FjaGU9VFJVRX0KbGlicmFyeShsbWU0KQptMiA8LSBsbWVyKFJlYWN0aW9ufkRheXMrKDF8U3ViamVjdCkrKDArRGF5c3xTdWJqZWN0KSxzbGVlcHN0dWR5LFJFTUw9RkFMU0UpCm0xIDwtIHVwZGF0ZShtMiwufkRheXMrKDF8U3ViamVjdCkpCm0wIDwtIGxtKFJlYWN0aW9ufkRheXMsc2xlZXBzdHVkeSkKYW5vdmEobTIsbTEsbTApICMjIHR3byBzZXF1ZW50aWFsIHRlc3RzCmBgYApXaXRoIHJlY2VudCB2ZXJzaW9ucyBvZiBgbG1lNGAsIGdvb2RuZXNzLW9mLWZpdCAoZGV2aWFuY2UpIGNhbiBiZSBjb21wYXJlZCBiZXR3ZWVuIGAoZylsbWVyYCBhbmQgYChnKWxtYCBtb2RlbHMsIGFsdGhvdWdoIGBhbm92YSgpYCBtdXN0IGJlIGNhbGxlZCB3aXRoIHRoZSBtaXhlZCAoYChnKWxtZXJgKSBtb2RlbCBsaXN0ZWQgZmlyc3QuCktlZXAgaW4gbWluZCB0aGF0IExSVC1iYXNlZCBudWxsIGh5cG90aGVzaXMgdGVzdHMgYXJlIGNvbnNlcnZhdGl2ZSB3aGVuIHRoZSBudWxsIHZhbHVlIChzdWNoIGFzICRcc2lnbWFeMj0wJCkgaXMgb24gdGhlIGJvdW5kYXJ5IG9mIHRoZSBmZWFzaWJsZSBzcGFjZSBbQHNlbGZfYXN5bXB0b3RpY18xOTg3O0BzdHJhbV92YXJpYW5jZV8xOTk0O0BHb2xkbWFuV2hlbGFuMjAwMF07IGluIHRoZSBzaW1wbGVzdCBjYXNlIChzaW5nbGUgcmFuZG9tIGVmZmVjdCB2YXJpYW5jZSksIHRoZSBwLXZhbHVlIGlzIGFwcHJveGltYXRlbHkgdHdpY2UgYXMgbGFyZ2UgYXMgaXQgc2hvdWxkIGJlIFtAcGluaGVpcm9fbWl4ZWQtZWZmZWN0c18yMDAwXS4KCi0gQ29uc2lkZXIgKm5vdCogdGVzdGluZyB0aGUgc2lnbmlmaWNhbmNlIG9mIHJhbmRvbSBlZmZlY3RzLiBJZiB0aGUgcmFuZG9tIGVmZmVjdCBpcyBwYXJ0IG9mIHRoZSBleHBlcmltZW50YWwgZGVzaWduLCB0aGlzIHByb2NlZHVyZSBtYXkgYmUgY29uc2lkZXJlZCAnc2FjcmlmaWNpYWwgcHNldWRvcmVwbGljYXRpb24nIFtASHVybGJlcnQxOTg0XS4gVXNpbmcgc3RlcHdpc2UgYXBwcm9hY2hlcyB0byBlbGltaW5hdGUgbm9uLXNpZ25pZmljYW50IHRlcm1zIGluIG9yZGVyIHRvIHNxdWVlemUgbW9yZSBzaWduaWZpY2FuY2Ugb3V0IG9mIHRoZSByZW1haW5pbmcgdGVybXMgaXMgZGFuZ2Vyb3VzIGluIGFueSBjYXNlLgotIGNvbnNpZGVyIHVzaW5nIHRoZSBgUkxSc2ltYCBwYWNrYWdlLCB3aGljaCBoYXMgYSBmYXN0IGltcGxlbWVudGF0aW9uIG9mIHNpbXVsYXRpb24tYmFzZWQgdGVzdHMgb2YgbnVsbCBoeXBvdGhlc2VzIGFib3V0IHplcm8gdmFyaWFuY2VzLCBmb3Igc2ltcGxlIHRlc3RzLiAoSG93ZXZlciwgaXQgb25seSBhcHBsaWVzIHRvIGBsbWVyYCBtb2RlbHMsIGFuZCBpcyBhIGJpdCB0cmlja3kgdG8gdXNlIGZvciBtb3JlIGNvbXBsZXggbW9kZWxzLikKCmBgYHtyIFJMUnNpbV9jaGVjayxlY2hvPUZBTFNFfQppZiAocGFja2FnZVZlcnNpb24oIlJMUnNpbSIpPCIzLjEtNiIpIHsKICBzdG9wKCJuZWVkIHJlY2VudCB2ZXJzaW9uIG9mIFJMUnNpbTogY29uc2lkZXIiLAogICAgICAgIidyZW1vdGVzOjppbnN0YWxsX2dpdGh1YihcImZhYmlhbi1zL1JMUnNpbVwiKSciKQp9CmBgYApgYGB7ciBSTFJzaW0sbWVzc2FnZT1GQUxTRX0KbGlicmFyeShSTFJzaW0pCiMjIGNvbXBhcmUgbTAgYW5kIG0xCmV4YWN0TFJUKG0xLG0wKQojIyBjb21wYXJlIG0xIGFuZCBtMgptQSA8LSB1cGRhdGUobTIsUkVNTD1UUlVFKQptMEIgPC0gdXBkYXRlKG1BLCAuIH4gLiAtICgwICsgRGF5c3xTdWJqZWN0KSkKbS5zbG9wZSAgPC0gdXBkYXRlKG1BLCAuIH4gLiAtICgxfFN1YmplY3QpKQpleGFjdFJMUlQobTA9bTBCLG09bS5zbG9wZSxtQT1tQSkKYGBgCgotIFBhcmFtZXRyaWMgYm9vdHN0cmFwOiBmaXQgdGhlIHJlZHVjZWQgbW9kZWwsIHRoZW4gcmVwZWF0ZWRseSBzaW11bGF0ZSBmcm9tIGl0IGFuZCBjb21wdXRlIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBkZXZpYW5jZSBvZiB0aGUgcmVkdWNlZCBhbmQgdGhlIGZ1bGwgbW9kZWwgZm9yIGVhY2ggc2ltdWxhdGVkIGRhdGEgc2V0LiAgQ29tcGFyZSB0aGlzIG51bGwgZGlzdHJpYnV0aW9uIHRvIHRoZSBvYnNlcnZlZCBkZXZpYW5jZSBkaWZmZXJlbmNlLiBUaGlzIHByb2NlZHVyZSBpcyBpbXBsZW1lbnRlZCBpbiB0aGUgYHBia3J0ZXN0YCBwYWNrYWdlIChtZXNzYWdlcyBhbmQgd2FybmluZ3Mgc3VwcHJlc3NlZCkuCmBgYHtyIHBib290X3ZhcnRlc3RfY29tcCxjYWNoZT1UUlVFLCBtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9CihwYiA8LSBwYmtydGVzdDo6UEJtb2Rjb21wKG0yLG0xLHNlZWQ9MTAxKSkKYGBgCgojIyMgU3RhbmRhcmQgZXJyb3JzIG9mIHZhcmlhbmNlIGVzdGltYXRlcwoKPGEgaWQ9InZhcmlhbmNlLXN0YW5kYXJkLWVycm9ycyI+PC9hPgoKLSBQYXJhcGhyYXNpbmcgRG91ZyBCYXRlczogdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB2YXJpYW5jZSBlc3RpbWF0ZXMgaXMgaW4gZ2VuZXJhbCBzdHJvbmdseSBhc3ltbWV0cmljOiB0aGUgc3RhbmRhcmQgZXJyb3IgbWF5IGJlIGEgcG9vciBjaGFyYWN0ZXJpemF0aW9uIG9mIHRoZSB1bmNlcnRhaW50eS4KLSBgbG1lNGAgYWxsb3dzIGZvciBjb21wdXRpbmcgbGlrZWxpaG9vZCBwcm9maWxlcyBvZiB2YXJpYW5jZXMgYW5kIGNvbXB1dGluZyBjb25maWRlbmNlIGludGVydmFscyBvbiB0aGVpciBiYXNpczsgdGhlc2UgbGlrZWxpaG9vZCBwcm9maWxlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFyZSBzdWJqZWN0IHRvIHRoZSB1c3VhbCBjYXZlYXRzIGFib3V0IHRoZSBMUlQgd2l0aCBmaW5pdGUgc2FtcGxlIHNpemVzLgotIFVzaW5nIGFuIE1DTUMtYmFzZWQgYXBwcm9hY2ggKHRoZSBzaW1wbGVzdC9tb3N0IGNhbm5lZCBpcyBwcm9iYWJseSB0byB1c2UgdGhlIGBNQ01DZ2xtbWAgcGFja2FnZSwgYWx0aG91Z2ggaXRzIG1vZGUgc3BlY2lmaWNhdGlvbnMgYXJlIG5vdCBpZGVudGljYWwgdG8gdGhvc2Ugb2YgbG1lNCkgd2lsbCBwcm92aWRlIHBvc3RlcmlvciBkaXN0cmlidXRpb25zIG9mIHRoZSB2YXJpYW5jZSBwYXJhbWV0ZXJzOiBxdWFudGlsZXMgb3IgY3JlZGlibGUgaW50ZXJ2YWxzIChgSFBEaW50ZXJ2YWwoKWAgaW4gdGhlIGBjb2RhYCBwYWNrYWdlKSB3aWxsIGNoYXJhY3Rlcml6ZSB0aGUgdW5jZXJ0YWludHkuCi0gKGRvbid0IHNheSB3ZSBkaWRuJ3Qgd2FybiB5b3UgLi4uKSBgW25dbG1lYCBmaXRzIGNvbnRhaW4gYW4gZWxlbWVudCBjYWxsZWQgYGFwVmFyYCB3aGljaCBjb250YWlucyB0aGUgYXBwcm94aW1hdGUgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXggKGRlcml2ZWQgZnJvbSB0aGUgSGVzc2lhbiwgdGhlIG1hdHJpeCBvZiAobnVtZXJpY2FsbHkgYXBwcm94aW1hdGVkKSBzZWNvbmQgZGVyaXZhdGl2ZXMgb2YgdGhlIGxpa2VsaWhvb2QgKFJFTUw/KSBhdCB0aGUgbWF4aW11bSAocmVzdHJpY3RlZD8pIGxpa2VsaWhvb2QgdmFsdWVzKTogeW91IGNhbiBkZXJpdmUgdGhlIHN0YW5kYXJkIGVycm9ycyBmcm9tIHRoaXMgbGlzdCBlbGVtZW50IHZpYSBgc3FydChkaWFnKGxtZS5vYmokYXBWYXIpKWAuIEZvciB3aGF0ZXZlciBpdCdzIHdvcnRoLCB0aG91Z2gsIFt0aGVzZSBlc3RpbWF0ZXMgbWlnaHQgbm90IG1hdGNoXShodHRwOi8vd3d3LmJpb3N0YXQud3VzdGwuZWR1L2FyY2hpdmVzL2h0bWwvcy1uZXdzLzIwMDMtMDcvbXNnMDAxMjcuaHRtbCkgdGhlIFtlc3RpbWF0ZXMgdGhhdCBTQVMgZ2l2ZXNdKGh0dHA6Ly93d3cudGF1LmFjLmlsL2NjL3BhZ2VzL2RvY3Mvc2FzOC9zdGF0L2NoYXA0MS9zZWN0MjUuaHRtI21peGVkY3BlKSB3aGljaCBhcmUgc3VwcG9zZWRseSBkZXJpdmVkIGluIHRoZSBzYW1lIHdheS4KLSBpdCdzIG5vdCBhIGZ1bGwgc29sdXRpb24sIGJ1dCB0aGVyZSBpcyBzb21lIG1vcmUgaW5mb3JtYXRpb24gW2hlcmVdKGh0dHBzOi8vcnB1YnMuY29tL2Jib2xrZXIvd2FsZHZhcikuIEkgaGF2ZSBzb21lIGRlbHRhLW1ldGhvZCBjb21wdXRhdGlvbnMgdGhlcmUgdGhhdCBhcmUgb2ZmIGJ5IGEgZmFjdG9yIG9mIDIgZm9yIHRoZSByZXNpZHVhbCBzdGFuZGFyZCBkZXZpYXRpb24sIGFzIHdlbGwgYXMgc29tZSBjb21wdXRhdGlvbnMgYmFzZWQgb24gcmVwYXJhbWV0ZXJpemluZyB0aGUgZGV2aWFuY2UgZnVuY3Rpb24uCgojIyMgUC12YWx1ZXM6IE1DTUMgYW5kIHBhcmFtZXRyaWMgYm9vdHN0cmFwIAoKQWJhbmRvbmluZyB0aGUgYXBwcm94aW1hdGUgJEYkLyR0JC1zdGF0aXN0aWMgcm91dGUsIG9uZSBlbmRzIHVwIHdpdGggdGhlIG1vcmUgZ2VuZXJhbCBwcm9ibGVtIG9mIGVzdGltYXRpbmcgJHAkLXZhbHVlcy4gIFRoZXJlIGlzIGEgd2lkZXIgcmFuZ2Ugb2Ygb3B0aW9ucyBoZXJlLCBhbHRob3VnaCBtYW55IG9mIHRoZW0gYXJlIGNvbXB1dGF0aW9uYWxseSBpbnRlbnNpdmUgLi4uCgojIyMjIE1hcmtvdiBjaGFpbiBNb250ZSBDYXJsbyBzYW1wbGluZzoKLSBwc2V1ZG8tQmF5ZXNpYW46IHBvc3QtaG9jIHNhbXBsaW5nLCB0eXBpY2FsbHkgKDEpIGFzc3VtaW5nIGZsYXQgcHJpb3JzIGFuZCAoMikgc3RhcnRpbmcgZnJvbSB0aGUgTUxFLCBwb3NzaWJseSB1c2luZyB0aGUgYXBwcm94aW1hdGUgdmFyaWFuY2UtY292YXJpYW5jZSBlc3RpbWF0ZSB0byBjaG9vc2UgYSBjYW5kaWRhdGUgZGlzdHJpYnV0aW9uCiAgICAtIHZpYSBgbWNtY3NhbXBgIChpZiBhdmFpbGFibGUgZm9yIHlvdXIgcHJvYmxlbTogaS5lLiBMTU1zIHdpdGggc2ltcGxlIHJhbmRvbSBlZmZlY3RzIC0tIG5vdCBHTE1NcyBvciBjb21wbGV4IHJhbmRvbSBlZmZlY3RzKQogICAgLSB2aWEgYHB2YWxzLmZuY2AgaW4gdGhlIGBsYW5ndWFnZVJgIHBhY2thZ2UsIGEgd3JhcHBlciBmb3IgbWNtY3NhbXApCiAgICAtIGluIEFEIE1vZGVsIEJ1aWxkZXIsIHBvc3NpYmx5IHZpYSB0aGUgYGdsbW1BRE1CYCBwYWNrYWdlICh1c2UgdGhlIGBtY21jPVRSVUVgIG9wdGlvbikgb3IgdGhlIGBSMmFkbWJgIHBhY2thZ2UgKHdyaXRlIHlvdXIgb3duIG1vZGVsIGRlZmluaXRpb24gaW4gQUQgTW9kZWwgQnVpbGRlciksIG9yIG91dHNpZGUgb2YgUgogICAgLSB2aWEgdGhlIGBzaW1gIGZ1bmN0aW9uIGZyb20gdGhlIGBhcm1gIHBhY2thZ2UgKHNpbXVsYXRlcyB0aGUgcG9zdGVyaW9yIG9ubHkgZm9yIHRoZSBiZXRhIChmaXhlZC1lZmZlY3QpIGNvZWZmaWNpZW50czsgbm90IHlldCB3b3JraW5nIHdpdGggZGV2ZWxvcG1lbnQgbG1lNDsgd291bGQgbGlrZSBhIGJldHRlciBmb3JtYWwgZGVzY3JpcHRpb24gb2YgdGhlIGFsZ29yaXRobSAuLi4/KQotIGZ1bGx5IEJheWVzaWFuIGFwcHJvYWNoZXMKICAgIC0gdmlhIHRoZSBgTUNNQ2dsbW1gIHBhY2thZ2UKICAgIC0gYGdsbW1CVUdTYCAoYSBXaW5CVUdTIHdyYXBwZXIvUiBpbnRlcmZhY2UpCiAgICAtIEpBR1MvV2luQlVHUy9PcGVuQlVHUyBldGMuLCB2aWEgdGhlIGByamFnc2AvYHIyamFnc2AvYFIyV2luQlVHU2AvYEJSdWdzYCBwYWNrYWdlcwoKIyMjIyBTdGF0dXMgb2YgbWNtY3NhbXAKCmBtY21jc2FtcGAgaXMgYSBmdW5jdGlvbiBmb3IgbG1lNCB0aGF0IGlzIHN1cHBvc2VkIHRvIHNhbXBsZSBmcm9tIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIG9mIHRoZSBwYXJhbWV0ZXJzLCBiYXNlZCBvbiBmbGF0L2ltcHJvcGVyIHByaW9ycyBmb3IgdGhlIHBhcmFtZXRlcnMgW2VkOiBJIGJlbGlldmUsIGJ1dCBhbSBub3Qgc3VyZSwgdGhhdCB0aGVzZSBwcmlvcnMgYXJlIGZsYXQgKipvbiB0aGUgc2NhbGUgb2YgdGhlIHRoZXRhIChDaG9sZXNreS1mYWN0b3IpIHBhcmFtZXRlcnMqKl0uICBBdCBwcmVzZW50LCBpbiB0aGUgQ1JBTiB2ZXJzaW9uIChsbWU0IDAuOTk5OTk5LTApIGFuZCB0aGUgUi1mb3JnZSAic3RhYmxlIiB2ZXJzaW9uIChsbWU0LjAgMC45OTk5OTktMSksIHRoaXMgY292ZXJzIG9ubHkgbGluZWFyIG1peGVkIG1vZGVscyB3aXRoIHVuY29ycmVsYXRlZCByYW5kb20gZWZmZWN0cy4KCkFzIGhhcyBiZWVuIGRpc2N1c3NlZCBpbiBhIHZhcmlldHkgb2YgcGxhY2VzIChlLmcuIFtvbiByLXNpZy1taXhlZCBtb2RlbHNdKGh0dHA6Ly9hcnRpY2xlLmdtYW5lLm9yZy9nbWFuZS5jb21wLmxhbmcuci5sbWU0LmRldmVsLzE3ODgvKSwgYW5kIFtvbiB0aGUgci1mb3JnZSBidWcgdHJhY2tlcl0oaHR0cHM6Ly9yLWZvcmdlLnItcHJvamVjdC5vcmcvdHJhY2tlci8/ZnVuYz1kZXRhaWwmYWlkPTY4Jmdyb3VwX2lkPTYwJmF0aWQ9Mjk4KSwgaXQgaXMgY2hhbGxlbmdpbmcgdG8gY29tZSB1cCB3aXRoIGEgc2FtcGxlciB0aGF0IGFjY291bnRzIHByb3Blcmx5IGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbnMgZm9yIHNvbWUgb2YgdGhlIHZhcmlhbmNlIGNvbXBvbmVudHMgbWF5IGJlIG1peHR1cmVzIG9mIHBvaW50IG1hc3NlcyBhdCB6ZXJvIGFuZCBjb250aW51b3VzIGRpc3RyaWJ1dGlvbnMuICBOYWl2ZSBzYW1wbGVycyBhcmUgbGlrZWx5IHRvIGdldCBzdHVjayBhdCBvciBuZWFyIHplcm8uICBEb3VnIEJhdGVzIGhhcyBhbHdheXMgYmVlbiBhIGJpdCB1bnN1cmUgdGhhdCBgbWNtY3NhbXBgIGlzIHJlYWxseSBwZXJmb3JtaW5nIGFzIGludGVuZGVkLCBldmVuIGluIHRoZSBsaW1pdGVkIGNhc2VzIGl0IG5vdyBoYW5kbGVzLgoKR2l2ZW4gdGhpcyB1bmNlcnRhaW50eSBhYm91dCBob3cgZXZlbiB0aGUgYmFzaWMgdmVyc2lvbiB3b3JrcywgdGhlIGBsbWU0YCBkZXZlbG9wZXJzIGhhdmUgYmVlbiByZWx1Y3RhbnQgdG8gbWFrZSB0aGUgZWZmb3J0IHRvIGV4dGVuZCBpdCB0byBHTE1NcyBvciBtb3JlIGNvbXBsZXggTE1Ncywgb3IgdG8gaW1wbGVtZW50IGl0IGZvciB0aGUgZGV2ZWxvcG1lbnQgdmVyc2lvbiBvZiBsbWU0IC4uLiBzbyB1bmxlc3Mgc29tZXRoaW5nIG1pcmFjdWxvdXMgaGFwcGVucywgaXQgd2lsbCBub3QgYmUgaW1wbGVtZW50ZWQgZm9yIHRoZSBuZXcgdmVyc2lvbiBvZiBgbG1lNGAuIEFzIGFsd2F5cywgdXNlcnMgYXJlIGVuY291cmFnZWQgdG8gd3JpdGUgYW5kIHNoYXJlIHRoZWlyIG93biBjb2RlIHRoYXQgaW1wbGVtZW50cyB0aGVzZSBjYXBhYmlsaXRpZXMgLi4uCgojIyMjIFBhcmFtZXRyaWMgYm9vdHN0cmFwCgpUaGUgaWRlYSBoZXJlIGlzIHRoYXQgaW4gb3JkZXIgdG8gZG8gaW5mZXJlbmNlIG9uIHRoZSBlZmZlY3Qgb2YgKGEpIHByZWRpY3RvcihzKSwgeW91ICgxKSBmaXQgdGhlIHJlZHVjZWQgbW9kZWwgKHdpdGhvdXQgdGhlIHByZWRpY3RvcnMpIHRvIHRoZSBkYXRhOyAoMikgbWFueSB0aW1lcywgKDJhKSBzaW11bGF0ZSBkYXRhIGZyb20gdGhlIHJlZHVjZWQgbW9kZWw7ICgyYikgZml0IGJvdGggdGhlIHJlZHVjZWQgYW5kIHRoZSBmdWxsIG1vZGVsIHRvIHRoZSBzaW11bGF0ZWQgKG51bGwpIGRhdGE7ICgyYykgY29tcHV0ZSBzb21lIHN0YXRpc3RpYyhzKSBbZS5nLiB0LXN0YXRpc3RpYyBvZiB0aGUgZm9jYWwgcGFyYW1ldGVyLCBvciB0aGUgbG9nLWxpa2VsaWhvb2Qgb3IgZGV2aWFuY2UgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBtb2RlbHNdOyAoMykgY29tcGFyZSB0aGUgb2JzZXJ2ZWQgdmFsdWVzIG9mIHRoZSBzdGF0aXN0aWMgZnJvbSBmaXR0aW5nIHlvdXIgZnVsbCBtb2RlbCB0byB0aGUgZGF0YSB0byB0aGUgbnVsbCBkaXN0cmlidXRpb24gZ2VuZXJhdGVkIGluIHN0ZXAgMi4KLSBgUEJtb2Rjb21wYCBpbiB0aGUgYHBia3J0ZXN0YCBwYWNrYWdlCi0gc2VlIHRoZSBleGFtcGxlIGluIGBoZWxwKCJzaW11bGF0ZS1tZXIiKWAgaW4gdGhlIGBsbWU0YCBwYWNrYWdlIHRvIHJvbGwgeW91ciBvd24sIHVzaW5nIGEgY29tYmluYXRpb24gb2YgYHNpbXVsYXRlKClgIGFuZCBgcmVmaXQoKWAuCi0gYGJvb3RNZXJgIGluIGBsbWU0YCB2ZXJzaW9uID4xLjAuMAotIGEgcHJlc2VudGF0aW9uIGF0IFVzZVIhIDIwMDkgKFthYnN0cmFjdF0oaHR0cDovL3d3dy5hZ3JvY2FtcHVzLW91ZXN0LmZyL21hdGgvdXNlUi0yMDA5L2Fic3RyYWN0cy9wZGYvU2FuY2hlekVzcGlnYXJlcytPY2FuYS5wZGYpLCBbc2xpZGVzXShodHRwOi8vd3d3LmFncm9jYW1wdXMtb3Vlc3QuZnIvbWF0aC91c2VSLTIwMDkvc2xpZGVzL1NhbmNoZXpFc3BpZ2FyZXMrT2NhbmEucGRmKSkgd2VudCBpbnRvIGRldGFpbCBhYm91dCBhIHByb3Bvc2VkIGBib290TWVyYCBwYWNrYWdlIGFuZCBzdWdnZXN0ZWQgaXQgY291bGQgd29yayBmb3IgR0xNTXMgdG9vIC0tIApidXQgaXQgZG9lcyBub3Qgc2VlbSB0byBiZSBhY3RpdmUuCgojIyBQcmVkaWN0aW9ucyBhbmQvb3IgY29uZmlkZW5jZSAob3IgcHJlZGljdGlvbikgaW50ZXJ2YWxzIG9uIHByZWRpY3Rpb25zCgpOb3RlIHRoYXQgbm9uZSBvZiB0aGUgZm9sbG93aW5nIGFwcHJvYWNoZXMgdGFrZXMgdGhlIHVuY2VydGFpbnR5Cm9mIHRoZSByYW5kb20gZWZmZWN0cyBwYXJhbWV0ZXJzIGludG8gYWNjb3VudCAuLi4gaWYgeW91IHdhbnQgdG8gdGFrZSBSRSBwYXJhbWV0ZXIgdW5jZXJ0YWludHkgaW50byBhY2NvdW50LCBhIEJheWVzaWFuIGFwcHJvYWNoIGlzIHByb2JhYmx5IHRoZSBlYXNpZXN0IHdheSB0byBkbyBpdC4KClRoZSBnZW5lcmFsIHJlY2lwZSBmb3IgY29tcHV0aW5nIHByZWRpY3Rpb25zIGZyb20gYSBsaW5lYXIgb3IgZ2VuZXJhbGl6ZWQgbGluZWFyIG1vZGVsIGlzIHRvIAoKLSBmaWd1cmUgb3V0IHRoZSBtb2RlbCBtYXRyaXggJFgkIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG5ldyBkYXRhOwotICBtYXRyaXgtbXVsdGlwbHkgJFgkIGJ5IHRoZSBwYXJhbWV0ZXIgdmVjdG9yICRcYmV0YSQgdG8gZ2V0IHRoZSBwcmVkaWN0aW9ucyAob3IgbGluZWFyIHByZWRpY3RvciBpbiB0aGUgY2FzZSBvZiBHTE0oTSlzKTsgCi0gZXh0cmFjdCB0aGUgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXggb2YgdGhlIHBhcmFtZXRlcnMgJFYkIAotIGNvbXB1dGUgJFggViBYXntccHJpbWV9JCB0byBnZXQgdGhlIHZhcmlhbmNlLWNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBwcmVkaWN0aW9uczsgCi0gZXh0cmFjdCB0aGUgZGlhZ29uYWwgb2YgdGhpcyBtYXRyaXggdG8gZ2V0IHZhcmlhbmNlcyBvZiBwcmVkaWN0aW9uczsKLSBpZiBjb21wdXRpbmcgcHJlZGljdGlvbiByYXRoZXIgdGhhbiBjb25maWRlbmNlIGludGVydmFscywgYWRkIHRoZSByZXNpZHVhbCB2YXJpYW5jZTsgCi0gdGFrZSB0aGUgc3F1YXJlLXJvb3Qgb2YgdGhlIHZhcmlhbmNlcyB0byBnZXQgdGhlIHN0YW5kYXJkIGRldmlhdGlvbnMgKGVycm9ycykgb2YgdGhlIHByZWRpY3Rpb25zOyAKLSBjb21wdXRlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGJhc2VkIG9uIGEgTm9ybWFsIGFwcHJveGltYXRpb247Ci0gZm9yIEdMKE0pTXMsIHJ1biB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBib3VuZGFyaWVzIChub3QgdGhlIHN0YW5kYXJkIGVycm9ycykgdGhyb3VnaCB0aGUgaW52ZXJzZS1saW5rIGZ1bmN0aW9uLgoKIyMjIGxtZQoKYGBge3IgbG1lcHJlZCxjYWNoZT1UUlVFLG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkobmxtZSkgCmZtMSA8LSBsbWUoZGlzdGFuY2UgfiBhZ2UqU2V4LCByYW5kb20gPSB+IDEgKyBhZ2UgfCBTdWJqZWN0LAogICAgICAgICAgIGRhdGEgPSBPcnRob2RvbnQpIApwbG90KE9ydGhvZG9udCxhc3A9ImZpbGwiKSAjIyBwbG90IHJlc3BvbnNlcyBieSBpbmRpdmlkdWFsCiMjIG5vdGUgdGhhdCBleHBhbmQuZ3JpZCgpIG9yZGVycyBmYWN0b3IgbGV2ZWxzIGJ5ICpvcmRlciBvZgojIyBhcHBlYXJhbmNlKiAtLSBtdXN0IG1hdGNoIGxldmVscyhPcnRob2RvbnQkU2V4KQpuZXdkYXQgPC0gZXhwYW5kLmdyaWQoYWdlPWMoOCwxMCwxMiwxNCksIFNleD1jKCJGZW1hbGUiLCJNYWxlIikpIApuZXdkYXQkcHJlZCA8LSBwcmVkaWN0KGZtMSwgbmV3ZGF0LCBsZXZlbCA9IDApCgojIyBbLTJdIGRyb3BzIHJlc3BvbnNlIGZyb20gZm9ybXVsYQpEZXNpZ25tYXQgPC0gbW9kZWwubWF0cml4KGZvcm11bGEoZm0xKVstMl0sIG5ld2RhdCkKcHJlZHZhciA8LSBkaWFnKERlc2lnbm1hdCAlKiUgdmNvdihmbTEpICUqJSB0KERlc2lnbm1hdCkpIApuZXdkYXQkU0UgPC0gc3FydChwcmVkdmFyKSAKbmV3ZGF0JFNFMiA8LSBzcXJ0KHByZWR2YXIrZm0xJHNpZ21hXjIpCgpsaWJyYXJ5KGdncGxvdDIpIApwZCA8LSBwb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjQpIApnMCA8LSBnZ3Bsb3QobmV3ZGF0LGFlcyh4PWFnZSx5PXByZWQsY29sb3VyPVNleCkpKyAKICAgZ2VvbV9wb2ludChwb3NpdGlvbj1wZCkKY211bHQgPC0gMiAgIyMgY291bGQgdXNlIDEuOTYgaW5zdGVhZApnMCArIGdlb21fbGluZXJhbmdlKGFlcyh5bWluPXByZWQtY211bHQqU0UseW1heD1wcmVkK2NtdWx0KlNFKSwgcG9zaXRpb249cGQpCgojIyBwcmVkaWN0aW9uIGludGVydmFscyAKZzAgKyBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbj1wcmVkLWNtdWx0KlNFMix5bWF4PXByZWQrY211bHQqU0UyKSwgcG9zaXRpb249cGQpIApgYGAKCkEgc2ltaWxhciBhbnN3ZXIgaXMgbGFpZCBvdXQgaW4gdGhlIHJlc3BvbnNlcyB0byB0aGlzIFtTdGFja092ZXJmbG93IHF1ZXN0aW9uXShodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE0MzU4ODExL2V4dHJhY3QtcHJlZGljdGlvbi1iYW5kLWZyb20tbG1lLWZpdCkuCgojIyMgbG1lNAoKQ3VycmVudCB2ZXJzaW9ucyBvZiBsbWU0IGhhdmUgYSBgcHJlZGljdGAgbWV0aG9kLgoKYGBge3IgbG1lNHByZWQsY2FjaGU9VFJVRX0KbGlicmFyeShsbWU0KQpsaWJyYXJ5KGdncGxvdDIpCmRhdGEoIk9ydGhvZG9udCIscGFja2FnZT0iTUVNU1MiKQpmbTEgPC0gbG1lcigKCWZvcm11bGEgPSBkaXN0YW5jZSB+IGFnZSpTZXggKyAoYWdlfFN1YmplY3QpCgksIGRhdGEgPSBPcnRob2RvbnQKKQpuZXdkYXQgPC0gZXhwYW5kLmdyaWQoCglhZ2U9Yyg4LDEwLDEyLDE0KQoJLCBTZXg9YygiRmVtYWxlIiwiTWFsZSIpCgksIGRpc3RhbmNlID0gMAopCm5ld2RhdCRkaXN0YW5jZSA8LSBwcmVkaWN0KGZtMSxuZXdkYXQscmUuZm9ybT1OQSkKbW0gPC0gbW9kZWwubWF0cml4KHRlcm1zKGZtMSksbmV3ZGF0KQojIyBvciBuZXdkYXQkZGlzdGFuY2UgPC0gbW0gJSolIGZpeGVmKGZtMSkKcHZhcjEgPC0gZGlhZyhtbSAlKiUgdGNyb3NzcHJvZCh2Y292KGZtMSksbW0pKQp0dmFyMSA8LSBwdmFyMStWYXJDb3JyKGZtMSkkU3ViamVjdFsxXSAgIyMgbXVzdCBiZSBhZGFwdGVkIGZvciBtb3JlIGNvbXBsZXggbW9kZWxzCmNtdWx0IDwtIDIgIyMgY291bGQgdXNlIDEuOTYKbmV3ZGF0IDwtIGRhdGEuZnJhbWUoCgluZXdkYXQKCSwgcGxvID0gbmV3ZGF0JGRpc3RhbmNlLWNtdWx0KnNxcnQocHZhcjEpCgksIHBoaSA9IG5ld2RhdCRkaXN0YW5jZStjbXVsdCpzcXJ0KHB2YXIxKQoJLCB0bG8gPSBuZXdkYXQkZGlzdGFuY2UtY211bHQqc3FydCh0dmFyMSkKCSwgdGhpID0gbmV3ZGF0JGRpc3RhbmNlK2NtdWx0KnNxcnQodHZhcjEpCikKI3Bsb3QgY29uZmlkZW5jZQpnMCA8LSBnZ3Bsb3QobmV3ZGF0LCBhZXMoeD1hZ2UsIHk9ZGlzdGFuY2UsIGNvbG91cj1TZXgpKStnZW9tX3BvaW50KCkKZzAgKyBnZW9tX3BvaW50cmFuZ2UoYWVzKHltaW4gPSBwbG8sIHltYXggPSBwaGkpKSsKICAgIGxhYnModGl0bGU9IkNJIGJhc2VkIG9uIGZpeGVkLWVmZmVjdHMgdW5jZXJ0YWludHkgT05MWSIpCiNwbG90IHByZWRpY3Rpb24KZzAgKyBnZW9tX3BvaW50cmFuZ2UoYWVzKHltaW4gPSB0bG8sIHltYXggPSB0aGkpKSsKICAgIGxhYnModGl0bGU9IkNJIGJhc2VkIG9uIEZFIHVuY2VydGFpbnR5ICsgUkUgdmFyaWFuY2UiKQpybSgiT3J0aG9kb250IikgIyMgY2xlYW4gdXAKYGBgCgojIyMgZ2xtbVRNQgoKYGBge3IgZ2xtbVRNQnByZWQsY2FjaGU9VFJVRX0KbGlicmFyeShnbG1tVE1CKQpkYXRhKE9ydGhvZG9udCxwYWNrYWdlPSJubG1lIikKZm0yIDwtIGdsbW1UTUIoZGlzdGFuY2UgfiBhZ2UqU2V4ICsgKGFnZSB8IFN1YmplY3QpLAogICAgICAgICAgICAgICAgZGF0YSA9IE9ydGhvZG9udCwKICAgICAgICAgICAgICAgIGZhbWlseT0iZ2F1c3NpYW4iKQoKIyMgbWFrZSBwcmVkaWN0aW9uIGRhdGEgZnJhbWUKbmV3ZGF0IDwtIGV4cGFuZC5ncmlkKGFnZT1jKDgsMTAsMTIsMTQpLCBTZXg9YygiRmVtYWxlIiwiTWFsZSIpKQojIyBkZXNpZ24gbWF0cml4IChmaXhlZCBlZmZlY3RzKQptbSA8LSBtb2RlbC5tYXRyaXgoZGVsZXRlLnJlc3BvbnNlKHRlcm1zKGZtMikpLG5ld2RhdCkKIyMgbGluZWFyIHByZWRpY3RvciAoZm9yIEdMTU1zLCBiYWNrLXRyYW5zZm9ybSB0aGlzIHdpdGggdGhlCiMjICBpbnZlcnNlIGxpbmsgZnVuY3Rpb24gKGUuZy4gcGxvZ2lzKCkgZm9yIGJpbm9taWFsLCBiZXRhOwojIyAgZXhwKCkgZm9yIFBvaXNzb24sIG5lZ2F0aXZlIGJpbm9taWFsCm5ld2RhdCRkaXN0YW5jZSA8LSBkcm9wKG1tICUqJSBmaXhlZihmbTIpW1siY29uZCJdXSkKcHJlZHZhciA8LSBkaWFnKG1tICUqJSB2Y292KGZtMilbWyJjb25kIl1dICUqJSB0KG1tKSkKbmV3ZGF0JFNFIDwtIHNxcnQocHJlZHZhcikgCm5ld2RhdCRTRTIgPC0gc3FydChwcmVkdmFyK3NpZ21hKGZtMileMikKYGBgCgooUHJvYmFibHkgb3Zlcmx5IGNvbXBsaWNhdGVkKSBgZ2dwbG90YCBjb2RlOgpgYGB7ciBnZ3Bsb3R9CmxpYnJhcnkoZ2dwbG90Mik7ICB0aGVtZV9zZXQodGhlbWVfYncoKSkKcGQgPC0gcG9zaXRpb25fZG9kZ2Uod2lkdGg9MC40KQpnMCA8LSBnZ3Bsb3QoT3J0aG9kb250LGFlcyh4PWFnZSx5PWRpc3RhbmNlLGNvbG91cj1TZXgpKSsKICAgIHN0YXRfc3VtKGFscGhhPTAuMixhZXMoc2l6ZT0uLm4uLikpKwogICAgc2NhbGVfc2l6ZV9jb250aW51b3VzKGJyZWFrcz0xOjQscmFuZ2U9YygyLDUpKQpnMSA8LSBnMCtnZW9tX2xpbmUoZGF0YT1uZXdkYXQscG9zaXRpb249cGQpKwogICAgZ2VvbV9wb2ludChkYXRhPW5ld2RhdCxzaGFwZT0xNyxzaXplPTMscG9zaXRpb249cGQpCiMjIGNvbmZpZGVuY2UgaW50ZXJ2YWxzCmcyIDwtIGcxICsgZ2VvbV9saW5lcmFuZ2UoZGF0YT1uZXdkYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHltaW49ZGlzdGFuY2UtMipTRSx5bWF4PWRpc3RhbmNlKzIqU0UpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGx3ZD0yLCBwb3NpdGlvbj1wZCkKIyMgcHJlZGljdGlvbiBpbnRlcnZhbHMgCmcyICsgZ2VvbV9saW5lcmFuZ2UoZGF0YT1uZXdkYXQsCiAgICAgICAgICAgICAgICAgICAgYWVzKHltaW49ZGlzdGFuY2UtMipTRTIseW1heD1kaXN0YW5jZSsyKlNFMiksIHBvc2l0aW9uPXBkKQpgYGAKClRoZSBgZWZmZWN0c2AsIGBlbW1lYW5zYCwgYW5kIGBzalBsb3RgIHBhY2thZ2VzIGFyZSBhbHNvIHVzZWZ1bCBoZXJlLgoKIyMgQ29uZmlkZW5jZSBpbnRlcnZhbHMgb24gY29uZGl0aW9uYWwgbWVhbnMvQkxVUHMvcmFuZG9tIGVmZmVjdHMKCiMjIyBsbWU0IAoKKEZyb20gSGFyb2xkIERvcmFuLCB1cGRhdGVkIGJ5IEFzc2FmIE9yb24gTm92LiAyMDEzOikKCklmIHlvdSB3YW50IHRoZSBzdGFuZGFyZCBlcnJvcnMgb2YgdGhlIGNvbmRpdGlvbmFsIG1lYW5zLCB5b3UgY2FuIGV4dHJhY3QgdGhlbSBhcyBmb2xsb3dzOgpgYGB7ciBzdGRlcl9jb25kbWVhbnN9CmxpYnJhcnkobG1lNCkKZm0xIDwtIGxtZXIoUmVhY3Rpb24gfiBEYXlzICsgKERheXN8U3ViamVjdCksIHNsZWVwc3R1ZHkpCmNWIDwtIHJhbmVmKGZtMSwgY29uZFZhciA9IFRSVUUpICAgCmBgYApgY1ZgIGlzIGEgbGlzdDsgZWFjaCBlbGVtZW50IGlzIGEgZGF0YSBmcmFtZSBjb250YWluaW5nIHRoZSBjb25kaXRpb25hbCBtb2RlcyBmb3IgYSBwYXJ0aWN1bGFyIGdyb3VwaW5nIGZhY3Rvci4gSWYgeW91IHVzZSBzY2FsYXIgcmFuZG9tIGVmZmVjdHMgKHR5cGljYWxseSByYW5kb20gaW50ZXJjZXB0cyksIHRoZW4gc3BlY2lmeWluZyBgcmFuZWYoLi4uLGRyb3A9VFJVRSlgIHdpbGwgcmV0dXJuIHRoZSBjb25kaXRpb25hbCBtb2RlcyBhcyBhIHNpbmdsZSBuYW1lZCB2ZWN0b3IgaW5zdGVhZC4KClRoZSBjb25kaXRpb25hbCB2YXJpYW5jZXMgYXJlIHJldHVybmVkIGFzIGFuIGF0dHJpYnV0ZSBvZiB0aGUgY29uZGl0aW9uYWwgbW9kZXMuCkl0IG1heSBiZSBlYXNpZXN0IHRvIHVzZSBgYXMuZGF0YS5mcmFtZShjVilgLCBvciBgYnJvb20ubWl4ZWQ6OnRpZHkoZm0xLCBlZmZlY3RzPSJyYW5fdmFscyIpYCwgdG8gZXh0cmFjdCBhbGwgb2YgdGhlIGNvbmRpdGlvbmFsIG1lYW5zIGFuZCBzdGFuZGFyZCBkZXZpYXRpb25zLgoKT3IsIGRpZ2dpbmcgaW4gdG8gdGhlIGRhdGEgc3RydWN0dXJlIGJ5IGhhbmQ6IGlmIHdlIHNldApgYGB7ciByYW52YXJ9CnJhbnZhciA8LSBhdHRyKGNWW1sxXV0sICJwb3N0VmFyIikKYGBgCnRoZW4gYHJhbnZhcmAgaXMgYSAzLUQgYXJyYXkgKHRoZSBhdHRyaWJ1dGUgaXMgc3RpbGwgY2FsbGVkIGBwb3N0VmFyYCwgcmF0aGVyIHRoYW4gYGNvbmRWYXJgLCBmb3IgaGlzdG9yaWNhbCByZWFzb25zL2JhY2t3YXJkIGNvbXBhdGliaWxpdHkpLiBJbmRpdmlkdWFsLWxldmVsIGNvdmFyaWFuY2UgbWF0cmljZXMgb2YgdGhlIGNvbmRpdGlvbmFsIG1vZGVzIHdpbGwgc2l0IG9uIHRoZSBgWywsaV1gIGZhY2VzLiBGb3IgZXhhbXBsZSwgYHJhbnZhclssLDFdYCBpcyB0aGUgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXggb2YgdGhlIGNvbmRpdGlvbmFsIGRpc3RyaWJ1dGlvbiBmb3IgdGhlIGZpcnN0IGdyb3VwLCBzbwpgYGB7ciBzcXJ0ZGlhZ3JhbnZhcnN9CnNxcnQoZGlhZyhyYW52YXJbLCwxXSkpCmBgYAp3aWxsIHByb3ZpZGUgdGhlIGludGVyY2VwdCBhbmQgc2xvcGUgc3RhbmRhcmQgc3RhbmRhcmQgZGV2aWF0aW9ucyBmb3IgdGhlIGZpcnN0IGdyb3VwJ3MgY29uZGl0aW9uYWwgbW9kZXMuIElmIHlvdSBoYXZlIGEgc2NhbGFyIHJhbmRvbSBlZmZlY3QgYW5kIHVzZWQgYGRyb3A9VFJVRWAgaW4gYHJhbmVmKClgLCB0aGVuIHlvdSB3aWxsIChtZXJjaWZ1bGx5KSByZWNlaXZlIG9ubHkgYSB2ZWN0b3Igb2YgaW5kaXZpZHVhbCB2YXJpYW5jZXMgaGVyZSAob25lIGZvciBlYWNoIGxldmVsIG9mIHRoZSBncm91cGluZyBmYWN0b3IpLiBUaGUgZm9sbG93aW5nIGluY2FudGF0aW9uIHdpbGwgZ2l2ZSBhIG1hdHJpeCBvZiBjb25kaXRpb25hbCB2YXJpYW5jZXMgd2l0aCBvbmUgcm93IGZvciBlYWNoIGdyb3VwIGFuZCBvbmUgY29sdW1uIGZvciBlYWNoIHBhcmFtZXRlcnM6CmBgYHtyIHJhbnNlfQpuZyA8LSBkaW0ocmFudmFyKVszXQpucCA8LSBkaW0ocmFudmFyKVsyXQptbSA8LSBtYXRyaXgocmFudmFyW2NiaW5kKHJlcChzZXEobnApLG5nKSwKICAgICAgICAgICAgIHJlcChzZXEobnApLG5nKSwKICAgICAgICAgICAgIHJlcChuZyxlYWNoPW5wKSldLAogICAgICAgYnlyb3c9VFJVRSwKICAgICAgIG5yb3c9bmcpCmBgYCAgICAgICAgICAgICAKCkdldHRpbmcgdGhlIHVuY2VydGFpbnR5IG9mIHRoZSBjb2VmZmljaWVudHMgKGkuZS4sIHdoYXQncyByZXR1cm5lZCBieSBgY29lZigpYDogdGhlIHN1bSBvZiB0aGUgZml4ZWQtZWZmZWN0IGFuZCByYW5kb20tZWZmZWN0IHByZWRpY3Rpb25zIGZvciBhIHBhcnRpY3VsYXIgbGV2ZWwpIGlzIG5vdCAoYWxhcykgY3VycmVudGx5IGVhc3kgd2l0aCBgbG1lNGAuIElmIHRoZSBmaXhlZCBhbmQgcmFuZG9tIGVmZmVjdHMgd2VyZSBpbmRlcGVuZGVudCB0aGVuIHdlIGNvdWxkIHNpbXBseSBhZGQgdGhlIGNvbmRpdGlvbmFsIHZhcmlhbmNlIGFuZCB0aGUgdmFyaWFuY2Ugb2YgdGhlIGZpeGVkLWVmZmVjdCBwcmVkaWN0aW9ucywgYnV0IHRoZXkgYXJlbid0IGluIGdlbmVyYWwuIFRoZXJlIGlzIGEgbG9uZyBbci1zaWctbWl4ZWQtbW9kZWxzIG1haWxpbmcgbGlzdCB0aHJlYWRdKGh0dHBzOi8vc3RhdC5ldGh6LmNoL3BpcGVybWFpbC9yLXNpZy1taXhlZC1tb2RlbHMvMjAxM3ExLzAxOTc5NS5odG1sKSB0aGF0IGRpc2N1c3NlcyB0aGUgaXNzdWVzLCBmb2N1c2luZyBvbiAoMSkgaG93IHRvIGV4dHJhY3QgdGhlIGNvdmFyaWFuY2UgYmV0d2VlbiBmaXhlZC1lZmZlY3QgZXN0aW1hdGUgYW5kIHRoZSByYW5kb20tZWZmZWN0IHByZWRpY3Rpb247ICgyKSB3aGV0aGVyIHRoaXMgdmFsdWUgKHRoZSBjb3ZhcmlhbmNlIGJldHdlZW4gYW4gKmVzdGltYXRlZCogcGFyYW1ldGVyIGFuZCBhICpwcmVkaWN0ZWQqIG1vZGUgb2YgYSBjb25kaXRpb25hbCBkaXN0cmlidXRpb24gb2YgYSByYW5kb20gdmFyaWFibGUpIGV2ZW4gbWFrZXMgc2Vuc2UgaW4gYSBmcmVxdWVudGlzdCBmcmFtZXdvcmsuIElmIHlvdSdyZSB3aWxsaW5nIHRvICphc3N1bWUqIGluZGVwZW5kZW5jZSBvZiB0aGUgY29uZGl0aW9uYWwgdmFyaWFuY2UgYW5kIHRoZSBmaXhlZC1lZmZlY3Qgc2FtcGxpbmcgdmFyaWFuY2UsIHRoZW4gKGUuZy4pIHRoZSB2YXJpYW5jZSBvZiB0aGUgaW50ZXJjZXB0cyBmb3IgZWFjaCBncm91cCB3b3VsZCBiZSB0aGUgc3VtIG9mIHRoZSBmaXhlZC1lZmZlY3QgaW50ZXJjZXB0IHZhcmlhbmNlIGFuZCB0aGUgY29uZGl0aW9uYWwgdmFyaWFuY2Ugb2YgdGhlIGludGVyY2VwdCBmb3IgZWFjaCBncm91cDoKCmBgYHtyIGNvbWJ9CnZjb3YoZm0xKVsxLDFdK21tWywxXQpgYGAKCiMjIFBvd2VyIGFuYWx5c2lzCgpQb3dlciBhbmFseXNpcyBmb3IgKEcpTE1NcyBpcyBtb3N0bHkgZG9uZSBieSBzaW11bGF0aW9uLCBhbHRob3VnaAp0aGVyZSBhcmUgc29tZSBjbG9zZWQtZm9ybSBzb2x1dGlvbnMgYW5kIGFwcHJveGltYXRpb25zLCBlLmcuCkBzbmlqZGVyc19zdGFuZGFyZF8xOTkzIChTbmlqZGVycyBoYXMgbGlua3MgdG8gcHJvZ3JhbXMgYW5kIG90aGVyIHJlc291cmNlcwpvbiBbaGlzIHdlYiBwYWdlXShodHRwczovL3d3dy5zdGF0cy5veC5hYy51ay9+c25pamRlcnMvbXVsdGlsZXZlbC5odG0pKS4gVGhlcmUgYXJlIHJlc291cmNlcyBhbmQgYml0cyBvZiBjb2RlIGV4YW1wbGVzIHNwcmVhZCBhbGwgb3ZlciB0aGUgaW50ZXJuZXQuIGUuZy4gW2hlcmVdKGh0dHBzOi8vcnB1YnMuY29tL2Jib2xrZXIvMTE3MDMpLgoKQGthaW5fcHJhY3RpY2FsXzIwMTUgYW5kIEBqb2huc29uX3Bvd2VyXzIwMTUgYXJlIHBlZXItcmV2aWV3ZWQgcGFwZXJzCnRoYXQgZGlzY3VzcyBwb3dlciBhbmFseXNpcyB2aWEgc2ltdWxhdGlvbiBpbiBtb3JlIGRldGFpbC4KCmBgYHtyIGV2YWw9RkFMU0V9CmxpYnJhcnkoc29zKTsgZmluZEZuKCJ7cG93ZXIgYW5hbHlzaXN9IG1peGVkIHNpbXVsYXRpb24iKQpgYGAKbG9jYXRlcyB0aGUgYGZ1bGxmYWN0YCwgYHBhbW1gLCBgc2ltcmAsIGFuZCBgc2ltZ2xtYCBwYWNrYWdlcy4KRGVwZW5kaW5nIG9uIHRoZSBnb2FsLCBvbmUgb2YgdGhlc2UgcGFja2FnZXMgbWF5IGhhdmUgc3VmZmljaWVudApmbGV4aWJpbGl0eSB0byBkbyB3aGF0IHlvdSB3YW50LgoKIyBNb2RlbCBzZWxlY3Rpb24gYW5kIGF2ZXJhZ2luZwoKIyMgQ2FuIEkgdXNlIEFJQyBmb3IgbWl4ZWQgbW9kZWxzPyAgSG93IGRvIEkgY291bnQgdGhlIG51bWJlciBvZiBkZWdyZWVzIG9mIGZyZWVkb20gZm9yIGEgcmFuZG9tIGVmZmVjdD8KCi0gWWVzLCB3aXRoIGNhdXRpb24uCi0gSXQgZGVwZW5kcyBvbiB0aGUgImxldmVsIG9mIGZvY3VzIiAoKnNlbnN1KiBAc3BpZWdlbGhhbHRlcl9iYXllc2lhbl8yMDAyKSB3aGV0aGVyIChlLmcuKSBhIHNpbmdsZSByYW5kb20tZWZmZWN0IHZhcmlhbmNlIHNob3VsZCBiZSBjb3VudGVkIGFzIDEgZGVncmVlIG9mIGZyZWVkb20gKGkuZS4sIHRoZSB2YXJpYW5jZSBwYXJhbWV0ZXIgb3IgYXMgYSB2YWx1ZSBiZXR3ZWVuIDEgYW5kIE4tMSAod2hlcmUgTiBpcyB0aGUgbnVtYmVyIG9mIGdyb3Vwcyk6IHNlZSBAdmFpZGFfY29uZGl0aW9uYWxfMjAwNSBhbmQgQGdyZXZlbl9iZWhhdmlvdXJfMjAxMC4gIElmIHlvdSBhcmUgaW50ZXJlc3RlZCBpbiBwb3B1bGF0aW9uLWxldmVsIHByZWRpY3Rpb24vaW5mZXJlbmNlLCB0aGVuIHRoZSBmb3JtZXIgKGNhbGxlZCAqbWFyZ2luYWwgQUlDKiBbbUFJQ10pOyBpZiBpbmRpdmlkdWFsLWxldmVsIHByZWRpY3Rpb24vaW5mZXJlbmNlIChpLmUuLCB1c2luZyB0aGUgQkxVUHMvY29uZGl0aW9uYWwgbW9kZXMpLCB0aGVuIHRoZSBsYXR0ZXIgKGNhbGxlZCAqY29uZGl0aW9uYWwgQUlDKiBbY0FJQ10pLiBHcmV2ZW4gYW5kIEtuZWliIHByZXNlbnQgcmVzdWx0cyBmb3IgbGluZWFyIG1vZGVscywgZ2l2aW5nIGEgdmVyc2lvbiBvZiBjQUlDIHRoYXQgaXMgYm90aCBjb21wdXRhdGlvbmFsbHkgZWZmaWNpZW50IGFuZCB0YWtlcyB1bmNlcnRhaW50eSBpbiB0aGUgZXN0aW1hdGlvbiBvZiB0aGUgdmFyaWFuY2VzIGludG8gYWNjb3VudC4gIChCb2IgTydIYXJhIGhhcyBhIHZlcnkgbmljZSwgaWxsdXN0cmF0aXZlIFtibG9nIHBvc3RdKGh0dHA6Ly9kZWVwdGhvdWdodHNhbmRzaWxsaW5lc3MuYmxvZ3Nwb3QuY2EvMjAwNy8xMi9mb2N1cy1vbi1kaWMuaHRtbCkgb24gdGhpcyB0b3BpYyBpbiB0aGUgY29udGV4dCBvZiBESUMgLi4uKQotIGluIGNhc2VzIHdoZW4gdGVzdGluZyBhIHZhcmlhbmNlIHBhcmFtZXRlciwgQUlDIG1heSBiZSBzdWJqZWN0IHRvIHRoZSBzYW1lIGtpbmRzIG9mIGJvdW5kYXJ5IGVmZmVjdHMgYXMgbGlrZWxpaG9vZCByYXRpbyB0ZXN0IHAtdmFsdWVzIChpLmUuLCBBSUNzIG1heSBiZSBjb25zZXJ2YXRpdmUvb3ZlcmZpdCBzbGlnaHRseSB3aGVuIHRoZSBuZXN0ZWQgcGFyYW1ldGVyIHZhbHVlIGlzIG9uIHRoZSBib3VuZGFyeSBvZiB0aGUgZmVhc2libGUgc3BhY2UpLiBAZ3JldmVuX2JlaGF2aW91cl8yMDEwIGV4cGxvcmUgdGhlIHByb2JsZW1zIHdpdGggbUFJQyBpbiB0aGlzIGNvbnRleHQsIGJ1dCBkbyBub3Qgc3VnZ2VzdCBhIHNvbHV0aW9uICh0aGV5IHBvaW50IG91dCB0aGF0IEBodWdoZXNfbW9kZWxfMjAwMyBwcmVzZW50IGEgJ29uZS1zaWRlZCcgQUlDLCBidXQgbm90IG9uZSB0aGF0IGRlYWxzIHdpdGggdGhlIG5vbi1pbmRlcGVuZGVuY2Ugb2YgZGF0YSBwb2ludHMuICBJIGhhdmVuJ3QgcmVhZCBIdWdoZXMgYW5kIEtpbmcsIEkgc2hvdWxkIGdvIGRvIHRoYXQpLgotIEFJQyBhbHNvIGluaGVyaXRzIHRoZSBwcmltYXJ5IHByb2JsZW0gb2YgbGlrZWxpaG9vZCByYXRpbyB0ZXN0cyBpbiB0aGUgR0xNTSBjb250ZXh0IC0tIHRoYXQgaXMsIHRoYXQgTFJUcyBhcmUgYXN5bXB0b3RpYyB0ZXN0cy4gQSBmaW5pdGUtc2l6ZSBjb3JyZWN0aW9uIGZvciBBSUMgZG9lcyBleGlzdCAoQUlDYykgLS0gYnV0IGl0IHdhcyBkZXZlbG9wZWQgaW4gdGhlIGNvbnRleHQgb2YgbGluZWFyIG1vZGVscy4gQXMgZmFyIGFzIEkga25vdyBpdHMgYWRlcXVhY3kgaW4gdGhlIEdMTU0gY2FzZSBoYXMgbm90IGJlZW4gZXN0YWJsaXNoZWQuIFNlZSBlLmcuIEByaWNoYXJkc190ZXN0aW5nXzIwMDUgZm9yIGNhdXRpb24gYWJvdXQgQUlDYyBpbiB0aGUgR0xNIChub3QgR0xNTSkgY2FzZS4KLSBsbWU0IGFuZCBubG1lIGNvdW50IHBhcmFtZXRlcnMgZm9yIEFJQyhjKSBhcyBmb2xsb3dzOgogICAgLSB0aGUgbnVtYmVyIG9mIGZpeGVkLWVmZmVjdCBwYXJhbWV0ZXJzIGlzIHN0cmFpZ2h0Zm9yd2FyZCAodGhlIGxlbmd0aCBvZiB0aGUgZml4ZWQtZWZmZWN0IHBhcmFtZXRlciB2ZWN0b3IgYmV0YSwgaS5lLiBgbGVuZ3RoKGZpeGVmKG1vZGVsKSlgKQoJLSBlYWNoIHJhbmRvbSB0ZXJtIGluIHRoZSBtb2RlbCB3aXRoICRxJCBjb21wb25lbnRzIGNvdW50cyBmb3IgJHEocSsxKS8yJCBwYXJhbWV0ZXJzIC0tIGZvciBleGFtcGxlLCBhIHRlcm0gb2YgdGhlIGZvcm0gKHNsb3BlfGdyb3VwKSBoYXMgMyBwYXJhbWV0ZXJzIChpbnRlcmNlcHQgdmFyaWFuY2UsIHNsb3BlIHZhcmlhbmNlLCBjb3JyZWxhdGlvbiBiZXR3ZWVuIGludGVyY2VwdCBhbmQgc2xvcGUpLgogICAgLSBtb2RlbHMgdGhhdCB1c2UgYSBzY2FsZSBwYXJhbWV0ZXIgKGUuZy4gdGhlIHZhcmlhbmNlIHBhcmFtZXRlciBvZiBsaW5lYXIgbWl4ZWQgbW9kZWxzLCBvciB0aGUgc2NhbGUgcGFyYW1ldGVyIG9mIGEgR2FtbWEgR0xNTSAtLSBzdGFuZGFyZCBHTE1NcyBzdWNoIGFzIGJpbm9taWFsIGFuZCBQb2lzc29uIGRvIG5vdCkgZ2V0IGFuIGV4dHJhIHBhcmFtZXRlciBjb3VudGVkLiBXaGV0aGVyIHRvIGFkZCBudWlzYW5jZSBwYXJhbWV0ZXJzIG9yIG5vdCwgc3VjaCBhcyB0aGUgcmVzaWR1YWwgdmFyaWFuY2UgcGFyYW1ldGVyIChlc3RpbWF0ZWQgYmFzZWQgb24gdGhlIHJlc2lkdWFsIHZhcmlhbmNlLCByYXRoZXIgdGhhbiBhbiBleHBsaWNpdCBwYXJhbWV0ZXIgaW4gdGhlIG9wdGltaXphdGlvbikgaXMgYXMgZmFyIGFzIEkga25vdyBhbiBvcGVuIHF1ZXN0aW9uLiAgSW4gdGhlIGNsYXNzaWMgQUlDIGNvbnRleHQgaXQgZG9lc24ndCBtYXR0ZXIgYXMgbG9uZyBhcyBvbmUgaXMgY29uc2lzdGVudC4gIEluIHRoZSBBSUNjIGNvbnRleHQsIEkgZG9uJ3QgdGhpbmsgYW55b25lIHJlYWxseSBrbm93cyB0aGUgYW5zd2VyIC4uLiBhZGRpbmcgKzEgZm9yIHRoZSByZXNpZHVhbCB2YXJpYW5jZSBwYXJhbWV0ZXIgKGFzIGxtZTQgZG9lcykgd291bGQgbWFrZSB0aGUgbW9kZWwgc2VsZWN0aW9uIHByb2Nlc3Mgc2xpZ2h0bHkgbW9yZSBjb25zZXJ2YXRpdmUuCgojIE1vZGVsIHN1bW1hcmllcyAoZ29vZG5lc3Mtb2YtZml0LCBkZWNvbXBvc2l0aW9uIG9mIHZhcmlhbmNlLCBldGMuKQoKIyMgSG93IGRvIEkgY29tcHV0ZSBhIGNvZWZmaWNpZW50IG9mIGRldGVybWluYXRpb24gKCRSXjIkKSwgb3IgYW4gYW5hbG9ndWUsIGZvciAoRylMTU1zPwoKIyMjIFByb2JsZW0KCigqVGhpcyB0b3BpYyBhcHBsaWVzIHRvIGJvdGggTE1NcyBhbmQgR0xNTXMsIHBlcmhhcHMgbW9yZSBzbyB0byBMTU1zLCBiZWNhdXNlIHRoZSBpc3N1ZXMgYXJlIGV2ZW4gaGFyZGVyIGZvciBHTE1Ncy4qKQoKUmVzZWFyY2hlcnMgb2Z0ZW4gd2FudCB0byBrbm93IGlmIHRoZXJlIGlzIGEgc2ltcGxlIChvciBhdCBsZWFzdCBpbXBsZW1lbnRlZC1pbi1SKSB3YXkgdG8gZ2V0IGFuIGFuYWxvZ3VlIG9mICRSXjIkIG9yIGFub3RoZXIgc2ltcGxlIGdvb2RuZXNzLW9mLWZpdCBtZXRyaWMgZm9yIExNTXMgb3IgR0xNTXMuIFRoaXMgaXMgYSBjaGFsbGVuZ2luZyBxdWVzdGlvbiBpbiBib3RoIHRoZSBHTE0gYW5kIExNTSB3b3JsZHMgKGFuZCB0aGVyZWZvcmUgZG91Ymx5IHNvIGZvciBHTE1NcyksIGJlY2F1c2UgaXQgdHVybnMgb3V0IHRoYXQgdGhlIHdvbmRlcmZ1bCBzaW1wbGljaXR5IG9mICRSXjIkIGJyZWFrcyBkb3duIGluIHRoZSBleHRlbnNpb24gdG8gR0xNcyBvciBMTU1zLiBJZiB5b3UncmUgdHJ5aW5nIHRvIHF1YW50aWZ5ICJmcmFjdGlvbiBvZiB2YXJpYW5jZSBleHBsYWluZWQiIGluIHRoZSBHTE0gY29udGV4dCwgc2hvdWxkIHlvdSBpbmNsdWRlIG9yIGV4Y2x1ZGUgc2FtcGxpbmcgdmFyaWF0aW9uIChlLmcuLCBQb2lzc29uIHZhcmlhdGlvbiBhcm91bmQgdGhlIGV4cGVjdGVkIG1lYW4pPyBbQWNjb3JkaW5nIHRvIGFuIGBzb3M6OmZpbmRGbmAgc2VhcmNoIGZvciAiTmFnZWxrZXJrZSIsIG9uZSBvZiB0aGUgY29tbW9uIHNvbHV0aW9ucyB0byB0aGlzIHByb2JsZW0sIHRoZSBgTG9nUmVnUjJgIGZ1bmN0aW9uIGluIHRoZSBgZGVzY3JgIHBhY2thZ2UgY29tcHV0ZXMgc2V2ZXJhbCBkaWZmZXJlbnQgInBzZXVkby0kUl4yJCIgbWVhc3VyZXMgZm9yIGxvZ2lzdGljIHJlZ3Jlc3Npb24uXSAgSWYgeW91J3JlIHRyeWluZyB0byBxdWFudGlmeSBpdCBpbiB0aGUgTE1NIGNvbnRleHQsIHNob3VsZCB5b3UgaW5jbHVkZSBvciBleGNsdWRlIHZhcmlhdGlvbiBvZiBkaWZmZXJlbnQgcmFuZG9tLWVmZmVjdHMgdGVybXM/CgpUaGUgc2FtZSBxdWVzdGlvbnMgYXBwbHkgbW9yZSBnZW5lcmFsbHkgdG8gZGVjb21wb3NpdGlvbiBvZiB2YXJpYW5jZSAoaS5lLiB0cnlpbmcgdG8gYXNzZXNzIHRoZSBjb250cmlidXRpb24gb2YgdmFyaW91cyBtb2RlbCBjb21wb25lbnRzIHRvIHRoZSBvdmVyYWxsIGZpdCwgbm90IGp1c3QgdHJ5aW5nIHRvIGFzc2VzcyB0aGUgb3ZlcmFsbCBnb29kbmVzcy1vZi1maXQgb2YgdGhlIG1vZGVsKTsgdGhlcmUgaXMgdW5saWtlbHkgdG8gYmUgYSBzaW5nbGUgcmVjaXBlIHRoYXQgZG9lcyBldmVyeXRoaW5nIHlvdSB3YW50LgoKVGhpcyBoYXMgYmVlbiBkaXNjdXNzZWQgYXQgdmFyaW91cyB0aW1lcyBvbiB0aGUgbWFpbGluZyBsaXN0cy4gW1RoaXMgdGhyZWFkXShodHRwOi8vdGhyZWFkLmdtYW5lLm9yZy9nbWFuZS5jb21wLmxhbmcuci5sbWU0LmRldmVsLzMyODEpIGFuZCBbdGhpcyB0aHJlYWRdKGh0dHA6Ly90aHJlYWQuZ21hbmUub3JnL2dtYW5lLmNvbXAubGFuZy5yLmxtZTQuZGV2ZWwvNjg0KSBvbiB0aGUgci1zaWctbWl4ZWQtbW9kZWxzICBtYWlsaW5nIGxpc3QgYXJlIGdvb2Qgc3RhcnRpbmcgcG9pbnRzLCBhbmQgW3RoaXMgcG9zdF0oaHR0cDovL3RocmVhZC5nbWFuZS5vcmcvZ21hbmUuY29tcC5sYW5nLnIubG1lNC5kZXZlbC8yMTQzKSBpcyB1c2VmdWwgdG9vLgoKSW4gb25lIG9mIHRob3NlIHRocmVhZHMsIERvdWcgQmF0ZXMgc2FpZDoKCj4gQXNzdW1pbmcgdGhhdCBvbmUgd2FudHMgdG8gZGVmaW5lIGFuIFJeMiBtZWFzdXJlLCBJIHRoaW5rIGFuCj4gYXJndW1lbnQgY291bGQgYmUgbWFkZSBmb3IgdHJlYXRpbmcgdGhlIHBlbmFsaXplZCByZXNpZHVhbCBzdW0gb2YKPiBzcXVhcmVzIGZyb20gYSBsaW5lYXIgbWl4ZWQgbW9kZWwgaW4gdGhlIHNhbWUgd2F5IHRoYXQgd2UgY29uc2lkZXIgdGhlCj4gcmVzaWR1YWwgc3VtIG9mIHNxdWFyZXMgZnJvbSBhIGxpbmVhciBtb2RlbC4gIE9yIG9uZSBjb3VsZCB1c2UganVzdAo+IHRoZSByZXNpZHVhbCBzdW0gb2Ygc3F1YXJlcyB3aXRob3V0IHRoZSBwZW5hbHR5IG9yIHRoZSBtaW5pbXVtCj4gcmVzaWR1YWwgc3VtIG9mIHNxdWFyZXMgb2J0YWluYWJsZSBmcm9tIGEgZ2l2ZW4gc2V0IG9mIHRlcm1zLCB3aGljaAo+IGNvcnJlc3BvbmRzIHRvIGFuIGluZmluaXRlIHByZWNpc2lvbiBtYXRyaXguICBJIGRvbid0IGtub3csIHJlYWxseS4KPiBJdCBkZXBlbmRzIG9uIHdoYXQgeW91IGFyZSB0cnlpbmcgdG8gY2hhcmFjdGVyaXplLgoKIyMjIFNpbXBsZS9jcnVkZSBzb2x1dGlvbnMKCkluIG9uZSBvZiB0aG9zZSB0aHJlYWRzLCBKYXJyZXR0IEJ5cm5lcyBjb250cmlidXRlZCB0aGUgZm9sbG93aW5nIGNvZGU6CmBgYHtyIHIyY29ycn0KcjIuY29yci5tZXIgPC0gZnVuY3Rpb24obSkgewogICBsbWZpdCA8LSAgbG0obW9kZWwucmVzcG9uc2UobW9kZWwuZnJhbWUobSkpIH4gZml0dGVkKG0pKQogICBzdW1tYXJ5KGxtZml0KSRyLnNxdWFyZWQKfQpgYGAKCiRcT21lZ2FeMl8wJCBbQHh1X21lYXN1cmluZ18yMDAzXSwgd2hpY2ggaXMgYWxtb3N0IHRoZSBzYW1lLCBpcyBiYXNlZCBvbiBjb21wYXJpbmcgdGhlIHJlc2lkdWFsIHZhcmlhbmNlIG9mIHRoZSBmdWxsIG1vZGVsIGFnYWluc3QgdGhlIHJlc2lkdWFsIHZhcmlhbmNlIG9mIGEgKGZpeGVkKSBpbnRlcmNlcHQtb25seSBudWxsIG1vZGVsOiAKCmBgYHtyIHJlc3ZhcixldmFsPUZBTFNFfQoxLXZhcihyZXNpZHVhbHMobSkpL3Zhcihtb2RlbC5yZXNwb25zZShtb2RlbC5mcmFtZShtKSkpCmBgYAoKQW5vdGhlciBwb3NzaWJpbGl0eSBpcyB0aGUgc3F1YXJlZCBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSByZXNwb25zZSB2YXJpYWJsZSBhbmQgdGhlIHByZWRpY3RlZCB2YWx1ZXM6CgpgYGB7ciByZXNjb3JzcSwgZXZhbD1GQUxTRX0KY29yKG1vZGVsLnJlc3BvbnNlKG1vZGVsLmZyYW1lKG0pKSxwcmVkaWN0KG0sdHlwZT0icmVzcG9uc2UiKSleMgpgYGAKCiMjIyBTb3BoaXN0aWNhdGVkIHNvbHV0aW9ucwoKQGdlbG1hbl9iYXllc2lhbl8yMDA2IHByb3Bvc2UvZGlzY3VzcyBCYXllc2lhbiBtZWFzdXJlcyBvZiAkUl4yJCAoSSBkb24ndCBrbm93IGlmIGFueW9uZSBoYXMgY3JlYXRlZCBhIGNhbm5lZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGVzZSBtZWFzdXJlcyBpbiBSKS4KQG5ha2FnYXdhX2dlbmVyYWxfMjAxMyBhbmQgQGpvaG5zb25fZXh0ZW5zaW9uXzIwMTQgaGF2ZSBhbHNvIHByb3Bvc2VkIGEgZ2VuZXJhbCBtZXRob2RvbG9neSBmb3IgY29tcHV0aW5nICRSXjIkOyBKLiBMZWZjaGVjayBnaXZlcyBleGFtcGxlcyBbaGVyZV0oaHR0cHM6Ly9qb25sZWZjaGVjay5uZXQvMjAxMy8wMy8xMy9yMi1mb3ItbGluZWFyLW1peGVkLWVmZmVjdHMtbW9kZWxzLykgYW5kIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vanNsZWZjaGUvcGllY2V3aXNlU0VNL2Jsb2IvbWFzdGVyL1JFQURNRS5tZCNnZXQtcjItZm9yLWluZGl2aWR1YWwtbW9kZWxzKSwgYmFzZWQgb24gaGlzIGltcGxlbWVudGF0aW9uIGluIHRoZSBgcGllY2V3aXNlU0VNYCBwYWNrYWdlIChbQ1JBTl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3BpZWNld2lzZVNFTS9pbmRleC5odG1sKSwgW0dpdGh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL2pzbGVmY2hlL3BpZWNld2lzZVNFTSkpLiBTZWUgYWxzbyBAamFlZ2VyX3IyXzIwMTcsIEByaWdodHNfcXVhbnRpZnlpbmdfMjAxOCAuLi4KCkEgcmVsYXRlZCBxdWVzdGlvbiBpcyBob3cgdG8gcXVhbnRpZnkgInJlcGVhdGFiaWxpdHkiIChpLmUuLCByYXRpb3Mgb2YgdmFyaWFuY2UgYXQgZGlmZmVyZW50IGxldmVscykgaW4gR0xNTXMsIGVzcGVjaWFsbHkgaG93IHRvIGNvbXB1dGUgdGhlICJyZXNpZHVhbCBlcnJvciIgdGVybSBmb3IgR0xNTXM6IHNlZSBAbmFrYWdhd2FfcmVwZWF0YWJpbGl0eV8yMDEwIGFuZCB0aGUgW3JwdFIgcGFja2FnZV0oaHR0cDovL3JwdHIuci1mb3JnZS5yLXByb2plY3Qub3JnLykuCgpUaGUgYm90dG9tIGxpbmUgaXMgdGhhdCB0aGVyZSBhcmUgc29tZSBzaW1wbGUgcmVjaXBlcyAoYW5kIHNvbWUgbW9yZSBjb21wbGV4IHJlY2lwZXMgdGhhdCBtYXkgb3IgbWF5IG5vdCBoYXZlIGJlZW4gY29kZWQgdXAgYnkgc29tZW9uZSksIGJ1dCB0aGF0ICcnJ3lvdSBoYXZlIHRvIHRoaW5rIGNhcmVmdWxseSBhYm91dCB3aGF0IGluZm9ybWF0aW9uIHlvdSB3YW50IHRvIGdldCBvdXQgb2YgdGhlIGNvZWZmaWNpZW50IG9mIGRldGVybWluYXRpb24nJycsIGJlY2F1c2Ugbm8gcmVjaXBlIHdpbGwgaGF2ZSBhbGwgb2YgdGhlIHByb3BlcnRpZXMgb2YgJFJeMiQgaW4gdGhlIHNpbXBsZSBsaW5lYXIgbW9kZWwgY2FzZS4KCioqUGFja2FnZXMvZnVuY3Rpb25zKio6IFNlZSBbYHBlcmZvcm1hbmNlOjpyMigpYF0oaHR0cHM6Ly9lYXN5c3RhdHMuZ2l0aHViLmlvL3BlcmZvcm1hbmNlL3JlZmVyZW5jZS9yMi5odG1sKSwgYE11TUluOjpyLnNxdWFyZWRHTE1NKClgLCB0aGUgW2ByMmdsbW1gIHBhY2thZ2VdKGh0dHBzOi8vQ1JBTi5SLXByb2plY3Qub3JnL3BhY2thZ2U9cjJnbG1tKSwgdGhlIHN0YW5kYWxvbmUgW3IyTUxNIGZ1bmN0aW9uXShodHRwczovL215LnZhbmRlcmJpbHQuZWR1L2phc29ucmlnaHRzL3NvZnR3YXJlL3IyTUxNKSwgc3R1ZmYgaW4gdGhlIGBwaWVjZXdpc2VTRU1gIHBhY2thZ2UsIFtgcHN5Y2hvOjpSMl9uYWthZ2F3YWBdKGh0dHA6Ly9maW56aS5wc3ljaC51cGVubi5lZHUvUi9saWJyYXJ5L3BzeWNoby9odG1sL1IyX25ha2FnYXdhLmh0bWwpLCBbcGFydFIyXShodHRwczovL2dpdGh1Yi5jb20vbWFzdG9mZmVsL3BhcnRSMikgcGFja2FnZSAuLi4gKHRyeSBlLmcuIGBzb3M6OmZpbmRGbigiTmFrYWdhd2EgU2NoaWVsemV0aCIpYCBmb3IgYW4gdXAtdG8tZGF0ZSBsaXN0IC4uLikKCiMjIFZhcmlhYmxlIGltcG9ydGFuY2UKCi0gVGhlIHNpbXBsZXN0IHdheSB0byBnZXQgKHdpdGhpbi1zdHVkeSkgbWVhc3VyZXMgb2YgdmFyaWFibGUgaW1wb3J0YW5jZSBpcyB0byBzdGFuZGFyZGl6ZSB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcyAoc2NhbGluZyBieSAxIFNEIG9yIDJTRDogQGdlbG1hbl9zY2FsaW5nXzIwMDgsIEBzY2hpZWx6ZXRoX3NpbXBsZV8yMDEwKQotIFRoZSBgcjJnbG1tYCBwYWNrYWdlIGNvbXB1dGVzIHBhcnRpYWwgJFJeMiQgdmFsdWVzIGZvciBmaXhlZCBlZmZlY3RzIChvbmx5IGZvciBgbG1lcmAsIGBsbWVgLCBhbmQgYGdsbW1QUUxgIG1vZGVscykKLSBIZW5yaWsgU2luZ21hbm4gaGFzIGEgZGV0YWlsZWQgYW5zd2VyIFtoZXJlXShodHRwczovL2FmZXguc2luZ21hbm4uc2NpZW5jZS9mb3J1bXMvdG9waWMvY29tcHV0ZS1lZmZlY3Qtc2l6ZXMtZm9yLW1peGVkLW9iamVjdHMpIG9uIHdoeSBzdGFuZGFyZGl6ZWQgbWVhc3VyZXMgc3VjaCBhcyBwYXJ0aWFsIGV0YS1zcXVhcmVkIGFyZSBwcm9ibGVtYXRpYzoKCiAgICA+IFRoZSBmYWN0IHRoYXQgY2FsY3VsYXRpbmcgYSBnbG9iYWwgbWVhc3VyZSBvZiBtb2RlbCBmaXQgKHN1Y2ggYXMgUjIpIGlzIGFscmVhZHkgcmlkZGxlZCB3aXRoIGNvbXBsaWNhdGlvbnMgYW5kIHRoYXQgbm8gc2ltcGxlIHNpbmdsZSBudW1iZXIgY2FuIGJlIGZvdW5kLCBzaG91bGQgYmUgYSBoaW50IHRoYXQgZG9pbmcgc28gZm9yIGEgc3Vic2V0IG9mIHRoZSBtb2RlbCBwYXJhbWV0ZXJzIChpLmUuLCBtYWluLWVmZmVjdHMgb3IgaW50ZXJhY3Rpb25zKSBpcyBldmVuIG1vcmUgZGlmZmljdWx0LiBHaXZlbiB0aGlzLCBJIHdvdWxkIG5vdCByZWNvbW1lbmQgdG8gdHJ5IGZpbmRpbmcgYSBtZWFzdXJlIG9mIHN0YW5kYXJkaXplZCBlZmZlY3Qgc2l6ZXMgZm9yIG1peGVkIG1vZGVscy4KCiAgICBIZSBldmVuIGdpdmVzIHN1Z2dlc3RlZCB3b3JkaW5nIGZvciByZXNwb25kaW5nIHRvIHJldmlld2VycyB3aG8gd2FudCBzdGFuZGFyZGl6ZWQgbWVhc3VyZXMhCgojIyBEbyBJIGhhdmUgdG8gc3BlY2lmeSB0aGUgbGV2ZWxzIG9mIGZpeGVkIGVmZmVjdHMgaW4gbG1lcj8KCk5vLiBTZWUgRG91ZyBCYXRlcyByZXBseSB0byB0aGlzIHF1ZXN0aW9uIFtoZXJlXShodHRwOi8vci43ODk2OTUubjQubmFiYmxlLmNvbS9sbWU0LWFuZC1WYXJpYWJsZS1sZXZlbC1kZXRlY3Rpb24tdGQ4ODE2ODAuaHRtbCkKCiMgTWlzY2VsbGFuZW91cy9wcm9jZWR1cmFsCgojIyBQcm9udW5jaWF0aW9uIG9mIGBsbWVyYC9gZ2xtZXJgL2V0Yy4KCi0gYGxtZXJgOiBJIGhhdmUgaGVhcmQgImVsbCBlbW0gZWUgYXJyIiAoaS5lLiBwcm9ub3VuY2luZyBlYWNoIGxldHRlcik7ICJlbG1lciIgKHByb2JhYmx5IG1vc3QgY29tbW9uKTsgYW5kICJsZW11ciIKLSBgZ2xtZXJgOiAiZ2VlIGVsbCBlbW0gZWUgYXJyIiwgImdlZSBlbG1lciIsICJnbGltbWVyIiwgb3IgImdsZWFtZXIiCi0gZm9yIGBsbWVgIGFuZCBgbmxtZWAgcGVvcGxlIGp1c3Qgc2VlbSB0byBzcGVsbCBvdXQgdGhlIG5hbWVzIChyYXRoZXIgdGhhbiBzYXlpbmcgZS5nLiAibGVtbXkiIGFuZCAibmVsbXkiKQoKIyMgU3RvcmluZyBpbmZvcm1hdGlvbgoKUmVjZW50IHZlcnNpb25zIG9mIGBsbWU0YCBvdXRwdXQgY29udGFpbiBhbiBgQG9wdGluZm9gIHNsb3QgdGhhdCBzdG9yZXMgd2FybmluZ3MuCgpDb3BpZWQgZnJvbSBodHRwczovL3N0YXQuZXRoei5jaC9waXBlcm1haWwvci1oZWxwLzIwMTItRmVicnVhcnkvMzAyNzY3Lmh0bWwgOgoKPiBUaGVyZSdzIGEgc29tZXdoYXQgaGFjay1pc2ggc29sdXRpb24sIHdoaWNoIGlzIHRvIHVzZSBvcHRpb25zKHdhcm49MikgdG8gJ3VwZ3JhZGUnIHdhcm5pbmdzIHRvIGVycm9ycywgYW5kIHRoZW4gdXNlIHRyeSgpIG9yIHRyeUNhdGNoKCkgdG8gY2F0Y2ggdGhlbS4KCj4gTW9yZSBmYW5jaWx5LCBJIHVzZWQgY29kZSB0aGF0IGxvb2tlZCBzb21ldGhpbmcgbGlrZSB0aGlzIHRvIHNhdmUgd2FybmluZ3MgYXMgSSB3ZW50IGFsb25nIChzb3JyeSBhYm91dCB0aGUgPDwtICkgaW4gYSByZWNlbnQgc2ltdWxhdGlvbiBzdHVkeS4gIFlvdSBjb3VsZCBhbHNvIGNoZWNrIHckbWVzc2FnZSB0byBkbyBkaWZmZXJlbnQgdGhpbmdzIGluIHRoZSBjYXNlIG9mIGRpZmZlcmVudCB3YXJuaW5ncy4KCmBgYHtyIGNhdGNoX2Vycm9ycyxldmFsPUZBTFNFfQojIyBuLmIuIGhhdmUgdG8gc2V0IHVwIGEgM0Qgd2FybiBhcnJheSBmaXJzdCAuLi4Kd2l0aENhbGxpbmdIYW5kbGVycyh0cnlDYXRjaChmdW4obj1udmVjW2pdLHRhdT10YXV2ZWNbaV0sLi4uKSwKICAgICAgICAgICAgICAgIGVycm9yID0gZnVuY3Rpb24oZSkgewogICAgICAgICAgICAgICAgICB3YXJuW2ssaSxqXSA8PC0gcGFzdGUoIkVSUk9SOiIsZSRtZXNzYWdlKQogICAgICAgICAgICAgIE5BX2Fuc30pLAogICAgICAgICAgICAgICB3YXJuaW5nID0gZnVuY3Rpb24odykgewogICAgICAgICAgICAgICAgICB3YXJuW2ssaSxqXSA8PC0gdyRtZXNzYWdlCiAgICAgICAgICAgICAgICAgIGludm9rZVJlc3RhcnQoIm11ZmZsZVdhcm5pbmciKQogICAgICAgICAgICAgfSkKYGBgCgojIE1peGVkIG1vZGVsaW5nIHBhY2thZ2VzIAoKLSBhbHNvIHNlZSB0aGUgW3BhY2thZ2UgY29tcGFyaXNvbl0oaHR0cDovL2dsbW0ud2lraWRvdC5jb20vcGtnLWNvbXBhcmlzb24pIG9uIGBnbG1tLndpa2lkb3QuY29tYAoKIyMgV2hpY2ggUiBwYWNrYWdlcyAoZnVuY3Rpb25zKSBmaXQgR0xNTXM/CgotIE1BU1M6OmdsbW1QUUwgKHBlbmFsaXplZCBxdWFzaS1saWtlbGlob29kKQotIGxtZTQ6OmdsbWVyIChMYXBsYWNlIGFwcHJveGltYXRpb24gYW5kIGFkYXB0aXZlIEdhdXNzLUhlcm1pdGUgcXVhZHJhdHVyZSBbQUdIUV0pCi0gTUNNQ2dsbW0gKE1hcmtvdiBjaGFpbiBNb250ZSBDYXJsbykKLSBnbG1tTUwgKEFHSFEpCi0gZ2xtbUFLIChBR0hRPykKLSBnbG1tQURNQiAoTGFwbGFjZSkKLSBnbG1tIChmcm9tIEppbSBMaW5kc2V5J3MgYHJlcGVhdGVkYCBwYWNrYWdlOiBBR0hRKQotIGdhbWxzcy5teAotIEFTUkVNTC1SCi0gc2FicmVSCgojIyBTaG91bGQgSSB1c2UgYGFvdigpYCwgYG5sbWVgLCBvciBgbG1lNGAsIG9yIHNvbWUgb3RoZXIgcGFja2FnZT8KCi0gYGFvdigpYCAoaW4gdGhlIGBzdGF0c2AgcGFja2FnZSBpbiBiYXNlIFI6IGJhbGFuY2VkLCBvcnRob2dvbmFsIGRlc2lnbnMgb25seSAoUiBhbmFsb2d1ZSBvZiBTQVMgUFJPQyBHTE0pCi0gYG5sbWVgIChhbmFsb2d1ZSBvZiBTQVMgYFBST0MgTUlYRURgL2BOTE1JWEVEYCkKICAgIC0gYWxsb3dzIG1vcmUgY29tcGxleCBkZXNpZ25zIHRoYW4gYGFvdmAgKHVuYmFsYW5jZWQsIGhldGVyb3NjZWRhc3RpY2l0eSBhbmQvb3IgY29ycmVsYXRpb24gYW1vbmcgcmVzaWR1YWwgZXJyb3JzKQogICAgLSBtb3JlIG1hdHVyZSB0aGFuIGBsbWU0YAogICAgLSB3ZWxsLWRvY3VtZW50ZWQgW0BwaW5oZWlyb19taXhlZC1lZmZlY3RzXzIwMDBdCiAgICAtIGltcGxlbWVudHMgUi1zaWRlIGVmZmVjdHMgKGhldGVyb3NjZWRhc3RpY2l0eSBhbmQgY29ycmVsYXRpb24pCiAgICAtIGVzdGltYXRlcyAiZGVub21pbmF0b3IgZGVncmVlcyBvZiBmcmVlZG9tIiBmb3IgJEYkIHN0YXRpc3RpY3MsIGFuZCBoZW5jZSAkcCQgdmFsdWVzLCBmb3IgTE1NcyAoYnV0IHNlZSBhYm92ZSkKLSBgbG1lNGAgKGFsc28gU0FTIGBQUk9DIE1JWEVEYC9gTkxNSVhFRGApOiAKICAgIC0gZmFzdGVzdAogICAgLSBiZXN0IGZvciBjcm9zc2VkIGRlc2lnbnMgKGFsdGhvdWdoIHRoZXkgYXJlIHBvc3NpYmxlIGluIGBsbWVgKQogICAgLSBHTE1NcwogICAgLSBjdXR0aW5nLWVkZ2UgKGZvciBiZXR0ZXIgb3Igd29yc2UhKQogICAgLSBsaWtlbGlob29kIHByb2ZpbGVzCiAgICAtIHVzZSBgbG1lNGAgZm9yIEdMTU1zLCBvciBpZiB5b3UgaGF2ZSBiaWcgZGF0YSAodGhvdXNhbmRzIHRvIHRlbnMgb2YgdGhvdXNhbmRzIG9mIHJlY29yZHMpCgpUaGUgZm9sbG93aW5nIGlzIG1vZGlmaWVkIGZyb20gYSBjb250cmlidXRpb24gYnkgS2luZ3Nmb3JkIEpvbmVzLCBmb3VuZCAyMDEwLTAzLTE2CgojIyMgbGluZWFyIGFuZCBub25saW5lYXIgbWl4ZWQgbW9kZWxzCgotIFtsbWVdKGh0dHA6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2xtZTQvaW5kZXguaHRtbCkgLS0gTGluZWFyIG1peGVkLWVmZmVjdHMgbW9kZWxzIHVzaW5nIFM0IGNsYXNzZXMKLSBgbG1tYCAtLSBMaW5lYXIgbWl4ZWQgbW9kZWxzCi0gYG5sbWVgIC0tIExpbmVhciBhbmQgTm9ubGluZWFyIE1peGVkIEVmZmVjdHMgTW9kZWxzCi0gYHNhYnJlUmAKLSBbcmVncmVzc10oaHR0cDovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmVncmVzcy9pbmRleC5odG1sKSBMaW5lYXIgbWl4ZWQgbW9kZWxzCgojIyMgR0xNTXMKLSBnbG1tQUsgLS0gR2VuZXJhbGl6ZWQgTGluZWFyIE1peGVkIE1vZGVscwotIE1BU1MgLS0gTWFpbiBQYWNrYWdlIG9mIFZlbmFibGVzIGFuZCBSaXBsZXkncyBNQVNTIChzZWUgZnVuY3Rpb24gZ2xtbVBRTCkKLSBNQ01DZ2xtbSAtLSBNQ01DIEdlbmVyYWxpc2VkIExpbmVhciBNaXhlZCBNb2RlbHMKLSBsbWU0IChnbG1lcikKLSBnbG1tTUwKLSBnYW1sc3MubXgKLSBzYWJyZVIKIAojIyMgQWRkaXRpdmUgYW5kIGdlbmVyYWxpemVkLWFkZGl0aXZlIG1peGVkIG1vZGVscwotIGFtZXIgLS0gQWRkaXRpdmUgbWl4ZWQgbW9kZWxzIHdpdGggbG1lNAotIGdhbW00IC0tIEdlbmVyYWxpemVkIGFkZGl0aXZlIG1peGVkIG1vZGVscyB1c2luZyBtZ2N2IGFuZCBsbWU0Ci0gbWdjdiAoZ2FtbSBmdW5jdGlvbiwgdmlhIGdsbW1QUUwgaW4gTUFTUyBwYWNrYWdlKQotIGdhbWxzcy5teAoKIyMjIEhpZXJhcmNoaWNhbCBHTE1zCi0gaGdsbSAtLSBoZ2xtIGlzIHVzZWQgdG8gZml0IGhpZXJhcmNoaWNhbCBnZW5lcmFsaXplZCBsaW5lYXIgbW9kZWxzCi0gSEdMTU1NIC0tIEhpZXJhcmNoaWNhbCBHZW5lcmFsaXplZCBMaW5lYXIgTW9kZWxzCgojIyMgZGlhZ25vc3RpYyBhbmQgbW9kZWxpbmcgZnJhbWV3b3JrcwotIGluZmx1ZW5jZS5NRSAtLSBUb29scyBmb3IgZGV0ZWN0aW5nIGluZmx1ZW50aWFsIGRhdGEgaW4gbWl4ZWQgZWZmZWN0cyBtb2RlbHMKLSBhcm0gLS0gRGF0YSBBbmFseXNpcyBVc2luZyBSZWdyZXNzaW9uIGFuZCBNdWx0aWxldmVsL0hpZXJhcmNoaWNhbCBNb2RlbHMKLSBwYW1tIC0tIFBvd2VyIGFuYWx5c2lzIGZvciByYW5kb20gZWZmZWN0cyBpbiBtaXhlZCBtb2RlbHMKLSBSTFJzaW0gLS0gRXhhY3QgKFJlc3RyaWN0ZWQpIExpa2VsaWhvb2QgUmF0aW8gdGVzdHMgZm9yIG1peGVkIGFuZCBhZGRpdGl2ZSBtb2RlbHMKLSBucGRlIC0tIE5vcm1hbGlzZWQgcHJlZGljdGlvbiBkaXN0cmlidXRpb24gZXJyb3JzIGZvciBub25saW5lYXIgbWl4ZWQtZWZmZWN0IG1vZGVscwotIG11bHRpbGV2ZWwgLS0gTXVsdGlsZXZlbCBGdW5jdGlvbnMgKHBzeWNob2xvZ3ktb3JpZW50ZWQ7IHdpdGhpbi1ncm91cCBhZ3JlZW1lbnQsIHJhbmRvbSBncm91cCByZXNhbXBsaW5nLCBldGMuKQotIGxhbmd1YWdlUgotIHBia3J0ZXN0IC0tIHBhcmFtZXRyaWMgYm9vdHN0cmFwIGFuZCBLZW53YXJkLVJvZ2VyIHRlc3RzCgojIyMgZGF0YSBhbmQgZXhhbXBsZXMKLSBNRU1TUyAtLSBEYXRhIHNldHMgZnJvbSBNaXhlZC1lZmZlY3RzIE1vZGVscyBpbiBTCi0gbWxtUmV2IC0tIEV4YW1wbGVzIGZyb20gTXVsdGlsZXZlbCBNb2RlbGxpbmcgU29mdHdhcmUgUmV2aWV3Ci0gU0FTbWl4ZWQgLS0gRGF0YSBzZXRzIGZyb20gIlNBUyBTeXN0ZW0gZm9yIE1peGVkIE1vZGVscyIKCiMjIyBleHRlbnNpb25zCi0gbG1lU3BsaW5lcyAtLSBsbWVTcGxpbmVzCi0gbG1lYyAtLSBMaW5lYXIgTWl4ZWQtRWZmZWN0cyBNb2RlbHMgd2l0aCBDZW5zb3JlZCBSZXNwb25zZXMKLSBraW5zaGlwIC0tIG1peGVkLWVmZmVjdHMgQ294IG1vZGVscywgc3BhcnNlIG1hdHJpY2VzLCBhbmQgbW9kZWxpbmcgZGF0YSBmcm9tIGxhcmdlIHBlZGlncmVlcwotIGNveG1lIC0tIE1peGVkIEVmZmVjdHMgQ294IE1vZGVscwotIG9yZGluYWwgLS0gUmVncmVzc2lvbiBNb2RlbHMgZm9yIE9yZGluYWwgRGF0YQotIHBobW0gLS0gUHJvcG9ydGlvbmFsIEhhemFyZHMgTWl4ZWQtZWZmZWN0cyBNb2RlbCAoUEhNTSkKLSBwZWRpZ3JlZW1tIC0tIFBlZGlncmVlLWJhc2VkIG1peGVkLWVmZmVjdHMgbW9kZWxzCi0gKHNlZSBhbHNvIE1DTUNnbG1tIGZvciBwZWRpZ3JlZS1iYXNlZCBhcHByb2FjaGVzKQotIGhlYXZ5IC0tIEVzdGltYXRpb24gaW4gdGhlIGxpbmVhciBtaXhlZCBtb2RlbCB1c2luZyBoZWF2eS10YWlsZWQgZGlzdHJpYnV0aW9ucwotIEdMTU1hcnAgLS0gR2VuZXJhbGl6ZWQgTGluZWFyIE11bHRpbGV2ZWwgTW9kZWwgd2l0aCBBUihwKSBFcnJvcnMgUGFja2FnZQotIGdsbW1sYXNzbyAtLSBwZW5hbGl6ZWQgR0xNTSBmaXR0aW5nCi0gc3BhdGlhbENvdmFyaWFuY2UgLS0gc3BhdGlhbCBjb3ZhcmlhbmNlIG1hdHJpeCBjYWxjdWxhdGlvbnMKCiMjIyBJbnRlcmZhY2VzIHRvIG90aGVyIHN5c3RlbXMKLSBnbG1tQlVHUyAtLSBHZW5lcmFsaXNlZCBMaW5lYXIgTWl4ZWQgTW9kZWxzIGFuZCBTcGF0aWFsIE1vZGVscyB3aXRoIEJVR1MKLSBJbnRlcmZhY2VzIHRvIFdpbkJVR1MvT3BlbkJVR1MvSkFHUyAocm9sbCB5b3VyIG93biBtb2RlbCBmaWxlKToKICogUjJXaW5CVUdTCiAqIHIyamFncwogKiByamFncwogKiBSQnVncwoKIyMjIG1vZGVsaW5nIGJhc2VkIG9uIExNTXMKCi0gYG5sbWVPREVgIC0tIE5vbi1saW5lYXIgbWl4ZWQtZWZmZWN0cyBtb2RlbGxpbmcgaW4gbmxtZSB1c2luZyBkaWZmZXJlbnRpYWwgZXF1YXRpb25zCi0gYGxvbmdSUGFydGAgLS0gUmVjdXJzaXZlIHBhcnRpdGlvbmluZyBvZiBsb25naXR1ZGluYWwgZGF0YSB1c2luZyBtaXhlZC1lZmZlY3RzIG1vZGVscwotIGBQU01gIC0tIE5vbi1MaW5lYXIgTWl4ZWQtRWZmZWN0cyBtb2RlbGxpbmcgdXNpbmcgU3RvY2hhc3RpYyBEaWZmZXJlbnRpYWwgRXF1YXRpb25zCgojIyBPZmYtQ1JBTiBtaXhlZCBtb2RlbGluZyBwYWNrYWdlczoKCiMjIyBSLWZvcmdlIGFuZCBHaXRodWI6CgotIGBnbG1tQURNQmAgKFItZm9yZ2UsIGludGVyZmFjZSB0byBBRCBNb2RlbCBCdWlsZGVyKQotIGBzcGlkYWAsIGBwM2RgIChHZW9yZ2VzIE1vbmV0dGUpCgojIyMgT3RoZXIgb3BlbiBzb3VyY2U6Ci0gW2Jlcm5vcl0oaHR0cDovL3d3dy5zdGF0LnVtbi5lZHUvZ2V5ZXIvYmVybm9yLyBiZXJub3IpIHBhY2thZ2UgKGxvZ2l0LW5vcm1hbCBmaXR0aW5nKSwgYnkgWXVuIEp1IFN1bmcgYW5kIENoYXJsZXMgSi4gR2V5ZXIKLSBgZ2xtbWAgKGluIEppbSBMaW5kc2V5J3MgYHJlcGVhdGVkYCBwYWNrYWdlOiBhdCBbTGluZHNleSdzIHdlYiBzaXRlXShodHRwOi8vd3d3LmNvbW1hbnN0ZXIuZXUvcmNvZGUuaHRtbCkKCgojIyMgQ29tbWVyY2lhbDoKLSBgT3Blbk14YCAtLSBBZHZhbmNlZCBTdHJ1Y3R1cmFsIEVxdWF0aW9uIE1vZGVsaW5nCi0gYEFTUmVtbC1SYCAoY29tbWVyY2lhbCwgYnV0IDMwIGRheXMnIGZyZWUgdXNlL2ZyZWUgbGljZW5zZSBmb3IgYWNhZGVtaWMgb3IgZGV2ZWxvcGluZy1jb3VudHJ5IHVzZSBhdmFpbGFibGUpLiAgVmVyeSBnb29kIGF0IGNvbXBsZXggTE1NcyAoZmFzdCwgZmxleGlibGUgY292YXJpYW5jZSBzdHJ1Y3R1cmVzLCBldGMuKSwgYnV0IG9ubHkgb2ZmZXJzIFBRTCBmb3IgR0xNTXMsIGFuZCB0aGUgbWFudWFsIHNheXM6IAo+IHdlIGNhbm5vdCByZWNvbW1lbmQgdGhlIHVzZSBvZiB0aGlzIHRlY2huaXF1ZSBmb3IgZ2VuZXJhbCB1c2UuIEl0IGlzIGluY2x1ZGVkIGluIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgYXNyZW1sKCkgZm9yIGFkdmFuY2VkIHVzZXJzLiBJdCBpcyBoaWdobHkgcmVjb21tZW5kZWQgdGhhdCBpdHMgdXNlIGJlIGFjY29tcGFuaWVkIGJ5IHNvbWUgZm9ybSBvZiBjcm9zcy12YWxpZGF0b3J5IGFzc2Vzc21lbnQgZm9yIHRoZSBzcGVjaWZpYyBkYXRhc2V0IGNvbmNlcm5lZC4iClJlc291cmNlczoKLSBbc2hvcnQgUiB3aWtpIHR1dG9yaWFsXShodHRwOi8vcndpa2kuc2Npdmlld3Mub3JnL2Rva3UucGhwP2lkPWd1aWRlczp0dXRvcmlhbHM6YXNyZW1sKQotIFtyZWZlcmVuY2UgbWFudWFsXShodHRwOi8vd3d3LnZzbmkuY28udWsvZG93bmxvYWRzL2FzcmVtbC9yZWxlYXNlMy9hc3JlbWwtUi5wZGYgcmVmZXJlbmNlIG1hbnVhbCkgKFBERikKLSBMdWlzIEFwaW9sYXphJ3MgW2FzcmVtbC1yIGNvb2tib29rXShodHRwOi8vYXBpb2xhemEubmV0L2FzcmVtbC1yLykKCgojIyBQYWNrYWdlIHZlcnNpb25zIHVzZWQKCmBgYHtyIHNlc3Npb25pbmZvfQpzZXNzaW9uSW5mbygpCmBgYAoKIyMgVG8gZG8KCi0gYWRkIGxpbmtzIHRvIGBtZXJEZXJpdmAgZm9yIHN0YW5kYXJkIGRldnMgb2YgdmFyaWFuY2VzLCByb2J1c3QgZXN0aW1hdGVzLiBNb3JlIG9uIFJpem9wb3Vsb3MgcGFja2FnZQotIHVwZGF0ZSBwYWNrYWdlIGRlc2NyaXB0aW9uczsgY3Jvc3MtbGluayB3aXRoIFtUYXNrIFZpZXddKGh0dHA6Ly9iYm9sa2VyLmdpdGh1Yi5pby9taXhlZG1vZGVscy1taXNjL01peGVkTW9kZWxzLmh0bWwpID8gYHJldGhpbmtpbmdgLCBgYnJtc2AsIC4uLgotIG1vcmUgb24gcG9zdC1hbmFseXNpcyAoYGJyb29tKC5taXhlZClgLCBgZW1tZWFuc2AsIGBtdWx0Y29tcGAsIC4uLikKLSBtb3JlIG9uIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLCBzaW11bGF0aW5nIGZyb20gY29uZGl0aW9uYWwgZGlzdHJpYnV0aW9ucywgZXRjLikKCiMgQmlibGlvZ3JhcGh5Cgo=
+
LS0tCmF1dGhvcjogQmVuIEJvbGtlciBhbmQgb3RoZXJzCnRpdGxlOiBHTE1NIEZBUQpiaWJsaW9ncmFwaHk6IGdsbW0uYmliCmRhdGU6ICAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlYiAlWScpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgICB0b2M6IHRydWUKLS0tCgo8IS0tIEdvb2dsZSB0YWcgKGd0YWcuanMpIC0tPgo8c2NyaXB0IGFzeW5jIHNyYz0iaHR0cHM6Ly93d3cuZ29vZ2xldGFnbWFuYWdlci5jb20vZ3RhZy9qcz9pZD1HLUtZMUpZMEM1M1MiPjwvc2NyaXB0Pgo8c2NyaXB0PgogIHdpbmRvdy5kYXRhTGF5ZXIgPSB3aW5kb3cuZGF0YUxheWVyIHx8IFtdOwogIGZ1bmN0aW9uIGd0YWcoKXtkYXRhTGF5ZXIucHVzaChhcmd1bWVudHMpO30KICBndGFnKCdqcycsIG5ldyBEYXRlKCkpOwoKICBndGFnKCdjb25maWcnLCAnRy1LWTFKWTBDNTNTJyk7Cjwvc2NyaXB0PgoKYGBge3Igc2V0dXAsbWVzc2FnZT1GQUxTRSxlY2hvPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQprbml0cjo6b3B0c19jaHVuayRzZXQoZGV2LmFyZ3MgPSBsaXN0KHBuZyA9IGxpc3QodHlwZSA9ICJjYWlybyIpKSkKbGlicmFyeShwYW5kZXIpCmxpYnJhcnkoQ2Fpcm8pCmBgYAoKYGBge3IgcGtncywgZXZhbD1GQUxTRSxlY2hvPUZBTFNFfQpwa2dzIDwtIGMoImxtZTQiLCJnbG1tQURNQiIsInNvcyIsImJsbWUiLCJSTFJzaW0iLCJnZ3Bsb3QyIiwgIk1FTVNTIikKaTEgPC0gaW5zdGFsbGVkLnBhY2thZ2VzKCkKcGtncyA8LSBzZXRkaWZmKHBrZ3MsIHJvd25hbWVzKGkxKSkKcmVwb3MgPC0gYygiaHR0cDovL2dsbW1hZG1iLnItZm9yZ2Uuci1wcm9qZWN0Lm9yZy9yZXBvcyIsCiAgICAgICAgICAgIGdldE9wdGlvbigicmVwb3MiKSkKaWYgKGxlbmd0aChwa2dzKT4wKSAKICAgIGluc3RhbGwucGFja2FnZXMocGtncyxyZXBvcz1yZXBvcywgdHlwZT0ic291cmNlIikKYGBgCgojIEludHJvZHVjdGlvbgoKVGhpcyBpcyBhbiBpbmZvcm1hbCBGQVEgbGlzdCBmb3IgdGhlIGByLXNpZy1taXhlZC1tb2RlbHNgIG1haWxpbmcgbGlzdC4KClRoZSBtb3N0IGNvbW1vbmx5IHVzZWQgZnVuY3Rpb25zIGZvciBtaXhlZCBtb2RlbGluZyBpbiBSIGFyZSAKCi0gKmxpbmVhciBtaXhlZCBtb2RlbHMqOiBgYW92KClgLCBgbmxtZTo6bG1lYFteMV0sIGBsbWU0OjpsbWVyYDsgYGJybXM6OmJybWAKLSAqZ2VuZXJhbGl6ZWQgbGluZWFyIG1peGVkIG1vZGVscyogKEdMTU1zKQogICAgLSBmcmVxdWVudGlzdDogYE1BU1M6OmdsbW1QUUxgLCBgbG1lNDo6Z2xtZXJgOyBgZ2xtbVRNQmAKICAgIC0gQmF5ZXNpYW46IGBNQ01DZ2xtbTo6TUNNQ2dsbW1gOyBgYnJtczo6YnJtYAotICpub25saW5lYXIgbWl4ZWQgbW9kZWxzKjogYG5sbWU6Om5sbWVgLCBgbG1lNDo6bmxtZXJgOyBgYnJtczo6YnJtYAotICpHTkxNTXMqOiBgYnJtczo6YnJtYAkKClteMV06IGluIFIsIGBmb286OmJhcmAgKG9yIGBmb286OmJhcigpYCkgZGVub3RlcyAiZnVuY3Rpb24gYGJhcmAgaW4gcGFja2FnZSBgZm9vYCIpLgoKQW5vdGhlciBxdWljay1hbmQtZGlydHkgd2F5IHRvIHNlYXJjaCBmb3IgbWl4ZWQtbW9kZWwgcmVsYXRlZCBwYWNrYWdlcyBvbiBDUkFOOgoKYGBge3IgYXZhaWwsY2FjaGU9VFJVRX0KZ3JlcCgibC4/bVttZV1bXnRdIixyb3duYW1lcyhhdmFpbGFibGUucGFja2FnZXMoKSksdmFsdWU9VFJVRSkKYGBgCgpUaGVyZSBhcmUgc29tZSBmYWxzZSBwb3NpdGl2ZXMgaGVyZSAoZS5nLiBgcGFsbWVycGVuZ3VpbnNgKTsgc2VlIFtoZXJlXShodHRwczovL3hrY2QuY29tLzEzMTMvKSBpZiB5b3UncmUgaW50ZXJlc3RlZCBpbiAicmVnZXggZ29sZiIuCgojIyBPdGhlciBzb3VyY2VzIG9mIGhlbHAKCi0gdGhlIG1haWxpbmcgbGlzdCBpcyBgci1zaWctbWl4ZWQtbW9kZWxzQHItcHJvamVjdC5vcmdgCiAgICAtIHNpZ24gdXAgW2hlcmVdKGh0dHBzOi8vc3RhdC5ldGh6LmNoL21haWxtYW4vbGlzdGluZm8vci1zaWctbWl4ZWQtbW9kZWxzKQoJLSBhcmNoaXZlcyBbaGVyZV0oaHR0cHM6Ly9zdGF0LmV0aHouY2gvcGlwZXJtYWlsL3Itc2lnLW1peGVkLW1vZGVscy8pCgktIG9yIEdvb2dsZSBzZWFyY2ggd2l0aCB0aGUgdGFnIGBzaXRlOmh0dHBzOi8vc3RhdC5ldGh6LmNoL3BpcGVybWFpbC9yLXNpZy1taXhlZC1tb2RlbHMvYAotIFRoZSBzb3VyY2UgY29kZSBvZiB0aGlzIGRvY3VtZW50IGlzIGF2YWlsYWJsZSBbb24gR2l0SHViXShodHRwczovL2dpdGh1Yi5jb20vYmJvbGtlci9taXhlZG1vZGVscy1taXNjL2Jsb2IvbWFzdGVyL2dsbW1GQVEucm1kKTsgdGhlIHJlbmRlcmVkIChIVE1MKSB2ZXJzaW9uIGxpdmVzIG9uIFtHaXRIdWIgcGFnZXNdKGh0dHA6Ly9iYm9sa2VyLmdpdGh1Yi5pby9taXhlZG1vZGVscy1taXNjL2dsbW1GQVEuaHRtbCkuCi0gU2VhcmNoaW5nIG9uIFN0YWNrT3ZlcmZsb3cgd2l0aCB0aGUgW1tyXSBbbWl4ZWQtbW9kZWxzXSB0YWdzXShodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zL3RhZ2dlZC9yJTIwbWl4ZWQtbW9kZWxzP21vZGU9YWxsKSwgb3Igb24gQ3Jvc3NWYWxpZGF0ZWQgd2l0aCB0aGUgW1ttaXhlZC1tb2RlbF0gdGFnXShodHRwOi8vc3RhdHMuc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zL3RhZ2dlZC9taXhlZC1tb2RlbCkgbWF5IGJlIGhlbHBmdWwgKHRoZXNlIHNpdGVzIGFsc28gaGF2ZSBhbiBgW2xtZTRdYCB0YWcpLgoKCioqRElTQ0xBSU1FUlM6KioKCi0gKEcpTE1NcyBhcmUgaGFyZCAtIGhhcmRlciB0aGFuIHlvdSBtYXkgdGhpbmsgYmFzZWQgb24gd2hhdCB5b3UgbWF5IGhhdmUgbGVhcm5lZCBpbiB5b3VyIHNlY29uZCBzdGF0aXN0aWNzIGNsYXNzLCB3aGljaCBwcm9iYWJseSBmb2N1c2VkIG9uIHBpY2tpbmcgdGhlIGFwcHJvcHJpYXRlIHN1bXMgb2Ygc3F1YXJlcyB0ZXJtcyBhbmQgZGVncmVlcyBvZiBmcmVlZG9tIGZvciB0aGUgbnVtZXJhdG9yIGFuZCBkZW5vbWluYXRvciBvZiBhbiAkRiQgdGVzdC4gJ01vZGVybicgbWl4ZWQgbW9kZWwgYXBwcm9hY2hlcywgYWx0aG91Z2ggbW9yZSBwb3dlcmZ1bCAodGhleSBjYW4gaGFuZGxlIG1vcmUgY29tcGxleCBkZXNpZ25zLCBsYWNrIG9mIGJhbGFuY2UsIGNyb3NzZWQgcmFuZG9tIGZhY3RvcnMsIHNvbWUga2luZHMgb2Ygbm9uLU5vcm1hbGx5IGRpc3RyaWJ1dGVkIHJlc3BvbnNlcywgZXRjLiksIGFsc28gcmVxdWlyZSBhIG5ldyBzZXQgb2YgY29uY2VwdHVhbCB0b29scy4gSW4gb3JkZXIgdG8gdXNlIHRoZXNlIHRvb2xzIHlvdSBzaG91bGQgaGF2ZSBhdCBsZWFzdCBhIGdlbmVyYWwgYWNxdWFpbnRhbmNlIHdpdGggY2xhc3NpY2FsIG1peGVkLW1vZGVsIGV4cGVyaW1lbnRhbCBkZXNpZ25zIGJ1dCB5b3Ugc2hvdWxkIGFsc28sIHByb2JhYmx5LCByZWFkIHNvbWV0aGluZyBhYm91dCBtb2Rlcm4gbWl4ZWQgbW9kZWwgYXBwcm9hY2hlcy4gQGxpdHRlbGxfc2FzXzIwMDYgYW5kIEBwaW5oZWlyb19taXhlZC1lZmZlY3RzXzIwMDAgYXJlIHR3byBwbGFjZXMgdG8gc3RhcnQsIGFsdGhvdWdoIFBpbmhlaXJvIGFuZCBCYXRlcyBpcyBwcm9iYWJseSBtb3JlIHVzZWZ1bCBpZiB5b3Ugd2FudCB0byB1c2UgUi4gT3RoZXIgdXNlZnVsIHJlZmVyZW5jZXMgaW5jbHVkZSBAZ2VsbWFuX2RhdGFfMjAwNiAoZm9jdXNlZCBvbiBCYXllc2lhbiBtZXRob2RzKSBhbmQgQHp1dXJfbWl4ZWRfMjAwOS4gSWYgeW91IGFyZSBnb2luZyB0byB1c2UgZ2VuZXJhbGl6ZWQgbGluZWFyIG1peGVkIG1vZGVscywgeW91IHNob3VsZCB1bmRlcnN0YW5kIGdlbmVyYWxpemVkIGxpbmVhciBtb2RlbHMgKEBkb2Jzb25faW50cm9kdWN0aW9uXzIwMDgsIEBmYXJhd2F5X2V4dGVuZGluZ18yMDA2LCBhbmQgQE1jQ3VsbGFnaE5lbGRlcjE5ODkgYXJlIHN0YW5kYXJkIHJlZmVyZW5jZXM7IHRoZSBsYXN0IGlzIHRoZSBjYW5vbmljYWwgcmVmZXJlbmNlLCBidXQgYWxzbyB0aGUgbW9zdCBjaGFsbGVuZ2luZykuCi0gQWxsIG9mIHRoZSBpc3N1ZXMgdGhhdCBhcmlzZSB3aXRoIHJlZ3VsYXIgbGluZWFyIG9yIGdlbmVyYWxpemVkLWxpbmVhciBtb2RlbGluZyAoZS5nLjogaW5hZGVxdWFjeSBvZiBwLXZhbHVlcyBhbG9uZSBmb3IgdGhvcm91Z2ggc3RhdGlzdGljYWwgYW5hbHlzaXM7IG5lZWQgdG8gIHVuZGVyc3RhbmQgaG93IG1vZGVscyBhcmUgcGFyYW1ldGVyaXplZDsgbmVlZCB0byB1bmRlcnN0YW5kIHRoZSBwcmluY2lwbGUgb2YgbWFyZ2luYWxpdHkgYW5kIGhvdyBpbnRlcmFjdGlvbnMgY2FuIGJlIHRyZWF0ZWQ7IGRhbmdlcnMgb2Ygb3ZlcmZpdHRpbmcsIHdoaWNoIGFyZSBub3QgbWl0aWdhdGVkIGJ5IHN0ZXB3aXNlIHByb2NlZHVyZXM7IHRoZSBub24tZXhpc3RlbmNlIG9mIGZyZWUgbHVuY2hlcykgYWxzbyBhcHBseSwgYW5kIGNhbiBhcHBseSBtb3JlIHNldmVyZWx5LCB0byBtaXhlZCBtb2RlbHMuCiogV2hlbiBTQVMgKG9yIFN0YXRhLCBvciBHZW5zdGF0L0FTLVJFTUwgb3IgLi4uKSBhbmQgUiBkaWZmZXIgaW4gdGhlaXIgYW5zd2VycywgUiBtYXkgbm90IGJlIHdyb25nLiBCb3RoIFNBUyBhbmQgUiBtYXkgYmUgYHJpZ2h0JyBidXQgcHJvY2VlZGluZyBpbiBhIGRpZmZlcmVudCB3YXkvYW5zd2VyaW5nIGRpZmZlcmVudCBxdWVzdGlvbnMvdXNpbmcgYSBkaWZmZXJlbnQgcGhpbG9zb3BoaWNhbCBhcHByb2FjaCAob3IgYm90aCBtYXkgYmUgd3JvbmcgLi4uKQotIFRoZSBhZHZpY2UgaW4gdGhpcyBGQVEgY29tZXMgd2l0aCAqKmFic29sdXRlbHkgbm8gd2FycmFudHkgb2YgYW55IHNvcnQqKi4KCiMgUmVmZXJlbmNlcwoKIyMgbGluZWFyIG1peGVkIG1vZGVscwoKIyMjIHdlYi9vcGVuCgotIFtVQ0xBIElEUkUgc3RhdGlzdGljYWwgY29uc3VsdGluZ10oaHR0cHM6Ly9zdGF0cy5pZHJlLnVjbGEuZWR1L290aGVyL211bHQtcGtnL2ludHJvZHVjdGlvbi10by1saW5lYXItbWl4ZWQtbW9kZWxzLykKLSBAYmFycl9sZWFybmluZ18yMDIwIENoYXB0ZXJzIDUtOAoKIyMjIGJvb2tzIChkZWFkLXRyZWUvY2xvc2VkKQoKLSBwaW5oZWlyb19taXhlZC1lZmZlY3RzXzIwMDA6IExNTSBvbmx5LgotIEB6dXVyX21peGVkXzIwMDk6IEZvY3VzZWQgb24gZWNvbG9neS4KLSBAZ2VsbWFuX2RhdGFfMjAwNjogTE1NIGFuZCBHTE1NOyBCYXllc2lhbjsgZXhhbXBsZXMgZnJvbSBzb2NpYWwgc2NpZW5jZS4gSW50ZXJtZWRpYXRlIG1hdGhlbWF0aWNzLgotIChSZXRoaW5raW5nKQoKIyBNb2RlbCBkZWZpbml0aW9uCgojIyBNb2RlbCBzcGVjaWZpY2F0aW9uCgpUaGUgZm9sbG93aW5nIGZvcm11bGEgZXh0ZW5zaW9ucyBmb3Igc3BlY2lmeWluZyByYW5kb20tZWZmZWN0cyBzdHJ1Y3R1cmVzIGluIFIgYXJlIHVzZWQgYnkgCgotIGBsbWU0YAotIGBubG1lYCAobmVzdGVkIGVmZmVjdHMgb25seSwgYWx0aG91Z2ggY3Jvc3NlZCBlZmZlY3RzIGNhbiBiZSBzcGVjaWZpZWQgd2l0aCBtb3JlIHdvcmspCi0gYGdsbW1BRE1CYCBhbmQgYGdsbW1UTUJgIAoKYE1DTUNnbG1tYCB1c2VzIGEgZGlmZmVyZW50IHNwZWNpZmljYXRpb24sIGluaGVyaXRlZCBmcm9tIEFTLVJFTUwuCgooTW9kaWZpZWQgZnJvbSBSb2JpbiBKZWZmcmllcywgVUNMQTopCgpgYGB7ciBnbG1tX3N5bnRheCxlY2hvPUZBTFNFfQpzcGVjdGFiIDwtIHJlYWQudGFibGUoc2VwPSImIixoZWFkZXI9VFJVRSx0ZXh0PSIKZm9ybXVsYSAgICAgJiBtZWFuaW5nCmAoMXxncm91cClgICYgIHJhbmRvbSBncm91cCBpbnRlcmNlcHQKYCh4fGdyb3VwKWAgPSBgKDEreHxncm91cClgICYgcmFuZG9tIHNsb3BlIG9mIHggd2l0aGluIGdyb3VwIHdpdGggY29ycmVsYXRlZCBpbnRlcmNlcHQKYCgwK3h8Z3JvdXApYCA9IGAoLTEreHxncm91cClgICYgcmFuZG9tIHNsb3BlIG9mIHggd2l0aGluIGdyb3VwOiBubyB2YXJpYXRpb24gaW4gaW50ZXJjZXB0CmAoMXxncm91cCkgKyAoMCt4fGdyb3VwKWAgICYgdW5jb3JyZWxhdGVkIHJhbmRvbSBpbnRlcmNlcHQgYW5kIHJhbmRvbSBzbG9wZSB3aXRoaW4gZ3JvdXAKYCgxfHNpdGUvYmxvY2spYCA9IGAoMXxzaXRlKSsoMXxzaXRlOmJsb2NrKWAgJiBpbnRlcmNlcHQgdmFyeWluZyBhbW9uZyBzaXRlcyBhbmQgYW1vbmcgYmxvY2tzIHdpdGhpbiBzaXRlcyAobmVzdGVkIHJhbmRvbSBlZmZlY3RzKQpgc2l0ZSsoMXxzaXRlOmJsb2NrKWAgJiAqZml4ZWQqIGVmZmVjdCBvZiBzaXRlcyBwbHVzIHJhbmRvbSB2YXJpYXRpb24gaW4gaW50ZXJjZXB0IGFtb25nIGJsb2NrcyB3aXRoaW4gc2l0ZXMKYCh4fHNpdGUvYmxvY2spYCA9IGAoeHxzaXRlKSsoeHxzaXRlOmJsb2NrKWAgPSBgKDEgKyB4fHNpdGUpKygxK3h8c2l0ZTpibG9jaylgICYgc2xvcGUgYW5kIGludGVyY2VwdCB2YXJ5aW5nIGFtb25nIHNpdGVzIGFuZCBhbW9uZyBibG9ja3Mgd2l0aGluIHNpdGVzCmAoeDF8c2l0ZSkrKHgyfGJsb2NrKWAgJiB0d28gZGlmZmVyZW50IGVmZmVjdHMsIHZhcnlpbmcgYXQgZGlmZmVyZW50IGxldmVscwpgeCpzaXRlKyh4fHNpdGU6YmxvY2spYCAmIGZpeGVkIGVmZmVjdCB2YXJpYXRpb24gb2Ygc2xvcGUgYW5kIGludGVyY2VwdCB2YXJ5aW5nIGFtb25nIHNpdGVzIGFuZCByYW5kb20gdmFyaWF0aW9uIG9mIHNsb3BlIGFuZCBpbnRlcmNlcHQgYW1vbmcgYmxvY2tzIHdpdGhpbiBzaXRlcwpgKDF8Z3JvdXAxKSsoMXxncm91cDIpYCAmIGludGVyY2VwdCB2YXJ5aW5nIGFtb25nIGNyb3NzZWQgcmFuZG9tIGVmZmVjdHMgKGUuZy4gc2l0ZSwgeWVhcikiKQpzZXQuYWxpZ25tZW50KGRlZmF1bHQ9YygiY2VudHJlIiwibGVmdCIpKQpwYW5kZXIoc3BlY3RhYikKYGBgCgpPciBpbiBhIGxpdHRsZSBtb3JlIGRldGFpbDoKCmBgYHtyIGZ0YWIsZWNobz1GQUxTRSxyZXN1bHRzPSJhc2lzIn0KZnRhYiA8LSBtYXRyaXgoYygizrJfMCArIM6yX3sxfVhfe2l9ICsgZV97c2l9IiwKICAgICAgICAgICAgICAgICAibi9hIChOb3QgYSBtaXhlZC1lZmZlY3RzIG1vZGVsKSIsCiAgICAgICAgICAgICAgICAgIijOsl8wICsgYl97Uywwc30pICsgzrJfezF9WF9pICsgZV97c2l9IiwKICAgICAgICAgICAgICAgICAi4oi8IFggKyAoMeKIo1N1YmplY3QpIiwKICAgICAgICAgICAgICAgICAiKM6yXzAgKyBiX3tTLDBzfSkgKyAgKM6yX3sxfSArIGJfe1MsMXN9KSBYX2kgKyBlX3tzaX0iLAogICAgICAgICAgICAgICAgICJ+IFggKyAoMSArIFjiiKNTdWJqZWN0KSIsCiAgICAgICAgICAgICAgICAgIijOsl8wICsgYl97Uywwc30gKyBiX3tJLDBpfSkgKyAozrJfezF9ICsgYl97Uywxc30pIFhfaSArIGVfe3NpfSIsCiAgICAgICAgICAgICAgICAgIuKIvCBYICsgKDEgKyBY4oijU3ViamVjdCkgKyAoMeKIo0l0ZW0pIiwKICAgICAgICAgICAgICAgICAiQXMgYWJvdmUsIGJ1dCAkU197MHN9JCwgJFNfezFzfSQgaW5kZXBlbmRlbnQiLAogICAgICAgICAgICAgICAgICLiiLwgWCArICgx4oijU3ViamVjdCkgKyAoMCArIFjiiKMgU3ViamVjdCkgKyAoMeKIo0l0ZW0pIiwgCiAgICAgICAgICAgICAgICAgIijOsl8wICsgYl97Uywwc30gKyBiX3tJLDBpfSkgKyDOsl97MX1YX2kgKyBlX3tzaX0iLAogICAgICAgICAgICAgICAgICLiiLwgWCArICgx4oijU3ViamVjdCkgKyAoMeKIo0l0ZW0pIiwgCiAgICAgICAgICAgICAgICAgIijOsl8wICsgYl97SSwwaX0pICsgICjOsl97MX0gKyBiX3tTLDFzfSlYX2kgKyBlX3tzaX0iLAogICAgICAgICAgICAgICAgICLiiLwgWCArICgwICsgWOKIo1N1YmplY3QpICsgKDHiiKNJdGVtKSIpLAogICAgICAgICAgICAgICBieXJvdz1UUlVFLG5jb2w9MiwKICAgICAgICAgICAgICAgZGltbmFtZXM9bGlzdChOVUxMLGMoImVxdWF0aW9uIiwiZm9ybXVsYSIpKSkKZnRhYiA8LSBkYXRhLmZyYW1lKGZ0YWIsc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkKZmYgPC0gIWdyZXBsKCJBcyBhYm92ZSIsZnRhYiRlcXVhdGlvbikKZnRhYiRlcXVhdGlvbltmZl0gPC0gc3ByaW50ZigiJCVzJCIsZnRhYiRlcXVhdGlvbltmZl0pCmZmIDwtICFncmVwbCgibi9hIixmdGFiJGZvcm11bGEpCmZ0YWIkZm9ybXVsYVtmZl0gPC0gc3ByaW50ZigiYCVzYCIsZnRhYiRmb3JtdWxhW2ZmXSkKcGFuZGVyOjpwYW5kZXIoZnRhYixqdXN0aWZ5PSJsZWZ0IikKYGBgCgpNb2RpZmllZCBmcm9tOiBodHRwOi8vc3RhdHMuc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzEzMTY2L3JzLWxtZXItY2hlYXQtc2hlZXQ/bHE9MSAoTGl2aXVzKQoKClRoZSAqKm1hZ2ljKiogZGV2ZWxvcG1lbnQgdmVyc2lvbiBvZiB0aGUgW2VxdWF0aW9tYXRpYyBwYWNrYWdlXShodHRwczovL2dpdGh1Yi5jb20vZGF0YWxvcmF4L2VxdWF0aW9tYXRpYykgY2FuIGhhbmRsZSBtaXhlZCBtb2RlbHMgKGByZW1vdGVzOjppbnN0YWxsX2dpdGh1YigiZGF0YWxvcmF4L2VxdWF0aW9tYXRpYyIpYCksIGUuZy4KCmBgYHtyIGVxdWF0aW9tYXRpYywgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0iYXNpcyJ9CmxpYnJhcnkobG1lNCkKbGlicmFyeShlcXVhdGlvbWF0aWMpCmZtMSA8LSBsbWVyKFJlYWN0aW9uIH4gRGF5cyArIChEYXlzfFN1YmplY3QpLCBzbGVlcHN0dWR5KQplcXVhdGlvbWF0aWM6OmV4dHJhY3RfZXEoZm0xKQpgYGAKCkl0IGRvZXNuJ3QgaGFuZGxlIEdMTU1zICh5ZXQpLCBidXQgeW91IGNvdWxkIGZpdCB0d28gZmFrZSBtb2RlbHMgJm1kYXNoOyBvbmUgTE1NIGxpa2UgeW91ciBHTE1NIGJ1dCB3aXRoIGEgR2F1c3NpYW4gcmVzcG9uc2UsIGFuZCBvbmUgR0xNIHdpdGggdGhlIHNhbWUgZmFtaWx5L2xpbmsgZnVuY3Rpb24gYXMgeW91ciBHTE1NIGJ1dCB3aXRob3V0IHRoZSByYW5kb20gZWZmZWN0cyAmbWRhc2g7IGFuZCBwdXQgdGhlIHBpZWNlcyB0b2dldGhlci4KCk1vcmUgcG9zc2libHkgdXNlZnVsIGxpbmtzOgoKLSBSZW5zZSBOaWV1d2VuaHVpcydzIFtibG9ncG9zdC9sZXNzb24gb24gbG1lNCBtb2RlbCBzcGVjaWZpY2F0aW9uXShodHRwOi8vd3d3LnJlbnNlbmlldXdlbmh1aXMubmwvci1zZXNzaW9ucy0xNi1tdWx0aWxldmVsLW1vZGVsLXNwZWNpZmljYXRpb24tbG1lNC8pCi0gQ3Jvc3NWYWxpZGF0ZWQncyBbbG1lciBjaGVhdCBzaGVldF0oaHR0cHM6Ly9zdGF0cy5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvMTMxNjYvcnMtbG1lci1jaGVhdC1zaGVldCkKLSBLcmlzdG9mZmVyIE1hZ251c3NvbidzIFtVc2luZyBSIGFuZCBsbWUvbG1lciB0byBmaXQgZGlmZmVyZW50IHR3by0gYW5kIHRocmVlLWxldmVsIGxvbmdpdHVkaW5hbCBtb2RlbHNdKGh0dHBzOi8vcnBzeWNob2xvZ2lzdC5jb20vci1ndWlkZS1sb25naXR1ZGluYWwtbG1lLWxtZXIpCgojIyBTaG91bGQgSSB0cmVhdCBmYWN0b3IgeHh4IGFzIGZpeGVkIG9yIHJhbmRvbT8KClRoaXMgaXMgaW4gZ2VuZXJhbCBhIGZhciBtb3JlIGRpZmZpY3VsdCBxdWVzdGlvbiB0aGFuIGl0IHNlZW1zIG9uIHRoZSBzdXJmYWNlLiBUaGVyZSBhcmUgbWFueSBjb21wZXRpbmcgcGhpbG9zb3BoaWVzIGFuZCBkZWZpbml0aW9ucy4gRm9yIGV4YW1wbGUsIGZyb20gQGdlbG1hbl9hbmFseXNpc18yMDA1OgoKPiBCZWZvcmUgZGlzY3Vzc2luZyB0aGUgdGVjaG5pY2FsIGlzc3Vlcywgd2UgYnJpZWZseSByZXZpZXcgd2hhdCBpcyBtZWFudCBieSBmaXhlZCBhbmQgcmFuZG9tIGVmZmVjdHMuIEl0IHR1cm5zIG91dCB0aGF0IGRpZmZlcmVudOKAlGluIGZhY3QsIGluY29tcGF0aWJsZeKAlGRlZmluaXRpb25zIGFyZSB1c2VkIGluIGRpZmZlcmVudCBjb250ZXh0cy4gW1NlZSBhbHNvIEtyZWZ0IGFuZCBkZSBMZWV1dyAoMTk5OCksIFNlY3Rpb24gMS4zLjMsIGZvciBhIGRpc2N1c3Npb24gb2YgdGhlIG11bHRpcGxpY2l0eSBvZiBkZWZpbml0aW9ucyBvZiBmaXhlZCBhbmQgcmFuZG9tIGVmZmVjdHMgYW5kIGNvZWZmaWNpZW50cywgYW5kIFJvYmluc29uICgxOTk4KSBmb3IgYSBoaXN0b3JpY2FsIG92ZXJ2aWV3Ll0gSGVyZSB3ZSBvdXRsaW5lIGZpdmUgZGVmaW5pdGlvbnMgdGhhdCB3ZSBoYXZlIHNlZW46IDEuIEZpeGVkIGVmZmVjdHMgYXJlIGNvbnN0YW50IGFjcm9zcyBpbmRpdmlkdWFscywgYW5kIHJhbmRvbSBlZmZlY3RzIHZhcnkuIEZvciBleGFtcGxlLCBpbiBhIGdyb3d0aCBzdHVkeSwgYSBtb2RlbCB3aXRoIHJhbmRvbSBpbnRlcmNlcHRzIM6xaSBhbmQgZml4ZWQgc2xvcGUgzrIgY29ycmVzcG9uZHMgdG8gcGFyYWxsZWwgbGluZXMgZm9yIGRpZmZlcmVudCBpbmRpdmlkdWFscyBpLCBvciB0aGUgbW9kZWwgeWl0ID0gzrFpICsgzrJ0LiBLcmVmdCBhbmQgZGUgTGVldXcgWygxOTk4KSwgcGFnZSAxMl0gdGh1cyBkaXN0aW5ndWlzaCBiZXR3ZWVuIGZpeGVkIGFuZCByYW5kb20gY29lZmZpY2llbnRzLiAyLiBFZmZlY3RzIGFyZSBmaXhlZCBpZiB0aGV5IGFyZSBpbnRlcmVzdGluZyBpbiB0aGVtc2VsdmVzIG9yIHJhbmRvbSBpZiB0aGVyZSBpcyBpbnRlcmVzdCBpbiB0aGUgdW5kZXJseWluZyBwb3B1bGF0aW9uLiBTZWFybGUsIENhc2VsbGEgYW5kIE1jQ3VsbG9jaCBbKDE5OTIpLCBTZWN0aW9uIDEuNF0gZXhwbG9yZSB0aGlzIGRpc3RpbmN0aW9uIGluIGRlcHRoLiAzLiDigJxXaGVuIGEgc2FtcGxlIGV4aGF1c3RzIHRoZSBwb3B1bGF0aW9uLCB0aGUgY29ycmVzcG9uZGluZyB2YXJpYWJsZSBpcyBmaXhlZDsgd2hlbiB0aGUgc2FtcGxlIGlzIGEgc21hbGwgKGkuZS4sIG5lZ2xpZ2libGUpIHBhcnQgb2YgdGhlIHBvcHVsYXRpb24gdGhlIGNvcnJlc3BvbmRpbmcgdmFyaWFibGUgaXMgcmFuZG9t4oCdIFtHcmVlbiBhbmQgVHVrZXkgKDE5NjApXS4gNC4g4oCcSWYgYW4gZWZmZWN0IGlzIGFzc3VtZWQgdG8gYmUgYSByZWFsaXplZCB2YWx1ZSBvZiBhIHJhbmRvbSB2YXJpYWJsZSwgaXQgaXMgY2FsbGVkIGEgcmFuZG9tIGVmZmVjdOKAnSBbTGFNb3R0ZSAoMTk4MyldLiA1LiBGaXhlZCBlZmZlY3RzIGFyZSBlc3RpbWF0ZWQgdXNpbmcgbGVhc3Qgc3F1YXJlcyAob3IsIG1vcmUgZ2VuZXJhbGx5LCBtYXhpbXVtIGxpa2VsaWhvb2QpIGFuZCByYW5kb20gZWZmZWN0cyBhcmUgZXN0aW1hdGVkIHdpdGggc2hyaW5rYWdlIFvigJxsaW5lYXIgdW5iaWFzZWQgcHJlZGljdGlvbuKAnSBpbiB0aGUgdGVybWlub2xvZ3kgb2YgUm9iaW5zb24gKDE5OTEpXS4gVGhpcyBkZWZpbml0aW9uIGlzIHN0YW5kYXJkIGluIHRoZSBtdWx0aWxldmVsIG1vZGVsaW5nIGxpdGVyYXR1cmUgW3NlZSwgZS5nLiwgU25pamRlcnMgYW5kIEJvc2tlciAoMTk5OSksIFNlY3Rpb24gNC4yXSBhbmQgaW4gZWNvbm9tZXRyaWNzLgoKQW5vdGhlciB1c2VmdWwgY29tbWVudCAodmlhIEtldmluIFdyaWdodCkgcmVpbmZvcmNpbmcgdGhlIGlkZWEgdGhhdCAicmFuZG9tIHZzLiBmaXhlZCIgaXMgbm90IGEgc2ltcGxlLCBjdXQtYW5kLWRyaWVkIGRlY2lzaW9uOiBmcm9tIEBzY2hhYmVuYmVyZ2VyX2NvbnRlbXBvcmFyeV8yMDAxLCBwLiA2Mjc6Cgo+IEJlZm9yZSBwcm9jZWVkaW5nIGZ1cnRoZXIgd2l0aCByYW5kb20gZmllbGQgbGluZWFyIG1vZGVscyB3ZSBuZWVkIHRvIHJlbWluZCB0aGUgcmVhZGVyIG9mIHRoZSBhZGFnZSB0aGF0IG9uZSBtb2RlbGVyJ3MgcmFuZG9tIGVmZmVjdCBpcyBhbm90aGVyIG1vZGVsZXIncyBmaXhlZCBlZmZlY3QuCgpAY2xhcmsyMDE1c2hvdWxkIGFkZHJlc3MgdGhpcyBxdWVzdGlvbiBmcm9tIGEgbW9zdGx5IGVjb25vbWV0cmljIHBlcnNwZWN0aXZlLCBmb2N1c2luZyBtb3N0bHkgb24gcHJhY3RpY2FsIHZhcmlhbmNlL2JpYXMvUk1TRSBjcml0ZXJpYS4KCk9uZSBwb2ludCBvZiBwYXJ0aWN1bGFyIHJlbGV2YW5jZSB0byAnbW9kZXJuJyBtaXhlZCBtb2RlbCBlc3RpbWF0aW9uIChyYXRoZXIgdGhhbiAnY2xhc3NpY2FsJyBtZXRob2Qtb2YtbW9tZW50cyBlc3RpbWF0aW9uKSBpcyB0aGF0LCBmb3IgcHJhY3RpY2FsIHB1cnBvc2VzLCB0aGVyZSBtdXN0IGJlIGEgcmVhc29uYWJsZSBudW1iZXIgb2YgcmFuZG9tLWVmZmVjdHMgbGV2ZWxzIChlLmcuIGJsb2NrcykgLS0gbW9yZSB0aGFuIDUgb3IgNiBhdCBhIG1pbmltdW0uIFRoaXMgaXMgbm90IHN1cnByaXNpbmcgaWYgeW91IGNvbnNpZGVyIHRoYXQgcmFuZG9tIGVmZmVjdHMgZXN0aW1hdGlvbiBpcyB0cnlpbmcgdG8gZXN0aW1hdGUgYW4gYW1vbmctYmxvY2sgdmFyaWFuY2UuIEZvciBleGFtcGxlLCBmcm9tIEBDcmF3bGV5MjAwMiBwLiA2NzA6IAoKPiBBcmUgdGhlcmUgZW5vdWdoIGxldmVscyBvZiB0aGUgZmFjdG9yIGluIHRoZSBkYXRhIG9uIHdoaWNoIHRvIGJhc2UgYW4gZXN0aW1hdGUgb2YgdGhlIHZhcmlhbmNlIG9mIHRoZSBwb3B1bGF0aW9uIG9mIGVmZmVjdHM/IE5vLCBtZWFucyBbeW91IHNob3VsZCBwcm9iYWJseSB0cmVhdCB0aGUgdmFyaWFibGUgYXNdIGZpeGVkIGVmZmVjdHMuCgpTb21lIHJlc2VhcmNoZXJzICh3aG8gdHJlYXQgZml4ZWQgdnMgcmFuZG9tIGFzIGEgcGhpbG9zb3BoaWNhbCByYXRoZXIgdGhhbiBhIHByYWdtYXRpYyBkZWNpc2lvbikgb2JqZWN0IHRvIHRoaXMgYXBwcm9hY2guCgpBbHNvIHNlZSBhIHZlcnkgdGhvdWdodGZ1bCBjaGFwdGVyIGluIEBob2RnZXNfcmljaGx5XzIwMTYuCgpUcmVhdGluZyBmYWN0b3JzIHdpdGggc21hbGwgbnVtYmVycyBvZiBsZXZlbHMgYXMgcmFuZG9tIHdpbGwgaW4gdGhlIGJlc3QgY2FzZSAgbGVhZCB0byB2ZXJ5IHNtYWxsIGFuZC9vciBpbXByZWNpc2UgZXN0aW1hdGVzIG9mIHJhbmRvbSBlZmZlY3RzOyBpbiB0aGUgd29yc3QgY2FzZSBpdCB3aWxsIGxlYWQgdG8gdmFyaW91cyBudW1lcmljYWwgZGlmZmljdWx0aWVzIHN1Y2ggYXMgbGFjayBvZiBjb252ZXJnZW5jZSwgemVybyB2YXJpYW5jZSBlc3RpbWF0ZXMsIGV0Yy4uIChBIHNtYWxsIFtzaW11bGF0aW9uIGV4ZXJjaXNlXShodHRwczovcnB1YnMuY29tL2Jib2xrZXIvNDE4Nykgc2hvd3MgdGhhdCBhdCBsZWFzdCB0aGUgZXN0aW1hdGVzIG9mIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gYXJlIGRvd253YXJkbHkgYmlhc2VkIGluIHRoaXMgY2FzZTsgaXQncyBub3QgY2xlYXIgd2hldGhlci9ob3cgdGhpcyBiaWFzIHdvdWxkIGFmZmVjdCB0aGUgcG9pbnQgZXN0aW1hdGVzIG9mICBmaXhlZCBlZmZlY3RzIG9yIHRoZWlyIGVzdGltYXRlZCBjb25maWRlbmNlIGludGVydmFscy4pIEluIHRoZSBjbGFzc2ljYWwgbWV0aG9kLW9mLW1vbWVudHMgYXBwcm9hY2ggdGhlc2UgcHJvYmxlbXMgbWF5IG5vdCBhcmlzZSAoYmVjYXVzZSB0aGUgc3VtcyBvZiBzcXVhcmVzIGFyZSBhbHdheXMgd2VsbCBkZWZpbmVkIGFzIGxvbmcgYXMgdGhlcmUgYXJlIGF0IGxlYXN0IHR3byB1bml0cyksIGJ1dCB0aGUgdW5kZXJseWluZyBwcm9ibGVtcyBvZiBsYWNrIG9mIHBvd2VyIGFyZSB0aGVyZSBuZXZlcnRoZWxlc3MuCgoKVGhpZXJyeSBPbmtlbGlueCBoYXMgW2EgYmxvZyBwb3N0XShodHRwczovL3d3dy5tdXNjYXJkaW51cy5iZS8yMDE4LzA5L251bWJlci1yYW5kb20tZWZmZWN0LWxldmVscy8pIHdpdGggc29tZSBzaW11bGF0aW9ucyBvbiB0aGUgaW1wYWN0IG9mIHRoZSBudW1iZXIgb2YgbGV2ZWxzIGFuZCBjb25jbHVkZXMgd2l0aCBhIGZldyByZWNvbW1lbmRhdGlvbnMgZm9yIHRoZSBudW1iZXIgb2YgbGV2ZWxzIG9mIHRoZSBncm91cGluZyB2YXJpYWJsZSAkbl9zJDoKPiAtIGdldCAkbl9zID4gMTAwMCQgbGV2ZWxzIHdoZW4gYW4gYWNjdXJhdGUgZXN0aW1hdGUgb2YgdGhlIHJhbmRvbSBlZmZlY3QgdmFyaWFuY2UgaXMgY3J1Y2lhbC4gRS5nLiB3aGVuIGEgc2luZ2xlIG51bWJlciB3aWxsIGJlIHVzZSBmb3IgcG93ZXIgY2FsY3VsYXRpb25zLgo+IC0gZ2V0ICRuX3MgPiAxMDAkIGxldmVscyB3aGVuIGEgcmVhc29uYWJsZSBlc3RpbWF0ZSBvZiB0aGUgcmFuZG9tIGVmZmVjdCB2YXJpYW5jZSBpcyBzdWZmaWNpZW50LiBFLmcuIHBvd2VyIGNhbGN1bGF0aW9ucyB3aXRoIHNlbnNpdGl2aXR5IGFuYWx5c2lzIG9mIHRoZSByYW5kb20gZWZmZWN0IHZhcmlhbmNlLgo+IC0gZ2V0ICRuX3MgPiAyMCQgbGV2ZWxzIGZvciBhbiBleHBlcmltZW50YWwgc3R1ZHkKPiAtIGluIGNhc2UgJDEwIDwgbl9zIDwyMCQgeW91IHNob3VsZCB2YWxpZGF0ZSB0aGUgbW9kZWwgdmVyeSBjYXV0aW91cyBiZWZvcmUgdXNpbmcgdGhlIG91dHB1dAo+IC0gaW4gY2FzZSAkbl9zIDwgMTAkIGl0IGlzIHNhZmVyIHRvIHVzZSB0aGUgdmFyaWFibGUgYXMgYSBmaXhlZCBlZmZlY3QuCgpAb2JlcnByaWxsZXJfZml4ZWRfMjAyMSBhbHNvIHBlcmZvcm1lZCBhIHNpbXVsYXRpb24gc3R1ZHkgYW5kIGZvdW5kIHRoYXQgd2hpbGUgdGhlIGVzdGltYXRlcyBhcmUgc2ltaWxhciBmb3IgdHJlYXRpbmcgYSB2YXJpYWJsZSB3aXRoIGEgc21hbGwgbnVtYmVyIG9mIGxldmVscyBhcyBmaXhlZCBvciByYW5kb20gYXJlIHNpbWlsYXIsIHRoZXJlIHdhcyBhbiBpbXBhY3Qgb24gVHlwZSAxIGFuZCBUeXBlIDIgZXJyb3IgcmF0ZXMuIFRoZXkgYWxzbyBmb3VuZCB0aGF0IHRoZSBwcmVjaXNlIHJhbmRvbSBlZmZlY3RzIHN0cnVjdHVyZSAoZS5nLiwgaW5jbHVzaW9uIG9mIHJhbmRvbSBzbG9wZXMpIGhhZCBhIGxhcmdlIGltcGFjdCBvbiB0aGVzZSBwcm9wZXJ0aWVzLgoKQWxzbyBzZWUgW3RoaXMgdGhyZWFkXShodHRwczovL3N0YXQuZXRoei5jaC9waXBlcm1haWwvci1zaWctbWl4ZWQtbW9kZWxzLzIwMTBxMi8wMDM3MDkuaHRtbCkgb24gdGhlIHItc2lnLW1peGVkLW1vZGVscyBtYWlsaW5nIGxpc3QgYW5kIFt0aGlzIHF1ZXN0aW9uXShodHRwczovL3N0YXRzLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy8zNzY0Ny93aGF0LWlzLXRoZS1taW5pbXVtLXJlY29tbWVuZGVkLW51bWJlci1vZi1ncm91cHMtZm9yLWEtcmFuZG9tLWVmZmVjdHMtZmFjdG9yKSBvbiBDcm9zc1ZhbGlkYXRlZC4KCiMjIE5lc3RlZCBvciBjcm9zc2VkPwoKPGEgaWQ9Im5lc3RlZF9vcl9jcm9zc2VkIj48L2E+CgotIFJlbGF0aXZlbHkgZmV3IG1peGVkIGVmZmVjdCBtb2RlbGluZyBwYWNrYWdlcyBjYW4gaGFuZGxlIGNyb3NzZWQgcmFuZG9tIGVmZmVjdHMsIGkuZS4gdGhvc2Ugd2hlcmUgb25lIGxldmVsIG9mIGEgcmFuZG9tIGVmZmVjdCBjYW4gYXBwZWFyIGluIGNvbmp1bmN0aW9uIHdpdGggbW9yZSB0aGFuIG9uZSBsZXZlbCBvZiBhbm90aGVyIGVmZmVjdC4gIChUaGlzIGRlZmluaXRpb24gaXMgY29uZnVzaW5nLCBhbmQgSSB3b3VsZCBoYXBwaWx5IGFjY2VwdCBhIGJldHRlciBvbmUuKSAgQSBjbGFzc2ljIGV4YW1wbGUgaXMgY3Jvc3NlZCB0ZW1wb3JhbCBhbmQgc3BhdGlhbCBlZmZlY3RzLiBJZiB0aGVyZSBpcyByYW5kb20gdmFyaWF0aW9uIGFtb25nIHRlbXBvcmFsIGJsb2NrcyAoZS5nLiB5ZWFycykgJydhbmQnJyByYW5kb20gdmFyaWF0aW9uIGFtb25nIHNwYXRpYWwgYmxvY2tzIChlLmcuIHNpdGVzKSwgJydhbmQnJyBpZiB0aGVyZSBpcyBhIGNvbnNpc3RlbnQgeWVhciBlZmZlY3QgYWNyb3NzIHNpdGVzIGFuZCAnJ3ZpY2UgdmVyc2EnJywgdGhlbiB0aGUgcmFuZG9tIGVmZmVjdHMgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgY3Jvc3NlZC4KLSBgbG1lNGAgZG9lcyBoYW5kbGVkIGNyb3NzZWQgZWZmZWN0cywgZWZmaWNpZW50bHkKLSBpZiB5b3UgbmVlZCB0byBkZWFsIHdpdGggY3Jvc3NlZCBSRXMgaW4gY29uanVuY3Rpb24gd2l0aCBzb21lIG9mIHRoZSBmZWF0dXJlcyB0aGF0IGBubG1lYCBvZmZlcnMgKGUuZy4gaGV0ZXJvc2NlZGFzdGljaXR5IG9mIHJlc2lkdWFscyB2aWEgYHdlaWdodHNgL2B2YXJTdHJ1Y3RgLCBjb3JyZWxhdGlvbiBvZiByZXNpZHVhbHMgdmlhIGBjb3JyZWxhdGlvbmAvYGNvclN0cnVjdGAsICBvciBpZiB5b3Ugd2FudCB0byB1c2VkIGNyb3NzZWQgUkVzIHdpdGggdGhlIGBnYW1sc3NgIHBhY2thZ2UsIHNlZSBwLiAxNjNmZiBvZiBAcGluaGVpcm9fbWl4ZWQtZWZmZWN0c18yMDAwIChzZWN0aW9uIDQuMi4yOiAgW0dvb2dsZSBib29rcyBsaW5rXShodHRwOi8vdGlueXVybC5jb20vY3Jvc3NlZFJFKSkuIEkgZ2l2ZSBhIHdvcmtlZCBleGFtcGxlIFtoZXJlXShodHRwczovL2dpc3QuZ2l0aHViLmNvbS9iYm9sa2VyLzgzYzFmZjAzNmQ0ODUwZDdkYzRjYTgzMmUzNTRmNmE4KS4gQXMgZmFyIGFzIEkgY2FuIHRlbGwsIGEgY291cGxlIG9mIGhhY2tzIGFyZSBuZWNlc3NhcnkgdG8gZ2V0IHRoaXMgdG8gd29yazogKDEpIHRoZSBkYXRhIG11c3QgYmUgZXhwcmVzc2VkIGFzIGEgYGdyb3VwZWREYXRhYCBvYmplY3QgKGF0IGxlYXN0LCBJIGhhdmVuJ3QgbWFuYWdlZCB0byBnZXQgaXQgdG8gd29yayBpbiBhbnkgb3RoZXIgd2F5KTsgKDIpIHRoZSBjcm9zc2VkIGVmZmVjdHMgbXVzdCBiZSAqbmVzdGVkIHdpdGhpbiBhbm90aGVyIGdyb3VwaW5nIGZhY3RvciogLSBpbiB0aGUgZXhhbXBsZSBoZXJlIEkgZGVmaW5lIGEgZHVtbXkgZ3JvdXAsIHdoaWNoIGlzIGF3a3dhcmQgKGl0IG1ha2VzIHRoZSB2YXJpYW5jZSBjb21wb25lbnQgZm9yIHRoaXMgZ3JvdXAgYW5kIHRoZSByZXNpZHVhbCB2YXJpYW5jZSBqb2ludGx5IHVuaWRlbnRpZmlhYmxlKSwgYnV0IG90aGVyd2lzZSBzZWVtcyB0byB3b3JrIE9LLgotIEkgcmFyZWx5IGZpbmQgaXQgdXNlZnVsIHRvIHRoaW5rIG9mIGZpeGVkIGVmZmVjdHMgYXMgIm5lc3RlZCIgKGFsdGhvdWdoIG90aGVycyBkaXNhZ3JlZSk7IGlmIGZvciBleGFtcGxlIHRyZWF0bWVudHMgQSBhbmQgQiBhcmUgb25seSBtZWFzdXJlZCBpbiBibG9jayAxLCBhbmQgdHJlYXRtZW50cyBDIGFuZCBEIGFyZSBvbmx5IG1lYXN1cmVkIGluIGJsb2NrIDIsIG9uZSBzdGlsbCBhc3N1bWVzIChiZWNhdXNlIHRoZXkgYXJlIGZpeGVkIGVmZmVjdHMpIHRoYXQgZWFjaCB0cmVhdG1lbnQgd291bGQgaGF2ZSB0aGUgc2FtZSBlZmZlY3QgaWYgYXBwbGllZCBpbiB0aGUgb3RoZXIgYmxvY2suIChPbmUgbWlnaHQgbGlrZSB0byBlc3RpbWF0ZSB0cmVhdG1lbnQtYnktYmxvY2sgaW50ZXJhY3Rpb25zLCBidXQgaW4gdGhpcyBjYXNlIHRoZSBleHBlcmltZW50YWwgZGVzaWduIGRvZXNuJ3QgYWxsb3cgaXQ7IG9uZSB3b3VsZCBoYXZlIHRvIGhhdmUgbXVsdGlwbGUgdHJlYXRtZW50cyBtZWFzdXJlZCB3aXRoaW4gZWFjaCBibG9jaywgYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IGFsbCB0cmVhdG1lbnRzIGluIGV2ZXJ5IGJsb2NrLikgIE9uZSB3b3VsZCBjb2RlIHRoaXMgYW5hbHlzaXMgYXMgYHJlc3BvbnNlfnRyZWF0bWVudCsoMXxibG9jaylgIGluIGBsbWU0YC4gQWxzbywgaW4gdGhlIGNhc2Ugb2YgZml4ZWQgZWZmZWN0cywgY3Jvc3NlZCBhbmQgbmVzdGVkIHNwZWNpZmljYXRpb25zIGNoYW5nZSB0aGUgcGFyYW1ldGVyaXphdGlvbiBvZiB0aGUgbW9kZWwsIGJ1dCBub3QgYW55dGhpbmcgZWxzZSAoZS5nLiB0aGUgbnVtYmVyIG9mIHBhcmFtZXRlcnMgZXN0aW1hdGVkLCBsb2ctbGlrZWxpaG9vZCwgbW9kZWwgcHJlZGljdGlvbnMgYXJlIGFsbCBpZGVudGljYWwpLiAgVGhhdCBpcywgaW4gUidzIGBtb2RlbC5tYXRyaXhgIGZ1bmN0aW9uICh3aGljaCBpbXBsZW1lbnRzIGEgdmVyc2lvbiBvZiBXaWxraW5zb24tUm9nZXJzIG5vdGF0aW9uKSBgYSpiYCBhbmQgYGEvYmAgKHdoaWNoIGV4cGFuZCB0byBgMSthK2IrYTpiYCBhbmQgYDErYSthOmJgIHJlc3BlY3RpdmVseSkgZ2l2ZSBtb2RlbCBtYXRyaWNlcyB3aXRoIHRoZSBzYW1lIG51bWJlciBvZiBjb2x1bW5zLgotIFdoZXRoZXIgeW91IGV4cGxpY2l0bHkgc3BlY2lmeSBhIHJhbmRvbSBlZmZlY3QgYXMgbmVzdGVkIG9yIG5vdCBkZXBlbmRzIChpbiBwYXJ0KSBvbiB0aGUgd2F5IHRoZSBsZXZlbHMgb2YgdGhlIHJhbmRvbSBlZmZlY3RzIGFyZSBjb2RlZC4gSWYgdGhlICdsb3dlci1sZXZlbCcgcmFuZG9tIGVmZmVjdCBpcyBjb2RlZCB3aXRoIHVuaXF1ZSBsZXZlbHMsIHRoZW4gdGhlIHR3byBzeW50YXhlcyBgKDF8YS9iKWAgKG9yIGAoMXxhKSsoMXxhOmIpYCkgYW5kIGAoMXxhKSsoMXxiKWAgYXJlIGVxdWl2YWxlbnQuIElmIHRoZSBsb3dlci1sZXZlbCByYW5kb20gZWZmZWN0IGhhcyB0aGUgc2FtZSBsYWJlbHMgd2l0aGluIGVhY2ggbGFyZ2VyIGdyb3VwIChlLmcuIGJsb2NrcyAxLCAyLCAzLCA0IHdpdGhpbiBzaXRlcyBBLCBCLCBhbmQgQykgdGhlbiB0aGUgZXhwbGljaXQgbmVzdGluZyBgKDF8YS9iKWAgaXMgcmVxdWlyZWQuIEl0IHNlZW1zIHRvIGJlIGNvbnNpZGVyZWQgYmVzdCBwcmFjdGljZSB0byBjb2RlIHRoZSBuZXN0ZWQgbGV2ZWwgdW5pcXVlbHkgKGUuZy4gQTEsIEEyLCAuLi4sIEIxLCBCMiwgLi4uKSBzbyB0aGF0IGNvbmZ1c2lvbiBiZXR3ZWVuIG5lc3RlZCBhbmQgY3Jvc3NlZCBlZmZlY3RzIGlzIGxlc3MgbGlrZWx5LgoKIyMgKFdoZW4pIGNhbiBJIGluY2x1ZGUgYSBwcmVkaWN0b3IgYXMgYm90aCBmaXhlZCBhbmQgcmFuZG9tPwoKU2VlIFtibG9nIHBvc3QgYnkgVGhpZXJyeSBPbmtlbGlueF0oaHR0cHM6Ly93d3cubXVzY2FyZGludXMuYmUvMjAxNy8wOC9maXhlZC1hbmQtcmFuZG9tLykKCiMgTW9kZWwgZXh0ZW5zaW9ucwoKIyMgT3ZlcmRpc3BlcnNpb24KCjxhIGlkPSJvdmVyZGlzcGVyc2lvbiI+PC9hPgoKIyMjIFRlc3RpbmcgZm9yIG92ZXJkaXNwZXJzaW9uL2NvbXB1dGluZyBvdmVyZGlzcGVyc2lvbiBmYWN0b3IKCi0gd2l0aCB0aGUgdXN1YWwgY2F2ZWF0cywgcGx1cyBhIGZldyBleHRyYXMgLS0gY291bnRpbmcgZGVncmVlcyBvZiBmcmVlZG9tLCBldGMuIC0tIHRoZSB1c3VhbCBwcm9jZWR1cmUgb2YgY2FsY3VsYXRpbmcgdGhlIHN1bSBvZiBzcXVhcmVkIFBlYXJzb24gcmVzaWR1YWxzIGFuZCBjb21wYXJpbmcgaXQgdG8gdGhlIHJlc2lkdWFsIGRlZ3JlZXMgb2YgZnJlZWRvbSBzaG91bGQgZ2l2ZSBhdCBsZWFzdCBhIGNydWRlIGlkZWEgb2Ygb3ZlcmRpc3BlcnNpb24uICBUaGUgZm9sbG93aW5nIGF0dGVtcHQgY291bnRzIGVhY2ggdmFyaWFuY2Ugb3IgY292YXJpYW5jZSBwYXJhbWV0ZXIgYXMgb25lIG1vZGVsIGRlZ3JlZSBvZiBmcmVlZG9tIGFuZCBwcmVzZW50cyB0aGUgc3VtIG9mIHNxdWFyZWQgUGVhcnNvbiByZXNpZHVhbHMsIHRoZSByYXRpbyBvZiAoU1NRIHJlc2lkdWFscy9yZGYpLCB0aGUgcmVzaWR1YWwgZGYsIGFuZCB0aGUgJHAkLXZhbHVlIGJhc2VkIG9uIHRoZSAoYXBwcm94aW1hdGVseSEhKSBhcHByb3ByaWF0ZSAkXGNoaV4yJCBkaXN0cmlidXRpb24uICoqRG8gUExFQVNFIG5vdGUgdGhlIHVzdWFsLCBhbmQgZXh0cmEsIGNhdmVhdHMgbm90ZWQgaGVyZTogdGhpcyBpcyBhbiBBUFBST1hJTUFURSBlc3RpbWF0ZSBvZiBhbiBvdmVyZGlzcGVyc2lvbiBwYXJhbWV0ZXIqKi4gRXZlbiBpbiB0aGUgR0xNIGNhc2UsIHRoZSBleHBlY3RlZCBkZXZpYW5jZSBwZXIgcG9pbnQgZXF1YWxpbmcgMSBpcyBvbmx5IHRydWUgYXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiBpbmRpdmlkdWFsIGRldmlhdGVzIGFwcHJvYWNoZXMgbm9ybWFsaXR5LCBpLmUuIHRoZSB1c3VhbCAkXGxhbWJkYT41JCBydWxlcyBvZiB0aHVtYiBmb3IgUG9pc3NvbiB2YWx1ZXMgYW5kICRcdGV4dHJte21pbn0oTnAsIE4oMS1wKSkgPiA1JCBmb3IgYmlub21pYWwgdmFsdWVzIChlLmcuIHNlZSBAdmVuYWJsZXNfbW9kZXJuXzIwMDIsIFtwLiAyMDgtMjA5XShodHRwOi8vYm9va3MuZ29vZ2xlLmNvbS9ib29rcz9pZD05NzRjNHZLdXJOa0MmcGc9UEEyMDkpKS4gKEFuZCB0aGF0J3Mgd2l0aG91dCB0aGUgZXh0cmEgY29tcGxleGl0aWVzIGR1ZSB0byBHTE1NLCBpLmUuIHRoZSAiZWZmZWN0aXZlIiByZXNpZHVhbCBkZiBzaG91bGQgYmUgbGFyZ2UgZW5vdWdoIHRvIG1ha2UgdGhlIHN1bXMgb2Ygc3F1YXJlcyBjb252ZXJnZSBvbiBhICRcY2hpXjIkIGRpc3RyaWJ1dGlvbiAuLi4pCi0gUmVtZW1iZXIgdGhhdCAoMSkgb3ZlcmRpc3BlcnNpb24gaXMgaXJyZWxldmFudCBmb3IgbW9kZWxzIHRoYXQgZXN0aW1hdGUgYSBzY2FsZSBwYXJhbWV0ZXIgKGkuZS4gYWxtb3N0IGFueXRoaW5nIGJ1dCBQb2lzc29uIG9yIGJpbm9taWFsOiBHYXVzc2lhbiwgR2FtbWEsIG5lZ2F0aXZlIGJpbm9taWFsIC4uLikgYW5kICgyKSBvdmVyZGlzcGVyc2lvbiBpcyBub3QgZXN0aW1hYmxlIChhbmQgaGVuY2UgcHJhY3RpY2FsbHkgaXJyZWxldmFudCkgZm9yIEJlcm5vdWxsaSBtb2RlbHMgKD0gYmluYXJ5IGRhdGEgPSBiaW5vbWlhbCB3aXRoICROPTEkKS4KLSBUaGUgcmVjaXBlcyBiZWxvdyBtYXkgbmVlZCBhZGp1c3RtZW50IGZvciBzb21lIG9mIHRoZSBtb3JlIGNvbXBsZXggbW9kZWwgdHlwZXMgYWxsb3dlZCBieSBgZ2xtbVRNQmAgKGUuZy4gemVyby1pbmZsYXRpb24vdmFyaWFibGUgZGlzcGVyc2lvbiksIHdoZXJlIGl0J3MgbGVzcyBjbGVhciB3aGF0IHRvIG1lYXN1cmUgdG8gZXN0aW1hdGUgb3ZlcmRpc3BlcnNpb24uCgpUaGUgZm9sbG93aW5nIGZ1bmN0aW9uIHNob3VsZCB3b3JrIGZvciBhIHZhcmlldHkgb2YgbW9kZWwgdHlwZXMKKGF0IGxlYXN0IGBnbG1tQURNQmAsIGBnbG1tVE1CYCwgYGxtZTRgLCAuLi4pLgoKYGBge3Igb3ZlcmRpc3BfZnVufQpvdmVyZGlzcF9mdW4gPC0gZnVuY3Rpb24obW9kZWwpIHsKICAgIHJkZiA8LSBkZi5yZXNpZHVhbChtb2RlbCkKICAgIHJwIDwtIHJlc2lkdWFscyhtb2RlbCx0eXBlPSJwZWFyc29uIikKICAgIFBlYXJzb24uY2hpc3EgPC0gc3VtKHJwXjIpCiAgICBwcmF0IDwtIFBlYXJzb24uY2hpc3EvcmRmCiAgICBwdmFsIDwtIHBjaGlzcShQZWFyc29uLmNoaXNxLCBkZj1yZGYsIGxvd2VyLnRhaWw9RkFMU0UpCiAgICBjKGNoaXNxPVBlYXJzb24uY2hpc3EscmF0aW89cHJhdCxyZGY9cmRmLHA9cHZhbCkKfQpgYGAKCkV4YW1wbGU6CmBgYHtyIGxtZTQsbWVzc2FnZT1GQUxTRX0KbGlicmFyeShsbWU0KQpsaWJyYXJ5KGdsbW1UTUIpCmBgYAoKYGBge3Igb3ZlcmRpc3BfZXgsY2FjaGU9VFJVRSxtZXNzYWdlPUZBTFNFfQpzZXQuc2VlZCgxMDEpICAKZCA8LSBkYXRhLmZyYW1lKHg9cnVuaWYoMTAwMCksCiAgICAgICAgICAgICAgICBmPWZhY3RvcihzYW1wbGUoMToxMCxzaXplPTEwMDAscmVwbGFjZT1UUlVFKSkpCnN1cHByZXNzTWVzc2FnZXMoZCR5IDwtIHNpbXVsYXRlKH54KygxfGYpLCBmYW1pbHk9cG9pc3NvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdkYXRhPWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3cGFyYW1zPWxpc3QodGhldGE9MSxiZXRhPWMoMCwyKSkpW1sxXV0pCm0xIDwtIGdsbWVyKHl+eCsoMXxmKSxkYXRhPWQsZmFtaWx5PXBvaXNzb24pCm92ZXJkaXNwX2Z1bihtMSkKbTIgPC0gZ2xtbVRNQih5fngrKDF8ZiksZGF0YT1kLGZhbWlseT0icG9pc3NvbiIpCm92ZXJkaXNwX2Z1bihtMikKYGBgCgpUaGUgYGdvZmAgZnVuY3Rpb24gaW4gdGhlIGBhb2RzM2AgcHJvdmlkZXMgc2ltaWxhciBmdW5jdGlvbmFsaXR5CihpdCByZXBvcnRzIGJvdGggZGV2aWFuY2UtIGFuZCAkXGNoaV4yJC1iYXNlZCBlc3RpbWF0ZXMgb2YKb3ZlcmRpc3BlcnNpb24gYW5kIHRlc3RzKS4KCiMjIyBGaXR0aW5nIG1vZGVscyB3aXRoIG92ZXJkaXNwZXJzaW9uPwoKLSBxdWFzaWxpa2VsaWhvb2QgZXN0aW1hdGlvbjogW01BU1M6OmdsbW1QUUxdKGh0dHA6Ly9maW56aS5wc3ljaC51cGVubi5lZHUvUi9saWJyYXJ5L01BU1MvaHRtbC9nbG1tUFFMLmh0bWwpLiBRdWFzaS0gd2FzIGRlZW1lZCB1bnJlbGlhYmxlIGluIGBsbWU0YCwgYW5kIGlzIG5vIGxvbmdlciBhdmFpbGFibGUuIChQYXJ0IG9mIHRoZSBwcm9ibGVtIHdhcyBxdWVzdGlvbmFibGUgbnVtZXJpY2FsIHJlc3VsdHMgaW4gc29tZSBjYXNlczsgdGhlIG90aGVyIHByb2JsZW0gd2FzIHRoYXQgREIgZmVsdCB0aGF0IGhlIGRpZCBub3QgaGF2ZSBhIHN1ZmZpY2llbnRseSBnb29kIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHRoZW9yZXRpY2FsIGZyYW1ld29yayB0aGF0IHdvdWxkIGV4cGxhaW4gd2hhdCB0aGUgYWxnb3JpdGhtIHdhcyBhY3R1YWxseSBlc3RpbWF0aW5nIGluIHRoaXMgY2FzZS4pIFtnZWVwYWNrOjpnZWVsZ21dKGh0dHA6Ly9maW56aS5wc3ljaC51cGVubi5lZHUvUi9saWJyYXJ5L2dlZXBhY2svaHRtbC9nZWVnbG0uaHRtbCkgbWF5IGJlIHdvcmthYmxlIChoYXZlbid0IHRyaWVkIGl0KQoKICAgIElmIHlvdSByZWFsbHkgd2FudCBxdWFzaS1saWtlbGlob29kIGFuYWx5c2lzIGZvciBgZ2xtZXJgIGZpdHMsIHlvdSBjYW4gZG8gaXQgeW91cnNlbGYgYnkgYWRqdXN0aW5nIHRoZQpjb2VmZmljaWVudCB0YWJsZSAtIGkuZS4sIGJ5IG11bHRpcGx5aW5nIHRoZSBzdGFuZGFyZCBlcnJvciBieSB0aGUgc3F1YXJlIHJvb3QKb2YgdGhlIGRpc3BlcnNpb24gZmFjdG9yIFteMl0gYW5kIHJlY29tcHV0aW5nIHRoZSAkWiQtIGFuZCAkcCQtdmFsdWVzCmFjY29yZGluZ2x5LCBhcyBmb2xsb3dzOgoKW14yXTogdGhlIGRpc3BlcnNpb24gZmFjdG9yIGlzIGVzdGltYXRlZCBvbiBhCnZhcmlhbmNlLCBzbyB3ZSBuZWVkIHRvIHRha2UgdGhlIHNxdWFyZSByb290IHRvIGFwcGx5IGl0IHRvIHRoZQpzdGFuZGFyZCBlcnJvcgoKYGBge3IgcXVhc2l9CiMjIGV4dHJhY3Qgc3VtbWFyeSB0YWJsZTsgeW91IG1heSBhbHNvIGJlIGFibGUgdG8gZG8gdGhpcyB2aWEKIyMgIGJyb29tOjp0aWR5IG9yIGJyb29tLm1peGVkOjp0aWR5CnF1YXNpX3RhYmxlIDwtIGZ1bmN0aW9uKG1vZGVsLGN0YWI9Y29lZihzdW1tYXJ5KG1vZGVsKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBoaT1vdmVyZGlzcF9mdW4obW9kZWwpWyJyYXRpbyJdKSB7CiAgICBxY3RhYiA8LSB3aXRoaW4oYXMuZGF0YS5mcmFtZShjdGFiKSwKICAgIHsgICBgU3RkLiBFcnJvcmAgPC0gYFN0ZC4gRXJyb3JgKnNxcnQocGhpKQogICAgICAgIGB6IHZhbHVlYCA8LSBFc3RpbWF0ZS9gU3RkLiBFcnJvcmAKICAgICAgICBgUHIoPnx6fClgIDwtIDIqcG5vcm0oYWJzKGB6IHZhbHVlYCksIGxvd2VyLnRhaWw9RkFMU0UpCiAgICB9KQogICAgcmV0dXJuKHFjdGFiKQp9CnByaW50Q29lZm1hdChxdWFzaV90YWJsZShtMSksZGlnaXRzPTMpCiMjIHRvIHVzZSB0aGlzIHdpdGggZ2xtbVRNQiwgd2UgbmVlZCB0byBzZXBhcmF0ZSBvdXQgdGhlCiMjICBjb25kaXRpb25hbCBjb21wb25lbnQgb2YgdGhlIHN1bW1hcnkKcHJpbnRDb2VmbWF0KHF1YXNpX3RhYmxlKG0yLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RhYj1jb2VmKHN1bW1hcnkobTIpKVtbImNvbmQiXV0pLAogICAgICAgICAgICAgZGlnaXRzPTMpCmBgYAoKQW5vdGhlciB2ZXJzaW9uLCB0aGlzIG9uZSB0aWR5dmVyc2UtY2VudHJpYzoKCmBgYHtyIHRpZHlxdWFzaSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeShicm9vbS5taXhlZCkKbGlicmFyeShkcGx5cikKdGlkeV9xdWFzaSA8LSBmdW5jdGlvbihtb2RlbCwgcGhpPW92ZXJkaXNwX2Z1bihtb2RlbClbInJhdGlvIl0sCiAgICAgICAgICAgICAgICAgICAgICAgY29uZi5sZXZlbD0wLjk1KSB7CiAgICB0dCA8LSAodGlkeShtb2RlbCwgZWZmZWN0cz0iZml4ZWQiKQogICAgICAgICU+JSBtdXRhdGUoc3RkLmVycm9yPXN0ZC5lcnJvcipzcXJ0KHBoaSksCiAgICAgICAgICAgICAgICAgICBzdGF0aXN0aWM9ZXN0aW1hdGUvc3RkLmVycm9yLAogICAgICAgICAgICAgICAgICAgcC52YWx1ZT0yKnBub3JtKGFicyhzdGF0aXN0aWMpLCBsb3dlci50YWlsPUZBTFNFKSkKICAgICkKICAgIHJldHVybih0dCkKfQp0aWR5X3F1YXNpKG0xKQp0aWR5X3F1YXNpKG0yKQpgYGAKClRoZXNlIGZ1bmN0aW9ucyBtYWtlIHNvbWUgc2ltcGxpZnlpbmcgYXNzdW1wdGlvbnM6ICgxKSB0aGlzIG92ZXJkaXNwZXJzaW9uIGNvbXB1dGF0aW9uIGlzIGFwcHJveGltYXRlCgpJbiB0aGlzIGNhc2UgdXNpbmcgcXVhc2ktbGlrZWxpaG9vZCBkb2Vzbid0IG1ha2UgbXVjaCBkaWZmZXJlbmNlLCBzaW5jZSB0aGUgZGF0YSB3ZSBzaW11bGF0ZWQgaW4gdGhlIGZpcnN0IHBsYWNlIHdlcmUgUG9pc3Nvbi4pIEtlZXAgaW4gbWluZCB0aGF0IG9uY2UgeW91IHN3aXRjaCB0byBxdWFzaS1saWtlbGlob29kIHlvdSB3aWxsIGVpdGhlciBoYXZlIHRvIGVzY2hldyBpbmZlcmVudGlhbCBtZXRob2RzIHN1Y2ggYXMgdGhlIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCwgcHJvZmlsZSBjb25maWRlbmNlIGludGVydmFscywgQUlDLCBldGMuLCBvciBtYWtlIG1vcmUgaGVyb2ljIGFzc3VtcHRpb25zIHRvIGNvbXB1dGUgInF1YXNpLSIgYW5hbG9ncyBvZiBhbGwgb2YgdGhlIGFib3ZlIChzdWNoIGFzIFFBSUMpLiAKCi0gb2JzZXJ2YXRpb24tbGV2ZWwgcmFuZG9tIGVmZmVjdHMgKE9MUkU6IHRoaXMgYXBwcm9hY2ggc2hvdWxkIHdvcmsgaW4gbW9zdCBwYWNrYWdlcykuIElmIHlvdSB3YW50IHRvIGEgY2l0YXRpb24gZm9yIHRoaXMgYXBwcm9hY2gsIHRyeSBAZWxzdG9uX2FuYWx5c2lzXzIwMDEsIHdobyBjaXRlIEBsYXdzb25fZGlzZWFzZV8xOTk5OyBhcHBhcmVudGx5IHRoZXJlIGlzIGFsc28gYW4gZXhhbXBsZSBpbiBzZWN0aW9uIDEwLjUgb2YgQG1haW5kb25hbGRfZGF0YV8yMDEwLCBhbmQgKGFjY29yZGluZyB0byBhbiBSLXNpZy1taXhlZC1tb2RlbHMgcG9zdCkgdGhpcyBpcyBhbHNvIGRpc2N1c3NlZCBieSBAcmFiZWhlc2tldGhfbXVsdGlsZXZlbF8yMDA4LiBBbHNvIHNlZSBAYnJvd25lX3ZhcmlhbmNlXzIwMDUgZm9yIGFuIGV4YW1wbGUgaW4gdGhlIGJpbm9taWFsIGNvbnRleHQgKGkuZS4gbG9naXQtbm9ybWFsLWJpbm9taWFsIHJhdGhlciB0aGFuIGxvZ25vcm1hbC1Qb2lzc29uKS4gQWdyZXN0aSdzIGV4Y2VsbGVudCAoMjAwMikgYm9vayBAYWdyZXN0aV9jYXRlZ29yaWNhbF8yMDAyIGFsc28gZGlzY3Vzc2VzIHRoaXMgKHNlY3Rpb24gMTMuNSksIHJlZmVycmluZyBiYWNrIHRvIEBicmVzbG93X2V4dHJhcG9pc3Nvbl8xOTg0IGFuZCBAaGluZGVfY29tcG91bmRfMTk4Mi4gWyoqTm90ZXMqKjogKGEpIEkgaGF2ZW4ndCBjaGVja2VkIGFsbCB0aGVzZSByZWZlcmVuY2VzIG15c2VsZiwgKGIpIEkgY2FuJ3QgZmluZCB0aGUgcmVmZXJlbmNlIGFueSBtb3JlLCBidXQgSSBoYXZlIHNlZW4gaXQgc3RhdGVkIHRoYXQgb2JzZXJ2YXRpb24tbGV2ZWwgcmFuZG9tIGVmZmVjdCBlc3RpbWF0aW9uIGlzIHByb2JhYmx5IGRvZGd5IGZvciBQUUwgYXBwcm9hY2hlcyBhcyB1c2VkIGluIEVsc3RvbiBldCBhbCAyMDAxXSAKLSBhbHRlcm5hdGl2ZSBkaXN0cmlidXRpb25zCiAgICAtIFBvaXNzb24tbG9nbm9ybWFsIG1vZGVsIGZvciBjb3VudHMgb3IgYmlub21pYWwtbG9naXQtTm9ybWFsIG1vZGVsIGZvciBwcm9wb3J0aW9ucyAoc2VlIGFib3ZlLCAib2JzZXJ2YXRpb24tbGV2ZWwgcmFuZG9tIGVmZmVjdHMiKQogICAgLSBuZWdhdGl2ZSBiaW5vbWlhbCBmb3IgY291bnRzIG9yIGJldGEtYmlub21pYWwgZm9yIHByb3BvcnRpb25zCiAgICAgICAgIC0gYGxtZTQ6OmdsbWVyLm5iKClgIHNob3VsZCBmaXQgYSBuZWdhdGl2ZSBiaW5vbWlhbCwgYWx0aG91Z2ggaXQgaXMgc29tZXdoYXQgc2xvdyBhbmQgZnJhZ2lsZSBjb21wYXJlZCB0byBzb21lIG9mIHRoZSBvdGhlciBtZXRob2RzIHN1Z2dlc3RlZCBoZXJlLiBgbG1lNGAgY2Fubm90IGZpdCBiZXRhLWJpbm9taWFsIG1vZGVscyAodGhlc2UgY2Fubm90IGJlIGZvcm11bGF0ZWQgYXMgYSBwYXJ0IG9mIHRoZSBleHBvbmVudGlhbCBmYW1pbHkgb2YgZGlzdHJpYnV0aW9ucykKCSAgICAgLSBbZ2xtbVRNQl0oaHR0cHM6Ly9naXRodWIuY29tL2dsbW10bWIvZ2xtbVRNQi8pIHdpbGwgZml0IHR3byBwYXJhbWV0ZXJpemF0aW9ucyBvZiB0aGUgbmVnYXRpdmUgYmlub21pYWw6IGBmYW1pbHk9Im5iaW5vbTIiYCBnaXZlcyB0aGUgY2xhc3NpYyBwYXJhbWV0ZXJpemF0aW9uIHdpdGggJFxzaWdtYV4yPVxtdSgxK1xtdS9rKSQgKCJOQjIiIGluIEhhcmRpbiBhbmQgSGlsYmUncyB0ZXJtaW5vbG9neSkgd2hpbGUgYGZhbWlseT0ibmJpbm9tMSJgIGdpdmVzIGEgcGFyYW1ldGVyaXphdGlvbiB3aXRoICRcc2lnbWFeMj1ccGhpIFxtdSQsICRccGhpPjEkICgiTkIxIiB0byBIYXJkaW4gYW5kIEhpbGJlKS4gVGhlIGxhdHRlciBtaWdodCBhbHNvIGJlIGNhbGxlZCBhICJxdWFzaS1Qb2lzc29uIiBwYXJhbWV0ZXJpemF0aW9uIGJlY2F1c2UgaXQgbWF0Y2hlcyB0aGUgbWVhbi12YXJpYW5jZSByZWxhdGlvbnNoaXAgYXNzdW1lZCBieSBxdWFzaS1Qb2lzc29uIG1vZGVscywgaS5lLiB0aGUgdmFyaWFuY2UgaXMgc3RyaWN0bHkgcHJvcG9ydGlvbmFsIHRvIHRoZSBtZWFuIChhbHRob3VnaCB0aGUgcHJvcG9ydGlvbmFsaXR5IGNvbnN0YW50IG11c3QgYmUgPjEsIGEgbGltaXRhdGlvbiB0aGF0IGRvZXMgbm90IGFwcGx5IHRvIHF1YXNpLWxpa2VsaWhvb2QgYXBwcm9hY2hlcykuIChbZ2xtbUFETUJdKGh0dHA6Ly9naXRodWIuY29tL2Jib2xrZXIvZ2xtbUFETUIvKSB3aWxsIGFsc28gZml0IHRoZXNlIG1vZGVscywgd2l0aCBgZmFtaWx5PSJuYmlub20iYCBmb3IgTkIyLCBidXQgaXMgZGVwcmVjYXRlZCBpbiBmYXZvdXIgb2YgZ2xtbVRNQi4pCgkgICAtIGBnbG1tVE1CYCBhbGxvd3MgYmV0YS1iaW5vbWlhbCBtb2RlbHMgKFtAaGFycmlzb25fY29tcGFyaXNvbl8yMDE1XSBzdWdnZXN0cyBjb21wYXJpbmcgYmV0YS1iaW5vbWlhbCB3aXRoIE9MUkUgbW9kZWxzIHRvIGFzc2VzcyByZWxpYWJpbGl0eSkKCSAgIC0gdGhlIGBicm1zYCBwYWNrYWdlIGhhcyBhIGBuZWdiaW5vbWlhbGAgZmFtaWx5IChubyBiZXRhLWJpbm9taWFsLCBidXQgaXQgZG9lcyBoYXZlIGEgd2lkZSByYW5nZSBvZiBvdGhlciBmYW1pbGllcykKLSBvdGhlciBwYWNrYWdlcy9hcHByb2FjaGVzIChsZXNzIHdpZGVseSB1c2VkLCBvciByZXF1aXJpbmcgYSBiaXQgbW9yZSBlZmZvcnQpCiAgICAtIGBnYW1sc3MubXg6Z2FtbHNzTlBgCiAgICAtIFdpbkJVR1MvSkFHUyAodmlhIFIyV2luQlVHUy9SamFncykKICAgIC0gQUQgTW9kZWwgQnVpbGRlciAocG9zc2libHkgdmlhIGBSMmFkbWJgIHBhY2thZ2UpIG9yIGBUTUJgCiAgICAtIGBnbmxtbWAgaW4gdGhlIGByZXBlYXRlZGAgcGFja2FnZSAoW29mZi1DUkFOXShodHRwOi8vd3d3LmNvbW1hbnN0ZXIuZXUvcmNvZGUuaHRtbCkpCiAgKiBbQVNSRU1MXShodHRwOi8vd3d3LmFzcmVtbC5jb20vc29mdHdhcmUvZ2Vuc3RhdC9odG1saGVscC9zZXJ2ZXIvR0xNTS5odG0pCgpOZWdhdGl2ZSBiaW5vbWlhbCBtb2RlbHMgaW4gYGdsbW1UTUJgIGFuZCBsb2dub3JtYWwtUG9pc3NvbiBtb2RlbHMgaW4gYGdsbWVyYCAob3IgYE1DTUNnbG1tYCkgYXJlIHByb2JhYmx5IHRoZSBiZXN0IHF1aWNrIGFsdGVybmF0aXZlcyBmb3Igb3ZlcmRpc3BlcnNlZCBjb3VudCBkYXRhLiBJZiB5b3UgbmVlZCB0byBleHBsb3JlIGFsdGVybmF0aXZlcyAoZGlmZmVyZW50IHZhcmlhbmNlLW1lYW4gcmVsYXRpb25zaGlwcywgZGlmZmVyZW50IGRpc3RyaWJ1dGlvbnMpLCB0aGVuIGBBRE1CYCwgYFRNQmAsIGBXaW5CVUdTYCwgYFN0YW5gLCBgTklNQkxFYCBhcmUgdGhlIG1vc3QgZmxleGlibGUgYWx0ZXJuYXRpdmVzLgoKIyMjIFVuZGVyZGlzcGVyc2lvbgoKVW5kZXJkaXNwZXJzaW9uIChtdWNoICpsZXNzKiB2YXJpYWJpbGl0eSB0aGFuIGV4cGVjdGVkKSBpcyBhIGxlc3MgY29tbW9uIHByb2JsZW0gdGhhbiBvdmVyZGlzcGVyc2lvbi4KCi0gbWlsZCB1bmRlcmRpc3BlcnNpb24gaXMgc29tZXRpbWVzIGlnbm9yZWQsIHNpbmNlIGl0IHRlbmRzIGluIGdlbmVyYWwgdG8gbGVhZCB0byBjb25zZXJ2YXRpdmUgcmF0aGVyIHRoYW4gYW50aS1jb25zZXJ2YXRpdmUgcmVzdWx0cwotIHF1YXNpLWxpa2VsaWhvb2QgKGFuZCB0aGUgcXVhc2ktaGFjayBsaXN0ZWQgYWJvdmUpIGNhbiBoYW5kbGUgdW5kZXItIGFzIHdlbGwgYXMgb3ZlcmRpc3BlcnNpb24KLSBzb21lIG90aGVyIHNvbHV0aW9ucyBleGlzdCwgYnV0IGFyZSBsZXNzIHdpZGVseSBpbXBsZW1lbnRlZAogICAgLSBmb3IgZGlzdHJpYnV0aW9ucyB3aXRoIGEgc21hbGwgcmFuZ2UgKGUuZy4gbGl0dGVyIHNpemVzIG9mIGxhcmdlIG1hbW1hbHMpLCBvbmUgY2FuIHRyZWF0IHJlc3BvbnNlcyBhcyBvcmRpbmFsIChlLmcuIHVzaW5nIHRoZSBgb3JkaW5hbGAgcGFja2FnZSwgb3IgYE1DTUNnbG1tYCBvciBgYnJtc2AgZm9yIEJheWVzaWFuIHNvbHV0aW9ucykKICAgIC0gdGhlIENPTS1Qb2lzc29uIGRpc3RyaWJ1dGlvbiBhbmQgZ2VuZXJhbGl6ZWQgUG9pc3NvbiBkaXN0cmlidXRpb25zLCBpbXBsZW1lbnRlZCBpbiBgZ2xtbVRNQmAsIGNhbiBoYW5kbGUgdW5kZXJkaXNwZXJzaW9uIChKLiBIaWxiZSByZWNvbW1lbmRzIHRoZSBsYXR0ZXIgaW4gW3RoaXMgQ3Jvc3NWYWxpZGF0ZWQgYW5zd2VyXShodHRwczovL3N0YXRzLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy82NzM4NS93aGF0LWlzLXRoZS1hcHByb3ByaWF0ZS1tb2RlbC1mb3ItdW5kZXJkaXNwZXJzZWQtY291bnQtZGF0YSkpLiAoYFZHQU1gIGhhcyBhIGdlbmVyYWxpemVkIFBvaXNzb24gZGlzdHJpYnV0aW9uLCBidXQgZG9lc24ndCBoYW5kbGUgcmFuZG9tIGVmZmVjdHMuKQogICAgIAoKCiMjIEdhbW1hIEdMTU1zCgpXaGlsZSBvbmUgKHdlbGwsIE9LIEkpIHdvdWxkIG5haXZlbHkgdGhpbmsgdGhhdCBHTE1NcyB3aXRoIEdhbW1hIGRpc3RyaWJ1dGlvbnMgd291bGQgYmUganVzdCBhcyBlYXN5IChvciBoYXJkKSBhcyBhbnkgb3RoZXIgc29ydCBvZiBHTE1NcywgaXQgc2VlbXMgdGhhdCB0aGV5IGFyZSBpbiBmYWN0IGhhcmRlciB0byBpbXBsZW1lbnQuIEJhc2ljIHNpbXVsYXRlZCBleGFtcGxlcyBvZiBHYW1tYSBHTE1NcyBjYW4gZmFpbCBpbiBsbWU0IGRlc3BpdGUgYW5hbG9nb3VzIHByb2JsZW1zIHdpdGggUG9pc3NvbiwgYmlub21pYWwsIGV0Yy4gZGlzdHJpYnV0aW9ucy4gIFNvbHV0aW9uczoKLSB0aGUgZGVmYXVsdCBpbnZlcnNlIGxpbmsgc2VlbXMgcGFydGljdWxhcmx5IHByb2JsZW1hdGljOyB0cnkgb3RoZXIgbGlua3MgKGVzcGVjaWFsbHkgYGZhbWlseT1HYW1tYShsaW5rPSJsb2ciKWApIGlmIHRoYXQgaXMgcG9zc2libGUvbWFrZXMgc2Vuc2UKLSBjb25zaWRlciB3aGV0aGVyIGEgbG9nbm9ybWFsIG1vZGVsIChpLmUuIGEgcmVndWxhciBMTU0gb24gbG9nZ2VkIGRhdGEpIHdvdWxkIHdvcmsvbWFrZXMgc2Vuc2UuCi0gQGxvX3RyYW5zZm9ybV8yMDE1IGFyZ3VlIHRoYXQgdGhlIEdhbW1hIGZhbWlseSB3aXRoIGFuICppZGVudGl0eSogbGluayBpcyBzdXBlcmlvciB0byBsb2dub3JtYWwgbW9kZWxzIGZvciByZWFjdGlvbi10aW1lIGRhdGEuIEkgKEJNQikgZG9uJ3QgZmluZCB0aGVpciBhcmd1bWVudCBwYXJ0aWN1bGFybHkgY29udmluY2luZywgYnV0IGxvdHMgb2YgcGVvcGxlIHdhbnQgdG8gZG8gdGhpcy4gVW5mb3J0dW5hdGVseSB0aGlzIGlzIHRlY2huaWNhbGx5IGNoYWxsZW5naW5nIChzZWUgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9sbWU0L2xtZTQvaXNzdWVzLzU3MykpLCBiZWNhdXNlIGl0IGlzIGxpa2VseSB0aGF0IHNvbWUgImlsbGVnYWwiIHZhbHVlcyAocHJlZGljdGVkIHJlc3BvbnNlcyAkXGxlIDAkKSB3aWxsIG9jY3VyIHdoaWxlIGZpdHRpbmcgdGhlIG1vZGVsLCBldmVuIGlmIHRoZSBmaW5hbCBmaXR0ZWQgbW9kZWwgbWFrZXMgbm8gaW1wb3NzaWJsZSBwcmVkaWN0aW9ucy4gVGh1cyBzb21ldGhpbmcgaGFzIHRvIGJlIGRvbmUgdG8gbWFrZSB0aGUgbW9kZWwtZml0dGluZyBtYWNoaW5lcnkgdG9sZXJhbnQgb2Ygc3VjaCB2YWx1ZXMgKGkuZS4gcmV0dXJuaW5nIGBOQWAgZm9yIHRoZXNlIG1vZGVsIGV2YWx1YXRpb25zLCBvciBjbGFtcGluZyBpbGxlZ2FsIHZhbHVlcyB0byB0aGUgY29uc3RyYWluZWQgc3BhY2Ugd2l0aCBhbiBhcHByb3ByaWF0ZSBzbW9vdGggcGVuYWx0eSBmdW5jdGlvbikuCgpHYW1tYSBtb2RlbHMgY2FuIGJlIGZpdHRlZCBieSBhIHdpZGUgdmFyaWV0eSBvZiBwbGF0Zm9ybXMgKGBsbWU0OjpnbG1lcmAsIGBNQVNTOjpnbG1tUFFMYCwgYGdsbW1BRE1CYCwgYGdsbW1UTUJgLCBgTWl4ZWRNb2RlbHMuamxgLCBgTUNNQ2dsbW1gLCBgYnJtc2AgLi4uIG5vdCBzdXJlIGFib3V0IG90aGVycy4KCiMjIEJldGEgR0xNTXMKClByb3BvcnRpb24gZGF0YSB3aGVyZSB0aGUgZGVub21pbmF0b3IgKGUuZy4gbWF4aW11bSBwb3NzaWJsZSBudW1iZXIgb2Ygc3VjY2Vzc2VzIGZvciBhIGdpdmVuIG9ic2VydmF0aW9uKSBpcyBub3Qga25vd24gY2FuIGJlIG1vZGVsZWQgdXNpbmcgYSBCZXRhIGRpc3RyaWJ1dGlvbi4gQHNtaXRoc29uX2JldHRlcl8yMDA2IGlzIGEgZ29vZCBpbnRyb2R1Y3Rpb24gZm9yIG5vbi1zdGF0aXN0aWNpYW5zICgqbm90KiBpbiB0aGUgbWl4ZWQtbW9kZWwgY2FzZSksIGFuZCB0aGUgYGJldGFyZWdgIHBhY2thZ2UgW0BjcmliYXJpLW5ldG9fYmV0YV8yMDA5XSBoYW5kbGVzICpub24qLW1peGVkIEJldGEgcmVncmVzc2lvbnMuIFRoZSBgZ2xtbVRNQmAgYW5kIGBicm1zYCBwYWNrYWdlcyBoYW5kbGUgQmV0YSBtaXhlZCBtb2RlbHMgKGBicm1zYCBhbHNvIGhhbmRsZXMgemVyby1pbmZsYXRlZCBhbmQgemVyby1vbmUgaW5mbGF0ZWQgbW9kZWxzKS4KCiMjIFplcm8taW5mbGF0aW9uCgpTZWUgZS5nLiBAbWFydGluX3plcm9fMjAwNSBvciBAd2FydG9uX21hbnlfMjAwNSAoIm1hbnkgemVyb3MgZG9lcyBub3QgbWVhbiB6ZXJvIGluZmxhdGlvbiIpIG9yIEB6dXVyX3plcm8tdHJ1bmNhdGVkXzIwMDkgZm9yIGdlbmVyYWwgaW5mb3JtYXRpb24gb24gemVyby1pbmZsYXRpb24uCgojIyMgQ291bnQgZGF0YQoKLSBgTUNNQ2dsbW1gIGhhbmRsZXMgemVyby10cnVuY2F0ZWQsIHplcm8taW5mbGF0ZWQsIGFuZCB6ZXJvLWFsdGVyZWQgbW9kZWxzLCBhbHRob3VnaCBzcGVjaWZ5aW5nIHRoZSBtb2RlbHMgaXMgYSBsaXR0bGUgYml0IHRyaWNreTogc2VlIFNlY3Rpb25zIDUuMyB0byA1LjUgb2YgdGhlIFtDb3Vyc2VOb3RlcyB2aWduZXR0ZV0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL01DTUNnbG1tL3ZpZ25ldHRlcy9Db3Vyc2VOb3Rlcy5wZGYpCi0gYGdsbW1BRE1CYCBoYW5kbGVzIAogICAgLSB6ZXJvLWluZmxhdGVkIG1vZGVscyAod2l0aCBhIHNpbmdsZSB6ZXJvLWluZmxhdGlvbiBwYXJhbWV0ZXIgLS0gaS5lLiwgdGhlIGxldmVsIG9mIHplcm8taW5mbGF0aW9uIGlzIGFzc3VtZWQgY29uc3RhbnQgYWNyb3NzIHRoZSB3aG9sZSBkYXRhIHNldCkKICAgIC0gdHJ1bmNhdGVkIFBvaXNzb24gYW5kIG5lZ2F0aXZlIGJpbm9taWFsIGRpc3RyaWJ1dGlvbnMgKHdoaWNoIGFsbG93cyB0d28tc3RhZ2UgZml0dGluZyBvZiBodXJkbGUgbW9kZWxzKQotIGBnbG1tVE1CYCBoYW5kbGVzIGEgdmFyaWV0eSBvZiBaLUkgYW5kIFotVCBtb2RlbHMgKGFsbG93cyBjb3ZhcmlhdGVzLCBhbmQgcmFuZG9tIGVmZmVjdHMsIGluIHRoZSB6ZXJvLWFsdGVyYXRpb24gbW9kZWwpCi0gYGJybXNgIGRvZXMgdG9vCi0gc28gZG9lcyBgR0xNTWFkYXB0aXZlYAotIEdhdmluIFNpbXBzb24gaGFzIGEgW2RldGFpbGVkIHdyaXRldXBdKGh0dHA6Ly93d3cuZnJvbXRoZWJvdHRvbW9mdGhlaGVhcC5uZXQvMjAxNy8wNS8wNC9jb21wYXJlLW1nY3Ytd2l0aC1nbG1tVE1CLykgc2hvd2luZyB0aGF0IGBtZ2N2OjpnYW0oKWAgY2FuIGRvIHNpbXBsZSBtaXhlZCBtb2RlbHMgKFBvaXNzb24sIG5vdCBOQikgd2l0aCB6ZXJvLWluZmxhdGlvbiwgYW5kIGNvbXBhcmluZyBgbWdjdmAgd2l0aCBgZ2xtbVRNQmAgcmVzdWx0cwotIGBnYW1sc3NOUGAgaW4gdGhlIGBnYW1sc3MubXhgIHBhY2thZ2Ugc2hvdWxkIGhhbmRsZSB6ZXJvLWluZmxhdGlvbiwgYW5kIHRoZSBgZ2FtbHNzLnRyYCBwYWNrYWdlIHNob3VsZCBoYW5kbGUgdHJ1bmNhdGVkIChpLmUuIGh1cmRsZSkgbW9kZWxzIC0tIGJ1dCBJIGhhdmVuJ3QgdHJpZWQgdGhlbQotIHJvbGwteW91ci1vd246IEFETUIvUjJhZG1iLCBXaW5CVUdTL1IyV2luQlVHUywgVE1CLCBTdGFuLCAuLi4gCgojIyMgQ29udGludW91cyBkYXRhCgpDb250aW51b3VzIGRhdGEgYXJlIGEgc3BlY2lhbCBjYXNlIHdoZXJlIHRoZSBtaXh0dXJlIG1vZGVsIGZvciB6ZXJvLWluZmxhdGVkIGRhdGEgaXMgbGVzcyByZWxldmFudCwgYmVjYXVzZSBvYnNlcnZhdGlvbnMgdGhhdCBhcmUgZXhhY3RseSB6ZXJvIG9jY3VyIHdpdGggKnByb2JhYmlsaXR5KiAoYnV0IG5vdCBwcm9iYWJpbGl0eSBkZW5zaXR5KSB6ZXJvLiBUaGVyZSBhcmUgdHdvIGNhc2VzIG9mIGludGVyZXN0OgoKIyMjIyBQcm9iYWJpbGl0eSBkZW5zaXR5IG9mICR4JCB6ZXJvIG9yIGluZmluaXRlCgpJbiB0aGlzIGNhc2UgemVybyBpcyBhIHByb2JsZW1hdGljIG9ic2VydmF0aW9uIGZvciB0aGUgZGlzdHJpYnV0aW9uOyBpdCdzIGVpdGhlciBpbXBvc3NpYmxlIG9yIGluZmluaXRlbHkgKGxvY2FsbHkpIGxpa2VseS4gU29tZSBleGFtcGxlczoKCi0gR2FtbWEgZGlzdHJpYnV0aW9uOiBwcm9iYWJpbGl0eSBkZW5zaXR5IGF0IHplcm8gaXMgaW5maW5pdGUgKGlmIHNoYXBlPDEpIG9yIHplcm8gKGlmIHNoYXBlPjEpOyBpdCdzIGZpbml0ZSBvbmx5IGZvciBhbiBleHBvbmVudGlhbCBkaXN0cmlidXRpb24gKHNoYXBlPT0xKQotIExvZ25vcm1hbCBkaXN0cmlidXRpb246IHRoZSBwcm9iYWJpbGl0eSBkZW5zaXR5IGF0IHplcm8gaXMgemVyby4KLSBCZXRhIGRpc3RyaWJ1dGlvbjogdGhlIHByb2JhYmlsaXR5IGRlbnNpdGllcyBhdCAwIGFuZCAxIGFyZSB6ZXJvIChpZiB0aGUgY29ycmVzcG9uZGluZyBzaGFwZSBwYXJhbWV0ZXIgaXMgPjEpIG9yIGluZmluaXRlIChpZiBzaGFwZTwxKQoKVGhlIGJlc3Qgc29sdXRpb24gZGVwZW5kcyB2ZXJ5IG11Y2ggb24gdGhlIGRhdGEtZ2VuZXJhdGluZyBtZWNoYW5pc20uCgotIElmIHRoZSBiYWQgKDAvMSkgdmFsdWVzIGFyZSBnZW5lcmF0ZWQgYnkgcm91bmRpbmcgKGUuZy4gcHJvcG9ydGlvbnMgdGhhdCBhcmUgdG9vIGNsb3NlIHRvIHRoZSBib3VuZGFyaWVzIGFyZSByZXBvcnRlZCBhcyBiZWluZyBvbiB0aGUgYm91bmRhcmllcyksIHRoZSBzaW1wbGVzdCBzb2x1dGlvbiBpcyB0byAic3F1ZWV6ZSIgdGhlc2UgaW4gc2xpZ2h0bHksIGUuZy4gJHkgXHRvICh5ICthKS8yYSQgZm9yIHNvbWUgc2Vuc2libGUgdmFsdWUgb2YgJGEkIFtAc21pdGhzb25fYmV0dGVyXzIwMDZdCi0gSWYgeW91IHRoaW5rIHRoYXQgemVybyB2YWx1ZXMgYXJlIGdlbmVyYXRlZCBieSBhIHNlcGFyYXRlIHByb2Nlc3MsIHRoZSBzaW1wbGVzdCBzb2x1dGlvbiBpcyB0byBmaXQgYSBCZXJub3VsbGkgbW9kZWwgdG8gdGhlIHplcm8vbm9uLXplcm8gZGF0YSwgdGhlbiBhICpjb25kaXRpb25hbCogY29udGludW91cyBtb2RlbCBmb3IgdGhlIG5vbi16ZXJvIHZhbHVlczsgdGhpcyBpcyBlZmZlY3RpdmVseSBhICpodXJkbGUgbW9kZWwqLgotIHlvdSBtaWdodCBoYXZlICpjZW5zb3JlZCogZGF0YSB3aGVyZSBhbGwgdmFsdWVzIGJlbG93IGEgY2VydGFpbiBsaW1pdCAoZS5nLiBhIGRldGVjdGlvbiBsaW1pdCkgYXJlIHJlY29yZGVkIGFzIHplcm8uIFRoZSBUaGUgW2xtZWMgcGFja2FnZV0oaHR0cHM6Ly9DUkFOLlItcHJvamVjdC5vcmcvcGFja2FnZT1sbWVjKSBoYW5kbGVzICpsaW5lYXIqIG1peGVkIG1vZGVsczsgYGJybXNgIGFuZCBgR0xNTWFkYXB0aXZlYCBib3RoIHByb3ZpZGUgc3VwcG9ydCBmb3IgY2Vuc29yZWQgZGF0YSBpbiBtaXhlZCBtb2RlbHMuCi0gVGhlIGBjcGxtYCBhbmQgYGdsbW1UTUJgIHBhY2thZ2VzIGhhbmRsZXMgJ1R3ZWVkaWUgY29tcG91bmQgUG9pc3NvbiBsaW5lYXIgbW9kZWxzJywgd2hpY2ggaW4gYSBwYXJ0aWN1bGFyIHJhbmdlIG9mIHBhcmFtZXRlcnMgYWxsb3dzIGZvciBza2V3ZWQgY29udGludW91cyByZXNwb25zZXMgd2l0aCBhIHNwaWtlIGF0IHplcm8KCiMjIyMgUHJvYmFiaWxpdHkgZGVuc2l0eSBvZiAkeCQgcG9zaXRpdmUgYW5kIGZpbml0ZQoKSW4gdGhpcyBjYXNlIChlLmcuIGEgc3Bpa2Ugb2YgemVyb3MgaW4gdGhlIGNlbnRlciBvZiBhbiBvdGhlcndpc2UgY29udGludW91cyBkaXN0cmlidXRpb24pLCB0aGUgaHVyZGxlIG1vZGVsIHByb2JhYmx5IG1ha2VzIHRoZSBtb3N0IHNlbnNlLgoKIyMjIFRlc3RzIGZvciB6ZXJvLWluZmxhdGlvbgoKLSB5b3UgY2FuIHVzZSBhIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCBiZXR3ZWVuIHRoZSByZWd1bGFyIGFuZCB6ZXJvLWluZmxhdGVkIHZlcnNpb24gb2YgdGhlIG1vZGVsLCBidXQgYmUgYXdhcmUgb2YgYm91bmRhcnkgaXNzdWVzIChzZWFyY2ggImJvdW5kYXJ5IiBlbHNld2hlcmUgb24gdGhpcyBwYWdlIC4uLikgLS0gdGhlIG51bGwgdmFsdWUgKG5vIHplcm8gaW5mbGF0aW9uKSBpcyBvbiB0aGUgYm91bmRhcnkgb2YgdGhlIGZlYXNpYmxlIHNwYWNlCi0geW91IGNhbiB1c2UgQUlDIG9yIHZhcmlhdGlvbnMsIHdpdGggdGhlIHNhbWUgY2F2ZWF0cwotIHlvdSBjYW4gdXNlIFZ1b25nJ3MgdGVzdCwgd2hpY2ggaXMgb2Z0ZW4gcmVjb21tZW5kZWQgZm9yIHRlc3RpbmcgemVyby1pbmZsYXRpb24gaW4gR0xNcywgYmVjYXVzZSB1bmRlciBzb21lIGNpcmN1bXN0YW5jZXMgdGhlIHZhcmlvdXMgbW9kZWwgZmxhdm9ycyB1bmRlciBjb25zaWRlcmF0aW9uIChodXJkbGUgdnMgemVyby1pbmZsYXRlZCB2cyAidmFuaWxsYSIpIGFyZSBub3QgbmVzdGVkLiBWdW9uZydzIHRlc3QgaXMgaW1wbGVtZW50ZWQgKGFuZCByZWZlcmVuY2VkKSBpbiB0aGUgYHBzY2xgIHBhY2thZ2UsIGJ1dCBub3QgZm9yIChHKUxNTXMuIEhvd2V2ZXIsIHRoZSBgbm9ubmVzdGAgcGFja2FnZSBwcm92aWRlcyBhbiBleGFtcGxlIChpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSBgbWVyRGVyaXZgIHBhY2thZ2UpIGZvciB1c2luZyBpdHMgYHZ1b25ndGVzdGAgZnVuY3Rpb24gd2l0aCBgbWVyTW9kYCBvYmplY3RzLiAoTWF5IGFsc28gd29yayB3aXRoIGBnbG1tVE1CYCwgaGF2ZW4ndCB0cmllZCBpdCAuLi4pCi0gdHdvIHVudGVzdGVkIGJ1dCByZWFzb25hYmxlIGFwcHJvYWNoZXM6CiAgICAtICB1c2UgYSBgc2ltdWxhdGUoKWAgbWV0aG9kIGlmIGl0IGV4aXN0cyB0byBjb25zdHJ1Y3QgYSBzaW11bGF0ZWQgZGlzdHJpYnV0aW9uIG9mIHRoZSBwcm9wb3J0aW9uIG9mIHplcm9zIGV4cGVjdGVkIG92ZXJhbGwgZnJvbSB5b3VyIG1vZGVsLCBhbmQgY29tcGFyZSBpdCB0byB0aGUgb2JzZXJ2ZWQgcHJvcG9ydGlvbiBvZiB6ZXJvcyBpbiB0aGUgZGF0YSBzZXQKICAgIC0gY29tcHV0ZSB0aGUgcHJvYmFiaWxpdHkgb2YgYSB6ZXJvIGZvciBlYWNoIG9ic2VydmF0aW9uLiAgT24gdGhlIGJhc2lzIG9mIChjb25kaXRpb25hbGx5KSBpbmRlcGVuZGVudCBCZXJub3VsbGkgdHJpYWxzLCBjb21wdXRlIHRoZSBleHBlY3RlZCBudW1iZXIgb2YgemVyb3MgYW5kIHRoZSBjb25maWRlbmNlIGludGVydmFscyAtLSBjb21wYXJlIGl0IHdpdGggdGhlIG9ic2VydmVkIG51bWJlci4KCiMjIFNwYXRpYWwgYW5kIHRlbXBvcmFsIGNvcnJlbGF0aW9uIG1vZGVscywgaGV0ZXJvc2NlZGFzdGljaXR5ICgiUi1zaWRlIiBtb2RlbHMpCgpJbiBgbmxtZWAgdGhlc2Ugc28tY2FsbGVkICoqUi1zaWRlKiogKFIgZm9yICJyZXNpZHVhbCIpIHN0cnVjdHVyZXMgYXJlIGFjY2Vzc2libGUgdmlhIHRoZSBgd2VpZ2h0c2AvYFZhclN0cnVjdGAgKGhldGVyb3NjZWRhc3RpY2l0eSkgYW5kIGBjb3JyZWxhdGlvbmAvYGNvclN0cnVjdGAgKHNwYXRpYWwgb3IgdGVtcG9yYWwgY29ycmVsYXRpb24pIGFyZ3VtZW50cyBhbmQgZGF0YSBzdHJ1Y3R1cmVzLiBUaGlzIGV4dGVuc2lvbiBpcyBhIGJpdCBoYXJkZXIgdGhhbiBpdCBtaWdodCBzZWVtLiBJbiBMTU1zIGl0IGlzIGEgbmF0dXJhbCBleHRlbnNpb24gdG8gYWxsb3cgdGhlIHJlc2lkdWFsIGVycm9yIHRlcm1zIHRvIGJlIGNvbXBvbmVudHMgb2YgYSBzaW5nbGUgbXVsdGl2YXJpYXRlIG5vcm1hbCBkcmF3OyBpZiB0aGF0IE1WTiBkaXN0cmlidXRpb24gaXMgdW5jb3JyZWxhdGVkIGFuZCBob21vc2NlZGFzdGljIChpLmUuIHByb3BvcnRpb25hbCB0byBhbiBpZGVudGl0eSBtYXRyaXgpIHdlIGdldCB0aGUgY2xhc3NpYyBtb2RlbCwgYnV0IHdlIGNhbiBpbiBwcmluY2lwbGUgYWxsb3cgaXQgdG8gYmUgY29ycmVsYXRlZCBhbmQvb3IgaGV0ZXJvc2NlZGFzdGljLgoKSXQgaXMgbm90IHRvbyBoYXJkIHRvIGRlZmluZSBtYXJnaW5hbCBjb3JyZWxhdGlvbiBzdHJ1Y3R1cmVzIHRoYXQgZG9uJ3QgbWFrZSBzZW5zZS4gIE9uZSBjbGFzcyBvZiByZWFzb25hYmx5IHNlbnNpYmxlIG1vZGVscyBpcyB0byBhbHdheXMgYXNzdW1lIGFuIG9ic2VydmF0aW9uLWxldmVsIHJhbmRvbSBlZmZlY3QgKGFzIE1DTUNnbG1tIGRvZXMgZm9yIGNvbXB1dGF0aW9uYWwgcmVhc29ucykgYW5kIHRvIGFsbG93IHRoYXQgcmFuZG9tIGVmZmVjdCB0byBiZSBNVk4gb24gdGhlIGxpbmsgc2NhbGUgKHNvIHRoYXQgdGhlIGZ1bGwgbW9kZWwgaXMgbG9nbm9ybWFsLVBvaXNzb24sIGxvZ2l0LW5vcm1hbCBiaW5vbWlhbCwgZXRjLiwgZGVwZW5kaW5nIG9uIHRoZSBsaW5rIGZ1bmN0aW9uIGFuZCBmYW1pbHkpLgoKRm9yIGV4YW1wbGUsIGEgcmVsYXRpdmVseSBzaW1wbGUgUG9pc3NvbiBtb2RlbCB3aXRoIHNwYXRpYWxseSBjb3JyZWxhdGVkIGVycm9ycyBtaWdodCBsb29rIGxpa2UgdGhpczoKCiQkClxiZWdpbntzcGxpdH0KXGV0YSAmIFxzaW0gXHRleHRybXtNVk59KGEgKyBiIHgsIFxTaWdtYSkgXFwKXFNpZ21hX3tpan0gJiA9IFxzaWdtYV4yIFxleHAoLWRfe2lqfS9zKSBcXAp5X2kgJiBcc2ltIFx0ZXh0cm17UG9pc3Nvbn0oXGxhbWJkYT1cZXhwKFxldGFfaSkpClxlbmR7c3BsaXR9CiQkCgpUaGF0IGlzLCB0aGUgbWFyZ2luYWwgZGlzdHJpYnV0aW9ucyBvZiB0aGUgcmVzcG9uc2UgdmFsdWVzIGFyZSBQb2lzc29uLWxvZ25vcm1hbCwgYnV0IG9uIHRoZSBsaW5rIChsb2cpIHNjYWxlIHRoZSBsYXRlbnQgTm9ybWFsIHZhcmlhYmxlcyB1bmRlcmx5aW5nIHRoZSByZXNwb25zZSBhcmUgKm11bHRpdmFyaWF0ZSogbm9ybWFsLCB3aXRoIGEgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXggZGVzY3JpYmVkIGJ5IGFuIGV4cG9uZW50aWFsIHNwYXRpYWwgY29ycmVsYXRpb24gZnVuY3Rpb24gd2l0aCBzY2FsZSBwYXJhbWV0ZXIgJHMkLgoKSG93IGNhbiBvbmUgYWNoaWV2ZSB0aGlzPwoKLSBUaGVzZSB0eXBlcyBvZiBtb2RlbHMgYXJlIG5vdCBpbXBsZW1lbnRlZCBpbiBgbG1lNGAsIGZvciBlaXRoZXIgTE1NcyBvciBHTE1NczsgdGhleSBhcmUgZmFpcmx5IGxvdyBwcmlvcml0eSwgYW5kIGl0IGlzIGhhcmQgdG8gc2VlIGhvdyB0aGV5IGNvdWxkIGJlIGltcGxlbWVudGVkIGZvciBHTE1NcyAodGhlIGVxdWl2YWxlbnQgZm9yIExNTXMgaXMgdGVkaW91cyBidXQgc2hvdWxkIGJlIHN0cmFpZ2h0Zm9yd2FyZCB0byBpbXBsZW1lbnQpLgotIEZvciBMTU1zLCB5b3UgY2FuIHVzZSB0aGUgc3BhdGlhbC90ZW1wb3JhbCBjb3JyZWxhdGlvbiBzdHJ1Y3R1cmVzIHRoYXQgYXJlIGJ1aWx0IGludG8gKG4pbG1lCi0gWW91IGNhbiB1c2UgdGhlIHNwYXRpYWwvdGVtcG9yYWwgY29ycmVsYXRpb24gc3RydWN0dXJlcyBhdmFpbGFibGUgZm9yIChuKWxtZSwgd2hpY2ggaW5jbHVkZSBiYXNpYyBnZW9zdGF0aXN0aWNhbCAoc3BhY2UpIGFuZCBBUk1BLXR5cGUgKHRpbWUpIG1vZGVscy4gCmBgYHtyIGZpbmRjb3JzLGV2YWw9RkFMU0V9CmxpYnJhcnkoc29zKQpmaW5kRm4oImNvclN0cnVjdCIpCmBgYApmaW5kcyBhZGRpdGlvbmFsIHBvc3NpYmlsaXRpZXMgaW4gdGhlIGByYW1wc2AgKGV4dGVuZGVkIGdlb3N0YXRpc3RpY2FsKSBhbmQgYGFwZWAgKHBoeWxvZ2VuZXRpYykgcGFja2FnZXMuCgotIFlvdSBjYW4gdXNlIHRoZXNlIHN0cnVjdHVyZXMgaW4gR0xNTXMgdmlhIGBNQVNTOjpnbG1tUFFMYCAoc2VlIERvcm1hbm4gZXQgYWwuKQotIGdlZXBhY2s6OmdlZWdsbQotIGdlb1IsIGdlb1JnbG0gKHBvd2VyIHRvb2xzKTsgdGhlc2UgYXJlIG1vc3RseSBkZXNpZ25lZCBmb3IgZml0dGluZyBzcGF0aWFsIHJhbmRvbSBmaWVsZCBHTE1NcyB2aWEgTUNNQyAtLSBub3Qgc3VyZSB0aGF0IHRoZXkgZG8gcmFuZG9tIGVmZmVjdHMgb3RoZXIgdGhhbiB0aGUgc3BhdGlhbCByYW5kb20gZWZmZWN0Ci0gW1ItSU5MQV0oaHR0cDovL3ItaW5sYS5vcmcpIChzdXBlci1wb3dlciB0b29sKQotIGl0IGlzIHBvc3NpYmxlIHRvIHVzZSBBRCBNb2RlbCBCdWlsZGVyIHRvIGZpdCBzcGF0aWFsIEdMTU1zLCBhcyBzaG93biBpbiB0aGVzZSBbQUQgTW9kZWwgQnVpbGRlciBleGFtcGxlc10oaHR0cDovL2FkbWItcHJvamVjdC5vcmcvZXhhbXBsZXMvc3BhdGlhbC1tb2RlbHMpOyB0aGlzIGNhcGFiaWxpdHkgaXMgbm90IGluIHRoZSBgZ2xtbUFETUJgIHBhY2thZ2UgKGFuZCBtYXkgbm90IGJlIGZvciBhIHdoaWxlISksIGJ1dCBpdCB3b3VsZCBiZSBwb3NzaWJsZSB0byBydW4gQUQgTW9kZWwgQnVpbGRlciB2aWEgdGhlIFIyYWRtYiBwYWNrYWdlIChyZXF1aXJlcyBpbnN0YWxsaW5nIC0tIGFuZCBsZWFybmluZyEgQURNQikKLSBbZ2VvQlVHU10oaHR0cDovL21hdGhzdGF0LmhlbHNpbmtpLmZpL29wZW5idWdzL01hbnVhbHMvR2VvQlVHUy9NYW51YWwuaHRtbCksIHRoZSBnZW9zdGF0aXN0aWNhbC9zcGF0aWFsIGNvcnJlbGF0aW9uIG1vZHVsZSBmb3IgV2luQlVHUywgaXMgYW5vdGhlciBhbHRlcm5hdGl2ZSAoYnV0IGFnYWluIHJlcXVpcmVzIGdvaW5nIG91dHNpZGUgb2YgUikKCiMjIFBlbmFsaXphdGlvbi9oYW5kbGluZyBjb21wbGV0ZSBzZXBhcmF0aW9uCgoqQ29tcGxldGUgc2VwYXJhdGlvbiogb2NjdXJzIGluIGEgYmluYXJ5LXJlc3BvbnNlIG1vZGVsIHdoZW4gdGhlcmUgaXMKc29tZSBsaW5lYXIgY29tYmluYXRpb24gb2YgdGhlIHBhcmFtZXRlcnMgdGhhdCBwZXJmZWN0bHkgc2VwYXJhdGVzIGZhaWx1cmVzCmZyb20gc3VjY2Vzc2VzIC0gZm9yIGV4YW1wbGUsIHdoZW4gYWxsIG9mIHRoZSBvYnNlcnZhdGlvbnMgYXJlIHplcm8KZm9yIHNvbWUgcGFydGljdWxhciBjb21iaW5hdGlvbiBvZiBjYXRlZ29yaWVzLiBUaGUgc3ltcHRvbXMgb2YgdGhpcwpwcm9ibGVtIGFyZSB1bnJlYWxpc3RpY2FsbHkgbGFyZ2UgcGFyYW1ldGVyIGVzdGltYXRlczsgcmlkaWN1bG91c2x5CmxhcmdlIFdhbGQgc3RhbmRhcmQgZXJyb3JzICh0aGUgKkhhdWNrLURvbm5lciBlZmZlY3QqKTsgYW5kIHZhcmlvdXMKd2FybmluZ3MuCgpJbiBwYXJ0aWN1bGFyLCBiaW5vbWlhbCBgZ2xtZXIoKWAgbW9kZWxzIHdpdGggY29tcGxldGUgc2VwYXJhdGlvbiBjYW4gbGVhZCB0bwoiRG93bmRhdGVkIFZ0ViBpcyBub3QgcG9zaXRpdmUgZGVmaW5pdGUiIChlLmcuIHNlZSBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL2xtZTQvbG1lNC9pc3N1ZXMvNDgzKSkgb3IgIlBJUkxTIHN0ZXAtaGFsdmluZ3MgZmFpbGVkIHRvIHJlZHVjZSBkZXZpYW5jZSBpbiBwd3Jzc1VwZGF0ZSIgZXJyb3JzIChlLmcuIHNlZSBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL2xtZTQvbG1lNC9pc3N1ZXMvMTc5I2lzc3VlY29tbWVudC00MjQ0NDUxODcpKS4gUm91Z2hseSBzcGVha2luZywgdGhlIGNvbXBsZXRlIHNlcGFyYXRpb24gaXMgbGlrZWx5IHRvIGFwcGVhciBldmVuIGlmIG9uZSBjb25zaWRlcnMgb25seSB0aGUgZml4ZWQgZWZmZWN0cyBwYXJ0IG9mIHRoZSBtb2RlbCAoY291bnRlcmFyZ3VtZW50cyBvciBjb3VudGVyZXhhbXBsZXMgd2VsY29tZSEpLCBzdWdnZXN0aW5nIHR3byBxdWljay1hbmQtZGlydHkgZGlhZ25vc3RpYyBtZXRob2RzLiBJZiBgZml4ZWRfZm9ybWAgaXMgdGhlIGZvcm11bGEgaW5jbHVkaW5nIG9ubHkgdGhlIGZpeGVkIGVmZmVjdHM6CgotIGBzdW1tYXJ5KGcxIDwtIGdsbShmaXhlZF9mb3JtLCBmYW1pbHk9Ymlub21pYWwsIGRhdGE9Li4uKSlgIHdpbGwgc2hvdyBvbmUgb3IgbW9yZSBvZiB0aGUgZm9sbG93aW5nIHN5bXB0b21zOgogICAgIC0gd2FybmluZ3MgdGhhdCBgZ2xtLmZpdDogZml0dGVkIHByb2JhYmlsaXRpZXMgbnVtZXJpY2FsbHkgMCBvciAxIG9jY3VycmVkYAogICAgIC0gcGFyYW1ldGVyIGVzdGltYXRlcyBvZiBsYXJnZSBtYWduaXR1ZGUgKGUuZy4gYGFueShhYnMoZzEkY29lZmZpY2llbnRzKT44KWAsIGFzc3VtaW5nIHRoYXQgcHJlZGljdG9ycyBhcmUgZWl0aGVyIGNhdGVnb3JpY2FsIG9yIHNjYWxlZCB0byBoYXZlIHN0YW5kYXJkIGRldmlhdGlvbnMgb2YgJFxhcHByb3ggMSQpCgkgLSBleHRyZW1lbHkgbGFyZ2UgV2FsZCBzdGFuZGFyZCBlcnJvcnMsIGFuZCBsYXJnZSBwLXZhbHVlcyAoKkhhdWNrLURvbm5lciBlZmZlY3QqKQoJIC0gdGhlIGBkZXRlY3RzZXBhcmF0aW9uYCBwYWNrYWdlIGhhcyBhIG1ldGhvZCBmb3IgZGV0ZWN0aW5nIGNvbXBsZXRlIHNlcGFyYXRpb246IGBsaWJyYXJ5KCJkZXRlY3RzZXBhcmF0aW9uIik7IHVwZGF0ZShnMSxtZXRob2Q9ImRldGVjdF9zZXBhcmF0aW9uIilgLiBUaGlzIHNob3VsZCBzYXkgd2hldGhlciBjb21wbGV0ZSBzZXBhcmF0aW9uIG9jY3VycywgYW5kIGluIHdoaWNoIChjb21iaW5hdGlvbnMgb2YpIHZhcmlhYmxlcywgZS5nLgoKYGBgClNlcGFyYXRpb246IFRSVUUgCkV4aXN0ZW5jZSBvZiBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGVzCihJbnRlcmNlcHQpICAgICAgaGVpZ2h0IAogICAgICAgIEluZiAgICAgICAgIEluZiAKMDogZmluaXRlIHZhbHVlLCBJbmY6IGluZmluaXR5LCAtSW5mOiAtaW5maW5pdHkKYGBgCgpJZiBjb21wbGV0ZSBzZXBhcmF0aW9uIGlzIG9jY3VycmluZyBiZXR3ZWVuIGNhdGVnb3JpZXMgb2YgYSBzaW5nbGUgY2F0ZWdvcmljYWwgZml4ZWQtZWZmZWN0IHByZWRpY3RvciB3aXRoIGEgbGFyZ2UgbnVtYmVyIG9mIGxldmVscywgb25lIG9wdGlvbiB3b3VsZCBiZSB0byB0cmVhdCB0aGlzIGZpeGVkIGVmZmVjdCBhcyBhIHJhbmRvbSBlZmZlY3QsIHdoaWNoIHdpbGwgYWxsb3cgc29tZSBkZWdyZWUgb2Ygc2hyaW5rYWdlIHRvIHRoZSBtZWFuLiAoSXQgbWlnaHQgYmUgcmVhc29uYWJsZSB0byBzcGVjaWZ5IHRoZSB2YXJpYW5jZSBvZiB0aGlzIHRlcm0gKmEgcHJpb3JpKiB0byBhIGxhcmdlIHZhbHVlIFttaW5pbWFsIHNocmlua2FnZV0sIHJhdGhlciB0aGFuIHRyeWluZyB0byBlc3RpbWF0ZSBpdCBmcm9tIHRoZSBkYXRhLikKCigqKlRPRE8qKjogd29ya2VkIGV4YW1wbGUpCgpUaGUgZ2VuZXJhbCBhcHByb2FjaCB0byBoYW5kbGluZyBjb21wbGV0ZSBzZXBhcmF0aW9uIGluIGxvZ2lzdGljIHJlZ3Jlc3Npb24KaXMgY2FsbGVkICpwZW5hbGl6ZWQgcmVncmVzc2lvbio7IGl0J3MgYXZhaWxhYmxlIGluIHRoZSBgYnJnbG1gLApgYnJnbG0yYCwgYGxvZ2lzdGZgLCBhbmQgYHJtc2AgcGFja2FnZXMuIEhvd2V2ZXIsIHRoZXNlIHBhY2thZ2VzCmRvbid0IGhhbmRsZSBtaXhlZCBtb2RlbHMsIHNvIHRoZSBiZXN0IGF2YWlsYWJsZSAqZ2VuZXJhbCogYXBwcm9hY2ggaXMgdG8KdXNlIGEgQmF5ZXNpYW4gbWV0aG9kIHRoYXQgYWxsb3dzIHlvdSB0byBzZXQgYSBwcmlvciBvbiB0aGUgZml4ZWQgZWZmZWN0cywKZS5nLiBhIEdhdXNzaWFuIHdpdGggc3RhbmRhcmQgZGV2aWF0aW9uIG9mIDM7IHRoaXMgY2FuIGJlIGRvbmUKaW4gYW55IG9mIHRoZSBCYXllc2lhbiBHTE1NIHBhY2thZ2VzIChlLmcuIGBibG1lYCwgYE1DTUNnbG1tYCwgYGJybXNgLCAuLi4pCihTZWUgW3N1cHBsZW1lbnRhcnkgbWF0ZXJpYWwgZm9yIEZveCBldCBhbC4gMjAxNl0oaHR0cDovL2Jib2xrZXIuZ2l0aHViLmlvL21peGVkbW9kZWxzLW1pc2MvZWNvc3RhdHNfY2hhcC5odG1sI2RpZ3Jlc3Npb24tY29tcGxldGUtc2VwYXJhdGlvbikgZm9yIGEgd29ya2VkIGV4YW1wbGUuKQoKIyMgTm9uLUdhdXNzaWFuIHJhbmRvbSBlZmZlY3RzCgpJJ20gbm90IGF3YXJlIG9mIGVhc3kgd2F5cyB0byBmaXQgbWl4ZWQgbW9kZWxzIHdpdGggbm9uLUdhdXNzaWFuIHJhbmRvbSBlZmZlY3RzIGRpc3RyaWJ1dGlvbnMgaW4gUiAoaS5lLiwgY29udmVuaWVudCwgZmxleGlibGUsIHdlbGwtdGVzdGVkIGltcGxlbWVudGF0aW9ucykuIEBtY2N1bGxvY2hfbWlzc3BlY2lmeWluZ18yMDExIGRpc2N1c3NlcyB3aGVuIHRoaXMgbWlzc3BlY2lmaWNhdGlvbiBtYXkgYmUgaW1wb3J0YW50LiBbVGhpcyBwcmVzZW50YXRpb25dKGh0dHBzOi8vbmlhc3JhLnVvdy5lZHUuYXUvY29udGVudC9ncm91cHMvcHVibGljL0B3ZWIvQGluZi9AbWF0aC9kb2N1bWVudHMvbW0vdW93MjM2Mjk2LnBkZikgZGlzY3Vzc2VzIHZhcmlvdXMgYXBwcm9hY2hlcyB0byBzb2x2aW5nIHRoZSBwcm9ibGVtIChlLmcuIHVzaW5nIGEgR2FtbWEgcmF0aGVyIHRoYW4gYSBOb3JtYWwgZGlzdHJpYnV0aW9uIG9mIFJFcyBpbiBsb2ctbGluayAgbW9kZWxzKS4gVGhlIGBzcGFNTWAgcGFja2FnZSBpbXBsZW1lbnRzIEgtbGlrZWxpaG9vZCBtb2RlbHMgW0BsZWVfZ2VuZXJhbGl6ZWRfMjAxN10sIGFuZCBjbGFpbXMgdG8gYWxsb3cgYSByYW5nZSBvZiByYW5kb20tZWZmZWN0cyBkaXN0cmlidXRpb25zIChwZXJoYXBzIG5vdCB3ZWxsIHRlc3RlZCB0aG91Z2ggLi4uKQoKSW4gcHJpbmNpcGxlIHlvdSBjYW4gaW1wbGVtZW50IGFueSByYW5kb20tZWZmZWN0cyBkaXN0cmlidXRpb24geW91IHdhbnQgaW4gYSBmdWxseSBjYXBhYmxlIEJheWVzaWFuIG1vZGVsaW5nIGxhbmd1YWdlIChlLmcuIEpBR1MvU3Rhbi9QeU1DL2V0Yy4pOyBzZWUgZS5nLiBbdGhpcyBTdGFja092ZXJmbG93IGFuc3dlcl0oaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDU2NTY3MTQvdXNlci1kZWZpbmVkLXJhbmRvbS1pbnRlcmNlcHQtZGlzdHJpYnV0aW9uLWZvci1nbG1lciksIHdoaWNoIHVzZXMgdGhlIGByZXRoaW5raW5nYCBwYWNrYWdlJ3MgaW50ZXJmYWNlIHRvIFN0YW4uCgojIEVzdGltYXRpb24gCgojIyBXaGF0IG1ldGhvZHMgYXJlIGF2YWlsYWJsZSB0byBmaXQgKGVzdGltYXRlKSBHTE1Ncz8KCihhZGFwdGVkIGZyb20gQm9sa2VyIGV0IGFsIFRSRUUgMjAwOSkKCmBgYHtyIGdsbW10YWIsZWNobz1GQUxTRSxyZXN1bHRzPSJhc2lzIn0KbWV0aHRhYiA8LSByZWFkLnRhYmxlKHNlcD0ifCIsaGVhZGVyPVRSVUUsdGV4dD0iCk1ldGhvZCB8IEFkdmFudGFnZXMgfCBEaXNhZHZhbnRhZ2VzIHwgUGFja2FnZXMKUGVuYWxpemVkIHF1YXNpLWxpa2VsaWhvb2QgfCBGbGV4aWJsZSwgd2lkZWx5IGltcGxlbWVudGVkIHwgTGlrZWxpaG9vZCBpbmZlcmVuY2UgbWF5IGJlIGluYXBwcm9wcmlhdGU7IGJpYXNlZCBmb3IgbGFyZ2UgdmFyaWFuY2Ugb3Igc21hbGwgbWVhbnMgfCBQUk9DIEdMSU1NSVggKFNBUyksIEdMTU0gKEdlblN0YXQpLCBnbG1tUFFMIChSOk1BU1MpLCBBU1JFTUwtUgpMYXBsYWNlIGFwcHJveGltYXRpb24gfCBNb3JlIGFjY3VyYXRlIHRoYW4gUFFMIHwgU2xvd2VyIGFuZCBsZXNzIGZsZXhpYmxlIHRoYW4gUFFMIHwgZ2xtZXIgKFI6bG1lNCxsbWU0YSksIGdsbW0uYWRtYiAoUjpnbG1tQURNQiksIElOTEEsIGdsbW1UTUIsIEFEIE1vZGVsIEJ1aWxkZXIsIEhMTSAKR2F1c3MtSGVybWl0ZSBxdWFkcmF0dXJlIHwgTW9yZSBhY2N1cmF0ZSB0aGFuIExhcGxhY2UgfCBTbG93ZXIgdGhhbiBMYXBsYWNlOyBsaW1pdGVkIHRvIDLigJEzIHJhbmRvbSBlZmZlY3RzIHwgUFJPQyBOTE1JWEVEIChTQVMpLCBnbG1lciAoUjpsbWU0LCBsbWU0YSksIGdsbW1NTCAoUjpnbG1tTUwpLCB4dGxvZ2l0IChTdGF0YSkKTWFya292IGNoYWluIE1vbnRlIENhcmxvIHwgSGlnaGx5IGZsZXhpYmxlLCBhcmJpdHJhcnkgbnVtYmVyIG9mIHJhbmRvbSBlZmZlY3RzOyBhY2N1cmF0ZSB8IFNsb3csIHRlY2huaWNhbGx5IGNoYWxsZW5naW5nLCBCYXllc2lhbiBmcmFtZXdvcmsgfCBNQ01DZ2xtbSAoUjpNQ01DZ2xtbSksIHJzdGFuYXJtIChSKSwgYnJtcyAoUiksIE1DTUNwYWNrIChSKSwgV2luQlVHUy9PcGVuQlVHUyAoUiBpbnRlcmZhY2U6IEJSdWdzL1IyV2luQlVHUyksIEpBR1MgKFIgaW50ZXJmYWNlOiByamFncy9SMmphZ3MpLCBBRCBNb2RlbCBCdWlsZGVyIChSIGludGVyZmFjZTogUjJhZG1iKSwgZ2xtbS5hZG1iIChwb3N0IGhvYyBNQ01DIGFmdGVyIExhcGxhY2UgZml0KSAoUjpnbG1tQURNQikiCikKc2V0LmFsaWdubWVudChkZWZhdWx0PSJsZWZ0IikKcGFuZGVyKG1ldGh0YWIsc3BsaXQudGFibGU9SW5mKQpgYGAKCiMjIFRyb3VibGVzaG9vdGluZwoKLSBkb3VibGUtY2hlY2sgdGhlIG1vZGVsIHNwZWNpZmljYXRpb24gYW5kIHRoZSBkYXRhIGZvciBtaXN0YWtlcwotIGNlbnRlciBhbmQgc2NhbGUgY29udGludW91cyBwcmVkaWN0b3IgdmFyaWFibGVzIChlLmcuIHdpdGggYHNjYWxlKClgKQotIHRyeSBhbGwgYXZhaWxhYmxlIG9wdGltaXplcnMgKGUuZy4gc2V2ZXJhbCBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb25zIG9mIEJPQllRQSBhbmQgTmVsZGVyLU1lYWQsIEwtQkZHUy1CIGZyb20gIGBvcHRpbWAsIGBubG1pbmIoKWAsIC4uLikuICBXaGlsZSB0aGlzIHdpbGwgb2YgY291cnNlIGJlIHNsb3cgZm9yIGxhcmdlIGZpdHMsIHdlIGNvbnNpZGVyIGl0IHRoZSBnb2xkIHN0YW5kYXJkOyBpZiBhbGwgb3B0aW1pemVycyBjb252ZXJnZSB0byB2YWx1ZXMgdGhhdCBhcmUgcHJhY3RpY2FsbHkgZXF1aXZhbGVudCAoaXQncyB1cCB0byB0aGUgdXNlciB0byBkZWNpZGUgd2hhdCAicHJhY3RpY2FsbHkgZXF1aXZhbGVudCBtZWFucyBmb3IgdGhlaXIgY2FzZSIpLCB0aGVuIHdlIHdvdWxkIGNvbnNpZGVyIHRoZSBtb2RlbCBmaXQgdG8gYmUgZ29vZCBlbm91Z2guIEZvciBleGFtcGxlOgpgYGB7ciBhbGxmaXQsZXZhbD1GQUxTRX0KbW9kZWxmaXQuYWxsIDwtIGxtZTQ6OmFsbEZpdChtb2RlbCkKc3MgPC0gc3VtbWFyeShtb2RlbGZpdC5hbGwpCmBgYAoKIyMjIENvbnZlcmdlbmNlIHdhcm5pbmdzCgpNb3N0IG9mIHRoZSBjdXJyZW50IGFkdmljZSBhYm91dCB0cm91Ymxlc2hvb3RpbmcgYGxtZTRgIGNvbnZlcmdlbmNlIHByb2JsZW1zIGNhbiBiZSBmb3VuZCBpbiB0aGUgaGVscCBwYWdlIGA/Y29udmVyZ2VuY2VgLiBUaGF0IHBhZ2UgZXhwbGFpbnMgdGhhdCB0aGUgY29udmVyZ2VuY2UgdGVzdHMgaW4gdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBgbG1lNGAgKDEuMS0xMSwgRmVicnVhcnkgMjAxNikgZ2VuZXJhdGUgbG90cyBvZiBmYWxzZSBwb3NpdGl2ZXMuIFdlIGFyZSBjb25zaWRlcmluZyByYWlzaW5nIHRoZSBncmFkaWVudCB3YXJuaW5nIHRocmVzaG9sZCB0byAwLjAxIGluIGZ1dHVyZSByZWxlYXNlcyBvZiBgbG1lNGAuIEluIGFkZGl0aW9uIHRvIHRoZSBnZW5lcmFsIHRyb3VibGVzaG9vdGluZyB0aXBzIGFib3ZlOgoKLSBkb3VibGUtY2hlY2sgdGhlIEhlc3NpYW4gY2FsY3VsYXRpb24gd2l0aCB0aGUgbW9yZSBleHBlbnNpdmUgUmljaGFyZHNvbiBleHRyYXBvbGF0aW9uIG1ldGhvZCAoc2VlIGV4YW1wbGVzKQotIHJlc3RhcnQgdGhlIGZpdCBmcm9tIHRoZSBhcHBhcmVudCBvcHRpbXVtLCBvciBmcm9tIGEgcG9pbnQgcGVydHVyYmVkIHNsaWdodGx5IGF3YXkgZnJvbSB0aGUgb3B0aW11bSAoYGdldE1FKG1vZGVsLGMoInRoZXRhIiwiYmV0YSIpKWAgc2hvdWxkIHJldHJpZXZlIHRoZSBwYXJhbWV0ZXJzIGluIGEgZm9ybSBzdWl0YWJsZSB0byBiZSB1c2VkIGFzIHRoZSBgc3RhcnRgIHBhcmFtZXRlcikKLSBhIGNvbW1vbiBlcnJvciBpcyB0byBzcGVjaWZ5IGFuIG9mZnNldCB0byBhIGxvZy1saW5rIG1vZGVsIGFzIGEgcmF3IHNlYXJjaGluZy1lZmZvcnQgdmFsdWUsIGkuZS4gYG9mZnNldChlZmZvcnQpYCByYXRoZXIgdGhhbiBgb2Zmc2V0KGxvZyhlZmZvcnQpKWAuIFdoaWxlIHRoZSBpbnRlbnRpb24gaXMgdG8gZml0IGEgbW9kZWwgd2hlcmUgJFx0ZXh0cm17Y291bnRzfSBccHJvcHRvIFx0ZXh0cm17ZWZmb3J0fSQsIHNwZWNpZnlpbmcgYG9mZnNldChlZmZvcnQpYCBsZWFkcyB0byBhIG1vZGVsIHdoZXJlICRcdGV4dHJte2NvdW50c30gXHByb3B0byBcZXhwKFx0ZXh0cm17ZWZmb3J0fSkkIGluc3RlYWQ7IGBleHAoZWZmb3J0KWAgaXMgb2Z0ZW4gYSBodWdlIChhbmQgbW9kZWwtZGVzdGFiaWxpemluZykgbnVtYmVyLgoKPGEgaWQ9InNpbmd1bGFyLWZpdCI+PC9hPgo8YSBpZD0iemVyby12YXJpYW5jZSI+PC9hPgoKPCEtLSBwcmVzZXJ2ZSBsaW5rIGJhc2VkIG9uIHByZXZpb3VzIHNlY3Rpb24gdGl0bGUgLS0+CjxhIGlkID0gInNpbmd1bGFyLW1vZGVscy1yYW5kb20tZWZmZWN0LXZhcmlhbmNlcy1lc3RpbWF0ZWQtYXMtemVyby1vci1jb3JyZWxhdGlvbnMtZXN0aW1hdGVkLWFzLS0tMSI+PC9hPgoKIyMjIFNpbmd1bGFyIGZpdHMKCkl0IGlzIHZlcnkgY29tbW9uIGZvciBvdmVyZml0dGVkIG1peGVkIG1vZGVscyB0byByZXN1bHQgaW4gc2luZ3VsYXIgZml0cy4gVGVjaG5pY2FsbHksIHNpbmd1bGFyaXR5IG1lYW5zIHRoYXQgdGhlIHJhbmRvbSBlZmZlY3RzIHZhcmlhbmNlLWNvdmFyaWFuY2UgbWF0cml4IGlzIG9mICpsZXNzIHRoYW4gZnVsbCByYW5rKi4gVGhlcmUgYXJlIHZhcmlvdXMgd2F5cyB0byBkZXNjcmliZSB0aGlzLCBmcm9tIG1vcmUgdG8gbGVzcyB0ZWNobmljYWw6CgotIHNvbWUgb2YgdGhlIGVpZ2VudmFsdWVzIG9mIHRoZSBjb3ZhcmlhbmNlIG1hdHJpeCBhcmUgemVybywgb3IgZWZmZWN0aXZlbHkgemVybzsKLSBzb21lIGNvbWJpbmF0aW9ucyBvZiB0aGUgZWxlbWVudHMgb2YgdGhlIHJhbmRvbS1lZmZlY3RzIHZlY3RvciBhcmUgcGVyZmVjdGx5IG11bHRpY29sbGluZWFyOwotIHNvbWUgbGluZWFyIGNvbWJpbmF0aW9ucyBvZiBlbGVtZW50cyBvZiB0aGUgcmFuZG9tLWVmZmVjdHMgdmVjdG9yIGhhdmUgemVybyB2YXJpYW5jZTsKLSBhbiAkbiBcdGltZXMgbiQgY292YXJpYW5jZSBtYXRyaXggY29ycmVzcG9uZHMgdG8gYW4gJG4kLWRpbWVuc2lvbmFsIGVsbGlwc29pZCB3aGVyZSB0aGUgbGVuZ3RocyBvZiB0aGUgbWFqb3IgYXhlcyBhcmUgcHJvcG9ydGlvbmFsIHRvIHRoZSBlaWdlbnZhbHVlczsgdGhlIGVsbGlwc29pZCBpcyAiZmxhdCIgaW4gc29tZSBkaXJlY3Rpb25zLCBlLmcuIGFuIGVsbGlwc2UgaGFzIGNvbGxhcHNlZCB0byBhIGxpbmUgc2VnbWVudAoKLSBJbiBzaW1wbGUgY2FzZXMgd2hlcmUgYSByYW5kb20gZWZmZWN0IHRlcm0gaXMgcmVwcmVzZW50ZWQgYnkgYSBzaW5nbGUgdmFyaWFuY2UgKCpzY2FsYXIqIHJhbmRvbSBlZmZlY3RzKSwgdGhpcyBpcyByZWZsZWN0ZWQgaW4gYSB2YXJpYW5jZSBlc3RpbWF0ZSB0aGF0IGlzIHplcm8gb3IgbmVhciB6ZXJvLiBGdW5jdGlvbnMgc3VjaCBhcyBgbmxtZTo6bG1lKClgIG9yIGBnbG1tVE1CKClgIHRoYXQgZXN0aW1hdGUgdmFyaWFuY2VzIG9uIHRoZSBsb2cgc2NhbGUgd2lsbCBvZnRlbiAqbm90KiByZXBvcnQgYSBzaW5ndWxhciBmaXQsIGJ1dCB3aWxsIGluc3RlYWQgcmV0dXJuIGEgdmVyeSBzbWFsbCB2YWx1ZSAoMWUtNiBvciBsZXNzKSBmb3IgdGhlIHJhbmRvbS1lZmZlY3RzIHZhcmlhbmNlOyBvbiB0aGUgbG9nIHNjYWxlLCB0aGlzIHdpbGwgY29ycmVzcG9uZCB0byBhIHBhcmFtZXRlciBlc3RpbWF0ZSB0aGF0IGlzIGEgbGFyZ2UgbmVnYXRpdmUgbnVtYmVyICZtZGFzaDsgYW5kLCB1c3VhbGx5LCB3YXJuaW5ncyBhYm91dCBub24tcG9zaXRpdmUtZGVmaW5pdGUgSGVzc2lhbnMgb3IgKGluIHRoZSBjYXNlIG9mIGBsbWUoKWApIHJpZGljdWxvdXNseSBsYXJnZSBXYWxkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIHJldHVybmVkIGJ5IGBpbnRlcnZhbHMoKWAuCi0gSW4gdGhlIGNhc2Ugb2YgYSB0d28tZGltZW5zaW9uYWwgcmFuZG9tIGVmZmVjdCAoc3VjaCBhcyBhIHJhbmRvbS1zbG9wZXMgbW9kZWwpLCB0aGlzIHR5cGljYWxseSBjb3JyZXNwb25kcyB0byBhIHBlcmZlY3QgKCsvLSAxKSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSBzbG9wZSBhbmQgaW50ZXJjZXB0Ci0gaW4gaGlnaGVyLWRpbWVuc2lvbmFsIHJhbmRvbSBlZmZlY3RzIChzdWNoIGFzIHRoZSByYW5kb20gZWZmZWN0IG9mIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUgd2l0aCBtb3JlIHRoYW4gdHdvIGxldmVscywgb3IgYSByYW5kb20tc2xvcGVzIG1vZGVsIHdpdGggbW9yZSB0aGFuIG9uZSBjb3ZhcmlhdGUpLCBpdCdzIHByZXR0eSBtdWNoIGltcG9zc2libGUgdG8gc2VlIGF0IGEgZ2xhbmNlIHRoYXQgdGhlIGNvdmFyaWFuY2UgbWF0cml4IGlzIHNpbmd1bGFyLiBFeHRyYWN0aW5nIHRoZSBSRSBjb3ZhcmlhbmNlIG1hdHJpeCBhbmQgY29tcHV0aW5nIGl0cyBlaWdlbnZhbHVlcyAodGhpcyBpcyB3aGF0IGByZVBDQWAgaW4gdGhlIGBsbWU0YCBwYWNrYWdlIGRvZXMpIHdpbGwgdGVsbCB5b3UuIEluIHRoZSBwYXJ0aWN1bGFyIGNhc2Ugb2YgYGxtZTRgLCBzaW5ndWxhcml0eSBpcyBkZXRlY3RhYmxlIGJ5IHNlZWluZyBpZiBhbnkgb2YgdGhlIGVsZW1lbnRzIG9mIHRoZSAkXGJvbGRzeW1ib2wgXHRoZXRhJCAodmFyaWFuY2UtY292YXJpYW5jZSBDaG9sZXNreSBkZWNvbXBvc2l0aW9uKSB2ZWN0b3IgY29ycmVzcG9uZGluZyB0byBkaWFnb25hbCBlbGVtZW50cyBhcmUgKG5lYXIpIHplcm87IHRoaXMgaXMgd2hhdCBgP2lzU2luZ3VsYXJgIGRvZXMuCgpTaW5ndWxhciBmaXRzIGNvbW1vbmx5IG9jY3VyIGluIHR3byBzY2VuYXJpb3M6CgotIHNtYWxsIG51bWJlcnMgb2YgcmFuZG9tLWVmZmVjdCBsZXZlbHMgKGUuZy4gPDUpLCBhcyBpbGx1c3RyYXRlZCBpbiBbdGhlc2Ugc2ltdWxhdGlvbnNdKGh0dHA6Ly9ycHVicy5jb20vYmJvbGtlci80MTg3KSBhbmQgZGlzY3Vzc2VkIChpbiBhIHNvbWV3aGF0IGRpZmZlcmVudCwgQmF5ZXNpYW4gY29udGV4dCkgYnkgQGdlbG1hbl9wcmlvcl8yMDA2LgotIGNvbXBsZXggcmFuZG9tLWVmZmVjdHMgbW9kZWxzLCBlLmcuIG1vZGVscyBvZiB0aGUgZm9ybSBgKGZ8ZylgIHdoZXJlIGBmYCBpcyBhIGNhdGVnb3JpY2FsIHZhcmlhYmxlIHdpdGggYSByZWxhdGl2ZWx5IGxhcmdlIG51bWJlciBvZiBsZXZlbHMsIG9yIG1vZGVscyB3aXRoIHNldmVyYWwgZGlmZmVyZW50IHJhbmRvbS1zbG9wZXMgdGVybXMuCgotIEluIGBNQ01DZ2xtbWAsIHNpbmd1bGFyIG9yIG5lYXItc2luZ3VsYXIgZml0cyB3aWxsIHByb3Zva2UgYW4gZXJyb3IgYW5kIGEgcmVxdWlyZW1lbnQgdG8gc3BlY2lmeSBhIHN0cm9uZ2VyIHByaW9yLgoKQXQgcHJlc2VudCB0aGVyZSBhcmUgYSB2YXJpZXR5IG9mIHN0cm9uZyBvcGluaW9ucyBhYm91dCBob3cgdG8gcmVzb2x2ZSBzdWNoIHByb2JsZW1zLCB3aGljaCBhcmUgc29tZXRpbWVzIGNvbmZsYXRlZCB3aXRoIHRoZSBnZW5lcmFsIHByb2JsZW0gb2YgaG93IHRvIGRlY2lkZSBvbiB0aGUgYXBwcm9wcmlhdGUgY29tcGxleGl0eSBvZiB0aGUgcmFuZG9tLWVmZmVjdHMgY29tcG9uZW50IG9mIGEgbW9kZWwuIEJyaWVmbHk6CgotIElmIGEgdmFyaWFuY2UgY29tcG9uZW50IGlzIHplcm8sIGRyb3BwaW5nIGl0IGZyb20gdGhlIG1vZGVsIHdpbGwgaGF2ZSBubyBlZmZlY3Qgb24gYW55IG9mIHRoZSBlc3RpbWF0ZWQgcXVhbnRpdGllcyAoYWx0aG91Z2ggaXQgd2lsbCBhZmZlY3QgdGhlIEFJQywgYXMgdGhlIHZhcmlhbmNlIHBhcmFtZXRlciBpcyBjb3VudGVkIGV2ZW4gdGhvdWdoIGl0IGhhcyBubyBlZmZlY3QpLiBAcGFzY2hfaW50ZXJzcGVjaWZpY18yMDEzIGdpdmVzIG9uZSBleGFtcGxlIHdoZXJlIHJhbmRvbSBlZmZlY3RzIHdlcmUgZHJvcHBlZCBiZWNhdXNlIHRoZSB2YXJpYW5jZSBjb21wb25lbnRzIHdlcmUgY29uc2lzdGVudGx5IGVzdGltYXRlZCBhcyB6ZXJvLiBDb252ZXJzZWx5LCBpZiBvbmUgY2hvb3NlcyBmb3IgcGhpbG9zb3BoaWNhbCBncm91bmRzIHRvIHJldGFpbiB0aGVzZSAKcGFyYW1ldGVycywgaXQgd29uJ3QgY2hhbmdlIGFueSBvZiB0aGUgYW5zd2Vycy4KLSBAYmFycl9yYW5kb21fMjAxMyBzdWdnZXN0IGFsd2F5cyBzdGFydGluZyB3aXRoIHRoZSBtYXhpbWFsIG1vZGVsIChpLmUuIHRoZSBtb3N0IHJhbmRvbS1lZmZlY3RzIGNvbXBvbmVudCBvZiB0aGUgbW9kZWwgdGhhdCBpcyAqdGhlb3JldGljYWxseSogaWRlbnRpZmlhYmxlIGdpdmVuIHRoZSBleHBlcmltZW50YWwgZGVzaWduKSBhbmQgdGhlbiBkcm9wcGluZyB0ZXJtcyB3aGVuIHNpbmd1bGFyaXR5IG9yIG5vbi1jb252ZXJnZW5jZSBvY2N1cnMgKHBsZWFzZSBzZWUgdGhlIHBhcGVyIGZvciBkZXRhaWxlZCByZWNvbW1lbmRhdGlvbnMgLi4uKQotIEBtYXR1c2NoZWtfYmFsYW5jaW5nXzIwMTcgYW5kIEBiYXRlc19wYXJzaW1vbmlvdXNfMjAxNSBkaXNhZ3JlZSwgc3VnZ2VzdGluZyB0aGF0IG1vZGVscyBzaG91bGQgYmUgc2ltcGxpZmllZCAqYSBwcmlvcmkqIHdoZW5ldmVyIHBvc3NpYmxlLiBJbiBwYXJ0aWN1bGFyLCB0aGV5IHN1Z2dlc3QgJHAkLXZhbHVlLWJhc2VkIHN0ZXB3aXNlIHJlZHVjdGlvbiBvZiB0aGUgcmFuZG9tIGVmZmVjdHMgbW9kZWwgdXNpbmcgYSBsb29zZSAkcCQtdmFsdWUgY3JpdGVyaW9uIChlLmcuICRcYWxwaGFfe1x0ZXh0IExSVH0gPSAwLjIkKS4gVGhleSBhbHNvIHByb3ZpZGUgW3Rvb2xzXShodHRwczovL2dpdGh1Yi5jb20vZG1iYXRlcy9SZVBzeWNoTGluZykgZm9yIGRpYWdub3NpbmcgYW5kIG1pdGlnYXRpbmcgc2luZ3VsYXJpdHkuCi0gT25lIGFsdGVybmF0aXZlIChzdWdnZXN0ZWQgYnkgUm9iZXJ0IExhQnVkZGUpIGZvciB0aGUgc21hbGwtbnVtYmVycy1vZi1sZXZlbHMgc2NlbmFyaW8gaXMgdG8gImZpdCB0aGUgbW9kZWwgd2l0aCB0aGUgcmFuZG9tIGZhY3RvciBhcyBhIGZpeGVkIGVmZmVjdCwgZ2V0IHRoZSBsZXZlbCBjb2VmZmljaWVudHMgaW4gdGhlIHN1bSB0byB6ZXJvIGZvcm0sIGFuZCB0aGVuIGNvbXB1dGUgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgY29lZmZpY2llbnRzLiIgVGhpcyBpcyBhcHByb3ByaWF0ZSBmb3IgdXNlcnMgd2hvIGFyZSAoYSkgcHJpbWFyaWx5IGludGVyZXN0ZWQgaW4gbWVhc3VyaW5nIHZhcmlhdGlvbiAoaS5lLiB0aGUgcmFuZG9tIGVmZmVjdHMgYXJlIG5vdCBqdXN0IG51aXNhbmNlIHBhcmFtZXRlcnMsIGFuZCB0aGUgdmFyaWFiaWxpdHkgW3JhdGhlciB0aGFuIHRoZSBlc3RpbWF0ZWQgdmFsdWVzIGZvciBlYWNoIGxldmVsXSBpcyBvZiBzY2llbnRpZmljIGludGVyZXN0KSwgKGIpIHVuYWJsZSBvciB1bndpbGxpbmcgdG8gdXNlIG90aGVyIGFwcHJvYWNoZXMgKGUuZy4gTUNNQyB3aXRoIGhhbGYtQ2F1Y2h5IHByaW9ycyBpbiBXaW5CVUdTKSwgKGMpIHVuYWJsZSBvciB1bndpbGxpbmcgdG8gY29sbGVjdCBtb3JlIGRhdGEuIEZvciB0aGUgc2ltcGxlc3QgY2FzZSAoYmFsYW5jZWQsIG9ydGhvZ29uYWwsIG5lc3RlZCBkZXNpZ25zIHdpdGggbm9ybWFsIGVycm9ycykgdGhlc2UgZXN0aW1hdGVzIG9mIHN0YW5kYXJkIGRldmlhdGlvbnMgc2hvdWxkIGVxdWFsIHRoZSBjbGFzc2ljYWwgbWV0aG9kLW9mLW1vbWVudHMgZXN0aW1hdGVzLgotIEJheWVzaWFuIGFwcHJvYWNoZXMgYWxsb3cgdGhlIHVzZXIgdG8gc3BlY2lmeSBhIGluZm9ybWF0aXZlIHByaW9yIHRoYXQgYXZvaWRzIHNpbmd1bGFyaXR5LgogICAgLSBUaGUgYGJsbWVgIHBhY2thZ2UgW0BjaHVuZ19ub25kZWdlbmVyYXRlXzIwMTNdIHByb3ZpZGVzIGEgd3JhcHBlciBmb3IgdGhlIGBsbWU0YCBtYWNoaW5lcnkgdGhhdCBhZGRzIGEgcGFydGljdWxhciBmb3JtIG9mIHdlYWsgcHJpb3IgdG8gZ2V0IGFuIGFwcHJveGltYXRlIGEgQmF5ZXNpYW4gbWF4aW11bSAqYSBwb3N0ZXJpb3JpKiBlc3RpbWF0ZSB0aGF0IGF2b2lkcyBzaW5ndWxhcml0eS4KICAgIC0gVGhlIGBNQ01DZ2xtbWAgcGFja2FnZSBhbGxvd3MgZm9yIHByaW9ycyBvbiB0aGUgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXgKCS0gVGhlIGByc3RhbmFybWAgYW5kIGBicm1zYCBwYWNrYWdlcyBwcm92aWRlIHdyYXBwZXJzIGZvciB0aGUgU3RhbiBIYW1pbHRvbmlhbiBNQ01DIGVuZ2luZSB0aGF0IGZpdCBHTE1NcyB2aWEgYGxtZTRgIHN5bnRheCwgYWdhaW4gYWxsb3dpbmcgYSB2YXJpZXR5IG9mIHByaW9ycyB0byBiZSBzZXQuCgojIyMgU2V0dGluZyByZXNpZHVhbCB2YXJpYW5jZXMgdG8gYSBmaXhlZCB2YWx1ZSAoemVybyBvciBvdGhlcikKCkZvciBzb21lIHByb2JsZW1zIGl0IHdvdWxkIGJlIGNvbnZlbmllbnQgdG8gYmUgYWJsZSB0byBzZXQgdGhlIHJlc2lkdWFsIHZhcmlhbmNlIHRlcm0gdG8gemVybywgb3IgYSBmaXhlZCB2YWx1ZS4gVGhpcyBpcyBkaWZmaWN1bHQgaW4gYGxtZTRgLCBiZWNhdXNlIHRoZSBtb2RlbCBpcyBwYXJhbWV0ZXJpemVkIGludGVybmFsbHkgaW4gc3VjaCBhIHdheSB0aGF0IHRoZSByZXNpZHVhbCB2YXJpYW5jZSBpcyBwcm9maWxlZCBvdXQgKGkuZS4sIGNhbGN1bGF0ZWQgZGlyZWN0bHkgZnJvbSBhIHJlc2lkdWFsIGRldmlhbmNlIHRlcm0pIGFuZCB0aGUgcmFuZG9tLWVmZmVjdHMgdmFyaWFuY2VzIGFyZSBzY2FsZWQgYnkgdGhlIHJlc2lkdWFsIHZhcmlhbmNlLgoKW1NlYXJjaGluZyB0aGUgci1zaWctbWl4ZWQtbW9kZWxzIGxpc3QgZm9yICJmaXggcmVzaWR1YWwgdmFyaWFuY2UiXShodHRwczovL3d3dy5nb29nbGUuY2Evc2VhcmNoP3E9c2l0ZSUzQSUyRiUyRnN0YXQuZXRoei5jaCUyRnBpcGVybWFpbCUyRnItc2lnLW1peGVkLW1vZGVscyUyRitmaXgrcmVzaWR1YWwrdmFyaWFuY2UpCgotIFRoaXMgaXMgZG9uZSBpbiB0aGUgYG1ldGFmb3JgIHBhY2thZ2UsIGZvciBtZXRhLWFuYWx5dGljIG1vZGVscwotIFlvdSBjYW4gdXNlIHRoZSBgYmxtZWAgcGFja2FnZSB0byBmaXggdGhlIHJlc2lkdWFsIHZhcmlhbmNlOiBmcm9tIFZpbmNlbnQgRG9yaWUsCmBgYApsaWJyYXJ5KGJsbWUpCmJsbWVyKGZvcm11bGEgPSB5IH4gMSArICgxIHwgZ3JvdXApLCB3ZWlnaHRzID0gViwKICAgICAgcmVzaWQucHJpb3IgPSBwb2ludCgxLjApLCBjb3YucHJpb3IgPSBOVUxMKQpgYGAKVGhpcyBzZXRzIHRoZSByZXNpZHVhbCB2YXJpYW5jZSB0byAxLjAuICBZb3UgKmNhbm5vdCogdXNlIHRoaXMgdG8gbWFrZSBpdApleGFjdGx5IHplcm8sIGJ1dCB5b3UgY2FuIG1ha2UgaXQgdmVyeSBzbWFsbCAoYW5kIGV4cGVyaW1lbnQgd2l0aCBzZXR0aW5nCml0IHRvIGRpZmZlcmVudCBzbWFsbCB2YWx1ZXMsIGUuZy4gMC4wMDEgdnMgMC4wMDAxLCB0byBzZWUgaG93IHNlbnNpdGl2ZQp0aGUgcmVzdWx0cyBhcmUpLgotIFNpbWlsYXJseSwgeW91IGNhbiBmaXggdGhlIHJlc2lkdWFsIHZhcmlhbmNlIHRvIGEgc21hbGwgcG9zaXRpdmUgdmFsdWUgaW4gYFtuXWxtZWAgdmlhIHRoZSBgY29udHJvbCgpYCBhcmd1bWVudCBbQGhlaXN0ZXJrYW1wX3VwZGF0ZV8yMDE3XToKYGBge3IgbG1lX3p2YXIscmVzdWx0cz0iaGlkZSJ9Cm5sbWU6OmxtZShSZWFjdGlvbn5EYXlzLHJhbmRvbT1+MXxTdWJqZWN0LAogICAgICAgICAgZGF0YT1sbWU0OjpzbGVlcHN0dWR5LAogICAgICAgICAgY29udHJvbD1saXN0KHNpZ21hPTFlLTgpKQpgYGAKLSB0aGUgYGdsbW1UTUJgIHBhY2thZ2UgY2FuIHNldCB0aGUgcmVzaWR1YWwgdmFyaWFuY2UgdG8gKGFwcHJveGltYXRlbHkpIHplcm8sIGJ5IHNwZWNpZnlpbmcgYGRpc3Bmb3JtdWxhID0gfjBgIChpbiBmYWN0IHRoZSB2YWx1ZSBjYW4gYmUgc2V0IHZpYSBgZ2xtbVRNQkNvbnRyb2woemVyb2Rpc3BfdmFsPS4uLilgOyB0aGUgZGVmYXVsdCB2YWx1ZSBpcyBgbG9nKHNxcnQoLk1hY2hpbmUkZG91YmxlLmVwcykpYCkKLSBUaGVyZSBpcyBhbiBbcnJCbHVwTWV0aG9kNiBwYWNrYWdlXShodHRwczovL0NSQU4uUi1wcm9qZWN0Lm9yZy9wYWNrYWdlPXJyQmx1cE1ldGhvZDYpIG9uIENSQU4gKCJSZS1wYXJhbWV0cml6YXRpb24gb2YgbWl4ZWQgbW9kZWwgZm9ybXVsYXRpb24gdG8gYWxsb3cgZm9yIGEgZml4ZWQgcmVzaWR1YWwgdmFyaWFuY2Ugd2hlbiB1c2luZyBSUi1CTFVQIGZvciBnZW5vbVtlXXdpZGUgZXN0aW1hdGlvbiBvZiBtYXJrZXIgZWZmZWN0cyIpLCBidXQgaXQgc2VlbXMgZmFpcmx5IHNwZWNpYWwtcHVycG9zZS4KLSBpdCBtaWdodCBiZSBwb3NzaWJsZSAqaW4gcHJpbmNpcGxlKiB0byBhZGFwdCBgbG1lNGAncyBpbnRlcm5hbCBgZGV2ZnVuMigpYCBmdW5jdGlvbiAodXNlZCBpbiB0aGUgbGlrZWxpaG9vZCBwcm9maWxpbmcgY29tcHV0YXRpb24gZm9yIExNTXMpLCB3aGljaCB1c2VzIGEgc3BlY2lmaWVkIHZhbHVlIG9mIHRoZSByZXNpZHVhbCBzdGFuZGFyZCBkZXZpYXRpb24gaW4gY29tcHV0aW5nIGxpa2VsaWhvb2QsIGJ1dCBhcyBAYmF0ZXNfZml0dGluZ18yMDE1IHNheToKCj4gVGhlIHJlc3VsdGluZyBmdW5jdGlvbiBpcyBub3QgdXNlZnVsIGZvciBnZW5lcmFsIG5vbmxpbmVhciBvcHRpbWl6YXRpb24g4oCUIG9uZSBjYW4gZWFzaWx5IHdhbmRlciBpbnRvIHBhcmFtZXRlciByZWdpbWVzIGNvcnJlc3BvbmRpbmcgdG8gaW5mZWFzaWJsZSAobm9uLXBvc2l0aXZlIHNlbWlkZWZpbml0ZSkgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaWNlcyDigJQgYnV0IGl0IHNlcnZlcyBmb3IgbGlrZWxpaG9vZCBwcm9maWxpbmcsIHdoZXJlIG9uZSBmb2NhbCBwYXJhbWV0ZXIgaXMgdmFyaWVkIGF0IGEgdGltZSBhbmQgdGhlIG9wdGltaXphdGlvbiBvdmVyIHRoZSBvdGhlciBwYXJhbWV0ZXJzIGlzIGxpa2VseSB0byBzdGFydCBjbG9zZSB0byBhbiBvcHRpbXVtLgoKIyMjIE90aGVyIHByb2JsZW1zL2BsbWU0YCBlcnJvciBtZXNzYWdlcwoKTW9zdCBvZiB0aGUgZm9sbG93aW5nIGVycm9yIG1lc3NhZ2VzIGFyZSByZWxhdGl2ZWx5IHVudXN1YWwsIGFuZCBoYXBwZW4gbW9zdGx5IHdpdGggY29tcGxleC9sYXJnZS91bnN0YWJsZSBtb2RlbHMuIFRoZXJlIGlzIG9mdGVuIG5vIHNpbXBsZSBmaXg7IHRoZSBzdGFuZGFyZCBzdWdnZXN0aW9ucyBmb3IgdHJvdWJsZXNob290aW5nIGFyZSAoMSkgdHJ5IHJlc2NhbGluZyBhbmQvb3IgY2VudGVyaW5nIHByZWRpY3RvcnM7ICgyKSBzZWUgaWYgYSBzaW1wbGVyIG1vZGVsIGNhbiBiZSBtYWRlIHRvIHdvcms7ICgzKSBsb29rIGZvciBzZXZlcmUgbGFjayBvZiBiYWxhbmNlIGFuZC9vciBjb21wbGV0ZSBzZXBhcmF0aW9uIGluIHRoZSBkYXRhIHNldC4KCi0gYFBJUkxTIHN0ZXAtaGFsdmluZ3MgZmFpbGVkIHRvIHJlZHVjZSBkZXZpYW5jZSBpbiBwd3Jzc1VwZGF0ZWAKCS0gdGhpcyBjYW4gYWxzbyBvY2N1ciBkdWUgdG8gY29tcGxldGUgb3IgcXVhc2ktY29tcGxldGUgc2VwYXJhdGlvbiAoc2VlIFtQZW5hbGl6YXRpb24vaGFuZGxpbmcgY29tcGxldGUgc2VwYXJhdGlvbl0oI3BlbmFsaXphdGlvbmhhbmRsaW5nLWNvbXBsZXRlLXNlcGFyYXRpb24pCiAgICAtIFdoZW4gdXNpbmcgYGxtZTRgIHRvIGZpdCBHTE1NcyB3aXRoIGxpbmsgZnVuY3Rpb25zIHRoYXQgZG8gbm90IGF1dG9tYXRpY2FsbHkgY29uc3RyYWluIHRoZSByZXNwb25zZSB0byB0aGUgYWxsb3dhYmxlIHJhbmdlIG9mIHRoZSBkaXN0cmlidXRpb25hbCBmYW1pbHkgKGUuZy4gYmlub21pYWwgbW9kZWxzIHdpdGggYSBsb2cgbGluaywgd2hlcmUgdGhlIGVzdGltYXRlZCBwcm9iYWJpbGl0eSBjYW4gYmUgPjEsIG9yIGludmVyc2UtR2FtbWEgbW9kZWxzLCB3aGVyZSB0aGUgZXN0aW1hdGVkIG1lYW4gY2FuIGJlIG5lZ2F0aXZlKSwgaXQgaXMgbm90IHVudXN1YWwgdG8gZ2V0IHRoaXMgZXJyb3IuICBUaGlzIG9jY3VycyBiZWNhdXNlIGBsbWU0YCBkb2Vzbid0IGRvIGFueXRoaW5nIHRvIGNvbnN0cmFpbiB0aGUgcHJlZGljdGVkIHZhbHVlcywgc28gYE5hTmAgdmFsdWVzIHBvcCB1cCwgd2hpY2ggYXJlbid0IGhhbmRsZWQgZ3JhY2VmdWxseS4gSWYgcG9zc2libGUsIHN3aXRjaCB0byBhIGxpbmsgZnVuY3Rpb24gdG8gb25lIHRoYXQgY29uc3RyYWlucyB0aGUgcmVzcG9uc2UgKGUuZy4gbG9naXQgbGluayBmb3IgYmlub21pYWwgb3IgbG9nIGxpbmsgZm9yIEdhbW1hKS4KCS0gb3RoZXJ3aXNlIHRoaXMgbWVzc2FnZSBvZnRlbiBvY2N1cnMgd2hlbiB0aGVyZSBpcyBzb21ldGhpbmcgZWxzZSB3cm9uZyB3aXRoIHRoZSBtb2RlbCBvciBkYXRhLCBlLmcuIAoJICAgICAgLSBbYSBtb2RlbCBmaXR0ZWQgdG8gdW5kZXJkaXNwZXJzZWQgZGF0YSBpbmNsdWRlcyBib3RoIGEgbmVnYXRpdmUgYmlub21pYWwgcmVzcG9uc2UgYW5kIG9ic2VydmF0aW9uLWxldmVsIHJhbmRvbSBlZmZlY3RzXShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yODAzNjMzNC91c2luZy1nbG1lci1uYi10aGUtZXJyb3ItbWVzc2FnZW1heHN0ZXBoYWxmaXQtcGlybHMtc3RlcC1oYWx2aW5ncy1mYWlsZWQtdCkKCQkgIC0gW25lZ2F0aXZlIHJlc3BvbnNlIHZhbHVlcyBmb3IgYSBsaW5rIGZ1bmN0aW9uIHRoYXQgZG9lc24ndCBhbGxvdyB0aGVtXShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zNzUzMzgyNS9lcnJvci1tYXhzdGVwaGFsZml0LXBpcmxzLXN0ZXAtaGFsdmluZ3MtZmFpbGVkLXRvLXJlZHVjZS1kZXZpYW5jZS1pbi1wd3Jzc3VwZCkKLSBgRG93bmRhdGVkIFZ0ViBpcyBub3QgcG9zaXRpdmUgZGVmaW5pdGVgOiBubyBzcGVjaWZpYyBhZHZpY2UsIHNlZSBnZW5lcmFsIHN1Z2dlc3Rpb25zIGFib3ZlCi0gYGNvbnZlcmdlbmNlIGNvZGUgMyBmcm9tIGJvYnlxYTogYm9ieXFhIC0tIGEgdHJ1c3QgcmVnaW9uIHN0ZXAgZmFpbGVkIHRvIHJlZHVjZSBxYDogYWdhaW4gbm8gc3BlY2lmaWMgYWR2aWNlIGFib3V0IGZpeGluZyB0aGlzLCBhbHRob3VnaCB0aGVyZSBpcyBhIFt1c2VmdWwgZGlzY3Vzc2lvbiBvZiB0aGUgbWVhbmluZyBvZiB0aGUgZXJyb3IgbWVzc2FnZSBvbiBDcm9zc1ZhbGlkYXRlZF0oaHR0cHM6Ly9zdGF0cy5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvODk5NDUvbWVhbmluZy1vZi1hLWNvbnZlcmdlbmNlLXdhcm5pbmctaW4tZ2xtZXIpCgojIyBSRU1MIGZvciBHTE1NcwoKLSBXaGlsZSByZXN0cmljdGVkIG1heGltdW0gbGlrZWxpaG9vZCAoUkVNTCkgcHJvY2VkdXJlcyAoW1dpa2lwZWRpYV0oaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9SZXN0cmljdGVkX21heGltdW1fbGlrZWxpaG9vZCkgYXJlIHdlbGwgZXN0YWJsaXNoZWQgZm9yIGxpbmVhciBtaXhlZCBtb2RlbHMsIGl0IGlzIGxlc3MgY2xlYXIgaG93IG9uZSBzaG91bGQgZGVmaW5lIGFuZCBjb21wdXRlIHRoZSBlcXVpdmFsZW50IGNyaXRlcmlhIChpbnRlZ3JhdGluZyBvdXQgdGhlIGVmZmVjdHMgb2YgZml4ZWQgcGFyYW1ldGVycykgZm9yIEdMTU1zLiBAbWlsbGFyX21heGltdW1fMjAxMSBhbmQgQGJlcmdlcl9pbnRlZ3JhdGVkXzE5OTkgYXJlIHBvc3NpYmxlIHN0YXJ0aW5nIHBvaW50cyBpbiB0aGUgcGVlci1yZXZpZXdlZCBsaXRlcmF0dXJlLCBhbmQgdGhlcmUgYXJlIG1haWxpbmctbGlzdCBkaXNjdXNzaW9ucyBvZiB0aGVzZSBpc3N1ZXMgW2hlcmVdKGh0dHBzOi8vc3RhdC5ldGh6LmNoL3BpcGVybWFpbC9yLXNpZy1taXhlZC1tb2RlbHMvMjAwOXExLzAwMjEwNC5odG1sKSBhbmQgW2hlcmVdKGh0dHA6Ly9saXN0cy5hZG1iLXByb2plY3Qub3JnL3BpcGVybWFpbC91c2Vycy8yMDExLUp1bmUvMDAxMjI0Lmh0bWwpLgotIEF0dGVtcHRpbmcgdG8gdXNlIGBSRU1MPVRSVUVgIHdpdGggYGdsbWVyYCB3aWxsIHByb2R1Y2UgdGhlIHdhcm5pbmcgYGV4dHJhIGFyZ3VtZW50KHMpIOKAmFJFTUzigJkgZGlzcmVnYXJkZWRgCi0gYGdsbW1UTUJgIGFsbG93cyBgUkVNTD1UUlVFYCBmb3IgR0xNTXMgKGl0IHVzZXMgdGhlIExhcGxhY2UgYXBwcm94aW1hdGlvbiB0byBpbnRlZ3JhdGUgb3ZlciB0aGUgZml4ZWQgZWZmZWN0IHBhcmFtZXRlcnMpLCBzaW5jZSB2ZXJzaW9uIDAuMi4yIAoKIyBNb2RlbCBkaWFnbm9zdGljcwoKIyBJbmZlcmVuY2UgYW5kIGNvbmZpZGVuY2UgaW50ZXJ2YWxzCgojIyBUZXN0aW5nIGh5cG90aGVzZXMKCiMjIyBXaGF0IGFyZSB0aGUgcC12YWx1ZXMgbGlzdGVkIGJ5IGBzdW1tYXJ5KGdsbWVyZml0KWAgZXRjLj8gIEFyZSB0aGV5IHJlbGlhYmxlPwoKQnkgZGVmYXVsdCwgaW4ga2VlcGluZyB3aXRoIHRoZSB0cmFkaXRpb24gaW4gYW5hbHlzaXMgb2YgZ2VuZXJhbGl6ZWQgbGluZWFyIG1vZGVscywgYGxtZTRgIGFuZCBzaW1pbGFyIHBhY2thZ2VzIGRpc3BsYXkgdGhlIFdhbGQgWi1zdGF0aXN0aWNzIGZvciBlYWNoIHBhcmFtZXRlciBpbiB0aGUgbW9kZWwgc3VtbWFyeS4gVGhlc2UgaGF2ZSBvbmUgYmlnIGFkdmFudGFnZTogdGhleSdyZSBjb252ZW5pZW50IHRvIGNvbXB1dGUuICBIb3dldmVyLCB0aGV5IGFyZSBhc3ltcHRvdGljIGFwcHJveGltYXRpb25zLCBhc3N1bWluZyBib3RoIHRoYXQgKDEpIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb25zIG9mIHRoZSBwYXJhbWV0ZXJzIGFyZSBtdWx0aXZhcmlhdGUgbm9ybWFsIChvciBlcXVpdmFsZW50bHkgdGhhdCB0aGUgbG9nLWxpa2VsaWhvb2Qgc3VyZmFjZSBpcyBxdWFkcmF0aWMpIGFuZCB0aGF0ICgyKSB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBsb2ctbGlrZWxpaG9vZCBpcyAocHJvcG9ydGlvbmFsIHRvKSAkXGNoaV4yJC4gIFRoZSBzZWNvbmQgYXBwcm94aW1hdGlvbiBpcyBkaXNjdXNzZWQgZnVydGhlciB1bmRlciAiRGVncmVlcyBvZiBmcmVlZG9tIi4gIFRoZSBmaXJzdCBhc3N1bXB0aW9uIHVzdWFsbHkgcmVxdWlyZXMgYW4gZXZlbiBncmVhdGVyIGxlYXAgb2YgZmFpdGgsIGFuZCBpcyBrbm93biB0byBjYXVzZSBwcm9ibGVtcyBpbiBzb21lIGNvbnRleHRzIChmb3IgYmlub21pYWwgbW9kZWxzIGZhaWx1cmVzIG9mIHRoaXMgYXNzdW1wdGlvbiBhcmUgY2FsbGVkIHRoZSAqSGF1Y2stRG9ubmVyIGVmZmVjdCopLCBlc3BlY2lhbGx5IHdpdGggZXh0cmVtZS12YWx1ZWQgcGFyYW1ldGVycy4KCiMjIyBNZXRob2RzIGZvciB0ZXN0aW5nIHNpbmdsZSBwYXJhbWV0ZXJzCgpGcm9tIHdvcnN0IHRvIGJlc3Q6CgotIFdhbGQgJFokLXRlc3RzCi0gKipGb3IgYmFsYW5jZWQsIG5lc3RlZCBMTU1zKiogd2hlcmUgZGVncmVlcyBvZiBmcmVlZG9tIGNhbiBiZSBjb21wdXRlZCBhY2NvcmRpbmcgdG8gY2xhc3NpY2FsIHJ1bGVzOiBXYWxkICR0JC10ZXN0cyAKLSBMaWtlbGlob29kIHJhdGlvIHRlc3QsIGVpdGhlciBieSBzZXR0aW5nIHVwIHRoZSBtb2RlbCBzbyB0aGF0IHRoZSBwYXJhbWV0ZXIgY2FuIGJlIGlzb2xhdGVkL2Ryb3BwZWQgKHZpYSBgYW5vdmFgIG9yIGBkcm9wMWAsIG9yIHZpYSBjb21wdXRpbmcgbGlrZWxpaG9vZCBwcm9maWxlcwotIE1hcmtvdiBjaGFpbiBNb250ZSBDYXJsbyAoTUNNQykgb3IgcGFyYW1ldHJpYyBib290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbHMKCiMjIyBUZXN0cyBvZiBlZmZlY3RzIChpLmUuIHRlc3RpbmcgdGhhdCBzZXZlcmFsIHBhcmFtZXRlcnMgYXJlIHNpbXVsdGFuZW91c2x5IHplcm8pCgpGcm9tIHdvcnN0IHRvIGJlc3Q6CgotIFdhbGQgY2hpLXNxdWFyZSB0ZXN0cyAoZS5nLiBgY2FyOjpBbm92YWApCi0gTGlrZWxpaG9vZCByYXRpbyB0ZXN0ICh2aWEgYGFub3ZhYCBvciBgZHJvcDFgKQotICoqRm9yIGJhbGFuY2VkLCBuZXN0ZWQgTE1NcyoqIHdoZXJlIGRmIGNhbiBiZSBjb21wdXRlZDogY29uZGl0aW9uYWwgRi10ZXN0cyAKLSAqKkZvciBMTU1zKio6IGNvbmRpdGlvbmFsIEYtdGVzdHMgd2l0aCBkZiBjb3JyZWN0aW9uIChlLmcuIEtlbndhcmQtUm9nZXIgaW4gYHBia3J0ZXN0YCBwYWNrYWdlOiBzZWUgbm90ZXMgb24gSy1SIGV0YyBbYmVsb3ddKCNkZGYpLiAKLSBNQ01DIG9yIHBhcmFtZXRyaWMsIG9yIG5vbnBhcmFtZXRyaWMsIGJvb3RzdHJhcCBjb21wYXJpc29ucyAobm9ucGFyYW1ldHJpYyBib290c3RyYXBwaW5nIG11c3QgYmUgaW1wbGVtZW50ZWQgY2FyZWZ1bGx5IHRvIGFjY291bnQgZm9yIGdyb3VwaW5nIGZhY3RvcnMpCgojIyMgSXMgdGhlIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCByZWxpYWJsZSBmb3IgbWl4ZWQgbW9kZWxzPwoKLSBJdCBkZXBlbmRzLgotIE5vdCBmb3IgZml4ZWQgZWZmZWN0cyBpbiBmaW5pdGUtc2l6ZSBjYXNlcyAoc2VlIEBwaW5oZWlyb19taXhlZC1lZmZlY3RzXzIwMDApOiBtYXkgZGVwZW5kIG9uICdkZW5vbWluYXRvciBkZWdyZWVzIG9mIGZyZWVkb20nIChudW1iZXIgb2YgZ3JvdXBzKSBhbmQvb3IgdG90YWwgbnVtYmVyIG9mIHNhbXBsZXMgLSB0b3RhbCBudW1iZXIgb2YgcGFyYW1ldGVycwotIENvbmRpdGlvbmFsIEYtdGVzdHMgYXJlIHByZWZlcnJlZCBmb3IgTE1NcywgKippZioqIGRlbm9taW5hdG9yIGRlZ3JlZXMgb2YgZnJlZWRvbSBhcmUga25vd24KCjxhIGlkPSJkZGYiPjwvYT4KCiMjIyBXaHkgZG9lc24ndCBgbG1lNGAgZGlzcGxheSBkZW5vbWluYXRvciBkZWdyZWVzIG9mIGZyZWVkb20vcCB2YWx1ZXM/ICBXaGF0IG90aGVyIG9wdGlvbnMgZG8gSSBoYXZlPwoKVGhlcmUgaXMgYW4gW1IgRkFRIGVudHJ5XShodHRwOi8vY3Jhbi5yLXByb2plY3Qub3JnL2RvYy9GQVEvUi1GQVEuaHRtbCNXaHktYXJlLXBfMDAyZHZhbHVlcy1ub3QtZGlzcGxheWVkLXdoZW4tdXNpbmctbG1lcl8wMDI4XzAwMjlfMDAzZikgb24gdGhpcyB0b3BpYywgd2hpY2ggbGlua3MgdG8gYSBbbWFpbGluZyBsaXN0IHBvc3RdKGh0dHBzOi8vc3RhdC5ldGh6LmNoL3BpcGVybWFpbC9yLWhlbHAvMjAwNi1NYXkvMDk0NzY1Lmh0bWwpIGJ5IERvdWcgQmF0ZXMgKHRoZXJlIGlzIGFsc28gYSB2b2x1bWlub3VzIFttYWlsaW5nIGxpc3QgdGhyZWFkXShodHRwOi8vcndpa2kuc2Npdmlld3Mub3JnL2Rva3UucGhwP2lkPWd1aWRlczpsbWVyLXRlc3RzKSByZXByb2R1Y2VkIG9uIHRoZSBSIHdpa2kpLiBUaGUgYm90dG9tIGxpbmUgaXMgCgotIEZvciBzcGVjaWFsIGNhc2VzIHRoYXQgY29ycmVzcG9uZCB0byBjbGFzc2ljYWwgZXhwZXJpbWVudGFsIGRlc2lnbnMgKGkuZS4gYmFsYW5jZWQgZGVzaWducyB0aGF0IGFyZSBuZXN0ZWQsIHNwbGl0LXBsb3QsIHJhbmRvbWl6ZWQgYmxvY2ssIGV0Yy4pIC4uLiB3ZSBjYW4gc2hvdyB0aGF0IHRoZSBudWxsIGRpc3RyaWJ1dGlvbnMgb2YgcGFydGljdWxhciByYXRpb3Mgb2Ygc3VtcyBvZiBzcXVhcmVzIGZvbGxvdyBhbiAkRiQgZGlzdHJpYnV0aW9uIHdpdGgga25vd24gbnVtZXJhdG9yIGFuZCBkZW5vbWluYXRvciBkZWdyZWVzIG9mIGZyZWVkb20gKGFuZCBoZW5jZSB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBvZiBwYXJ0aWN1bGFyIGNvbnRyYXN0cyBhcmUgdC1kaXN0cmlidXRlZCB3aXRoIGtub3duIGRmKS4gSW4gbW9yZSBjb21wbGljYXRlZCBzaXR1YXRpb25zICh1bmJhbGFuY2VkLCBHTE1NcywgY3Jvc3NlZCByYW5kb20gZWZmZWN0cywgbW9kZWxzIHdpdGggdGVtcG9yYWwgb3Igc3BhdGlhbCBjb3JyZWxhdGlvbiwgZXRjLikgaXQgaXMgbm90IGluIGdlbmVyYWwgY2xlYXIgdGhhdCB0aGUgbnVsbCBkaXN0cmlidXRpb24gb2YgdGhlIGNvbXB1dGVkIHJhdGlvIG9mIHN1bXMgb2Ygc3F1YXJlcyBpcyByZWFsbHkgYW4gRiBkaXN0cmlidXRpb24sIGZvciAqYW55KiBjaG9pY2Ugb2YgZGVub21pbmF0b3IgZGVncmVlcyBvZiBmcmVlZG9tLgotIEZvciBlYWNoIHNpbXBsZSBkZWdyZWVzLW9mLWZyZWVkb20gcmVjaXBlIHRoYXQgaGFzIGJlZW4gc3VnZ2VzdGVkICh0cmFjZSBvZiB0aGUgaGF0IG1hdHJpeCwgZXRjLikgdGhlcmUgc2VlbXMgdG8gYmUgYXQgbGVhc3Qgb25lIGZhaXJseSBzaW1wbGUgY291bnRlcmV4YW1wbGUgd2hlcmUgdGhlIHJlY2lwZSBmYWlscyBiYWRseSAoZS5nLiBzZWUgW3RoaXMgci1oZWxwIHRocmVhZCBmcm9tIFNlcHRlbWJlciAyMDA2XShodHRwczovL3N0YXQuZXRoei5jaC9waXBlcm1haWwvci1oZWxwLzIwMDYtU2VwdGVtYmVyLzExMjQ5NS5odG1sKSkuCi0gV2hlbiB0aGUgcmVzcG9uc2VzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZCBhbmQgdGhlIGRlc2lnbiBpcyBiYWxhbmNlZCwgbmVzdGVkIGV0Yy4gKGkuZS4gdGhlIGNsYXNzaWNhbCBMTU0gc2l0dWF0aW9uKSwgdGhlIHNjYWxlZCBkZXZpYW5jZXMgYW5kIGRpZmZlcmVuY2VzIGluIGRldmlhbmNlcyBhcmUgZXhhY3RseSAkRiQtZGlzdHJpYnV0ZWQgYW5kIGxvb2tpbmcgYXQgdGhlIGV4cGVyaW1lbnRhbCBkZXNpZ24gKGkuZS4sIHdoaWNoIHRyZWF0bWVudHMgdmFyeS9hcmUgcmVwbGljYXRlZCBhdCB3aGljaCBsZXZlbHMpIHRlbGxzIHVzIHdoYXQgdGhlIHJlbGV2YW50IGRlZ3JlZXMgb2YgZnJlZWRvbSBhcmUgKHNlZSAiZGYgYWx0ZXJuYXRpdmVzIiBiZWxvdykKLSBUd28gYXBwcm9hY2hlcyB0byBhcHByb3hpbWF0aW5nIGRmIChTYXR0ZXJ0aHdhaXRlIGFuZCBLZW53YXJkLVJvZ2VyKSBoYXZlIGJlZW4gaW1wbGVtZW50ZWQgaW4gUiwgU2F0dGVydGh3YWl0ZSBpbiBgbG1lclRlc3RgIGFuZCBLZW53YXJkLVJvZ2VyIGluIGBwYmtydGVzdGAgKGFzIGBLUm1vZGNvbXBgKSAodmFyaW91cyBwYWNrYWdlcyBzdWNoIGFzIGBsbWVyVGVzdGAsIGBlbW1lYW5zYCwgYGNhcmAsIGV0Yy4sIGltcG9ydCBgcGJrcnRlc3Q6OmdldF9MYl9kZGZgKS4KICAgIC0gSy1SIGlzIHByb2JhYmx5IHRoZSBtb3N0IHJlbGlhYmxlIG9wdGlvbiBbQHNjaGFhbGplX2FkZXF1YWN5XzIwMDJdLCBhbHRob3VnaCBpdCBtYXkgYmUgcHJvaGliaXRpdmVseSBjb21wdXRhdGlvbmFsbHkgZXhwZW5zaXZlIGZvciBsYXJnZSBkYXRhIHNldHMuCiAgICAtIEstUiB3YXMgZGVyaXZlZCBmb3IgTE1NcyAoYW5kIGZvciBSRU1MPykgaW4gcGFydGljdWxhciwgaXQgaXNuJ3QgY2xlYXIgaG93IGl0IHdvdWxkIGFwcGx5IHRvIEdMTU1zLiBAc3Ryb3VwX3JldGhpbmtpbmdfMjAxNCBzdGF0ZXMgKHJlZmVyZW5jaW5nIEBzdHJvdXBfbm9uLW5vcm1hbF8yMDEzKSB0aGF0IEstUiBhY3R1YWxseSB3b3JrcyByZWFzb25hYmx5IHdlbGwgZm9yIEdMTU1zIChLLVIgaXMgbm90IGltcGxlbWVudGVkIGluIFIgZm9yIEdMTU1zOyBTdHJvdXAgc3VnZ2VzdHMgdGhhdCBhIHBzZXVkby1saWtlbGlob29kIFtAd29sZmluZ2VyX2dlbmVyYWxpemVkXzE5OTNdIGFwcHJvYWNoIGlzIG5lY2Vzc2FyeSBpbiBvcmRlciB0byBpbXBsZW1lbnQgSy1SIGZvciBHTE1Ncyk6CgogICAgICAgID4gTm90aWNlIHRoZSBub24taW50ZWdlciB2YWx1ZXMgb2YgdGhlIGRlbm9taW5hdG9yIGRmLiBUaGV5LCBhbmQgdGhlICRGJCBhbmQgJHAkIHZhbHVlcywgcmVmbGVjdCB0aGUgcHJvY2VkdXJlIGRldmVsb3BlZCBieSBLZW53YXJkIGFuZCBSb2dlciAoMjAwOSkgdG8gYWNjb3VudCBmb3IgdGhlIGVmZmVjdCBvZiB0aGUgY292YXJpYW5jZSAgc3RydWN0dXJlIG9uIGRlZ3JlZXMgb2YgZnJlZWRvbSBhbmQgc3RhbmRhcmQgZXJyb3JzLiBBbHRob3VnaCB0aGUgS2Vud2FyZOKAk1JvZ2VyIGFkanVzdG1lbnQgd2FzIGRlcml2ZWQgZm9yIHRoZSBMTU0gd2l0aCBub3JtYWxseSBkaXN0cmlidXRlZCBkYXRhIGFuZCBpcyBhbiBhZCBob2MgcHJvY2VkdXJlIGZvciBHTE1NcyB3aXRoIG5vbi1ub3JtYWwgZGF0YSwgaW5mb3JtYWwgc2ltdWxhdGlvbiBzdHVkaWVzIGNvbnNpc3RlbnRseSBoYXZlIHN1Z2dlc3RlZCB0aGF0IHRoZSBhZGp1c3RtZW50IGlzIGFjY3VyYXRlLiBUaGUgS2Vud2FyZC1Sb2dlciBhZGp1c3RtZW50IHJlcXVpcmVzIHRoYXQgdGhlIFNBUyBHTElNTUlYIGRlZmF1bHQgY29tcHV0aW5nIGFsZ29yaXRobSwgcHNldWRvLWxpa2VsaWhvb2QsIGJlIHVzZWQgcmF0aGVyIHRoYW4gdGhlIExhcGxhY2UgYWxnb3JpdGhtIHVzZWQgdG8gb2J0YWluIEFJQ0Mgc3RhdGlzdGljcy4gU3Ryb3VwICgyMDEzYikgZm91bmQgdGhhdCBmb3IgYmlub21pYWwgYW5kIFBvaXNzb24gR0xNTXMsIHBzZXVkby1saWtlbGlob29kIHdpdGggdGhlIEtlbndhcmTigJNSb2dlciBhZGp1c3RtZW50IHlpZWxkcyBiZXR0ZXIgVHlwZSBJIGVycm9yIGNvbnRyb2wgdGhhbiBMYXBsYWNlIHdoaWxlIHByZXNlcnZpbmcgdGhlIEdMTU3igJlzIGFkdmFudGFnZSB3aXRoIHJlc3BlY3QgdG8gcG93ZXIgYW5kIGFjY3VyYWN5IGluIGVzdGltYXRpbmcgdHJlYXRtZW50IG1lYW5zLgoJCi0gVGhlcmUgYXJlIHNldmVyYWwgZGlmZmVyZW50IGlzc3VlcyBhdCBwbGF5IGluIGZpbml0ZS1zaXplIChzbWFsbC1zYW1wbGUpIGFkanVzdG1lbnRzLCB3aGljaCBhcHBseSBzbGlnaHRseSBkaWZmZXJlbnRseSB0byBMTU1zIGFuZCBHTE1Ncy4KICAgICAtICBXaGVuIHRoZSBkYXRhIGRvbid0IGZpdCBpbnRvIHRoZSBjbGFzc2ljYWwgZnJhbWV3b3JrIChjcm9zc2VkLCB1bmJhbGFuY2VkLCBSLXNpZGUgZWZmZWN0cyksIHdlIG1pZ2h0IHN0aWxsIGd1ZXNzIHRoYXQgdGhlIGRldmlhbmNlcyBldGMuIGFyZSBhcHByb3hpbWF0ZWx5IEYtZGlzdHJpYnV0ZWQgYnV0IHRoYXQgd2UgZG9uJ3Qga25vdyB0aGUgcmVhbCBkZWdyZWVzIG9mIGZyZWVkb20gLS0gdGhpcyBpcyB3aGF0IHRoZSBTYXR0ZXJ0aHdhaXRlLCBLZW53YXJkLVJvZ2VyLCBGYWktQ29ybmVsaXVzLCBldGMuIGFwcHJveGltYXRpb25zIGFyZSBzdXBwb3NlZCB0byBkby4KICAgICAtIFdoZW4gdGhlIHJlc3BvbnNlcyBhcmUgbm90IG5vcm1hbGx5IGRpc3RyaWJ1dGVkIChhcyBpbiBHTE1zIGFuZCBHTE1NcyksIGFuZCB3aGVuIHRoZSBzY2FsZSBwYXJhbWV0ZXIgaXMgbm90IGVzdGltYXRlZCAoYXMgaW4gc3RhbmRhcmQgUG9pc3Nvbi0gYW5kIGJpbm9taWFsLXJlc3BvbnNlIG1vZGVscyksIHRoZW4gdGhlIGRldmlhbmNlIGRpZmZlcmVuY2VzIGFyZSBvbmx5IGFzeW1wdG90aWNhbGx5IEYtIG9yIGNoaS1zcXVhcmUtZGlzdHJpYnV0ZWQgKGkuZS4gbm90IGZvciBvdXIgcmVhbCwgZmluaXRlLXNpemUgc2FtcGxlcykuICBJbiBzdGFuZGFyZCBHTE0gcHJhY3RpY2UsIHdlIHVzdWFsbHkgaWdub3JlIHRoaXMgcHJvYmxlbTsgdGhlcmUgaXMgc29tZSBsaXRlcmF0dXJlIG9uIGZpbml0ZS1zaXplIGNvcnJlY3Rpb25zIGZvciBHTE1zIHVuZGVyIHRoZSBydWJyaWNzIG9mICJCYXJ0bGV0dCBjb3JyZWN0aW9ucyIgYW5kICJoaWdoZXIgb3JkZXIgYXN5bXB0b3RpY3MiIChzZWUgQE1jQ3VsbGFnaE5lbGRlcjE5ODksIEBjb3JkZWlyb19pbXByb3ZlZF8xOTk0LCBAY29yZGVpcm9fbm90ZV8xOTk4IGFuZCB0aGUgYGNvbmRgIHBhY2thZ2UgKFtvbiBDUkFOXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy9wYWNrYWdlPWNvbmQpKSBbd2hpY2ggd29ya3Mgd2l0aCBHTE1zLCBub3QgR0xNTXNdKSwgYnV0IGl0J3MgcmFyZWx5IHVzZWQuICAoVGhlIGJpYXMgY29ycmVjdGlvbi9GaXJ0aCBhcHByb2FjaCBpbXBsZW1lbnRlZCBpbiB0aGUgYGJyZ2xtYCBwYWNrYWdlIGF0dGVtcHRzIHRvIGFkZHJlc3MgdGhlIHByb2JsZW0gb2YgZmluaXRlLXNpemUgYmlhcywgbm90IGZpbml0ZS1zaXplIG5vbi1jaGktc3F1YXJlZG5lc3Mgb2YgdGhlIGRldmlhbmNlIGRpZmZlcmVuY2VzLikKICAgIC0gV2hlbiB0aGUgc2NhbGUgcGFyYW1ldGVyIGluIGEgR0xNIGlzIGVzdGltYXRlZCByYXRoZXIgdGhhbiBmaXhlZCAoYXMgaW4gR2FtbWEgb3IgcXVhc2ktbGlrZWxpaG9vZCBtb2RlbHMpLCBpdCBpcyBzb21ldGltZXMgcmVjb21tZW5kZWQgdG8gdXNlIGFuICRGJCB0ZXN0IHRvIGFjY291bnQgZm9yIHRoZSB1bmNlcnRhaW50eSBvZiB0aGUgc2NhbGUgcGFyYW1ldGVyIChlLmcuIEB2ZW5hYmxlc19tb2Rlcm5fMjAwMiByZWNvbW1lbmQgYGFub3ZhKC4uLix0ZXN0PSJGIilgIGZvciBxdWFzaS1saWtlbGlob29kIG1vZGVscykKICAgIC0gQ29tYmluaW5nIHRoZXNlIGlzc3Vlcywgb25lIGhhcyB0byBsb29rIHByZXR0eSBoYXJkIGZvciBpbmZvcm1hdGlvbiBvbiBzbWFsbC1zYW1wbGUgb3IgZmluaXRlLXNpemUgY29ycmVjdGlvbnMgZm9yIEdMTU1zOiBAZmVuZ19zbWFsbF8yMDA0IGFuZCBAYmVsbF9zbWFsbF8yMDEwIGxvb2sgbGlrZSBnb29kIHN0YXJ0aW5nIHBvaW50cywgYnV0IGl0J3Mgbm90IGF0IGFsbCB0cml2aWFsLgoKIyMjIyBEZiBhbHRlcm5hdGl2ZXM6CgotIHVzZSBNQVNTOjpnbG1tUFFMICh1c2VzIG9sZCBgbmxtZWAgcnVsZXMgYXBwcm94aW1hdGVseSBlcXVpdmFsZW50IHRvIFNBUyAnaW5uZXItb3V0ZXInLyd3aXRoaW4tYmV0d2VlbicgcnVsZXMpIGZvciBHTE1Ncywgb3IgYChuKWxtZWAgZm9yIExNTXMKLSBHdWVzcyB0aGUgZGVub21pbmF0b3IgZGYgZnJvbSBzdGFuZGFyZCBydWxlcyAoZm9yIHN0YW5kYXJkIGRlc2lnbnMsIGUuZy4gc2VlIEBHb3RlbGxpRWxsaXNvbjIwMDQpIGFuZCBhcHBseSB0aGVtIHRvICR0JCBvciAkRiQgdGVzdHMKLSBSdW4gdGhlIG1vZGVsIGluIGBsbWVgIChpZiBwb3NzaWJsZSkgYW5kIHVzZSB0aGUgZGVub21pbmF0b3IgZGYgcmVwb3J0ZWQgdGhlcmUgKHdoaWNoIGZvbGxvdyBhIHNpbXBsZSAnaW5uZXItb3V0ZXInIHJ1bGUgd2hpY2ggc2hvdWxkIGNvcnJlc3BvbmQgdG8gdGhlIGNhbm9uaWNhbCBhbnN3ZXIgZm9yIHNpbXBsZS9vcnRob2dvbmFsIGRlc2lnbnMpLCBhcHBsaWVkIHRvICR0JCBvciAkRiQgdGVzdHMuICBGb3IgdGhlIGV4cGxpY2l0IHNwZWNpZmljYXRpb24gb2YgdGhlIHJ1bGVzIHRoYXQgYGxtZWAgdXNlcywgc2VlIHBhZ2UgOTEgb2YgUGluaGVpcm8gYW5kIEJhdGVzICgqdGhpcyBwYWdlIHdhcyBwcmV2aW91c2x5IGF2YWlsYWJsZSBvbiBbR29vZ2xlIEJvb2tzXShodHRwOi8vdGlueXVybC5jb20vbnR5Z3EzKSwgYnV0IHRoZSBsaW5rIGlzIG5vIGxvbmdlciB1c2VmdWwsIHNvIGhlcmUgYXJlIHRoZSByZWxldmFudCBwYXJhZ3JhcGhzKik6Cgo+IFRoZXNlIGNvbmRpdGlvbmFsIHRlc3RzIGZvciBmaXhlZC1lZmZlY3RzIHRlcm1zIHJlcXVpcmUgZGVub21pbmF0b3IgZGVncmVlcyBvZiBmcmVlZG9tLiBJbiB0aGUgY2FzZSBvZiB0aGUgY29uZGl0aW9uYWwgJEYkLXRlc3RzLCB0aGUgbnVtZXJhdG9yIGRlZ3JlZXMgb2YgZnJlZWRvbSBhcmUgYWxzbyByZXF1aXJlZCwgYmVpbmcgZGV0ZXJtaW5lZCBieSB0aGUgdGVybSBpdHNlbGYuIFRoZSBkZW5vbWluYXRvciBkZWdyZWVzIG9mIGZyZWVkb20gYXJlIGRldGVybWluZWQgYnkgdGhlIGdyb3VwaW5nIGxldmVsIGF0IHdoaWNoIHRoZSB0ZXJtIGlzIGVzdGltYXRlZC4gQSB0ZXJtIGlzIGNhbGxlZCBpbm5lciByZWxhdGl2ZSB0byBhIGZhY3RvciBpZiBpdHMgdmFsdWUgY2FuIGNoYW5nZSB3aXRoaW4gYSBnaXZlbiBsZXZlbCBvZiB0aGUgZ3JvdXBpbmcgZmFjdG9yLiBBIHRlcm0gaXMgb3V0ZXIgdG8gYSBncm91cGluZyBmYWN0b3IgaWYgaXRzIHZhbHVlIGRvZXMgbm90IGNoYW5nZXMgd2l0aGluIGxldmVscyBvZiB0aGUgZ3JvdXBpbmcgZmFjdG9yLiBBIHRlcm0gaXMgc2FpZCB0byBiZSBlc3RpbWF0ZWQgYXQgbGV2ZWwgJGkkLCBpZiBpdCBpcyBpbm5lciB0byB0aGUgJGktMSRzdCBncm91cGluZyBmYWN0b3IgYW5kIG91dGVyIHRvIHRoZSAkaSR0aCBncm91cGluZyBmYWN0b3IuIEZvciBleGFtcGxlLCB0aGUgdGVybSBgTWFjaGluZWAgaW4gdGhlIGBmbTJNYWNoaW5lYCBtb2RlbCBpcyBvdXRlciB0byBgTWFjaGluZSAlaW4lIFdvcmtlcmAgYW5kIGlubmVyIHRvIGBXb3JrZXJgLCBzbyBpdCBpcyBlc3RpbWF0ZWQgYXQgbGV2ZWwgMiAoYE1hY2hpbmUgJWluJSBXb3JrZXJgKS4gSWYgYSB0ZXJtIGlzIGlubmVyIHRvIGFsbCAkUSQgZ3JvdXBpbmcgZmFjdG9ycyBpbiBhIG1vZGVsLCBpdCBpcyBlc3RpbWF0ZWQgYXQgdGhlIGxldmVsIG9mIHRoZSB3aXRoaW4tZ3JvdXAgZXJyb3JzLCB3aGljaCB3ZSBkZW5vdGUgYXMgdGhlICRRKzEkc3QgbGV2ZWwuCj4KPiAgVGhlIGludGVyY2VwdCwgd2hpY2ggaXMgdGhlIHBhcmFtZXRlciBjb3JyZXNwb25kaW5nIHRvIHRoZSBjb2x1bW4gb2YgYWxsIDEncyBpbiB0aGUgbW9kZWwgbWF0cmljZXMgJFhfaSQsIGlzIHRyZWF0ZWQgZGlmZmVyZW50bHkgZnJvbSBhbGwgdGhlIG90aGVyIHBhcmFtZXRlcnMsIHdoZW4gaXQgaXMgcHJlc2VudC4gQXMgYSBwYXJhbWV0ZXIgaXQgaXMgcmVnYXJkZWQgYXMgYmVpbmcgZXN0aW1hdGVkIGF0IGxldmVsIDAgYmVjYXVzZSBpdCBpcyBvdXRlciB0byBhbGwgdGhlIGdyb3VwaW5nIGZhY3RvcnMuIEhvd2V2ZXIsIGl0cyBkZW5vbWluYXRvciBkZWdyZWVzIG9mIGZyZWVkb20gYXJlIGNhbGN1bGF0ZWQgYXMgaWYgaXQgd2VyZSBlc3RpbWF0ZWQgYXQgbGV2ZWwgJFErMSQuIFRoaXMgaXMgYmVjYXVzZSB0aGUgaW50ZXJjZXB0IGlzIHRoZSBvbmUgcGFyYW1ldGVyIHRoYXQgcG9vbHMgaW5mb3JtYXRpb24gZnJvbSBhbGwgdGhlIG9ic2VydmF0aW9ucyBhdCBhIGxldmVsIGV2ZW4gd2hlbiB0aGUgY29ycmVzcG9uZGluZyBjb2x1bW4gaW4gJFhfaSQgZG9lc24ndCBjaGFuZ2Ugd2l0aCB0aGUgbGV2ZWwuCj4KPiAgICBMZXR0aW5nICRtX2kkIGRlbm90ZSB0aGUgdG90YWwgbnVtYmVyIG9mIGdyb3VwcyBpbiBsZXZlbCAkaSQgKHdpdGggdGhlIGNvbnZlbnRpb24gdGhhdCAkbV8wPTEkIHdoZW4gdGhlIGZpeGVkIGVmZmVjdHMgbW9kZWwgaW5jbHVkZXMgYW4gaW50ZXJjZXB0IGFuZCAwIG90aGVyd2lzZSwgYW5kICRtX3tRKzF9PU4kKSBhbmQgJHBfaSQgZGVub3RlIHRoZSBzdW0gb2YgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBjb3JyZXNwb25kaW5nIHRvIHRoZSB0ZXJtcyBlc3RpbWF0ZWQgYXQgbGV2ZWwgJGkkLCB0aGUgJGkkdGggbGV2ZWwgZGVub21pbmF0b3IgZGVncmVlcyBvZiBmcmVlZG9tIGlzIGRlZmluZWQgYXMKPgo+ICQkIFxtYXRocm17ZGVuREZ9X2kgPSBtX2kgLSAobV97aS0xfSArIHBfaSksIGkgPSAxLCBcZG90cywgUSAkJAo+IAo+IFRoaXMgZGVmaW5pdGlvbiBjb2luY2lkZXMgd2l0aCB0aGUgY2xhc3NpY2FsIGRlY29tcG9zaXRpb24gb2YgZGVncmVlcyBvZiBmcmVlZG9tIGluIGJhbGFuY2VkLCBtdWx0aWxldmVsIEFOT1ZBIGRlc2lnbnMgYW5kIGdpdmVzIGEgcmVhc29uYWJsZSBhcHByb3hpbWF0aW9uIGZvciBtb3JlIGdlbmVyYWwgbWl4ZWQtZWZmZWN0cyBtb2RlbHMuCgpOb3RlIHRoYXQgdGhlIGltcGxlbWVudGF0aW9uIHVzZWQgaW4gYGxtZWAgKipnZXRzIHRoZSB3cm9uZyBhbnN3ZXIgZm9yIHJhbmRvbS1zbG9wZXMgbW9kZWxzKio6CmBgYHtyIGxtZURGLG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkobmxtZSkKbG1lREYgPC0gZnVuY3Rpb24oZm9ybXVsYT1kaXN0YW5jZX5hZ2UscmFuZG9tPX4xfFN1YmplY3QpIHsKICAgICBtb2QgPC0gbG1lKGZvcm11bGEscmFuZG9tLGRhdGE9T3J0aG9kb250KQogICAgIGFhIDwtIGFub3ZhKG1vZCkKICAgIHJldHVybihzZXROYW1lcyhhYVssImRlbkRGIl0scm93bmFtZXMoYWEpKSkKfQpsbWVERigpCmxtZURGKHJhbmRvbT1+YWdlfFN1YmplY3QpICMjIHdyb25nIQpgYGAKSSAoQkIpIGhhdmUgcmUtaW1wbGVtZW50ZWQgdGhpcyBhbGdvcml0aG0gaW4gYSB3YXkgdGhhdCBkb2VzIHNsaWdodGx5IGJldHRlciBmb3IgcmFuZG9tLXNsb3BlcyBtb2RlbHMgKGJ1dCBtYXkgc3RpbGwgZ2V0IGNvbmZ1c2VkISksIHNlZSBbaGVyZV0oUi9jYWxjRGVuREYuUikuCgpgYGB7ciBjYWxjRGVuREZ9CnNvdXJjZSgiUi9jYWxjRGVuREYuUiIpCmNhbGNEZW5ERih+YWdlLCJTdWJqZWN0IixubG1lOjpPcnRob2RvbnQpCmNhbGNEZW5ERih+YWdlLGRhdGE9bmxtZTo6T3J0aG9kb250LHJhbmRvbT1+MXxTdWJqZWN0KQpjYWxjRGVuREYofmFnZSxkYXRhPW5sbWU6Ok9ydGhvZG9udCxyYW5kb209fmFnZXxTdWJqZWN0KSAjIyBvZmYgYnkgMQpgYGAKCi0gdXNlIFNBUywgR2Vuc3RhdCAoQVMtUkVNTCksIFN0YXRhPwotIEFzc3VtZSBpbmZpbml0ZSBkZW5vbWluYXRvciBkZiAoaS5lLiAkWiQvJFxjaGleMiQgdGVzdCByYXRoZXIgdGhhbiAkdCQvJEYkKSBpZiBudW1iZXIgb2YgZ3JvdXBzIGlzIGxhcmdlICg+NDU/IFZhcmlvdXMgcnVsZXMgb2YgdGh1bWIgZm9yIGhvdyBsYXJnZSBpcyAiYXBwcm94aW1hdGVseSBpbmZpbml0ZSIgaGF2ZSBiZWVuIHBvc2VkLCBpbmNsdWRpbmcgW2luIEBhbmdyaXN0X21vc3RseV8yMDA5XSwgNDIgKGluIGhvbWFnZSB0byBEb3VnbGFzIEFkYW1zKQoKIyMjIFRlc3Rpbmcgc2lnbmlmaWNhbmNlIG9mIHJhbmRvbSBlZmZlY3RzCgotIHRoZSBtb3N0IGNvbW1vbiB3YXkgdG8gZG8gdGhpcyBpcyB0byB1c2UgYSBsaWtlbGlob29kIHJhdGlvIHRlc3QsIGkuZS4gZml0IHRoZSBmdWxsIGFuZCByZWR1Y2VkIG1vZGVscyAodGhlIHJlZHVjZWQgbW9kZWwgaXMgdGhlIG1vZGVsIHdpdGggdGhlIGZvY2FsIHZhcmlhbmNlKHMpIHNldCB0byB6ZXJvKS4gRm9yIGV4YW1wbGU6CmBgYHtyIHJhbmVmZl90ZXN0LG1lc3NhZ2U9RkFMU0UsY2FjaGU9VFJVRX0KbGlicmFyeShsbWU0KQptMiA8LSBsbWVyKFJlYWN0aW9ufkRheXMrKDF8U3ViamVjdCkrKDArRGF5c3xTdWJqZWN0KSxzbGVlcHN0dWR5LFJFTUw9RkFMU0UpCm0xIDwtIHVwZGF0ZShtMiwufkRheXMrKDF8U3ViamVjdCkpCm0wIDwtIGxtKFJlYWN0aW9ufkRheXMsc2xlZXBzdHVkeSkKYW5vdmEobTIsbTEsbTApICMjIHR3byBzZXF1ZW50aWFsIHRlc3RzCmBgYApXaXRoIHJlY2VudCB2ZXJzaW9ucyBvZiBgbG1lNGAsIGdvb2RuZXNzLW9mLWZpdCAoZGV2aWFuY2UpIGNhbiBiZSBjb21wYXJlZCBiZXR3ZWVuIGAoZylsbWVyYCBhbmQgYChnKWxtYCBtb2RlbHMsIGFsdGhvdWdoIGBhbm92YSgpYCBtdXN0IGJlIGNhbGxlZCB3aXRoIHRoZSBtaXhlZCAoYChnKWxtZXJgKSBtb2RlbCBsaXN0ZWQgZmlyc3QuCktlZXAgaW4gbWluZCB0aGF0IExSVC1iYXNlZCBudWxsIGh5cG90aGVzaXMgdGVzdHMgYXJlIGNvbnNlcnZhdGl2ZSB3aGVuIHRoZSBudWxsIHZhbHVlIChzdWNoIGFzICRcc2lnbWFeMj0wJCkgaXMgb24gdGhlIGJvdW5kYXJ5IG9mIHRoZSBmZWFzaWJsZSBzcGFjZSBbQHNlbGZfYXN5bXB0b3RpY18xOTg3O0BzdHJhbV92YXJpYW5jZV8xOTk0O0BHb2xkbWFuV2hlbGFuMjAwMF07IGluIHRoZSBzaW1wbGVzdCBjYXNlIChzaW5nbGUgcmFuZG9tIGVmZmVjdCB2YXJpYW5jZSksIHRoZSBwLXZhbHVlIGlzIGFwcHJveGltYXRlbHkgdHdpY2UgYXMgbGFyZ2UgYXMgaXQgc2hvdWxkIGJlIFtAcGluaGVpcm9fbWl4ZWQtZWZmZWN0c18yMDAwXS4KCi0gQ29uc2lkZXIgKm5vdCogdGVzdGluZyB0aGUgc2lnbmlmaWNhbmNlIG9mIHJhbmRvbSBlZmZlY3RzLiBJZiB0aGUgcmFuZG9tIGVmZmVjdCBpcyBwYXJ0IG9mIHRoZSBleHBlcmltZW50YWwgZGVzaWduLCB0aGlzIHByb2NlZHVyZSBtYXkgYmUgY29uc2lkZXJlZCAnc2FjcmlmaWNpYWwgcHNldWRvcmVwbGljYXRpb24nIFtASHVybGJlcnQxOTg0XS4gVXNpbmcgc3RlcHdpc2UgYXBwcm9hY2hlcyB0byBlbGltaW5hdGUgbm9uLXNpZ25pZmljYW50IHRlcm1zIGluIG9yZGVyIHRvIHNxdWVlemUgbW9yZSBzaWduaWZpY2FuY2Ugb3V0IG9mIHRoZSByZW1haW5pbmcgdGVybXMgaXMgZGFuZ2Vyb3VzIGluIGFueSBjYXNlLgotIGNvbnNpZGVyIHVzaW5nIHRoZSBgUkxSc2ltYCBwYWNrYWdlLCB3aGljaCBoYXMgYSBmYXN0IGltcGxlbWVudGF0aW9uIG9mIHNpbXVsYXRpb24tYmFzZWQgdGVzdHMgb2YgbnVsbCBoeXBvdGhlc2VzIGFib3V0IHplcm8gdmFyaWFuY2VzLCBmb3Igc2ltcGxlIHRlc3RzLiAoSG93ZXZlciwgaXQgb25seSBhcHBsaWVzIHRvIGBsbWVyYCBtb2RlbHMsIGFuZCBpcyBhIGJpdCB0cmlja3kgdG8gdXNlIGZvciBtb3JlIGNvbXBsZXggbW9kZWxzLikKCmBgYHtyIFJMUnNpbV9jaGVjayxlY2hvPUZBTFNFfQppZiAocGFja2FnZVZlcnNpb24oIlJMUnNpbSIpPCIzLjEtNiIpIHsKICBzdG9wKCJuZWVkIHJlY2VudCB2ZXJzaW9uIG9mIFJMUnNpbTogY29uc2lkZXIiLAogICAgICAgIidyZW1vdGVzOjppbnN0YWxsX2dpdGh1YihcImZhYmlhbi1zL1JMUnNpbVwiKSciKQp9CmBgYApgYGB7ciBSTFJzaW0sbWVzc2FnZT1GQUxTRX0KbGlicmFyeShSTFJzaW0pCiMjIGNvbXBhcmUgbTAgYW5kIG0xCmV4YWN0TFJUKG0xLG0wKQojIyBjb21wYXJlIG0xIGFuZCBtMgptQSA8LSB1cGRhdGUobTIsUkVNTD1UUlVFKQptMEIgPC0gdXBkYXRlKG1BLCAuIH4gLiAtICgwICsgRGF5c3xTdWJqZWN0KSkKbS5zbG9wZSAgPC0gdXBkYXRlKG1BLCAuIH4gLiAtICgxfFN1YmplY3QpKQpleGFjdFJMUlQobTA9bTBCLG09bS5zbG9wZSxtQT1tQSkKYGBgCgotIFBhcmFtZXRyaWMgYm9vdHN0cmFwOiBmaXQgdGhlIHJlZHVjZWQgbW9kZWwsIHRoZW4gcmVwZWF0ZWRseSBzaW11bGF0ZSBmcm9tIGl0IGFuZCBjb21wdXRlIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBkZXZpYW5jZSBvZiB0aGUgcmVkdWNlZCBhbmQgdGhlIGZ1bGwgbW9kZWwgZm9yIGVhY2ggc2ltdWxhdGVkIGRhdGEgc2V0LiAgQ29tcGFyZSB0aGlzIG51bGwgZGlzdHJpYnV0aW9uIHRvIHRoZSBvYnNlcnZlZCBkZXZpYW5jZSBkaWZmZXJlbmNlLiBUaGlzIHByb2NlZHVyZSBpcyBpbXBsZW1lbnRlZCBpbiB0aGUgYHBia3J0ZXN0YCBwYWNrYWdlIChtZXNzYWdlcyBhbmQgd2FybmluZ3Mgc3VwcHJlc3NlZCkuCmBgYHtyIHBib290X3ZhcnRlc3RfY29tcCxjYWNoZT1UUlVFLCBtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9CihwYiA8LSBwYmtydGVzdDo6UEJtb2Rjb21wKG0yLG0xLHNlZWQ9MTAxKSkKYGBgCgojIyMgU3RhbmRhcmQgZXJyb3JzIG9mIHZhcmlhbmNlIGVzdGltYXRlcwoKPGEgaWQ9InZhcmlhbmNlLXN0YW5kYXJkLWVycm9ycyI+PC9hPgoKLSBQYXJhcGhyYXNpbmcgRG91ZyBCYXRlczogdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB2YXJpYW5jZSBlc3RpbWF0ZXMgaXMgaW4gZ2VuZXJhbCBzdHJvbmdseSBhc3ltbWV0cmljOiB0aGUgc3RhbmRhcmQgZXJyb3IgbWF5IGJlIGEgcG9vciBjaGFyYWN0ZXJpemF0aW9uIG9mIHRoZSB1bmNlcnRhaW50eS4KLSBgbG1lNGAgYWxsb3dzIGZvciBjb21wdXRpbmcgbGlrZWxpaG9vZCBwcm9maWxlcyBvZiB2YXJpYW5jZXMgYW5kIGNvbXB1dGluZyBjb25maWRlbmNlIGludGVydmFscyBvbiB0aGVpciBiYXNpczsgdGhlc2UgbGlrZWxpaG9vZCBwcm9maWxlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFyZSBzdWJqZWN0IHRvIHRoZSB1c3VhbCBjYXZlYXRzIGFib3V0IHRoZSBMUlQgd2l0aCBmaW5pdGUgc2FtcGxlIHNpemVzLgotIFVzaW5nIGFuIE1DTUMtYmFzZWQgYXBwcm9hY2ggKHRoZSBzaW1wbGVzdC9tb3N0IGNhbm5lZCBpcyBwcm9iYWJseSB0byB1c2UgdGhlIGBNQ01DZ2xtbWAgcGFja2FnZSwgYWx0aG91Z2ggaXRzIG1vZGUgc3BlY2lmaWNhdGlvbnMgYXJlIG5vdCBpZGVudGljYWwgdG8gdGhvc2Ugb2YgbG1lNCkgd2lsbCBwcm92aWRlIHBvc3RlcmlvciBkaXN0cmlidXRpb25zIG9mIHRoZSB2YXJpYW5jZSBwYXJhbWV0ZXJzOiBxdWFudGlsZXMgb3IgY3JlZGlibGUgaW50ZXJ2YWxzIChgSFBEaW50ZXJ2YWwoKWAgaW4gdGhlIGBjb2RhYCBwYWNrYWdlKSB3aWxsIGNoYXJhY3Rlcml6ZSB0aGUgdW5jZXJ0YWludHkuCi0gKGRvbid0IHNheSB3ZSBkaWRuJ3Qgd2FybiB5b3UgLi4uKSBgW25dbG1lYCBmaXRzIGNvbnRhaW4gYW4gZWxlbWVudCBjYWxsZWQgYGFwVmFyYCB3aGljaCBjb250YWlucyB0aGUgYXBwcm94aW1hdGUgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXggKGRlcml2ZWQgZnJvbSB0aGUgSGVzc2lhbiwgdGhlIG1hdHJpeCBvZiAobnVtZXJpY2FsbHkgYXBwcm94aW1hdGVkKSBzZWNvbmQgZGVyaXZhdGl2ZXMgb2YgdGhlIGxpa2VsaWhvb2QgKFJFTUw/KSBhdCB0aGUgbWF4aW11bSAocmVzdHJpY3RlZD8pIGxpa2VsaWhvb2QgdmFsdWVzKTogeW91IGNhbiBkZXJpdmUgdGhlIHN0YW5kYXJkIGVycm9ycyBmcm9tIHRoaXMgbGlzdCBlbGVtZW50IHZpYSBgc3FydChkaWFnKGxtZS5vYmokYXBWYXIpKWAuIEZvciB3aGF0ZXZlciBpdCdzIHdvcnRoLCB0aG91Z2gsIFt0aGVzZSBlc3RpbWF0ZXMgbWlnaHQgbm90IG1hdGNoXShodHRwOi8vd3d3LmJpb3N0YXQud3VzdGwuZWR1L2FyY2hpdmVzL2h0bWwvcy1uZXdzLzIwMDMtMDcvbXNnMDAxMjcuaHRtbCkgdGhlIFtlc3RpbWF0ZXMgdGhhdCBTQVMgZ2l2ZXNdKGh0dHA6Ly93d3cudGF1LmFjLmlsL2NjL3BhZ2VzL2RvY3Mvc2FzOC9zdGF0L2NoYXA0MS9zZWN0MjUuaHRtI21peGVkY3BlKSB3aGljaCBhcmUgc3VwcG9zZWRseSBkZXJpdmVkIGluIHRoZSBzYW1lIHdheS4KLSBpdCdzIG5vdCBhIGZ1bGwgc29sdXRpb24sIGJ1dCB0aGVyZSBpcyBzb21lIG1vcmUgaW5mb3JtYXRpb24gW2hlcmVdKGh0dHBzOi8vcnB1YnMuY29tL2Jib2xrZXIvd2FsZHZhcikuIEkgaGF2ZSBzb21lIGRlbHRhLW1ldGhvZCBjb21wdXRhdGlvbnMgdGhlcmUgdGhhdCBhcmUgb2ZmIGJ5IGEgZmFjdG9yIG9mIDIgZm9yIHRoZSByZXNpZHVhbCBzdGFuZGFyZCBkZXZpYXRpb24sIGFzIHdlbGwgYXMgc29tZSBjb21wdXRhdGlvbnMgYmFzZWQgb24gcmVwYXJhbWV0ZXJpemluZyB0aGUgZGV2aWFuY2UgZnVuY3Rpb24uCgojIyMgUC12YWx1ZXM6IE1DTUMgYW5kIHBhcmFtZXRyaWMgYm9vdHN0cmFwIAoKQWJhbmRvbmluZyB0aGUgYXBwcm94aW1hdGUgJEYkLyR0JC1zdGF0aXN0aWMgcm91dGUsIG9uZSBlbmRzIHVwIHdpdGggdGhlIG1vcmUgZ2VuZXJhbCBwcm9ibGVtIG9mIGVzdGltYXRpbmcgJHAkLXZhbHVlcy4gIFRoZXJlIGlzIGEgd2lkZXIgcmFuZ2Ugb2Ygb3B0aW9ucyBoZXJlLCBhbHRob3VnaCBtYW55IG9mIHRoZW0gYXJlIGNvbXB1dGF0aW9uYWxseSBpbnRlbnNpdmUgLi4uCgojIyMjIE1hcmtvdiBjaGFpbiBNb250ZSBDYXJsbyBzYW1wbGluZzoKLSBwc2V1ZG8tQmF5ZXNpYW46IHBvc3QtaG9jIHNhbXBsaW5nLCB0eXBpY2FsbHkgKDEpIGFzc3VtaW5nIGZsYXQgcHJpb3JzIGFuZCAoMikgc3RhcnRpbmcgZnJvbSB0aGUgTUxFLCBwb3NzaWJseSB1c2luZyB0aGUgYXBwcm94aW1hdGUgdmFyaWFuY2UtY292YXJpYW5jZSBlc3RpbWF0ZSB0byBjaG9vc2UgYSBjYW5kaWRhdGUgZGlzdHJpYnV0aW9uCiAgICAtIHZpYSBgbWNtY3NhbXBgIChpZiBhdmFpbGFibGUgZm9yIHlvdXIgcHJvYmxlbTogaS5lLiBMTU1zIHdpdGggc2ltcGxlIHJhbmRvbSBlZmZlY3RzIC0tIG5vdCBHTE1NcyBvciBjb21wbGV4IHJhbmRvbSBlZmZlY3RzKQogICAgLSB2aWEgYHB2YWxzLmZuY2AgaW4gdGhlIGBsYW5ndWFnZVJgIHBhY2thZ2UsIGEgd3JhcHBlciBmb3IgbWNtY3NhbXApCiAgICAtIGluIEFEIE1vZGVsIEJ1aWxkZXIsIHBvc3NpYmx5IHZpYSB0aGUgYGdsbW1BRE1CYCBwYWNrYWdlICh1c2UgdGhlIGBtY21jPVRSVUVgIG9wdGlvbikgb3IgdGhlIGBSMmFkbWJgIHBhY2thZ2UgKHdyaXRlIHlvdXIgb3duIG1vZGVsIGRlZmluaXRpb24gaW4gQUQgTW9kZWwgQnVpbGRlciksIG9yIG91dHNpZGUgb2YgUgogICAgLSB2aWEgdGhlIGBzaW1gIGZ1bmN0aW9uIGZyb20gdGhlIGBhcm1gIHBhY2thZ2UgKHNpbXVsYXRlcyB0aGUgcG9zdGVyaW9yIG9ubHkgZm9yIHRoZSBiZXRhIChmaXhlZC1lZmZlY3QpIGNvZWZmaWNpZW50czsgbm90IHlldCB3b3JraW5nIHdpdGggZGV2ZWxvcG1lbnQgbG1lNDsgd291bGQgbGlrZSBhIGJldHRlciBmb3JtYWwgZGVzY3JpcHRpb24gb2YgdGhlIGFsZ29yaXRobSAuLi4/KQotIGZ1bGx5IEJheWVzaWFuIGFwcHJvYWNoZXMKICAgIC0gdmlhIHRoZSBgTUNNQ2dsbW1gIHBhY2thZ2UKICAgIC0gYGdsbW1CVUdTYCAoYSBXaW5CVUdTIHdyYXBwZXIvUiBpbnRlcmZhY2UpCiAgICAtIEpBR1MvV2luQlVHUy9PcGVuQlVHUyBldGMuLCB2aWEgdGhlIGByamFnc2AvYHIyamFnc2AvYFIyV2luQlVHU2AvYEJSdWdzYCBwYWNrYWdlcwoKIyMjIyBTdGF0dXMgb2YgbWNtY3NhbXAKCmBtY21jc2FtcGAgaXMgYSBmdW5jdGlvbiBmb3IgbG1lNCB0aGF0IGlzIHN1cHBvc2VkIHRvIHNhbXBsZSBmcm9tIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIG9mIHRoZSBwYXJhbWV0ZXJzLCBiYXNlZCBvbiBmbGF0L2ltcHJvcGVyIHByaW9ycyBmb3IgdGhlIHBhcmFtZXRlcnMgW2VkOiBJIGJlbGlldmUsIGJ1dCBhbSBub3Qgc3VyZSwgdGhhdCB0aGVzZSBwcmlvcnMgYXJlIGZsYXQgKipvbiB0aGUgc2NhbGUgb2YgdGhlIHRoZXRhIChDaG9sZXNreS1mYWN0b3IpIHBhcmFtZXRlcnMqKl0uICBBdCBwcmVzZW50LCBpbiB0aGUgQ1JBTiB2ZXJzaW9uIChsbWU0IDAuOTk5OTk5LTApIGFuZCB0aGUgUi1mb3JnZSAic3RhYmxlIiB2ZXJzaW9uIChsbWU0LjAgMC45OTk5OTktMSksIHRoaXMgY292ZXJzIG9ubHkgbGluZWFyIG1peGVkIG1vZGVscyB3aXRoIHVuY29ycmVsYXRlZCByYW5kb20gZWZmZWN0cy4KCkFzIGhhcyBiZWVuIGRpc2N1c3NlZCBpbiBhIHZhcmlldHkgb2YgcGxhY2VzIChlLmcuIFtvbiByLXNpZy1taXhlZCBtb2RlbHNdKGh0dHA6Ly9hcnRpY2xlLmdtYW5lLm9yZy9nbWFuZS5jb21wLmxhbmcuci5sbWU0LmRldmVsLzE3ODgvKSwgYW5kIFtvbiB0aGUgci1mb3JnZSBidWcgdHJhY2tlcl0oaHR0cHM6Ly9yLWZvcmdlLnItcHJvamVjdC5vcmcvdHJhY2tlci8/ZnVuYz1kZXRhaWwmYWlkPTY4Jmdyb3VwX2lkPTYwJmF0aWQ9Mjk4KSwgaXQgaXMgY2hhbGxlbmdpbmcgdG8gY29tZSB1cCB3aXRoIGEgc2FtcGxlciB0aGF0IGFjY291bnRzIHByb3Blcmx5IGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbnMgZm9yIHNvbWUgb2YgdGhlIHZhcmlhbmNlIGNvbXBvbmVudHMgbWF5IGJlIG1peHR1cmVzIG9mIHBvaW50IG1hc3NlcyBhdCB6ZXJvIGFuZCBjb250aW51b3VzIGRpc3RyaWJ1dGlvbnMuICBOYWl2ZSBzYW1wbGVycyBhcmUgbGlrZWx5IHRvIGdldCBzdHVjayBhdCBvciBuZWFyIHplcm8uICBEb3VnIEJhdGVzIGhhcyBhbHdheXMgYmVlbiBhIGJpdCB1bnN1cmUgdGhhdCBgbWNtY3NhbXBgIGlzIHJlYWxseSBwZXJmb3JtaW5nIGFzIGludGVuZGVkLCBldmVuIGluIHRoZSBsaW1pdGVkIGNhc2VzIGl0IG5vdyBoYW5kbGVzLgoKR2l2ZW4gdGhpcyB1bmNlcnRhaW50eSBhYm91dCBob3cgZXZlbiB0aGUgYmFzaWMgdmVyc2lvbiB3b3JrcywgdGhlIGBsbWU0YCBkZXZlbG9wZXJzIGhhdmUgYmVlbiByZWx1Y3RhbnQgdG8gbWFrZSB0aGUgZWZmb3J0IHRvIGV4dGVuZCBpdCB0byBHTE1NcyBvciBtb3JlIGNvbXBsZXggTE1Ncywgb3IgdG8gaW1wbGVtZW50IGl0IGZvciB0aGUgZGV2ZWxvcG1lbnQgdmVyc2lvbiBvZiBsbWU0IC4uLiBzbyB1bmxlc3Mgc29tZXRoaW5nIG1pcmFjdWxvdXMgaGFwcGVucywgaXQgd2lsbCBub3QgYmUgaW1wbGVtZW50ZWQgZm9yIHRoZSBuZXcgdmVyc2lvbiBvZiBgbG1lNGAuIEFzIGFsd2F5cywgdXNlcnMgYXJlIGVuY291cmFnZWQgdG8gd3JpdGUgYW5kIHNoYXJlIHRoZWlyIG93biBjb2RlIHRoYXQgaW1wbGVtZW50cyB0aGVzZSBjYXBhYmlsaXRpZXMgLi4uCgojIyMjIFBhcmFtZXRyaWMgYm9vdHN0cmFwCgpUaGUgaWRlYSBoZXJlIGlzIHRoYXQgaW4gb3JkZXIgdG8gZG8gaW5mZXJlbmNlIG9uIHRoZSBlZmZlY3Qgb2YgKGEpIHByZWRpY3RvcihzKSwgeW91ICgxKSBmaXQgdGhlIHJlZHVjZWQgbW9kZWwgKHdpdGhvdXQgdGhlIHByZWRpY3RvcnMpIHRvIHRoZSBkYXRhOyAoMikgbWFueSB0aW1lcywgKDJhKSBzaW11bGF0ZSBkYXRhIGZyb20gdGhlIHJlZHVjZWQgbW9kZWw7ICgyYikgZml0IGJvdGggdGhlIHJlZHVjZWQgYW5kIHRoZSBmdWxsIG1vZGVsIHRvIHRoZSBzaW11bGF0ZWQgKG51bGwpIGRhdGE7ICgyYykgY29tcHV0ZSBzb21lIHN0YXRpc3RpYyhzKSBbZS5nLiB0LXN0YXRpc3RpYyBvZiB0aGUgZm9jYWwgcGFyYW1ldGVyLCBvciB0aGUgbG9nLWxpa2VsaWhvb2Qgb3IgZGV2aWFuY2UgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBtb2RlbHNdOyAoMykgY29tcGFyZSB0aGUgb2JzZXJ2ZWQgdmFsdWVzIG9mIHRoZSBzdGF0aXN0aWMgZnJvbSBmaXR0aW5nIHlvdXIgZnVsbCBtb2RlbCB0byB0aGUgZGF0YSB0byB0aGUgbnVsbCBkaXN0cmlidXRpb24gZ2VuZXJhdGVkIGluIHN0ZXAgMi4KLSBgUEJtb2Rjb21wYCBpbiB0aGUgYHBia3J0ZXN0YCBwYWNrYWdlCi0gc2VlIHRoZSBleGFtcGxlIGluIGBoZWxwKCJzaW11bGF0ZS1tZXIiKWAgaW4gdGhlIGBsbWU0YCBwYWNrYWdlIHRvIHJvbGwgeW91ciBvd24sIHVzaW5nIGEgY29tYmluYXRpb24gb2YgYHNpbXVsYXRlKClgIGFuZCBgcmVmaXQoKWAuCi0gYGJvb3RNZXJgIGluIGBsbWU0YCB2ZXJzaW9uID4xLjAuMAotIGEgcHJlc2VudGF0aW9uIGF0IFVzZVIhIDIwMDkgKFthYnN0cmFjdF0oaHR0cDovL3d3dy5hZ3JvY2FtcHVzLW91ZXN0LmZyL21hdGgvdXNlUi0yMDA5L2Fic3RyYWN0cy9wZGYvU2FuY2hlekVzcGlnYXJlcytPY2FuYS5wZGYpLCBbc2xpZGVzXShodHRwOi8vd3d3LmFncm9jYW1wdXMtb3Vlc3QuZnIvbWF0aC91c2VSLTIwMDkvc2xpZGVzL1NhbmNoZXpFc3BpZ2FyZXMrT2NhbmEucGRmKSkgd2VudCBpbnRvIGRldGFpbCBhYm91dCBhIHByb3Bvc2VkIGBib290TWVyYCBwYWNrYWdlIGFuZCBzdWdnZXN0ZWQgaXQgY291bGQgd29yayBmb3IgR0xNTXMgdG9vIC0tIApidXQgaXQgZG9lcyBub3Qgc2VlbSB0byBiZSBhY3RpdmUuCgojIyBQcmVkaWN0aW9ucyBhbmQvb3IgY29uZmlkZW5jZSAob3IgcHJlZGljdGlvbikgaW50ZXJ2YWxzIG9uIHByZWRpY3Rpb25zCgpOb3RlIHRoYXQgbm9uZSBvZiB0aGUgZm9sbG93aW5nIGFwcHJvYWNoZXMgdGFrZXMgdGhlIHVuY2VydGFpbnR5Cm9mIHRoZSByYW5kb20gZWZmZWN0cyBwYXJhbWV0ZXJzIGludG8gYWNjb3VudCAuLi4gaWYgeW91IHdhbnQgdG8gdGFrZSBSRSBwYXJhbWV0ZXIgdW5jZXJ0YWludHkgaW50byBhY2NvdW50LCBhIEJheWVzaWFuIGFwcHJvYWNoIGlzIHByb2JhYmx5IHRoZSBlYXNpZXN0IHdheSB0byBkbyBpdC4KClRoZSBnZW5lcmFsIHJlY2lwZSBmb3IgY29tcHV0aW5nIHByZWRpY3Rpb25zIGZyb20gYSBsaW5lYXIgb3IgZ2VuZXJhbGl6ZWQgbGluZWFyIG1vZGVsIGlzIHRvIAoKLSBmaWd1cmUgb3V0IHRoZSBtb2RlbCBtYXRyaXggJFgkIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG5ldyBkYXRhOwotICBtYXRyaXgtbXVsdGlwbHkgJFgkIGJ5IHRoZSBwYXJhbWV0ZXIgdmVjdG9yICRcYmV0YSQgdG8gZ2V0IHRoZSBwcmVkaWN0aW9ucyAob3IgbGluZWFyIHByZWRpY3RvciBpbiB0aGUgY2FzZSBvZiBHTE0oTSlzKTsgCi0gZXh0cmFjdCB0aGUgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXggb2YgdGhlIHBhcmFtZXRlcnMgJFYkIAotIGNvbXB1dGUgJFggViBYXntccHJpbWV9JCB0byBnZXQgdGhlIHZhcmlhbmNlLWNvdmFyaWFuY2UgbWF0cml4IG9mIHRoZSBwcmVkaWN0aW9uczsgCi0gZXh0cmFjdCB0aGUgZGlhZ29uYWwgb2YgdGhpcyBtYXRyaXggdG8gZ2V0IHZhcmlhbmNlcyBvZiBwcmVkaWN0aW9uczsKLSBpZiBjb21wdXRpbmcgcHJlZGljdGlvbiByYXRoZXIgdGhhbiBjb25maWRlbmNlIGludGVydmFscywgYWRkIHRoZSByZXNpZHVhbCB2YXJpYW5jZTsgCi0gdGFrZSB0aGUgc3F1YXJlLXJvb3Qgb2YgdGhlIHZhcmlhbmNlcyB0byBnZXQgdGhlIHN0YW5kYXJkIGRldmlhdGlvbnMgKGVycm9ycykgb2YgdGhlIHByZWRpY3Rpb25zOyAKLSBjb21wdXRlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGJhc2VkIG9uIGEgTm9ybWFsIGFwcHJveGltYXRpb247Ci0gZm9yIEdMKE0pTXMsIHJ1biB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBib3VuZGFyaWVzIChub3QgdGhlIHN0YW5kYXJkIGVycm9ycykgdGhyb3VnaCB0aGUgaW52ZXJzZS1saW5rIGZ1bmN0aW9uLgoKIyMjIGxtZQoKYGBge3IgbG1lcHJlZCxjYWNoZT1UUlVFLG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkobmxtZSkgCmZtMSA8LSBsbWUoZGlzdGFuY2UgfiBhZ2UqU2V4LCByYW5kb20gPSB+IDEgKyBhZ2UgfCBTdWJqZWN0LAogICAgICAgICAgIGRhdGEgPSBPcnRob2RvbnQpIApwbG90KE9ydGhvZG9udCxhc3A9ImZpbGwiKSAjIyBwbG90IHJlc3BvbnNlcyBieSBpbmRpdmlkdWFsCiMjIG5vdGUgdGhhdCBleHBhbmQuZ3JpZCgpIG9yZGVycyBmYWN0b3IgbGV2ZWxzIGJ5ICpvcmRlciBvZgojIyBhcHBlYXJhbmNlKiAtLSBtdXN0IG1hdGNoIGxldmVscyhPcnRob2RvbnQkU2V4KQpuZXdkYXQgPC0gZXhwYW5kLmdyaWQoYWdlPWMoOCwxMCwxMiwxNCksIFNleD1jKCJGZW1hbGUiLCJNYWxlIikpIApuZXdkYXQkcHJlZCA8LSBwcmVkaWN0KGZtMSwgbmV3ZGF0LCBsZXZlbCA9IDApCgojIyBbLTJdIGRyb3BzIHJlc3BvbnNlIGZyb20gZm9ybXVsYQpEZXNpZ25tYXQgPC0gbW9kZWwubWF0cml4KGZvcm11bGEoZm0xKVstMl0sIG5ld2RhdCkKcHJlZHZhciA8LSBkaWFnKERlc2lnbm1hdCAlKiUgdmNvdihmbTEpICUqJSB0KERlc2lnbm1hdCkpIApuZXdkYXQkU0UgPC0gc3FydChwcmVkdmFyKSAKbmV3ZGF0JFNFMiA8LSBzcXJ0KHByZWR2YXIrZm0xJHNpZ21hXjIpCgpsaWJyYXJ5KGdncGxvdDIpIApwZCA8LSBwb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjQpIApnMCA8LSBnZ3Bsb3QobmV3ZGF0LGFlcyh4PWFnZSx5PXByZWQsY29sb3VyPVNleCkpKyAKICAgZ2VvbV9wb2ludChwb3NpdGlvbj1wZCkKY211bHQgPC0gMiAgIyMgY291bGQgdXNlIDEuOTYgaW5zdGVhZApnMCArIGdlb21fbGluZXJhbmdlKGFlcyh5bWluPXByZWQtY211bHQqU0UseW1heD1wcmVkK2NtdWx0KlNFKSwgcG9zaXRpb249cGQpCgojIyBwcmVkaWN0aW9uIGludGVydmFscyAKZzAgKyBnZW9tX2xpbmVyYW5nZShhZXMoeW1pbj1wcmVkLWNtdWx0KlNFMix5bWF4PXByZWQrY211bHQqU0UyKSwgcG9zaXRpb249cGQpIApgYGAKCkEgc2ltaWxhciBhbnN3ZXIgaXMgbGFpZCBvdXQgaW4gdGhlIHJlc3BvbnNlcyB0byB0aGlzIFtTdGFja092ZXJmbG93IHF1ZXN0aW9uXShodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE0MzU4ODExL2V4dHJhY3QtcHJlZGljdGlvbi1iYW5kLWZyb20tbG1lLWZpdCkuCgojIyMgbG1lNAoKQ3VycmVudCB2ZXJzaW9ucyBvZiBsbWU0IGhhdmUgYSBgcHJlZGljdGAgbWV0aG9kLgoKYGBge3IgbG1lNHByZWQsY2FjaGU9VFJVRX0KbGlicmFyeShsbWU0KQpsaWJyYXJ5KGdncGxvdDIpCmRhdGEoIk9ydGhvZG9udCIscGFja2FnZT0iTUVNU1MiKQpmbTEgPC0gbG1lcigKCWZvcm11bGEgPSBkaXN0YW5jZSB+IGFnZSpTZXggKyAoYWdlfFN1YmplY3QpCgksIGRhdGEgPSBPcnRob2RvbnQKKQpuZXdkYXQgPC0gZXhwYW5kLmdyaWQoCglhZ2U9Yyg4LDEwLDEyLDE0KQoJLCBTZXg9YygiRmVtYWxlIiwiTWFsZSIpCgksIGRpc3RhbmNlID0gMAopCm5ld2RhdCRkaXN0YW5jZSA8LSBwcmVkaWN0KGZtMSxuZXdkYXQscmUuZm9ybT1OQSkKbW0gPC0gbW9kZWwubWF0cml4KHRlcm1zKGZtMSksbmV3ZGF0KQojIyBvciBuZXdkYXQkZGlzdGFuY2UgPC0gbW0gJSolIGZpeGVmKGZtMSkKcHZhcjEgPC0gZGlhZyhtbSAlKiUgdGNyb3NzcHJvZCh2Y292KGZtMSksbW0pKQp0dmFyMSA8LSBwdmFyMStWYXJDb3JyKGZtMSkkU3ViamVjdFsxXSAgIyMgbXVzdCBiZSBhZGFwdGVkIGZvciBtb3JlIGNvbXBsZXggbW9kZWxzCmNtdWx0IDwtIDIgIyMgY291bGQgdXNlIDEuOTYKbmV3ZGF0IDwtIGRhdGEuZnJhbWUoCgluZXdkYXQKCSwgcGxvID0gbmV3ZGF0JGRpc3RhbmNlLWNtdWx0KnNxcnQocHZhcjEpCgksIHBoaSA9IG5ld2RhdCRkaXN0YW5jZStjbXVsdCpzcXJ0KHB2YXIxKQoJLCB0bG8gPSBuZXdkYXQkZGlzdGFuY2UtY211bHQqc3FydCh0dmFyMSkKCSwgdGhpID0gbmV3ZGF0JGRpc3RhbmNlK2NtdWx0KnNxcnQodHZhcjEpCikKI3Bsb3QgY29uZmlkZW5jZQpnMCA8LSBnZ3Bsb3QobmV3ZGF0LCBhZXMoeD1hZ2UsIHk9ZGlzdGFuY2UsIGNvbG91cj1TZXgpKStnZW9tX3BvaW50KCkKZzAgKyBnZW9tX3BvaW50cmFuZ2UoYWVzKHltaW4gPSBwbG8sIHltYXggPSBwaGkpKSsKICAgIGxhYnModGl0bGU9IkNJIGJhc2VkIG9uIGZpeGVkLWVmZmVjdHMgdW5jZXJ0YWludHkgT05MWSIpCiNwbG90IHByZWRpY3Rpb24KZzAgKyBnZW9tX3BvaW50cmFuZ2UoYWVzKHltaW4gPSB0bG8sIHltYXggPSB0aGkpKSsKICAgIGxhYnModGl0bGU9IkNJIGJhc2VkIG9uIEZFIHVuY2VydGFpbnR5ICsgUkUgdmFyaWFuY2UiKQpybSgiT3J0aG9kb250IikgIyMgY2xlYW4gdXAKYGBgCgojIyMgZ2xtbVRNQgoKYGBge3IgZ2xtbVRNQnByZWQsY2FjaGU9VFJVRX0KbGlicmFyeShnbG1tVE1CKQpkYXRhKE9ydGhvZG9udCxwYWNrYWdlPSJubG1lIikKZm0yIDwtIGdsbW1UTUIoZGlzdGFuY2UgfiBhZ2UqU2V4ICsgKGFnZSB8IFN1YmplY3QpLAogICAgICAgICAgICAgICAgZGF0YSA9IE9ydGhvZG9udCwKICAgICAgICAgICAgICAgIGZhbWlseT0iZ2F1c3NpYW4iKQoKIyMgbWFrZSBwcmVkaWN0aW9uIGRhdGEgZnJhbWUKbmV3ZGF0IDwtIGV4cGFuZC5ncmlkKGFnZT1jKDgsMTAsMTIsMTQpLCBTZXg9YygiRmVtYWxlIiwiTWFsZSIpKQojIyBkZXNpZ24gbWF0cml4IChmaXhlZCBlZmZlY3RzKQptbSA8LSBtb2RlbC5tYXRyaXgoZGVsZXRlLnJlc3BvbnNlKHRlcm1zKGZtMikpLG5ld2RhdCkKIyMgbGluZWFyIHByZWRpY3RvciAoZm9yIEdMTU1zLCBiYWNrLXRyYW5zZm9ybSB0aGlzIHdpdGggdGhlCiMjICBpbnZlcnNlIGxpbmsgZnVuY3Rpb24gKGUuZy4gcGxvZ2lzKCkgZm9yIGJpbm9taWFsLCBiZXRhOwojIyAgZXhwKCkgZm9yIFBvaXNzb24sIG5lZ2F0aXZlIGJpbm9taWFsCm5ld2RhdCRkaXN0YW5jZSA8LSBkcm9wKG1tICUqJSBmaXhlZihmbTIpW1siY29uZCJdXSkKcHJlZHZhciA8LSBkaWFnKG1tICUqJSB2Y292KGZtMilbWyJjb25kIl1dICUqJSB0KG1tKSkKbmV3ZGF0JFNFIDwtIHNxcnQocHJlZHZhcikgCm5ld2RhdCRTRTIgPC0gc3FydChwcmVkdmFyK3NpZ21hKGZtMileMikKYGBgCgooUHJvYmFibHkgb3Zlcmx5IGNvbXBsaWNhdGVkKSBgZ2dwbG90YCBjb2RlOgpgYGB7ciBnZ3Bsb3R9CmxpYnJhcnkoZ2dwbG90Mik7ICB0aGVtZV9zZXQodGhlbWVfYncoKSkKcGQgPC0gcG9zaXRpb25fZG9kZ2Uod2lkdGg9MC40KQpnMCA8LSBnZ3Bsb3QoT3J0aG9kb250LGFlcyh4PWFnZSx5PWRpc3RhbmNlLGNvbG91cj1TZXgpKSsKICAgIHN0YXRfc3VtKGFscGhhPTAuMixhZXMoc2l6ZT0uLm4uLikpKwogICAgc2NhbGVfc2l6ZV9jb250aW51b3VzKGJyZWFrcz0xOjQscmFuZ2U9YygyLDUpKQpnMSA8LSBnMCtnZW9tX2xpbmUoZGF0YT1uZXdkYXQscG9zaXRpb249cGQpKwogICAgZ2VvbV9wb2ludChkYXRhPW5ld2RhdCxzaGFwZT0xNyxzaXplPTMscG9zaXRpb249cGQpCiMjIGNvbmZpZGVuY2UgaW50ZXJ2YWxzCmcyIDwtIGcxICsgZ2VvbV9saW5lcmFuZ2UoZGF0YT1uZXdkYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHltaW49ZGlzdGFuY2UtMipTRSx5bWF4PWRpc3RhbmNlKzIqU0UpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGx3ZD0yLCBwb3NpdGlvbj1wZCkKIyMgcHJlZGljdGlvbiBpbnRlcnZhbHMgCmcyICsgZ2VvbV9saW5lcmFuZ2UoZGF0YT1uZXdkYXQsCiAgICAgICAgICAgICAgICAgICAgYWVzKHltaW49ZGlzdGFuY2UtMipTRTIseW1heD1kaXN0YW5jZSsyKlNFMiksIHBvc2l0aW9uPXBkKQpgYGAKClRoZSBgZWZmZWN0c2AsIGBlbW1lYW5zYCwgYW5kIGBzalBsb3RgIHBhY2thZ2VzIGFyZSBhbHNvIHVzZWZ1bCBoZXJlLgoKIyMgQ29uZmlkZW5jZSBpbnRlcnZhbHMgb24gY29uZGl0aW9uYWwgbWVhbnMvQkxVUHMvcmFuZG9tIGVmZmVjdHMKCiMjIyBsbWU0IAoKKEZyb20gSGFyb2xkIERvcmFuLCB1cGRhdGVkIGJ5IEFzc2FmIE9yb24gTm92LiAyMDEzOikKCklmIHlvdSB3YW50IHRoZSBzdGFuZGFyZCBlcnJvcnMgb2YgdGhlIGNvbmRpdGlvbmFsIG1lYW5zLCB5b3UgY2FuIGV4dHJhY3QgdGhlbSBhcyBmb2xsb3dzOgpgYGB7ciBzdGRlcl9jb25kbWVhbnN9CmxpYnJhcnkobG1lNCkKZm0xIDwtIGxtZXIoUmVhY3Rpb24gfiBEYXlzICsgKERheXN8U3ViamVjdCksIHNsZWVwc3R1ZHkpCmNWIDwtIHJhbmVmKGZtMSwgY29uZFZhciA9IFRSVUUpICAgCmBgYApgY1ZgIGlzIGEgbGlzdDsgZWFjaCBlbGVtZW50IGlzIGEgZGF0YSBmcmFtZSBjb250YWluaW5nIHRoZSBjb25kaXRpb25hbCBtb2RlcyBmb3IgYSBwYXJ0aWN1bGFyIGdyb3VwaW5nIGZhY3Rvci4gSWYgeW91IHVzZSBzY2FsYXIgcmFuZG9tIGVmZmVjdHMgKHR5cGljYWxseSByYW5kb20gaW50ZXJjZXB0cyksIHRoZW4gc3BlY2lmeWluZyBgcmFuZWYoLi4uLGRyb3A9VFJVRSlgIHdpbGwgcmV0dXJuIHRoZSBjb25kaXRpb25hbCBtb2RlcyBhcyBhIHNpbmdsZSBuYW1lZCB2ZWN0b3IgaW5zdGVhZC4KClRoZSBjb25kaXRpb25hbCB2YXJpYW5jZXMgYXJlIHJldHVybmVkIGFzIGFuIGF0dHJpYnV0ZSBvZiB0aGUgY29uZGl0aW9uYWwgbW9kZXMuCkl0IG1heSBiZSBlYXNpZXN0IHRvIHVzZSBgYXMuZGF0YS5mcmFtZShjVilgLCBvciBgYnJvb20ubWl4ZWQ6OnRpZHkoZm0xLCBlZmZlY3RzPSJyYW5fdmFscyIpYCwgdG8gZXh0cmFjdCBhbGwgb2YgdGhlIGNvbmRpdGlvbmFsIG1lYW5zIGFuZCBzdGFuZGFyZCBkZXZpYXRpb25zLgoKT3IsIGRpZ2dpbmcgaW4gdG8gdGhlIGRhdGEgc3RydWN0dXJlIGJ5IGhhbmQ6IGlmIHdlIHNldApgYGB7ciByYW52YXJ9CnJhbnZhciA8LSBhdHRyKGNWW1sxXV0sICJwb3N0VmFyIikKYGBgCnRoZW4gYHJhbnZhcmAgaXMgYSAzLUQgYXJyYXkgKHRoZSBhdHRyaWJ1dGUgaXMgc3RpbGwgY2FsbGVkIGBwb3N0VmFyYCwgcmF0aGVyIHRoYW4gYGNvbmRWYXJgLCBmb3IgaGlzdG9yaWNhbCByZWFzb25zL2JhY2t3YXJkIGNvbXBhdGliaWxpdHkpLiBJbmRpdmlkdWFsLWxldmVsIGNvdmFyaWFuY2UgbWF0cmljZXMgb2YgdGhlIGNvbmRpdGlvbmFsIG1vZGVzIHdpbGwgc2l0IG9uIHRoZSBgWywsaV1gIGZhY2VzLiBGb3IgZXhhbXBsZSwgYHJhbnZhclssLDFdYCBpcyB0aGUgdmFyaWFuY2UtY292YXJpYW5jZSBtYXRyaXggb2YgdGhlIGNvbmRpdGlvbmFsIGRpc3RyaWJ1dGlvbiBmb3IgdGhlIGZpcnN0IGdyb3VwLCBzbwpgYGB7ciBzcXJ0ZGlhZ3JhbnZhcnN9CnNxcnQoZGlhZyhyYW52YXJbLCwxXSkpCmBgYAp3aWxsIHByb3ZpZGUgdGhlIGludGVyY2VwdCBhbmQgc2xvcGUgc3RhbmRhcmQgc3RhbmRhcmQgZGV2aWF0aW9ucyBmb3IgdGhlIGZpcnN0IGdyb3VwJ3MgY29uZGl0aW9uYWwgbW9kZXMuIElmIHlvdSBoYXZlIGEgc2NhbGFyIHJhbmRvbSBlZmZlY3QgYW5kIHVzZWQgYGRyb3A9VFJVRWAgaW4gYHJhbmVmKClgLCB0aGVuIHlvdSB3aWxsIChtZXJjaWZ1bGx5KSByZWNlaXZlIG9ubHkgYSB2ZWN0b3Igb2YgaW5kaXZpZHVhbCB2YXJpYW5jZXMgaGVyZSAob25lIGZvciBlYWNoIGxldmVsIG9mIHRoZSBncm91cGluZyBmYWN0b3IpLiBUaGUgZm9sbG93aW5nIGluY2FudGF0aW9uIHdpbGwgZ2l2ZSBhIG1hdHJpeCBvZiBjb25kaXRpb25hbCB2YXJpYW5jZXMgd2l0aCBvbmUgcm93IGZvciBlYWNoIGdyb3VwIGFuZCBvbmUgY29sdW1uIGZvciBlYWNoIHBhcmFtZXRlcnM6CmBgYHtyIHJhbnNlfQpuZyA8LSBkaW0ocmFudmFyKVszXQpucCA8LSBkaW0ocmFudmFyKVsyXQptbSA8LSBtYXRyaXgocmFudmFyW2NiaW5kKHJlcChzZXEobnApLG5nKSwKICAgICAgICAgICAgIHJlcChzZXEobnApLG5nKSwKICAgICAgICAgICAgIHJlcChuZyxlYWNoPW5wKSldLAogICAgICAgYnlyb3c9VFJVRSwKICAgICAgIG5yb3c9bmcpCmBgYCAgICAgICAgICAgICAKCkdldHRpbmcgdGhlIHVuY2VydGFpbnR5IG9mIHRoZSBjb2VmZmljaWVudHMgKGkuZS4sIHdoYXQncyByZXR1cm5lZCBieSBgY29lZigpYDogdGhlIHN1bSBvZiB0aGUgZml4ZWQtZWZmZWN0IGFuZCByYW5kb20tZWZmZWN0IHByZWRpY3Rpb25zIGZvciBhIHBhcnRpY3VsYXIgbGV2ZWwpIGlzIG5vdCAoYWxhcykgY3VycmVudGx5IGVhc3kgd2l0aCBgbG1lNGAuIElmIHRoZSBmaXhlZCBhbmQgcmFuZG9tIGVmZmVjdHMgd2VyZSBpbmRlcGVuZGVudCB0aGVuIHdlIGNvdWxkIHNpbXBseSBhZGQgdGhlIGNvbmRpdGlvbmFsIHZhcmlhbmNlIGFuZCB0aGUgdmFyaWFuY2Ugb2YgdGhlIGZpeGVkLWVmZmVjdCBwcmVkaWN0aW9ucywgYnV0IHRoZXkgYXJlbid0IGluIGdlbmVyYWwuIFRoZXJlIGlzIGEgbG9uZyBbci1zaWctbWl4ZWQtbW9kZWxzIG1haWxpbmcgbGlzdCB0aHJlYWRdKGh0dHBzOi8vc3RhdC5ldGh6LmNoL3BpcGVybWFpbC9yLXNpZy1taXhlZC1tb2RlbHMvMjAxM3ExLzAxOTc5NS5odG1sKSB0aGF0IGRpc2N1c3NlcyB0aGUgaXNzdWVzLCBmb2N1c2luZyBvbiAoMSkgaG93IHRvIGV4dHJhY3QgdGhlIGNvdmFyaWFuY2UgYmV0d2VlbiBmaXhlZC1lZmZlY3QgZXN0aW1hdGUgYW5kIHRoZSByYW5kb20tZWZmZWN0IHByZWRpY3Rpb247ICgyKSB3aGV0aGVyIHRoaXMgdmFsdWUgKHRoZSBjb3ZhcmlhbmNlIGJldHdlZW4gYW4gKmVzdGltYXRlZCogcGFyYW1ldGVyIGFuZCBhICpwcmVkaWN0ZWQqIG1vZGUgb2YgYSBjb25kaXRpb25hbCBkaXN0cmlidXRpb24gb2YgYSByYW5kb20gdmFyaWFibGUpIGV2ZW4gbWFrZXMgc2Vuc2UgaW4gYSBmcmVxdWVudGlzdCBmcmFtZXdvcmsuIElmIHlvdSdyZSB3aWxsaW5nIHRvICphc3N1bWUqIGluZGVwZW5kZW5jZSBvZiB0aGUgY29uZGl0aW9uYWwgdmFyaWFuY2UgYW5kIHRoZSBmaXhlZC1lZmZlY3Qgc2FtcGxpbmcgdmFyaWFuY2UsIHRoZW4gKGUuZy4pIHRoZSB2YXJpYW5jZSBvZiB0aGUgaW50ZXJjZXB0cyBmb3IgZWFjaCBncm91cCB3b3VsZCBiZSB0aGUgc3VtIG9mIHRoZSBmaXhlZC1lZmZlY3QgaW50ZXJjZXB0IHZhcmlhbmNlIGFuZCB0aGUgY29uZGl0aW9uYWwgdmFyaWFuY2Ugb2YgdGhlIGludGVyY2VwdCBmb3IgZWFjaCBncm91cDoKCmBgYHtyIGNvbWJ9CnZjb3YoZm0xKVsxLDFdK21tWywxXQpgYGAKCiMjIFBvd2VyIGFuYWx5c2lzCgpQb3dlciBhbmFseXNpcyBmb3IgKEcpTE1NcyBpcyBtb3N0bHkgZG9uZSBieSBzaW11bGF0aW9uLCBhbHRob3VnaAp0aGVyZSBhcmUgc29tZSBjbG9zZWQtZm9ybSBzb2x1dGlvbnMgYW5kIGFwcHJveGltYXRpb25zLCBlLmcuCkBzbmlqZGVyc19zdGFuZGFyZF8xOTkzIChTbmlqZGVycyBoYXMgbGlua3MgdG8gcHJvZ3JhbXMgYW5kIG90aGVyIHJlc291cmNlcwpvbiBbaGlzIHdlYiBwYWdlXShodHRwczovL3d3dy5zdGF0cy5veC5hYy51ay9+c25pamRlcnMvbXVsdGlsZXZlbC5odG0pKS4gVGhlcmUgYXJlIHJlc291cmNlcyBhbmQgYml0cyBvZiBjb2RlIGV4YW1wbGVzIHNwcmVhZCBhbGwgb3ZlciB0aGUgaW50ZXJuZXQuIGUuZy4gW2hlcmVdKGh0dHBzOi8vcnB1YnMuY29tL2Jib2xrZXIvMTE3MDMpLgoKQGthaW5fcHJhY3RpY2FsXzIwMTUgYW5kIEBqb2huc29uX3Bvd2VyXzIwMTUgYXJlIHBlZXItcmV2aWV3ZWQgcGFwZXJzCnRoYXQgZGlzY3VzcyBwb3dlciBhbmFseXNpcyB2aWEgc2ltdWxhdGlvbiBpbiBtb3JlIGRldGFpbC4KCmBgYHtyIGV2YWw9RkFMU0V9CmxpYnJhcnkoc29zKTsgZmluZEZuKCJ7cG93ZXIgYW5hbHlzaXN9IG1peGVkIHNpbXVsYXRpb24iKQpgYGAKbG9jYXRlcyB0aGUgYGZ1bGxmYWN0YCwgYHBhbW1gLCBgc2ltcmAsIGFuZCBgc2ltZ2xtYCBwYWNrYWdlcy4KRGVwZW5kaW5nIG9uIHRoZSBnb2FsLCBvbmUgb2YgdGhlc2UgcGFja2FnZXMgbWF5IGhhdmUgc3VmZmljaWVudApmbGV4aWJpbGl0eSB0byBkbyB3aGF0IHlvdSB3YW50LgoKIyBNb2RlbCBzZWxlY3Rpb24gYW5kIGF2ZXJhZ2luZwoKIyMgQ2FuIEkgdXNlIEFJQyBmb3IgbWl4ZWQgbW9kZWxzPyAgSG93IGRvIEkgY291bnQgdGhlIG51bWJlciBvZiBkZWdyZWVzIG9mIGZyZWVkb20gZm9yIGEgcmFuZG9tIGVmZmVjdD8KCi0gWWVzLCB3aXRoIGNhdXRpb24uCi0gSXQgZGVwZW5kcyBvbiB0aGUgImxldmVsIG9mIGZvY3VzIiAoKnNlbnN1KiBAc3BpZWdlbGhhbHRlcl9iYXllc2lhbl8yMDAyKSB3aGV0aGVyIChlLmcuKSBhIHNpbmdsZSByYW5kb20tZWZmZWN0IHZhcmlhbmNlIHNob3VsZCBiZSBjb3VudGVkIGFzIDEgZGVncmVlIG9mIGZyZWVkb20gKGkuZS4sIHRoZSB2YXJpYW5jZSBwYXJhbWV0ZXIgb3IgYXMgYSB2YWx1ZSBiZXR3ZWVuIDEgYW5kIE4tMSAod2hlcmUgTiBpcyB0aGUgbnVtYmVyIG9mIGdyb3Vwcyk6IHNlZSBAdmFpZGFfY29uZGl0aW9uYWxfMjAwNSBhbmQgQGdyZXZlbl9iZWhhdmlvdXJfMjAxMC4gIElmIHlvdSBhcmUgaW50ZXJlc3RlZCBpbiBwb3B1bGF0aW9uLWxldmVsIHByZWRpY3Rpb24vaW5mZXJlbmNlLCB0aGVuIHRoZSBmb3JtZXIgKGNhbGxlZCAqbWFyZ2luYWwgQUlDKiBbbUFJQ10pOyBpZiBpbmRpdmlkdWFsLWxldmVsIHByZWRpY3Rpb24vaW5mZXJlbmNlIChpLmUuLCB1c2luZyB0aGUgQkxVUHMvY29uZGl0aW9uYWwgbW9kZXMpLCB0aGVuIHRoZSBsYXR0ZXIgKGNhbGxlZCAqY29uZGl0aW9uYWwgQUlDKiBbY0FJQ10pLiBHcmV2ZW4gYW5kIEtuZWliIHByZXNlbnQgcmVzdWx0cyBmb3IgbGluZWFyIG1vZGVscywgZ2l2aW5nIGEgdmVyc2lvbiBvZiBjQUlDIHRoYXQgaXMgYm90aCBjb21wdXRhdGlvbmFsbHkgZWZmaWNpZW50IGFuZCB0YWtlcyB1bmNlcnRhaW50eSBpbiB0aGUgZXN0aW1hdGlvbiBvZiB0aGUgdmFyaWFuY2VzIGludG8gYWNjb3VudC4gIChCb2IgTydIYXJhIGhhcyBhIHZlcnkgbmljZSwgaWxsdXN0cmF0aXZlIFtibG9nIHBvc3RdKGh0dHA6Ly9kZWVwdGhvdWdodHNhbmRzaWxsaW5lc3MuYmxvZ3Nwb3QuY2EvMjAwNy8xMi9mb2N1cy1vbi1kaWMuaHRtbCkgb24gdGhpcyB0b3BpYyBpbiB0aGUgY29udGV4dCBvZiBESUMgLi4uKQotIGluIGNhc2VzIHdoZW4gdGVzdGluZyBhIHZhcmlhbmNlIHBhcmFtZXRlciwgQUlDIG1heSBiZSBzdWJqZWN0IHRvIHRoZSBzYW1lIGtpbmRzIG9mIGJvdW5kYXJ5IGVmZmVjdHMgYXMgbGlrZWxpaG9vZCByYXRpbyB0ZXN0IHAtdmFsdWVzIChpLmUuLCBBSUNzIG1heSBiZSBjb25zZXJ2YXRpdmUvb3ZlcmZpdCBzbGlnaHRseSB3aGVuIHRoZSBuZXN0ZWQgcGFyYW1ldGVyIHZhbHVlIGlzIG9uIHRoZSBib3VuZGFyeSBvZiB0aGUgZmVhc2libGUgc3BhY2UpLiBAZ3JldmVuX2JlaGF2aW91cl8yMDEwIGV4cGxvcmUgdGhlIHByb2JsZW1zIHdpdGggbUFJQyBpbiB0aGlzIGNvbnRleHQsIGJ1dCBkbyBub3Qgc3VnZ2VzdCBhIHNvbHV0aW9uICh0aGV5IHBvaW50IG91dCB0aGF0IEBodWdoZXNfbW9kZWxfMjAwMyBwcmVzZW50IGEgJ29uZS1zaWRlZCcgQUlDLCBidXQgbm90IG9uZSB0aGF0IGRlYWxzIHdpdGggdGhlIG5vbi1pbmRlcGVuZGVuY2Ugb2YgZGF0YSBwb2ludHMuICBJIGhhdmVuJ3QgcmVhZCBIdWdoZXMgYW5kIEtpbmcsIEkgc2hvdWxkIGdvIGRvIHRoYXQpLgotIEFJQyBhbHNvIGluaGVyaXRzIHRoZSBwcmltYXJ5IHByb2JsZW0gb2YgbGlrZWxpaG9vZCByYXRpbyB0ZXN0cyBpbiB0aGUgR0xNTSBjb250ZXh0IC0tIHRoYXQgaXMsIHRoYXQgTFJUcyBhcmUgYXN5bXB0b3RpYyB0ZXN0cy4gQSBmaW5pdGUtc2l6ZSBjb3JyZWN0aW9uIGZvciBBSUMgZG9lcyBleGlzdCAoQUlDYykgLS0gYnV0IGl0IHdhcyBkZXZlbG9wZWQgaW4gdGhlIGNvbnRleHQgb2YgbGluZWFyIG1vZGVscy4gQXMgZmFyIGFzIEkga25vdyBpdHMgYWRlcXVhY3kgaW4gdGhlIEdMTU0gY2FzZSBoYXMgbm90IGJlZW4gZXN0YWJsaXNoZWQuIFNlZSBlLmcuIEByaWNoYXJkc190ZXN0aW5nXzIwMDUgZm9yIGNhdXRpb24gYWJvdXQgQUlDYyBpbiB0aGUgR0xNIChub3QgR0xNTSkgY2FzZS4KLSBsbWU0IGFuZCBubG1lIGNvdW50IHBhcmFtZXRlcnMgZm9yIEFJQyhjKSBhcyBmb2xsb3dzOgogICAgLSB0aGUgbnVtYmVyIG9mIGZpeGVkLWVmZmVjdCBwYXJhbWV0ZXJzIGlzIHN0cmFpZ2h0Zm9yd2FyZCAodGhlIGxlbmd0aCBvZiB0aGUgZml4ZWQtZWZmZWN0IHBhcmFtZXRlciB2ZWN0b3IgYmV0YSwgaS5lLiBgbGVuZ3RoKGZpeGVmKG1vZGVsKSlgKQoJLSBlYWNoIHJhbmRvbSB0ZXJtIGluIHRoZSBtb2RlbCB3aXRoICRxJCBjb21wb25lbnRzIGNvdW50cyBmb3IgJHEocSsxKS8yJCBwYXJhbWV0ZXJzIC0tIGZvciBleGFtcGxlLCBhIHRlcm0gb2YgdGhlIGZvcm0gKHNsb3BlfGdyb3VwKSBoYXMgMyBwYXJhbWV0ZXJzIChpbnRlcmNlcHQgdmFyaWFuY2UsIHNsb3BlIHZhcmlhbmNlLCBjb3JyZWxhdGlvbiBiZXR3ZWVuIGludGVyY2VwdCBhbmQgc2xvcGUpLgogICAgLSBtb2RlbHMgdGhhdCB1c2UgYSBzY2FsZSBwYXJhbWV0ZXIgKGUuZy4gdGhlIHZhcmlhbmNlIHBhcmFtZXRlciBvZiBsaW5lYXIgbWl4ZWQgbW9kZWxzLCBvciB0aGUgc2NhbGUgcGFyYW1ldGVyIG9mIGEgR2FtbWEgR0xNTSAtLSBzdGFuZGFyZCBHTE1NcyBzdWNoIGFzIGJpbm9taWFsIGFuZCBQb2lzc29uIGRvIG5vdCkgZ2V0IGFuIGV4dHJhIHBhcmFtZXRlciBjb3VudGVkLiBXaGV0aGVyIHRvIGFkZCBudWlzYW5jZSBwYXJhbWV0ZXJzIG9yIG5vdCwgc3VjaCBhcyB0aGUgcmVzaWR1YWwgdmFyaWFuY2UgcGFyYW1ldGVyIChlc3RpbWF0ZWQgYmFzZWQgb24gdGhlIHJlc2lkdWFsIHZhcmlhbmNlLCByYXRoZXIgdGhhbiBhbiBleHBsaWNpdCBwYXJhbWV0ZXIgaW4gdGhlIG9wdGltaXphdGlvbikgaXMgYXMgZmFyIGFzIEkga25vdyBhbiBvcGVuIHF1ZXN0aW9uLiAgSW4gdGhlIGNsYXNzaWMgQUlDIGNvbnRleHQgaXQgZG9lc24ndCBtYXR0ZXIgYXMgbG9uZyBhcyBvbmUgaXMgY29uc2lzdGVudC4gIEluIHRoZSBBSUNjIGNvbnRleHQsIEkgZG9uJ3QgdGhpbmsgYW55b25lIHJlYWxseSBrbm93cyB0aGUgYW5zd2VyIC4uLiBhZGRpbmcgKzEgZm9yIHRoZSByZXNpZHVhbCB2YXJpYW5jZSBwYXJhbWV0ZXIgKGFzIGxtZTQgZG9lcykgd291bGQgbWFrZSB0aGUgbW9kZWwgc2VsZWN0aW9uIHByb2Nlc3Mgc2xpZ2h0bHkgbW9yZSBjb25zZXJ2YXRpdmUuCgojIE1vZGVsIHN1bW1hcmllcyAoZ29vZG5lc3Mtb2YtZml0LCBkZWNvbXBvc2l0aW9uIG9mIHZhcmlhbmNlLCBldGMuKQoKIyMgSG93IGRvIEkgY29tcHV0ZSBhIGNvZWZmaWNpZW50IG9mIGRldGVybWluYXRpb24gKCRSXjIkKSwgb3IgYW4gYW5hbG9ndWUsIGZvciAoRylMTU1zPwoKIyMjIFByb2JsZW0KCigqVGhpcyB0b3BpYyBhcHBsaWVzIHRvIGJvdGggTE1NcyBhbmQgR0xNTXMsIHBlcmhhcHMgbW9yZSBzbyB0byBMTU1zLCBiZWNhdXNlIHRoZSBpc3N1ZXMgYXJlIGV2ZW4gaGFyZGVyIGZvciBHTE1Ncy4qKQoKUmVzZWFyY2hlcnMgb2Z0ZW4gd2FudCB0byBrbm93IGlmIHRoZXJlIGlzIGEgc2ltcGxlIChvciBhdCBsZWFzdCBpbXBsZW1lbnRlZC1pbi1SKSB3YXkgdG8gZ2V0IGFuIGFuYWxvZ3VlIG9mICRSXjIkIG9yIGFub3RoZXIgc2ltcGxlIGdvb2RuZXNzLW9mLWZpdCBtZXRyaWMgZm9yIExNTXMgb3IgR0xNTXMuIFRoaXMgaXMgYSBjaGFsbGVuZ2luZyBxdWVzdGlvbiBpbiBib3RoIHRoZSBHTE0gYW5kIExNTSB3b3JsZHMgKGFuZCB0aGVyZWZvcmUgZG91Ymx5IHNvIGZvciBHTE1NcyksIGJlY2F1c2UgaXQgdHVybnMgb3V0IHRoYXQgdGhlIHdvbmRlcmZ1bCBzaW1wbGljaXR5IG9mICRSXjIkIGJyZWFrcyBkb3duIGluIHRoZSBleHRlbnNpb24gdG8gR0xNcyBvciBMTU1zLiBJZiB5b3UncmUgdHJ5aW5nIHRvIHF1YW50aWZ5ICJmcmFjdGlvbiBvZiB2YXJpYW5jZSBleHBsYWluZWQiIGluIHRoZSBHTE0gY29udGV4dCwgc2hvdWxkIHlvdSBpbmNsdWRlIG9yIGV4Y2x1ZGUgc2FtcGxpbmcgdmFyaWF0aW9uIChlLmcuLCBQb2lzc29uIHZhcmlhdGlvbiBhcm91bmQgdGhlIGV4cGVjdGVkIG1lYW4pPyBbQWNjb3JkaW5nIHRvIGFuIGBzb3M6OmZpbmRGbmAgc2VhcmNoIGZvciAiTmFnZWxrZXJrZSIsIG9uZSBvZiB0aGUgY29tbW9uIHNvbHV0aW9ucyB0byB0aGlzIHByb2JsZW0sIHRoZSBgTG9nUmVnUjJgIGZ1bmN0aW9uIGluIHRoZSBgZGVzY3JgIHBhY2thZ2UgY29tcHV0ZXMgc2V2ZXJhbCBkaWZmZXJlbnQgInBzZXVkby0kUl4yJCIgbWVhc3VyZXMgZm9yIGxvZ2lzdGljIHJlZ3Jlc3Npb24uXSAgSWYgeW91J3JlIHRyeWluZyB0byBxdWFudGlmeSBpdCBpbiB0aGUgTE1NIGNvbnRleHQsIHNob3VsZCB5b3UgaW5jbHVkZSBvciBleGNsdWRlIHZhcmlhdGlvbiBvZiBkaWZmZXJlbnQgcmFuZG9tLWVmZmVjdHMgdGVybXM/CgpUaGUgc2FtZSBxdWVzdGlvbnMgYXBwbHkgbW9yZSBnZW5lcmFsbHkgdG8gZGVjb21wb3NpdGlvbiBvZiB2YXJpYW5jZSAoaS5lLiB0cnlpbmcgdG8gYXNzZXNzIHRoZSBjb250cmlidXRpb24gb2YgdmFyaW91cyBtb2RlbCBjb21wb25lbnRzIHRvIHRoZSBvdmVyYWxsIGZpdCwgbm90IGp1c3QgdHJ5aW5nIHRvIGFzc2VzcyB0aGUgb3ZlcmFsbCBnb29kbmVzcy1vZi1maXQgb2YgdGhlIG1vZGVsKTsgdGhlcmUgaXMgdW5saWtlbHkgdG8gYmUgYSBzaW5nbGUgcmVjaXBlIHRoYXQgZG9lcyBldmVyeXRoaW5nIHlvdSB3YW50LgoKVGhpcyBoYXMgYmVlbiBkaXNjdXNzZWQgYXQgdmFyaW91cyB0aW1lcyBvbiB0aGUgbWFpbGluZyBsaXN0cy4gW1RoaXMgdGhyZWFkXShodHRwOi8vdGhyZWFkLmdtYW5lLm9yZy9nbWFuZS5jb21wLmxhbmcuci5sbWU0LmRldmVsLzMyODEpIGFuZCBbdGhpcyB0aHJlYWRdKGh0dHA6Ly90aHJlYWQuZ21hbmUub3JnL2dtYW5lLmNvbXAubGFuZy5yLmxtZTQuZGV2ZWwvNjg0KSBvbiB0aGUgci1zaWctbWl4ZWQtbW9kZWxzICBtYWlsaW5nIGxpc3QgYXJlIGdvb2Qgc3RhcnRpbmcgcG9pbnRzLCBhbmQgW3RoaXMgcG9zdF0oaHR0cDovL3RocmVhZC5nbWFuZS5vcmcvZ21hbmUuY29tcC5sYW5nLnIubG1lNC5kZXZlbC8yMTQzKSBpcyB1c2VmdWwgdG9vLgoKSW4gb25lIG9mIHRob3NlIHRocmVhZHMsIERvdWcgQmF0ZXMgc2FpZDoKCj4gQXNzdW1pbmcgdGhhdCBvbmUgd2FudHMgdG8gZGVmaW5lIGFuIFJeMiBtZWFzdXJlLCBJIHRoaW5rIGFuCj4gYXJndW1lbnQgY291bGQgYmUgbWFkZSBmb3IgdHJlYXRpbmcgdGhlIHBlbmFsaXplZCByZXNpZHVhbCBzdW0gb2YKPiBzcXVhcmVzIGZyb20gYSBsaW5lYXIgbWl4ZWQgbW9kZWwgaW4gdGhlIHNhbWUgd2F5IHRoYXQgd2UgY29uc2lkZXIgdGhlCj4gcmVzaWR1YWwgc3VtIG9mIHNxdWFyZXMgZnJvbSBhIGxpbmVhciBtb2RlbC4gIE9yIG9uZSBjb3VsZCB1c2UganVzdAo+IHRoZSByZXNpZHVhbCBzdW0gb2Ygc3F1YXJlcyB3aXRob3V0IHRoZSBwZW5hbHR5IG9yIHRoZSBtaW5pbXVtCj4gcmVzaWR1YWwgc3VtIG9mIHNxdWFyZXMgb2J0YWluYWJsZSBmcm9tIGEgZ2l2ZW4gc2V0IG9mIHRlcm1zLCB3aGljaAo+IGNvcnJlc3BvbmRzIHRvIGFuIGluZmluaXRlIHByZWNpc2lvbiBtYXRyaXguICBJIGRvbid0IGtub3csIHJlYWxseS4KPiBJdCBkZXBlbmRzIG9uIHdoYXQgeW91IGFyZSB0cnlpbmcgdG8gY2hhcmFjdGVyaXplLgoKIyMjIFNpbXBsZS9jcnVkZSBzb2x1dGlvbnMKCkluIG9uZSBvZiB0aG9zZSB0aHJlYWRzLCBKYXJyZXR0IEJ5cm5lcyBjb250cmlidXRlZCB0aGUgZm9sbG93aW5nIGNvZGU6CmBgYHtyIHIyY29ycn0KcjIuY29yci5tZXIgPC0gZnVuY3Rpb24obSkgewogICBsbWZpdCA8LSAgbG0obW9kZWwucmVzcG9uc2UobW9kZWwuZnJhbWUobSkpIH4gZml0dGVkKG0pKQogICBzdW1tYXJ5KGxtZml0KSRyLnNxdWFyZWQKfQpgYGAKCiRcT21lZ2FeMl8wJCBbQHh1X21lYXN1cmluZ18yMDAzXSwgd2hpY2ggaXMgYWxtb3N0IHRoZSBzYW1lLCBpcyBiYXNlZCBvbiBjb21wYXJpbmcgdGhlIHJlc2lkdWFsIHZhcmlhbmNlIG9mIHRoZSBmdWxsIG1vZGVsIGFnYWluc3QgdGhlIHJlc2lkdWFsIHZhcmlhbmNlIG9mIGEgKGZpeGVkKSBpbnRlcmNlcHQtb25seSBudWxsIG1vZGVsOiAKCmBgYHtyIHJlc3ZhcixldmFsPUZBTFNFfQoxLXZhcihyZXNpZHVhbHMobSkpL3Zhcihtb2RlbC5yZXNwb25zZShtb2RlbC5mcmFtZShtKSkpCmBgYAoKQW5vdGhlciBwb3NzaWJpbGl0eSBpcyB0aGUgc3F1YXJlZCBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSByZXNwb25zZSB2YXJpYWJsZSBhbmQgdGhlIHByZWRpY3RlZCB2YWx1ZXM6CgpgYGB7ciByZXNjb3JzcSwgZXZhbD1GQUxTRX0KY29yKG1vZGVsLnJlc3BvbnNlKG1vZGVsLmZyYW1lKG0pKSxwcmVkaWN0KG0sdHlwZT0icmVzcG9uc2UiKSleMgpgYGAKCiMjIyBTb3BoaXN0aWNhdGVkIHNvbHV0aW9ucwoKQGdlbG1hbl9iYXllc2lhbl8yMDA2IHByb3Bvc2UvZGlzY3VzcyBCYXllc2lhbiBtZWFzdXJlcyBvZiAkUl4yJCAoSSBkb24ndCBrbm93IGlmIGFueW9uZSBoYXMgY3JlYXRlZCBhIGNhbm5lZCBpbXBsZW1lbnRhdGlvbiBvZiB0aGVzZSBtZWFzdXJlcyBpbiBSKS4KQG5ha2FnYXdhX2dlbmVyYWxfMjAxMyBhbmQgQGpvaG5zb25fZXh0ZW5zaW9uXzIwMTQgaGF2ZSBhbHNvIHByb3Bvc2VkIGEgZ2VuZXJhbCBtZXRob2RvbG9neSBmb3IgY29tcHV0aW5nICRSXjIkOyBKLiBMZWZjaGVjayBnaXZlcyBleGFtcGxlcyBbaGVyZV0oaHR0cHM6Ly9qb25sZWZjaGVjay5uZXQvMjAxMy8wMy8xMy9yMi1mb3ItbGluZWFyLW1peGVkLWVmZmVjdHMtbW9kZWxzLykgYW5kIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vanNsZWZjaGUvcGllY2V3aXNlU0VNL2Jsb2IvbWFzdGVyL1JFQURNRS5tZCNnZXQtcjItZm9yLWluZGl2aWR1YWwtbW9kZWxzKSwgYmFzZWQgb24gaGlzIGltcGxlbWVudGF0aW9uIGluIHRoZSBgcGllY2V3aXNlU0VNYCBwYWNrYWdlIChbQ1JBTl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3BpZWNld2lzZVNFTS9pbmRleC5odG1sKSwgW0dpdGh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL2pzbGVmY2hlL3BpZWNld2lzZVNFTSkpLiBTZWUgYWxzbyBAamFlZ2VyX3IyXzIwMTcsIEByaWdodHNfcXVhbnRpZnlpbmdfMjAxOCAuLi4KCkEgcmVsYXRlZCBxdWVzdGlvbiBpcyBob3cgdG8gcXVhbnRpZnkgInJlcGVhdGFiaWxpdHkiIChpLmUuLCByYXRpb3Mgb2YgdmFyaWFuY2UgYXQgZGlmZmVyZW50IGxldmVscykgaW4gR0xNTXMsIGVzcGVjaWFsbHkgaG93IHRvIGNvbXB1dGUgdGhlICJyZXNpZHVhbCBlcnJvciIgdGVybSBmb3IgR0xNTXM6IHNlZSBAbmFrYWdhd2FfcmVwZWF0YWJpbGl0eV8yMDEwIGFuZCB0aGUgW3JwdFIgcGFja2FnZV0oaHR0cDovL3JwdHIuci1mb3JnZS5yLXByb2plY3Qub3JnLykuCgpUaGUgYm90dG9tIGxpbmUgaXMgdGhhdCB0aGVyZSBhcmUgc29tZSBzaW1wbGUgcmVjaXBlcyAoYW5kIHNvbWUgbW9yZSBjb21wbGV4IHJlY2lwZXMgdGhhdCBtYXkgb3IgbWF5IG5vdCBoYXZlIGJlZW4gY29kZWQgdXAgYnkgc29tZW9uZSksIGJ1dCB0aGF0ICcnJ3lvdSBoYXZlIHRvIHRoaW5rIGNhcmVmdWxseSBhYm91dCB3aGF0IGluZm9ybWF0aW9uIHlvdSB3YW50IHRvIGdldCBvdXQgb2YgdGhlIGNvZWZmaWNpZW50IG9mIGRldGVybWluYXRpb24nJycsIGJlY2F1c2Ugbm8gcmVjaXBlIHdpbGwgaGF2ZSBhbGwgb2YgdGhlIHByb3BlcnRpZXMgb2YgJFJeMiQgaW4gdGhlIHNpbXBsZSBsaW5lYXIgbW9kZWwgY2FzZS4KCioqUGFja2FnZXMvZnVuY3Rpb25zKio6IFNlZSBbYHBlcmZvcm1hbmNlOjpyMigpYF0oaHR0cHM6Ly9lYXN5c3RhdHMuZ2l0aHViLmlvL3BlcmZvcm1hbmNlL3JlZmVyZW5jZS9yMi5odG1sKSwgYE11TUluOjpyLnNxdWFyZWRHTE1NKClgLCB0aGUgW2ByMmdsbW1gIHBhY2thZ2VdKGh0dHBzOi8vQ1JBTi5SLXByb2plY3Qub3JnL3BhY2thZ2U9cjJnbG1tKSwgdGhlIHN0YW5kYWxvbmUgW3IyTUxNIGZ1bmN0aW9uXShodHRwczovL215LnZhbmRlcmJpbHQuZWR1L2phc29ucmlnaHRzL3NvZnR3YXJlL3IyTUxNKSwgc3R1ZmYgaW4gdGhlIGBwaWVjZXdpc2VTRU1gIHBhY2thZ2UsIFtgcHN5Y2hvOjpSMl9uYWthZ2F3YWBdKGh0dHA6Ly9maW56aS5wc3ljaC51cGVubi5lZHUvUi9saWJyYXJ5L3BzeWNoby9odG1sL1IyX25ha2FnYXdhLmh0bWwpLCBbcGFydFIyXShodHRwczovL2dpdGh1Yi5jb20vbWFzdG9mZmVsL3BhcnRSMikgcGFja2FnZSAuLi4gKHRyeSBlLmcuIGBzb3M6OmZpbmRGbigiTmFrYWdhd2EgU2NoaWVsemV0aCIpYCBmb3IgYW4gdXAtdG8tZGF0ZSBsaXN0IC4uLikKCiMjIFZhcmlhYmxlIGltcG9ydGFuY2UKCi0gVGhlIHNpbXBsZXN0IHdheSB0byBnZXQgKHdpdGhpbi1zdHVkeSkgbWVhc3VyZXMgb2YgdmFyaWFibGUgaW1wb3J0YW5jZSBpcyB0byBzdGFuZGFyZGl6ZSB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcyAoc2NhbGluZyBieSAxIFNEIG9yIDJTRDogQGdlbG1hbl9zY2FsaW5nXzIwMDgsIEBzY2hpZWx6ZXRoX3NpbXBsZV8yMDEwKQotIFRoZSBgcjJnbG1tYCBwYWNrYWdlIGNvbXB1dGVzIHBhcnRpYWwgJFJeMiQgdmFsdWVzIGZvciBmaXhlZCBlZmZlY3RzIChvbmx5IGZvciBgbG1lcmAsIGBsbWVgLCBhbmQgYGdsbW1QUUxgIG1vZGVscykKLSBIZW5yaWsgU2luZ21hbm4gaGFzIGEgZGV0YWlsZWQgYW5zd2VyIFtoZXJlXShodHRwczovL2FmZXguc2luZ21hbm4uc2NpZW5jZS9mb3J1bXMvdG9waWMvY29tcHV0ZS1lZmZlY3Qtc2l6ZXMtZm9yLW1peGVkLW9iamVjdHMpIG9uIHdoeSBzdGFuZGFyZGl6ZWQgbWVhc3VyZXMgc3VjaCBhcyBwYXJ0aWFsIGV0YS1zcXVhcmVkIGFyZSBwcm9ibGVtYXRpYzoKCiAgICA+IFRoZSBmYWN0IHRoYXQgY2FsY3VsYXRpbmcgYSBnbG9iYWwgbWVhc3VyZSBvZiBtb2RlbCBmaXQgKHN1Y2ggYXMgUjIpIGlzIGFscmVhZHkgcmlkZGxlZCB3aXRoIGNvbXBsaWNhdGlvbnMgYW5kIHRoYXQgbm8gc2ltcGxlIHNpbmdsZSBudW1iZXIgY2FuIGJlIGZvdW5kLCBzaG91bGQgYmUgYSBoaW50IHRoYXQgZG9pbmcgc28gZm9yIGEgc3Vic2V0IG9mIHRoZSBtb2RlbCBwYXJhbWV0ZXJzIChpLmUuLCBtYWluLWVmZmVjdHMgb3IgaW50ZXJhY3Rpb25zKSBpcyBldmVuIG1vcmUgZGlmZmljdWx0LiBHaXZlbiB0aGlzLCBJIHdvdWxkIG5vdCByZWNvbW1lbmQgdG8gdHJ5IGZpbmRpbmcgYSBtZWFzdXJlIG9mIHN0YW5kYXJkaXplZCBlZmZlY3Qgc2l6ZXMgZm9yIG1peGVkIG1vZGVscy4KCiAgICBIZSBldmVuIGdpdmVzIHN1Z2dlc3RlZCB3b3JkaW5nIGZvciByZXNwb25kaW5nIHRvIHJldmlld2VycyB3aG8gd2FudCBzdGFuZGFyZGl6ZWQgbWVhc3VyZXMhCgojIyBEbyBJIGhhdmUgdG8gc3BlY2lmeSB0aGUgbGV2ZWxzIG9mIGZpeGVkIGVmZmVjdHMgaW4gbG1lcj8KCk5vLiBTZWUgRG91ZyBCYXRlcyByZXBseSB0byB0aGlzIHF1ZXN0aW9uIFtoZXJlXShodHRwOi8vci43ODk2OTUubjQubmFiYmxlLmNvbS9sbWU0LWFuZC1WYXJpYWJsZS1sZXZlbC1kZXRlY3Rpb24tdGQ4ODE2ODAuaHRtbCkKCiMgTWlzY2VsbGFuZW91cy9wcm9jZWR1cmFsCgojIyBQcm9udW5jaWF0aW9uIG9mIGBsbWVyYC9gZ2xtZXJgL2V0Yy4KCi0gYGxtZXJgOiBJIGhhdmUgaGVhcmQgImVsbCBlbW0gZWUgYXJyIiAoaS5lLiBwcm9ub3VuY2luZyBlYWNoIGxldHRlcik7ICJlbG1lciIgKHByb2JhYmx5IG1vc3QgY29tbW9uKTsgYW5kICJsZW11ciIKLSBgZ2xtZXJgOiAiZ2VlIGVsbCBlbW0gZWUgYXJyIiwgImdlZSBlbG1lciIsICJnbGltbWVyIiwgb3IgImdsZWFtZXIiCi0gZm9yIGBsbWVgIGFuZCBgbmxtZWAgcGVvcGxlIGp1c3Qgc2VlbSB0byBzcGVsbCBvdXQgdGhlIG5hbWVzIChyYXRoZXIgdGhhbiBzYXlpbmcgZS5nLiAibGVtbXkiIGFuZCAibmVsbXkiKQoKIyMgU3RvcmluZyBpbmZvcm1hdGlvbgoKUmVjZW50IHZlcnNpb25zIG9mIGBsbWU0YCBvdXRwdXQgY29udGFpbiBhbiBgQG9wdGluZm9gIHNsb3QgdGhhdCBzdG9yZXMgd2FybmluZ3MuCgpDb3BpZWQgZnJvbSBodHRwczovL3N0YXQuZXRoei5jaC9waXBlcm1haWwvci1oZWxwLzIwMTItRmVicnVhcnkvMzAyNzY3Lmh0bWwgOgoKPiBUaGVyZSdzIGEgc29tZXdoYXQgaGFjay1pc2ggc29sdXRpb24sIHdoaWNoIGlzIHRvIHVzZSBvcHRpb25zKHdhcm49MikgdG8gJ3VwZ3JhZGUnIHdhcm5pbmdzIHRvIGVycm9ycywgYW5kIHRoZW4gdXNlIHRyeSgpIG9yIHRyeUNhdGNoKCkgdG8gY2F0Y2ggdGhlbS4KCj4gTW9yZSBmYW5jaWx5LCBJIHVzZWQgY29kZSB0aGF0IGxvb2tlZCBzb21ldGhpbmcgbGlrZSB0aGlzIHRvIHNhdmUgd2FybmluZ3MgYXMgSSB3ZW50IGFsb25nIChzb3JyeSBhYm91dCB0aGUgPDwtICkgaW4gYSByZWNlbnQgc2ltdWxhdGlvbiBzdHVkeS4gIFlvdSBjb3VsZCBhbHNvIGNoZWNrIHckbWVzc2FnZSB0byBkbyBkaWZmZXJlbnQgdGhpbmdzIGluIHRoZSBjYXNlIG9mIGRpZmZlcmVudCB3YXJuaW5ncy4KCmBgYHtyIGNhdGNoX2Vycm9ycyxldmFsPUZBTFNFfQojIyBuLmIuIGhhdmUgdG8gc2V0IHVwIGEgM0Qgd2FybiBhcnJheSBmaXJzdCAuLi4Kd2l0aENhbGxpbmdIYW5kbGVycyh0cnlDYXRjaChmdW4obj1udmVjW2pdLHRhdT10YXV2ZWNbaV0sLi4uKSwKICAgICAgICAgICAgICAgIGVycm9yID0gZnVuY3Rpb24oZSkgewogICAgICAgICAgICAgICAgICB3YXJuW2ssaSxqXSA8PC0gcGFzdGUoIkVSUk9SOiIsZSRtZXNzYWdlKQogICAgICAgICAgICAgIE5BX2Fuc30pLAogICAgICAgICAgICAgICB3YXJuaW5nID0gZnVuY3Rpb24odykgewogICAgICAgICAgICAgICAgICB3YXJuW2ssaSxqXSA8PC0gdyRtZXNzYWdlCiAgICAgICAgICAgICAgICAgIGludm9rZVJlc3RhcnQoIm11ZmZsZVdhcm5pbmciKQogICAgICAgICAgICAgfSkKYGBgCgojIE1peGVkIG1vZGVsaW5nIHBhY2thZ2VzIAoKLSBhbHNvIHNlZSB0aGUgW3BhY2thZ2UgY29tcGFyaXNvbl0oaHR0cDovL2dsbW0ud2lraWRvdC5jb20vcGtnLWNvbXBhcmlzb24pIG9uIGBnbG1tLndpa2lkb3QuY29tYAoKIyMgV2hpY2ggUiBwYWNrYWdlcyAoZnVuY3Rpb25zKSBmaXQgR0xNTXM/CgotIE1BU1M6OmdsbW1QUUwgKHBlbmFsaXplZCBxdWFzaS1saWtlbGlob29kKQotIGxtZTQ6OmdsbWVyIChMYXBsYWNlIGFwcHJveGltYXRpb24gYW5kIGFkYXB0aXZlIEdhdXNzLUhlcm1pdGUgcXVhZHJhdHVyZSBbQUdIUV0pCi0gTUNNQ2dsbW0gKE1hcmtvdiBjaGFpbiBNb250ZSBDYXJsbykKLSBnbG1tTUwgKEFHSFEpCi0gZ2xtbUFLIChBR0hRPykKLSBnbG1tQURNQiAoTGFwbGFjZSkKLSBnbG1tIChmcm9tIEppbSBMaW5kc2V5J3MgYHJlcGVhdGVkYCBwYWNrYWdlOiBBR0hRKQotIGdhbWxzcy5teAotIEFTUkVNTC1SCi0gc2FicmVSCgojIyBTaG91bGQgSSB1c2UgYGFvdigpYCwgYG5sbWVgLCBvciBgbG1lNGAsIG9yIHNvbWUgb3RoZXIgcGFja2FnZT8KCi0gYGFvdigpYCAoaW4gdGhlIGBzdGF0c2AgcGFja2FnZSBpbiBiYXNlIFI6IGJhbGFuY2VkLCBvcnRob2dvbmFsIGRlc2lnbnMgb25seSAoUiBhbmFsb2d1ZSBvZiBTQVMgUFJPQyBHTE0pCi0gYG5sbWVgIChhbmFsb2d1ZSBvZiBTQVMgYFBST0MgTUlYRURgL2BOTE1JWEVEYCkKICAgIC0gYWxsb3dzIG1vcmUgY29tcGxleCBkZXNpZ25zIHRoYW4gYGFvdmAgKHVuYmFsYW5jZWQsIGhldGVyb3NjZWRhc3RpY2l0eSBhbmQvb3IgY29ycmVsYXRpb24gYW1vbmcgcmVzaWR1YWwgZXJyb3JzKQogICAgLSBtb3JlIG1hdHVyZSB0aGFuIGBsbWU0YAogICAgLSB3ZWxsLWRvY3VtZW50ZWQgW0BwaW5oZWlyb19taXhlZC1lZmZlY3RzXzIwMDBdCiAgICAtIGltcGxlbWVudHMgUi1zaWRlIGVmZmVjdHMgKGhldGVyb3NjZWRhc3RpY2l0eSBhbmQgY29ycmVsYXRpb24pCiAgICAtIGVzdGltYXRlcyAiZGVub21pbmF0b3IgZGVncmVlcyBvZiBmcmVlZG9tIiBmb3IgJEYkIHN0YXRpc3RpY3MsIGFuZCBoZW5jZSAkcCQgdmFsdWVzLCBmb3IgTE1NcyAoYnV0IHNlZSBhYm92ZSkKLSBgbG1lNGAgKGFsc28gU0FTIGBQUk9DIE1JWEVEYC9gTkxNSVhFRGApOiAKICAgIC0gZmFzdGVzdAogICAgLSBiZXN0IGZvciBjcm9zc2VkIGRlc2lnbnMgKGFsdGhvdWdoIHRoZXkgYXJlIHBvc3NpYmxlIGluIGBsbWVgKQogICAgLSBHTE1NcwogICAgLSBjdXR0aW5nLWVkZ2UgKGZvciBiZXR0ZXIgb3Igd29yc2UhKQogICAgLSBsaWtlbGlob29kIHByb2ZpbGVzCiAgICAtIHVzZSBgbG1lNGAgZm9yIEdMTU1zLCBvciBpZiB5b3UgaGF2ZSBiaWcgZGF0YSAodGhvdXNhbmRzIHRvIHRlbnMgb2YgdGhvdXNhbmRzIG9mIHJlY29yZHMpCgpUaGUgZm9sbG93aW5nIGlzIG1vZGlmaWVkIGZyb20gYSBjb250cmlidXRpb24gYnkgS2luZ3Nmb3JkIEpvbmVzLCBmb3VuZCAyMDEwLTAzLTE2CgojIyMgbGluZWFyIGFuZCBub25saW5lYXIgbWl4ZWQgbW9kZWxzCgotIFtsbWVdKGh0dHA6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2xtZTQvaW5kZXguaHRtbCkgLS0gTGluZWFyIG1peGVkLWVmZmVjdHMgbW9kZWxzIHVzaW5nIFM0IGNsYXNzZXMKLSBgbG1tYCAtLSBMaW5lYXIgbWl4ZWQgbW9kZWxzCi0gYG5sbWVgIC0tIExpbmVhciBhbmQgTm9ubGluZWFyIE1peGVkIEVmZmVjdHMgTW9kZWxzCi0gYHNhYnJlUmAKLSBbcmVncmVzc10oaHR0cDovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcmVncmVzcy9pbmRleC5odG1sKSBMaW5lYXIgbWl4ZWQgbW9kZWxzCgojIyMgR0xNTXMKLSBnbG1tQUsgLS0gR2VuZXJhbGl6ZWQgTGluZWFyIE1peGVkIE1vZGVscwotIE1BU1MgLS0gTWFpbiBQYWNrYWdlIG9mIFZlbmFibGVzIGFuZCBSaXBsZXkncyBNQVNTIChzZWUgZnVuY3Rpb24gZ2xtbVBRTCkKLSBNQ01DZ2xtbSAtLSBNQ01DIEdlbmVyYWxpc2VkIExpbmVhciBNaXhlZCBNb2RlbHMKLSBsbWU0IChnbG1lcikKLSBnbG1tTUwKLSBnYW1sc3MubXgKLSBzYWJyZVIKIAojIyMgQWRkaXRpdmUgYW5kIGdlbmVyYWxpemVkLWFkZGl0aXZlIG1peGVkIG1vZGVscwotIGFtZXIgLS0gQWRkaXRpdmUgbWl4ZWQgbW9kZWxzIHdpdGggbG1lNAotIGdhbW00IC0tIEdlbmVyYWxpemVkIGFkZGl0aXZlIG1peGVkIG1vZGVscyB1c2luZyBtZ2N2IGFuZCBsbWU0Ci0gbWdjdiAoZ2FtbSBmdW5jdGlvbiwgdmlhIGdsbW1QUUwgaW4gTUFTUyBwYWNrYWdlKQotIGdhbWxzcy5teAoKIyMjIEhpZXJhcmNoaWNhbCBHTE1zCi0gaGdsbSAtLSBoZ2xtIGlzIHVzZWQgdG8gZml0IGhpZXJhcmNoaWNhbCBnZW5lcmFsaXplZCBsaW5lYXIgbW9kZWxzCi0gSEdMTU1NIC0tIEhpZXJhcmNoaWNhbCBHZW5lcmFsaXplZCBMaW5lYXIgTW9kZWxzCgojIyMgZGlhZ25vc3RpYyBhbmQgbW9kZWxpbmcgZnJhbWV3b3JrcwotIGluZmx1ZW5jZS5NRSAtLSBUb29scyBmb3IgZGV0ZWN0aW5nIGluZmx1ZW50aWFsIGRhdGEgaW4gbWl4ZWQgZWZmZWN0cyBtb2RlbHMKLSBhcm0gLS0gRGF0YSBBbmFseXNpcyBVc2luZyBSZWdyZXNzaW9uIGFuZCBNdWx0aWxldmVsL0hpZXJhcmNoaWNhbCBNb2RlbHMKLSBwYW1tIC0tIFBvd2VyIGFuYWx5c2lzIGZvciByYW5kb20gZWZmZWN0cyBpbiBtaXhlZCBtb2RlbHMKLSBSTFJzaW0gLS0gRXhhY3QgKFJlc3RyaWN0ZWQpIExpa2VsaWhvb2QgUmF0aW8gdGVzdHMgZm9yIG1peGVkIGFuZCBhZGRpdGl2ZSBtb2RlbHMKLSBucGRlIC0tIE5vcm1hbGlzZWQgcHJlZGljdGlvbiBkaXN0cmlidXRpb24gZXJyb3JzIGZvciBub25saW5lYXIgbWl4ZWQtZWZmZWN0IG1vZGVscwotIG11bHRpbGV2ZWwgLS0gTXVsdGlsZXZlbCBGdW5jdGlvbnMgKHBzeWNob2xvZ3ktb3JpZW50ZWQ7IHdpdGhpbi1ncm91cCBhZ3JlZW1lbnQsIHJhbmRvbSBncm91cCByZXNhbXBsaW5nLCBldGMuKQotIGxhbmd1YWdlUgotIHBia3J0ZXN0IC0tIHBhcmFtZXRyaWMgYm9vdHN0cmFwIGFuZCBLZW53YXJkLVJvZ2VyIHRlc3RzCgojIyMgZGF0YSBhbmQgZXhhbXBsZXMKLSBNRU1TUyAtLSBEYXRhIHNldHMgZnJvbSBNaXhlZC1lZmZlY3RzIE1vZGVscyBpbiBTCi0gbWxtUmV2IC0tIEV4YW1wbGVzIGZyb20gTXVsdGlsZXZlbCBNb2RlbGxpbmcgU29mdHdhcmUgUmV2aWV3Ci0gU0FTbWl4ZWQgLS0gRGF0YSBzZXRzIGZyb20gIlNBUyBTeXN0ZW0gZm9yIE1peGVkIE1vZGVscyIKCiMjIyBleHRlbnNpb25zCi0gbG1lU3BsaW5lcyAtLSBsbWVTcGxpbmVzCi0gbG1lYyAtLSBMaW5lYXIgTWl4ZWQtRWZmZWN0cyBNb2RlbHMgd2l0aCBDZW5zb3JlZCBSZXNwb25zZXMKLSBraW5zaGlwIC0tIG1peGVkLWVmZmVjdHMgQ294IG1vZGVscywgc3BhcnNlIG1hdHJpY2VzLCBhbmQgbW9kZWxpbmcgZGF0YSBmcm9tIGxhcmdlIHBlZGlncmVlcwotIGNveG1lIC0tIE1peGVkIEVmZmVjdHMgQ294IE1vZGVscwotIG9yZGluYWwgLS0gUmVncmVzc2lvbiBNb2RlbHMgZm9yIE9yZGluYWwgRGF0YQotIHBobW0gLS0gUHJvcG9ydGlvbmFsIEhhemFyZHMgTWl4ZWQtZWZmZWN0cyBNb2RlbCAoUEhNTSkKLSBwZWRpZ3JlZW1tIC0tIFBlZGlncmVlLWJhc2VkIG1peGVkLWVmZmVjdHMgbW9kZWxzCi0gKHNlZSBhbHNvIE1DTUNnbG1tIGZvciBwZWRpZ3JlZS1iYXNlZCBhcHByb2FjaGVzKQotIGhlYXZ5IC0tIEVzdGltYXRpb24gaW4gdGhlIGxpbmVhciBtaXhlZCBtb2RlbCB1c2luZyBoZWF2eS10YWlsZWQgZGlzdHJpYnV0aW9ucwotIEdMTU1hcnAgLS0gR2VuZXJhbGl6ZWQgTGluZWFyIE11bHRpbGV2ZWwgTW9kZWwgd2l0aCBBUihwKSBFcnJvcnMgUGFja2FnZQotIGdsbW1sYXNzbyAtLSBwZW5hbGl6ZWQgR0xNTSBmaXR0aW5nCi0gc3BhdGlhbENvdmFyaWFuY2UgLS0gc3BhdGlhbCBjb3ZhcmlhbmNlIG1hdHJpeCBjYWxjdWxhdGlvbnMKCiMjIyBJbnRlcmZhY2VzIHRvIG90aGVyIHN5c3RlbXMKLSBnbG1tQlVHUyAtLSBHZW5lcmFsaXNlZCBMaW5lYXIgTWl4ZWQgTW9kZWxzIGFuZCBTcGF0aWFsIE1vZGVscyB3aXRoIEJVR1MKLSBJbnRlcmZhY2VzIHRvIFdpbkJVR1MvT3BlbkJVR1MvSkFHUyAocm9sbCB5b3VyIG93biBtb2RlbCBmaWxlKToKICogUjJXaW5CVUdTCiAqIHIyamFncwogKiByamFncwogKiBSQnVncwoKIyMjIG1vZGVsaW5nIGJhc2VkIG9uIExNTXMKCi0gYG5sbWVPREVgIC0tIE5vbi1saW5lYXIgbWl4ZWQtZWZmZWN0cyBtb2RlbGxpbmcgaW4gbmxtZSB1c2luZyBkaWZmZXJlbnRpYWwgZXF1YXRpb25zCi0gYGxvbmdSUGFydGAgLS0gUmVjdXJzaXZlIHBhcnRpdGlvbmluZyBvZiBsb25naXR1ZGluYWwgZGF0YSB1c2luZyBtaXhlZC1lZmZlY3RzIG1vZGVscwotIGBQU01gIC0tIE5vbi1MaW5lYXIgTWl4ZWQtRWZmZWN0cyBtb2RlbGxpbmcgdXNpbmcgU3RvY2hhc3RpYyBEaWZmZXJlbnRpYWwgRXF1YXRpb25zCgojIyBPZmYtQ1JBTiBtaXhlZCBtb2RlbGluZyBwYWNrYWdlczoKCiMjIyBSLWZvcmdlIGFuZCBHaXRodWI6CgotIGBnbG1tQURNQmAgKFItZm9yZ2UsIGludGVyZmFjZSB0byBBRCBNb2RlbCBCdWlsZGVyKQotIGBzcGlkYWAsIGBwM2RgIChHZW9yZ2VzIE1vbmV0dGUpCgojIyMgT3RoZXIgb3BlbiBzb3VyY2U6Ci0gW2Jlcm5vcl0oaHR0cDovL3d3dy5zdGF0LnVtbi5lZHUvZ2V5ZXIvYmVybm9yLyBiZXJub3IpIHBhY2thZ2UgKGxvZ2l0LW5vcm1hbCBmaXR0aW5nKSwgYnkgWXVuIEp1IFN1bmcgYW5kIENoYXJsZXMgSi4gR2V5ZXIKLSBgZ2xtbWAgKGluIEppbSBMaW5kc2V5J3MgYHJlcGVhdGVkYCBwYWNrYWdlOiBhdCBbTGluZHNleSdzIHdlYiBzaXRlXShodHRwOi8vd3d3LmNvbW1hbnN0ZXIuZXUvcmNvZGUuaHRtbCkKCgojIyMgQ29tbWVyY2lhbDoKLSBgT3Blbk14YCAtLSBBZHZhbmNlZCBTdHJ1Y3R1cmFsIEVxdWF0aW9uIE1vZGVsaW5nCi0gYEFTUmVtbC1SYCAoY29tbWVyY2lhbCwgYnV0IDMwIGRheXMnIGZyZWUgdXNlL2ZyZWUgbGljZW5zZSBmb3IgYWNhZGVtaWMgb3IgZGV2ZWxvcGluZy1jb3VudHJ5IHVzZSBhdmFpbGFibGUpLiAgVmVyeSBnb29kIGF0IGNvbXBsZXggTE1NcyAoZmFzdCwgZmxleGlibGUgY292YXJpYW5jZSBzdHJ1Y3R1cmVzLCBldGMuKSwgYnV0IG9ubHkgb2ZmZXJzIFBRTCBmb3IgR0xNTXMsIGFuZCB0aGUgbWFudWFsIHNheXM6IAo+IHdlIGNhbm5vdCByZWNvbW1lbmQgdGhlIHVzZSBvZiB0aGlzIHRlY2huaXF1ZSBmb3IgZ2VuZXJhbCB1c2UuIEl0IGlzIGluY2x1ZGVkIGluIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgYXNyZW1sKCkgZm9yIGFkdmFuY2VkIHVzZXJzLiBJdCBpcyBoaWdobHkgcmVjb21tZW5kZWQgdGhhdCBpdHMgdXNlIGJlIGFjY29tcGFuaWVkIGJ5IHNvbWUgZm9ybSBvZiBjcm9zcy12YWxpZGF0b3J5IGFzc2Vzc21lbnQgZm9yIHRoZSBzcGVjaWZpYyBkYXRhc2V0IGNvbmNlcm5lZC4iClJlc291cmNlczoKLSBbc2hvcnQgUiB3aWtpIHR1dG9yaWFsXShodHRwOi8vcndpa2kuc2Npdmlld3Mub3JnL2Rva3UucGhwP2lkPWd1aWRlczp0dXRvcmlhbHM6YXNyZW1sKQotIFtyZWZlcmVuY2UgbWFudWFsXShodHRwOi8vd3d3LnZzbmkuY28udWsvZG93bmxvYWRzL2FzcmVtbC9yZWxlYXNlMy9hc3JlbWwtUi5wZGYgcmVmZXJlbmNlIG1hbnVhbCkgKFBERikKLSBMdWlzIEFwaW9sYXphJ3MgW2FzcmVtbC1yIGNvb2tib29rXShodHRwOi8vYXBpb2xhemEubmV0L2FzcmVtbC1yLykKCgojIyBQYWNrYWdlIHZlcnNpb25zIHVzZWQKCmBgYHtyIHNlc3Npb25pbmZvfQpzZXNzaW9uSW5mbygpCmBgYAoKIyMgVG8gZG8KCi0gYWRkIGxpbmtzIHRvIGBtZXJEZXJpdmAgZm9yIHN0YW5kYXJkIGRldnMgb2YgdmFyaWFuY2VzLCByb2J1c3QgZXN0aW1hdGVzLiBNb3JlIG9uIFJpem9wb3Vsb3MgcGFja2FnZQotIHVwZGF0ZSBwYWNrYWdlIGRlc2NyaXB0aW9uczsgY3Jvc3MtbGluayB3aXRoIFtUYXNrIFZpZXddKGh0dHA6Ly9iYm9sa2VyLmdpdGh1Yi5pby9taXhlZG1vZGVscy1taXNjL01peGVkTW9kZWxzLmh0bWwpID8gYHJldGhpbmtpbmdgLCBgYnJtc2AsIC4uLgotIG1vcmUgb24gcG9zdC1hbmFseXNpcyAoYGJyb29tKC5taXhlZClgLCBgZW1tZWFuc2AsIGBtdWx0Y29tcGAsIC4uLikKLSBtb3JlIG9uIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLCBzaW11bGF0aW5nIGZyb20gY29uZGl0aW9uYWwgZGlzdHJpYnV0aW9ucywgZXRjLikKCiMgQmlibGlvZ3JhcGh5Cgo=