Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
insync / usr / lib / insync / PySide2 / Qt / resources / qtwebengine_resources_200p.pak
Size: Mime:
²Ø1ŽÙ1˜Ú1Û1ÃÜ1Ø)Ý1S<Þ1%Fß1bxà1¶{á1½â1¤ã1Çä1™å1"æ1£%ç1í.è1¬2é1ÒQê1}aë1ßqì1öxí1™‚î1،ï1”ð1â”ñ1ºšò1™ó1Ÿ ô1ó©õ1͹ö1QÏ÷1Âáø1kåù1Qêú1øøû1ýü1àý1Eþ19ÿ1n2" 2ñ"2E32Vœ2«c2´2-F2ˆX2Ga2ll2Xy2w2"(2B)2ÓBz?D{?J|?ÏT}?”Z~?Ó]?,_€?ëe?;m‚?(rƒ?Ã{„?í‚‹?劌?
?‘?°Ÿ“?L¡”?0¥•?ڥ–?SºÔb¾Õb*ÁÖbÄ×b#ÇØbÆÈÙbjÊœc@ΝcÈÒžcÕŸc†Ödy×d5dýWègÁ_égddêg¦mëg¯oìgöríg/xîg¨ñg™ƒògŠŠógôgƒ•õgwœög©Ÿ÷gC¤ùg.¨ûgZ«ýgN¯þg¦¹hí½h¡ÀhœÉhkÒh>Ô	h^×
hÛh˜âhÑãh²èh%ìhðh×õhŸ÷hŒúh´ýhÜ	h	h¡	 h	"h<6	#hæ7	$hÍ<	%hµA	&hãB	'hýD	(hF	)h6G	*h»G	+heH	,håI	-hkK	.hØL	/hpN	0h(P	1h§P	2hPQ	3h3R	4h’S	5hïT	6hMV	7hªW	8h	Y	9hgZ	:h/^	;hb	<häe	=hAg	>h¡h	?hj	@hö
AhF
Bh•
Chä	
Dhæ
Hh[
Ph¿
Qh=
Rh
ShÎ
Th–
UhŒ
Vh¯
WhÓ
Xhô
Yhè
ZhÞ
[h
\h%
]hF
^h:
_h
`hÆ 
p"
ïgZðgZøgdúgeügfÿgehfhehdhZhm
hmhwhxhyhxhyhxhw!hm<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no">
    
      <script>
        function setMessage(msg) {
          document.getElementById('message').textContent = msg;
        }
        function notifyDidFinishLoading() {
          if (plugin.didFinishLoading)
            plugin.didFinishLoading();

          if (plugin.didFinishIconRepositionForTesting)
            plugin.didFinishIconRepositionForTesting();
        }
      </script>
    
    
    <style>/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

html, body {
  -webkit-user-select: none;
  font-family: sans-serif;
  height: 100%;
  margin: 0;
  overflow: hidden;
  text-align: center;
  width: 100%;
}

h1 {
  display: none;
  font-size: 10pt;
  font-weight: normal;
  padding: 0pt 10pt;
}

p {
  font-size: 8pt;
  padding: 0pt 14pt;
}

#t {
  background-color: #f7f7f7;
  color: #646464;
}

#outer {
  align-items: center;
  box-sizing: border-box;
  display: flex;
  height: 100%;
  justify-content: center;
  position: absolute;
  width: 100%;
  flex-direction: column;
}

.icon {
  max-height: 100%;
  max-width: 100%;
  opacity: .3;
}

@media (orientation: landscape) and (min-height: 2em) and (min-width: 14em) {
  #outer {
    flex-direction: row;
  }
  .icon {
    max-height: 100%;
    max-width: 50%;
  }
  h1 {
    display: block;
  }
}

@media (min-height: 7em) and (min-width: 6em) {
  #outer {
    flex-direction: column;
  }
  .icon {
    max-height: 50%;
    max-width: 100%;
  }
  h1 {
    display: block;
  }
}
</style>
  </head>
  <body id="t" onload="notifyDidFinishLoading();">
    <div i18n-values="title:name" id="outer">
      <img class="icon"
           src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZmlsbD0iIzYyNjI2MiI+CiAgICA8cGF0aCBkPSJNMCAwaDQ4djQ4SDB6IiBmaWxsPSJub25lIi8+CiAgICA8cGF0aCBkPSJNNDEgMjJoLTN2LThjMC0yLjIxLTEuNzktNC00LTRoLThWN2MwLTIuNzYtMi4yNC01LTUtNXMtNSAyLjI0LTUgNXYzSDhjLTIuMjEgMC0zLjk4IDEuNzktMy45OCA0bC0uMDEgNy42SDdjMi45OCAwIDUuNCAyLjQyIDUuNCA1LjRTOS45OCAzMi40IDcgMzIuNEg0LjAxTDQgNDBjMCAyLjIxIDEuNzkgNCA0IDRoNy42di0zYzAtMi45OCAyLjQyLTUuNCA1LjQtNS40IDIuOTggMCA1LjQgMi40MiA1LjQgNS40djNIMzRjMi4yMSAwIDQtMS43OSA0LTR2LThoM2MyLjc2IDAgNS0yLjI0IDUtNXMtMi4yNC01LTUtNXoiLz4KPC9zdmc+Cg==">
      <h1 id="message">$i18n{message}</h1>
    </div>
  </body>
</html>
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no">
    <style>/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

html, body {
  -webkit-user-select: none;
  font-family: sans-serif;
  height: 100%;
  margin: 0;
  overflow: hidden;
  text-align: center;
  width: 100%;
}

h1 {
  display: none;
  font-size: 10pt;
  font-weight: normal;
  padding: 0pt 10pt;
}

p {
  font-size: 8pt;
  padding: 0pt 14pt;
}

#t {
  background-color: #f7f7f7;
  color: #646464;
}

#outer {
  align-items: center;
  box-sizing: border-box;
  display: flex;
  height: 100%;
  justify-content: center;
  position: absolute;
  width: 100%;
  flex-direction: column;
}

.icon {
  max-height: 100%;
  max-width: 100%;
  opacity: .3;
}

@media (orientation: landscape) and (min-height: 2em) and (min-width: 14em) {
  #outer {
    flex-direction: row;
  }
  .icon {
    max-height: 100%;
    max-width: 50%;
  }
  h1 {
    display: block;
  }
}

@media (min-height: 7em) and (min-width: 6em) {
  #outer {
    flex-direction: column;
  }
  .icon {
    max-height: 50%;
    max-width: 100%;
  }
  h1 {
    display: block;
  }
}
</style>
  </head>
  <body id="t" onLoad="insertLink()">
    <div i18n-values="title:name" id="outer">
      <img class="icon"
           src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZmlsbD0iIzYyNjI2MiI+CiAgICA8cGF0aCBkPSJNMCAwaDQ4djQ4SDB6IiBmaWxsPSJub25lIi8+CiAgICA8cGF0aCBkPSJNNDEgMjJoLTN2LThjMC0yLjIxLTEuNzktNC00LTRoLThWN2MwLTIuNzYtMi4yNC01LTUtNXMtNSAyLjI0LTUgNXYzSDhjLTIuMjEgMC0zLjk4IDEuNzktMy45OCA0bC0uMDEgNy42SDdjMi45OCAwIDUuNCAyLjQyIDUuNCA1LjRTOS45OCAzMi40IDcgMzIuNEg0LjAxTDQgNDBjMCAyLjIxIDEuNzkgNCA0IDRoNy42di0zYzAtMi45OCAyLjQyLTUuNCA1LjQtNS40IDIuOTggMCA1LjQgMi40MiA1LjQgNS40djNIMzRjMi4yMSAwIDQtMS43OSA0LTR2LThoM2MyLjc2IDAgNS0yLjI0IDUtNXMtMi4yNC01LTUtNXoiLz4KPC9zdmc+Cg==">
      <h1 id="message">$i18n{message}</h1>
    </div>
  </body>
</html>
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no">
    <style>
      html,
      body {
        height: 100%;
        width: 100%;
      }

      body {
        background-color: #f5f5f5;  /* google-grey-100 */
        margin: 0;
      }

      svg {
        height: 40px;
        width: 40px;
      }

      path {
        fill: #bdbdbd;  /* google-grey-400 */
      }

      #icon-container {
        align-items: center;
        display: flex;
        height: 100%;
        justify-content: center;
        width: 100%;
      }

      #footer {
        align-items: center;
        background-color: #4285f4;  /* google-blue-500 */
        border-radius: 2px;
        bottom: 0;
        color: white;
        display: flex;
        font-size: 14px;
        justify-content: space-between;
        left: 0;
        max-height: 52px;
        min-height: 20px;
        padding: 14px 24px;
        position: absolute;
        right: 0;
      }

      p,
      a {
        line-height: 20px;
      }

      p {
        font-family: Roboto;
        margin: 0;
      }

      a {
        font-family: Roboto Medium;
        margin-left: 48px;
        text-transform: uppercase;
      }

      a:link,
      a:visited {
        color: white;
        text-decoration: none;
      }

    </style>
  </head>
  <body>
    <div id="icon-container">
      <!-- Material Design PDF icon -->
      <svg viewbox="0 0 24 24">
        <path d="M7 11.5h1v-1H7v1zM19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-9.5 8.5c0 .83-.67 1.5-1.5 1.5H7v2H5.5V9H8c.83 0 1.5.67 1.5 1.5v1zm10-1H17v1h1.5V13H17v2h-1.5V9h4v1.5zm-5 3c0 .83-.67 1.5-1.5 1.5h-2.5V9H13c.83 0 1.5.67 1.5 1.5v3zm-2.5 0h1v-3h-1v3z"></path>
      </svg>
    </div>
    <div id="footer" i18n-values="title:name">
      <p>$i18n{fileName}</p>
      <a href="#" onclick="plugin.openPDF()">View PDF</a>
    </div>
  </body>
</html>
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, user-scalable=no">
  <script>
    function setMessage(msg) {
      document.getElementById('message').textContent = msg;
    }
    function notifyDidFinishLoading() {
      if (plugin.didFinishLoading)
        plugin.didFinishLoading();

      if (plugin.didFinishIconRepositionForTesting)
        plugin.didFinishIconRepositionForTesting();
    }
  </script>
  <style>/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

html, body {
  -webkit-user-select: none;
  font-family: sans-serif;
  height: 100%;
  margin: 0;
  overflow: hidden;
  text-align: center;
  width: 100%;
}

h1 {
  display: none;
  font-size: 10pt;
  font-weight: normal;
  padding: 0pt 10pt;
}

p {
  font-size: 8pt;
  padding: 0pt 14pt;
}

#t {
  background-color: #f7f7f7;
  color: #646464;
}

#outer {
  align-items: center;
  box-sizing: border-box;
  display: flex;
  height: 100%;
  justify-content: center;
  position: absolute;
  width: 100%;
  flex-direction: column;
}

.icon {
  max-height: 100%;
  max-width: 100%;
  opacity: .3;
}

@media (orientation: landscape) and (min-height: 2em) and (min-width: 14em) {
  #outer {
    flex-direction: row;
  }
  .icon {
    max-height: 100%;
    max-width: 50%;
  }
  h1 {
    display: block;
  }
}

@media (min-height: 7em) and (min-width: 6em) {
  #outer {
    flex-direction: column;
  }
  .icon {
    max-height: 50%;
    max-width: 100%;
  }
  h1 {
    display: block;
  }
}
</style>
  <style>
  #outer {
    cursor: pointer;
  }
  </style>
</head>
<body id="t" onload="notifyDidFinishLoading();">
  <div i18n-values="title:name" id="outer">
    <img class="icon"
         src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZmlsbD0iIzYyNjI2MiI+CiAgICA8cGF0aCBkPSJNMCAwaDQ4djQ4SDB6IiBmaWxsPSJub25lIi8+CiAgICA8cGF0aCBkPSJNNDEgMjJoLTN2LThjMC0yLjIxLTEuNzktNC00LTRoLThWN2MwLTIuNzYtMi4yNC01LTUtNXMtNSAyLjI0LTUgNXYzSDhjLTIuMjEgMC0zLjk4IDEuNzktMy45OCA0bC0uMDEgNy42SDdjMi45OCAwIDUuNCAyLjQyIDUuNCA1LjRTOS45OCAzMi40IDcgMzIuNEg0LjAxTDQgNDBjMCAyLjIxIDEuNzkgNCA0IDRoNy42di0zYzAtMi45OCAyLjQyLTUuNCA1LjQtNS40IDIuOTggMCA1LjQgMi40MiA1LjQgNS40djNIMzRjMi4yMSAwIDQtMS43OSA0LTR2LThoM2MyLjc2IDAgNS0yLjI0IDUtNXMtMi4yNC01LTUtNXoiLz4KPC9zdmc+Cg==">
    <h1 id="message">$i18n{message}</h1>
  </div>
  <script>
    window.onkeydown = function(e) {
      if (e.key == 'Enter' || e.key == ' ') {
        plugin.showPermissionBubble();
        e.preventDefault();
      }
    };

    document.getElementById('outer').onclick = function() {
      plugin.showPermissionBubble();
    };
  </script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<script>
  window.onload = function() {
    if (plugin.didFinishLoading)
      plugin.didFinishLoading();
  };

  window.onkeydown = function(e) {
    if (e.key == 'Enter' || e.key == ' ') {
      plugin.load();
      e.preventDefault();
    }
  };
</script>
<style>/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

html, body {
  -webkit-user-select: none;
  font-family: sans-serif;
  height: 100%;
  margin: 0;
  overflow: hidden;
  text-align: center;
  width: 100%;
}

h1 {
  display: none;
  font-size: 10pt;
  font-weight: normal;
  padding: 0pt 10pt;
}

p {
  font-size: 8pt;
  padding: 0pt 14pt;
}

#t {
  background-color: #f7f7f7;
  color: #646464;
}

#outer {
  align-items: center;
  box-sizing: border-box;
  display: flex;
  height: 100%;
  justify-content: center;
  position: absolute;
  width: 100%;
  flex-direction: column;
}

.icon {
  max-height: 100%;
  max-width: 100%;
  opacity: .3;
}

@media (orientation: landscape) and (min-height: 2em) and (min-width: 14em) {
  #outer {
    flex-direction: row;
  }
  .icon {
    max-height: 100%;
    max-width: 50%;
  }
  h1 {
    display: block;
  }
}

@media (min-height: 7em) and (min-width: 6em) {
  #outer {
    flex-direction: column;
  }
  .icon {
    max-height: 50%;
    max-width: 100%;
  }
  h1 {
    display: block;
  }
}
</style>
<style>
#outer {
  border: none;
  flex-direction: row;
  cursor: pointer;
}

#shielding {
  background-color: rgba(0, 0, 0, 0.5);
  height: 100%;
  left: 0px;
  position: absolute;
  top: 0px;
  width: 100%;
  z-index: 2;
}

#plugin-icon {
  opacity: 0.8;
  max-height: 100%;
  max-width: 100%;
  min-width: 0;
  min-height: 0;
}

#plugin-icon:hover {
  opacity: 0.95;
}

#poster {
  height: 100%;
  object-fit: contain;
  width: 100%;
  z-index: 1;
}

#inner-container {
  align-items: center;
  display: flex;
  height: 100%;
  justify-content: center;
  left: 0px;
  max-height: 100%;
  max-width: 100%;
  position: absolute;
  top: 0px;
  width: 100%;
  z-index: 2;
}
</style>
<base i18n-values="href:baseurl">
</head>

<body>
  <div i18n-values="title:name" id="outer">
    <img id="poster" i18n-values="srcset:poster">
    <div id="shielding"></div>
    <div id="inner-container"
         i18n-values=".style.width:visibleWidth;.style.height:visibleHeight">
      <img id="plugin-icon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAA8dJREFUaAXdWs9vEkEUZkvZQloNxJoY40kxJsDNo9GDif+Bf4CHpjEmJPoPeMce1F408dYjQePBgycv3vRG4GBMPREPLSlpCUWggN+3ncVl6PJrZ5a6k0x2Z2fnve/befPmzcwaIbVpGeLCyEsiG5L4Pso9kbu4nkj1CysSaAQ5trm5uV6pVB4eHx+/brVan3u93s9+v19Fbolc5TPW8R2+yzZsK2TIpPFYf6LS6Pb29rX9/f0NgPsIsA3kWVODbSmDsigT2TdCZjabvVyv158D9eGsyMe8f0iZlA0yJrK2FE4mkxer1eoTmMjvMYA8VVE2dVAXmHC8KU1mPp9Pdjqd755QztCYuqgTLJT1TrRYLN7T2Qtu/KiTukGGY8dTiu3t7T2CoqabMh+eN4kBLOjd5kpRQcIHrJNVCDIz94zJLoX4RfaEzK4pzGzqMRPmIFvEmJCRy2ViEg5gsjej2/PTO8lgJ5WJTbjmsePFpA+fJGzR9cQIFq4mZnBWPY8mJX84YhQRwJnhTFSEHXK7mcrNZvMdGjBQ1JqIFb0y4sUMBm3Q7Dl2KpVKd5jx1Xa1MgFWEWgO9UqEEagKxSSBL7WSy+WuIrJ9r0Kmmwxihi4uIwYpJkJxtzZTPxdE7IXVaq1We4bGWkyNmMHAmvGpMIQFzqppmg8GtNTccCXYSCQSb8rl8n2Q+aVG7D8pxEzs9pNlrtam/uQTXnT0iC2f14guUyN2yOcSO7TCpecEfFNXuxChHvY+Te0phCkzNWInB8uWw+HwLWrSnGxTe6vS1AT2JYtIJBK5oZmEU/yfTCbzbWtr62673f7grJjnXmC3xvoaupq7HUrSGNOScaoytSoEr1lMcHNB1uJDWZWpWdhtIj7g1qvCcltQUUe+pFfViHR+xBi82EY8Hn+Be9dodqTl8ANit1wix0ZtuE57ifPKFczMOyDxCtrmJRES2PvskR4WK7uYJZPa4Z8qiMIh3E6lUjuGYVz3qpPYyYHd2+t2uz+8CpyiPXVxQnycTqe/qCBBnQK7RaR7cHDwdQogXl5xmtJLCJrblGQQAjt39q2gcR22Ns8mNMfXUDpjHqEp6VqfNMSO/oCfzjBeaWzl/GojYTzonBwdHX0a0PJ+o82UnNAE5qHDosAsdUk0EJsPJBKY7SCSCcQGHYmEgrJlSi7B2MQmE6RAHCucUoEXC8JBj00mEEdvNplAHIbaZMxCoXDTzwMg6lJ9PG2TCcQPAzYZXv/7XzicZALxU41M6Fz85jR02uNEOOc9NzN4dMz1ObMsX9uPZ38BvwZw6z92PI4AAAAASUVORK5CYII=" />
    </div>
  </div>
  <script>
    document.getElementById('poster').onerror = function() {
      this.hidden = true;
    };

    document.getElementById('outer').onclick = function() {
      plugin.load();
    };

    window.resizePoster = function(marginLeft, marginTop, width, height) {
      var container = document.getElementById('inner-container');
      container.style.marginLeft = marginLeft;
      container.style.marginTop = marginTop;
      container.style.width = width;
      container.style.height = height;

      if (plugin.didFinishIconRepositionForTesting) {
        // Defer until reflow complete.
        window.setTimeout(function() {
          plugin.didFinishIconRepositionForTesting();
        });
      }
    };
  </script>
</body>
</html>
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the app API.

var appNatives = requireNative('app');
var process = requireNative('process');
var extensionId = process.GetExtensionId();
var logActivity = requireNative('activityLogger');

function wrapForLogging(fun) {
  if (!extensionId)
    return fun;  // nothing interesting to log without an extension

  return function() {
    // TODO(ataly): We need to make sure we use the right prototype for
    // fun.apply. Array slice can either be rewritten or similarly defined.
    logActivity.LogAPICall(extensionId, "app." + fun.name,
        $Array.slice(arguments));
    return $Function.apply(fun, this, arguments);
  };
}

// This becomes chrome.app
var app = {
  getIsInstalled: wrapForLogging(appNatives.GetIsInstalled),
  getDetails: wrapForLogging(appNatives.GetDetails),
  runningState: wrapForLogging(appNatives.GetRunningState)
};

// Tricky; "getIsInstalled" is actually exposed as the getter "isInstalled",
// but we don't have a way to express this in the schema JSON (nor is it
// worth it for this one special case).
//
// So, define it manually, and let the getIsInstalled function act as its
// documentation.
var isInstalled = wrapForLogging(appNatives.GetIsInstalled);
$Object.defineProperty(
    app, 'isInstalled',
    {
      __proto__: null,
      configurable: true,
      enumerable: true,
      get: function() { return isInstalled(); },
    });

// Called by app_bindings.cc.
function onInstallStateResponse(state, callbackId) {
  var callback = callbacks[callbackId];
  delete callbacks[callbackId];
  if (typeof callback == 'function') {
    try {
      callback(state);
    } catch (e) {
      console.error('Exception in chrome.app.installState response handler: ' +
                    e.stack);
    }
  }
}

// TODO(kalman): move this stuff to its own custom bindings.
var callbacks = { __proto__: null };
var nextCallbackId = 1;

function getInstallState(callback) {
  var callbackId = nextCallbackId++;
  callbacks[callbackId] = callback;
  appNatives.GetInstallState(callbackId);
}

$Object.defineProperty(
    app, 'installState',
    {
      __proto__: null,
      configurable: true,
      enumerable: true,
      value: wrapForLogging(getInstallState),
      writable: true,
    });

exports.$set('binding', app);
exports.$set('onInstallStateResponse', onInstallStateResponse);
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom bindings for the automation API.
var AutomationNode = require('automationNode').AutomationNode;
var AutomationRootNode = require('automationNode').AutomationRootNode;
var automation = apiBridge || require('binding').Binding.create('automation');
var automationInternal =
    getInternalApi ?
        getInternalApi('automationInternal') :
        require('binding').Binding.create('automationInternal').generate();
var exceptionHandler = require('uncaught_exception_handler');
var logging = requireNative('logging');
var nativeAutomationInternal = requireNative('automationInternal');
var DestroyAccessibilityTree =
    nativeAutomationInternal.DestroyAccessibilityTree;
var GetIntAttribute = nativeAutomationInternal.GetIntAttribute;
var StartCachingAccessibilityTrees =
    nativeAutomationInternal.StartCachingAccessibilityTrees;
var AddTreeChangeObserver = nativeAutomationInternal.AddTreeChangeObserver;
var RemoveTreeChangeObserver =
    nativeAutomationInternal.RemoveTreeChangeObserver;
var GetFocusNative = nativeAutomationInternal.GetFocus;

var jsLastError = bindingUtil ? undefined : require('lastError');
function hasLastError() {
  return bindingUtil ?
      bindingUtil.hasLastError() : jsLastError.hasError(chrome);
}

/**
 * A namespace to export utility functions to other files in automation.
 */
window.automationUtil = function() {};

// TODO(aboxhall): Look into using WeakMap
var idToCallback = {};

var DESKTOP_TREE_ID = 0;

automationUtil.storeTreeCallback = function(id, callback) {
  if (!callback)
    return;

  var targetTree = AutomationRootNode.get(id);
  if (!targetTree) {
    // If we haven't cached the tree, hold the callback until the tree is
    // populated by the initial onAccessibilityEvent call.
    if (id in idToCallback)
      idToCallback[id].push(callback);
    else
      idToCallback[id] = [callback];
  } else {
    callback(targetTree);
  }
};

/**
 * Global list of tree change observers.
 * @type {Object<number, TreeChangeObserver>}
 */
automationUtil.treeChangeObserverMap = {};

/**
 * The id of the next tree change observer.
 * @type {number}
 */
automationUtil.nextTreeChangeObserverId = 1;

/**
 * @type {AutomationNode} The current focused node. This is only updated
 *   when calling automationUtil.updateFocusedNode.
 */
automationUtil.focusedNode = null;

/**
 * Gets the currently focused AutomationNode.
 * @return {AutomationNode}
 */
automationUtil.getFocus = function() {
  var focusedNodeInfo = GetFocusNative(DESKTOP_TREE_ID);
  if (!focusedNodeInfo)
    return null;
  var tree = AutomationRootNode.getOrCreate(focusedNodeInfo.treeId);
  if (tree)
    return privates(tree).impl.get(focusedNodeInfo.nodeId);
};

/**
 * Update automationUtil.focusedNode to be the node that currently has focus.
 */
automationUtil.updateFocusedNode = function() {
  automationUtil.focusedNode = automationUtil.getFocus();
};

/**
 * Updates the focus on blur.
 */
automationUtil.updateFocusedNodeOnBlur = function() {
  var focus = automationUtil.getFocus();
  automationUtil.focusedNode = focus ? focus.root : null;
};

automation.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  // TODO(aboxhall, dtseng): Make this return the speced AutomationRootNode obj.
  apiFunctions.setHandleRequest('getTree', function getTree(tabID, callback) {
    StartCachingAccessibilityTrees();

    // enableTab() ensures the renderer for the active or specified tab has
    // accessibility enabled, and fetches its ax tree id to use as
    // a key in the idToAutomationRootNode map. The callback to
    // enableTab is bound to the callback passed in to getTree(), so that once
    // the tree is available (either due to having been cached earlier, or after
    // an accessibility event occurs which causes the tree to be populated), the
    // callback can be called.
    var params = { tabID: tabID };
    automationInternal.enableTab(params,
        function onEnable(id) {
          if (hasLastError()) {
            callback();
            return;
          }
          automationUtil.storeTreeCallback(id, callback);
        });
  });

  var desktopTree = null;
  apiFunctions.setHandleRequest('getDesktop', function(callback) {
    StartCachingAccessibilityTrees();
    desktopTree = AutomationRootNode.get(DESKTOP_TREE_ID);
    if (!desktopTree) {
      if (DESKTOP_TREE_ID in idToCallback)
        idToCallback[DESKTOP_TREE_ID].push(callback);
      else
        idToCallback[DESKTOP_TREE_ID] = [callback];

      // TODO(dtseng): Disable desktop tree once desktop object goes out of
      // scope.
      automationInternal.enableDesktop(function() {
        if (hasLastError()) {
          AutomationRootNode.destroy(DESKTOP_TREE_ID);
          callback();
          return;
        }
      });
    } else {
      callback(desktopTree);
    }
  });

  apiFunctions.setHandleRequest('getFocus', function(callback) {
    callback(automationUtil.getFocus());
  });

  function removeTreeChangeObserver(observer) {
    for (var id in automationUtil.treeChangeObserverMap) {
      if (automationUtil.treeChangeObserverMap[id] == observer) {
        RemoveTreeChangeObserver(id);
        delete automationUtil.treeChangeObserverMap[id];
        return;
      }
    }
  }
  apiFunctions.setHandleRequest('removeTreeChangeObserver', function(observer) {
    removeTreeChangeObserver(observer);
  });

  function addTreeChangeObserver(filter, observer) {
    removeTreeChangeObserver(observer);
    var id = automationUtil.nextTreeChangeObserverId++;
    AddTreeChangeObserver(id, filter);
    automationUtil.treeChangeObserverMap[id] = observer;
  }
  apiFunctions.setHandleRequest('addTreeChangeObserver',
      function(filter, observer) {
    addTreeChangeObserver(filter, observer);
  });

  apiFunctions.setHandleRequest('setDocumentSelection', function(params) {
    var anchorNodeImpl = privates(params.anchorObject).impl;
    var focusNodeImpl = privates(params.focusObject).impl;
    if (anchorNodeImpl.treeID !== focusNodeImpl.treeID)
      throw new Error('Selection anchor and focus must be in the same tree.');
    if (anchorNodeImpl.treeID === DESKTOP_TREE_ID) {
      throw new Error('Use AutomationNode.setSelection to set the selection ' +
          'in the desktop tree.');
    }
    automationInternal.performAction({ treeID: anchorNodeImpl.treeID,
                                       automationNodeID: anchorNodeImpl.id,
                                       actionType: 'setSelection'},
                                     { focusNodeID: focusNodeImpl.id,
                                       anchorOffset: params.anchorOffset,
                                       focusOffset: params.focusOffset });
  });

});

automationInternal.onChildTreeID.addListener(function(treeID,
                                                      nodeID) {
  var tree = AutomationRootNode.getOrCreate(treeID);
  if (!tree)
    return;

  var node = privates(tree).impl.get(nodeID);
  if (!node)
    return;

  // A WebView in the desktop tree has a different AX tree as its child.
  // When we encounter a WebView with a child AX tree id that we don't
  // currently have cached, explicitly request that AX tree from the
  // browser process and set up a callback when it loads to attach that
  // tree as a child of this node and fire appropriate events.
  var childTreeID = GetIntAttribute(treeID, nodeID, 'childTreeId');
  if (!childTreeID)
    return;

  var subroot = AutomationRootNode.get(childTreeID);
  if (!subroot || subroot.role == 'unknown') {
    automationUtil.storeTreeCallback(childTreeID, function(root) {
      // Return early if the root has already been attached.
      if (root.parent)
        return;

      privates(root).impl.setHostNode(node);

      if (root.docLoaded) {
        privates(root).impl.dispatchEvent('loadComplete', 'page');
      }

      privates(node).impl.dispatchEvent('childrenChanged', 'none');
    });

    automationInternal.enableFrame(childTreeID);
  } else {
    privates(subroot).impl.setHostNode(node);
  }
});

automationInternal.onTreeChange.addListener(function(observerID,
                                                     treeID,
                                                     nodeID,
                                                     changeType) {
  var tree = AutomationRootNode.getOrCreate(treeID);
  if (!tree)
    return;

  var node = privates(tree).impl.get(nodeID);
  if (!node)
    return;

  var observer = automationUtil.treeChangeObserverMap[observerID];
  if (!observer)
    return;

  try {
    observer({target: node, type: changeType});
  } catch (e) {
    exceptionHandler.handle('Error in tree change observer for ' +
        treeChange.type, e);
  }
});

automationInternal.onNodesRemoved.addListener(function(treeID, nodeIDs) {
  var tree = AutomationRootNode.getOrCreate(treeID);
  if (!tree)
    return;

  for (var i = 0; i < nodeIDs.length; i++) {
    privates(tree).impl.remove(nodeIDs[i]);
  }
});

/**
 * Dispatch accessibility events fired on individual nodes to its
 * corresponding AutomationNode. Handle focus events specially
 * (see below).
 */
automationInternal.onAccessibilityEvent.addListener(function(eventParams) {
  var id = eventParams.treeID;
  var targetTree = AutomationRootNode.getOrCreate(id);
  if (eventParams.eventType == 'blur') {
    // Work around an issue where Chrome sends us 'blur' events on the
    // root node when nothing has focus, we need to treat those as focus
    // events but otherwise not handle blur events specially.
    var node = privates(targetTree).impl.get(eventParams.targetID);
    if (node == node.root)
      automationUtil.updateFocusedNodeOnBlur();
  } else if (eventParams.eventType == 'mediaStartedPlaying' ||
      eventParams.eventType == 'mediaStoppedPlaying') {
    // These events are global to the tree.
    eventParams.targetID = privates(targetTree).impl.id;
  } else {
    var previousFocusedNode = automationUtil.focusedNode;
    automationUtil.updateFocusedNode();

    // Fire focus events if necessary.
    if (automationUtil.focusedNode &&
        automationUtil.focusedNode != previousFocusedNode) {
      var eventParamsCopy = {};
      for (var key in eventParams)
        eventParamsCopy[key] = eventParams[key];
      eventParamsCopy['eventType'] = 'focus';
      eventParamsCopy['treeID'] =
          privates(automationUtil.focusedNode.root).impl.treeID;
      eventParamsCopy['targetID'] =
          privates(automationUtil.focusedNode).impl.id;
      privates(automationUtil.focusedNode.root)
          .impl.onAccessibilityEvent(eventParamsCopy);
    }
  }

  // Note that focus type events have already been handled above if there was a
  // focused node. All other events, even non-focus events that triggered a
  // focus dispatch, still need to have their original event fired.
  if ((!automationUtil.focusedNode || eventParams.eventType != 'focus') &&
      !privates(targetTree).impl.onAccessibilityEvent(eventParams))
    return;

  // If we're not waiting on a callback to getTree(), we can early out here.
  if (!(id in idToCallback))
    return;

  // We usually get a 'placeholder' tree first, which doesn't have any url
  // attribute or child nodes. If we've got that, wait for the full tree before
  // calling the callback.
  // TODO(dmazzoni): Don't send down placeholder (crbug.com/397553)
  if (id != DESKTOP_TREE_ID && !targetTree.url &&
      targetTree.children.length == 0)
    return;

  // If the tree wasn't available when getTree() was called, the callback will
  // have been cached in idToCallback, so call and delete it now that we
  // have the complete tree.
  for (var i = 0; i < idToCallback[id].length; i++) {
    var callback = idToCallback[id][i];
    callback(targetTree);
  }
  delete idToCallback[id];
});

automationInternal.onAccessibilityTreeDestroyed.addListener(function(id) {
  // Destroy the AutomationRootNode.
  var targetTree = AutomationRootNode.get(id);
  if (targetTree) {
    privates(targetTree).impl.destroy();
    AutomationRootNode.destroy(id);
  } else {
    logging.WARNING('no targetTree to destroy');
  }

  // Destroy the native cache of the accessibility tree.
  DestroyAccessibilityTree(id);
});

automationInternal.onAccessibilityTreeSerializationError.addListener(
    function(id) {
  automationInternal.enableFrame(id);
});

automationInternal.onActionResult.addListener(
    function(treeID, requestID, result) {
  var targetTree = AutomationRootNode.get(treeID);
  if (!targetTree)
    return;

  privates(targetTree).impl.onActionResult(requestID, result);
    });

if (!apiBridge)
  exports.$set('binding', automation.generate());
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var utils = require('utils');

function AutomationEventImpl(type, target, eventFrom) {
  this.propagationStopped = false;
  this.type = type;
  this.target = target;
  this.eventPhase = Event.NONE;
  this.eventFrom = eventFrom;
}

AutomationEventImpl.prototype = {
  __proto__: null,
  stopPropagation: function() {
    this.propagationStopped = true;
  },
};

function AutomationEvent() {
  privates(AutomationEvent).constructPrivate(this, arguments);
}
utils.expose(AutomationEvent, AutomationEventImpl, {
  functions: [
    'stopPropagation',
  ],
  readonly: [
    'type',
    'target',
    'eventPhase',
    'eventFrom',
  ],
});

exports.$set('AutomationEvent', AutomationEvent);
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var AutomationEvent = require('automationEvent').AutomationEvent;
var automationInternal =
    getInternalApi ?
        getInternalApi('automationInternal') :
        require('binding').Binding.create('automationInternal').generate();
var exceptionHandler = require('uncaught_exception_handler');

var natives = requireNative('automationInternal');

var IsInteractPermitted = natives.IsInteractPermitted;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?number} The id of the root node.
 */
var GetRootID = natives.GetRootID;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?string} The title of the document.
 */
var GetDocTitle = natives.GetDocTitle;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?string} The url of the document.
 */
var GetDocURL = natives.GetDocURL;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?boolean} True if the document has finished loading.
 */
var GetDocLoaded = natives.GetDocLoaded;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?number} The loading progress, from 0.0 to 1.0 (fully loaded).
 */
var GetDocLoadingProgress =
    natives.GetDocLoadingProgress;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?number} The ID of the selection anchor object.
 */
var GetAnchorObjectID = natives.GetAnchorObjectID;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?number} The selection anchor offset.
 */
var GetAnchorOffset = natives.GetAnchorOffset;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?string} The selection anchor affinity.
 */
var GetAnchorAffinity = natives.GetAnchorAffinity;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?number} The ID of the selection focus object.
 */
var GetFocusObjectID = natives.GetFocusObjectID;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?number} The selection focus offset.
 */
var GetFocusOffset = natives.GetFocusOffset;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @return {?string} The selection focus affinity.
 */
var GetFocusAffinity = natives.GetFocusAffinity;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {?number} The id of the node's parent, or undefined if it's the
 *    root of its tree or if the tree or node wasn't found.
 */
var GetParentID = natives.GetParentID;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {?number} The number of children of the node, or undefined if
 *     the tree or node wasn't found.
 */
var GetChildCount = natives.GetChildCount;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @param {number} childIndex An index of a child of this node.
 * @return {?number} The id of the child at the given index, or undefined
 *     if the tree or node or child at that index wasn't found.
 */
var GetChildIDAtIndex = natives.GetChildIDAtIndex;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {?number} The ids of the children of the node, or undefined
 *     if the tree or node wasn't found.
 */
var GetChildIds = natives.GetChildIDs;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {?Object} An object mapping html attributes to values.
 */
var GetHtmlAttributes = natives.GetHtmlAttributes;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {?number} The index of this node in its parent, or undefined if
 *     the tree or node or node parent wasn't found.
 */
var GetIndexInParent = natives.GetIndexInParent;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {?Object} An object with a string key for every state flag set,
 *     or undefined if the tree or node or node parent wasn't found.
 */
var GetState = natives.GetState;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {string} The restriction, one of
 * "disabled", "readOnly" or undefined if enabled or other object not disabled
 */
var GetRestriction = natives.GetRestriction;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {string} The checked state, as undefined, "true", "false" or "mixed".
 */
var GetChecked = natives.GetChecked;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {string} The role of the node, or undefined if the tree or
 *     node wasn't found.
 */
var GetRole = natives.GetRole;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {?automation.Rect} The location of the node, or undefined if
 *     the tree or node wasn't found.
 */
var GetLocation = natives.GetLocation;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @param {number} startIndex The start index of the range.
 * @param {number} endIndex The end index of the range.
 * @return {?automation.Rect} The bounding box of the subrange of this node,
 *     or the location if there are no subranges, or undefined if
 *     the tree or node wasn't found.
 */
var GetBoundsForRange = natives.GetBoundsForRange;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {?automation.Rect} The unclipped location of the node, or
 * undefined if the tree or node wasn't found.
 */
var GetUnclippedLocation = natives.GetUnclippedLocation;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {!Array.<number>} The text offset where each line starts, or an empty
 *     array if this node has no text content, or undefined if the tree or node
 *     was not found.
 */
var GetLineStartOffsets = requireNative(
    'automationInternal').GetLineStartOffsets;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @param {string} attr The name of a string attribute.
 * @return {?string} The value of this attribute, or undefined if the tree,
 *     node, or attribute wasn't found.
 */
var GetStringAttribute = natives.GetStringAttribute;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @param {string} attr The name of an attribute.
 * @return {?boolean} The value of this attribute, or undefined if the tree,
 *     node, or attribute wasn't found.
 */
var GetBoolAttribute = natives.GetBoolAttribute;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @param {string} attr The name of an attribute.
 * @return {?number} The value of this attribute, or undefined if the tree,
 *     node, or attribute wasn't found.
 */
var GetIntAttribute = natives.GetIntAttribute;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @param {string} attr The name of an attribute.
 * @return {?number} The value of this attribute, or undefined if the tree,
 *     node, or attribute wasn't found.
 */
var GetFloatAttribute = natives.GetFloatAttribute;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @param {string} attr The name of an attribute.
 * @return {?Array.<number>} The value of this attribute, or undefined
 *     if the tree, node, or attribute wasn't found.
 */
var GetIntListAttribute =
    natives.GetIntListAttribute;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @param {string} attr The name of an HTML attribute.
 * @return {?string} The value of this attribute, or undefined if the tree,
 *     node, or attribute wasn't found.
 */
var GetHtmlAttribute = natives.GetHtmlAttribute;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {automation.NameFromType} The source of the node's name.
 */
var GetNameFrom = natives.GetNameFrom;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {boolean}
 */
var GetBold = natives.GetBold;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {boolean}
 */
var GetItalic = natives.GetItalic;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {boolean}
 */
var GetUnderline = natives.GetUnderline;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {boolean}
 */
var GetLineThrough = natives.GetLineThrough;

/**
 * @param {number} axTreeID The id of the accessibility tree.
 * @param {number} nodeID The id of a node.
 * @return {?Array.<automation.CustomAction>} List of custom actions of the
 *     node.
 */
var GetCustomActions = natives.GetCustomActions;

var logging = requireNative('logging');
var utils = require('utils');

/**
 * A single node in the Automation tree.
 * @param {AutomationRootNodeImpl} root The root of the tree.
 * @constructor
 */
function AutomationNodeImpl(root) {
  this.rootImpl = root;
  this.hostNode_ = null;
  this.listeners = {__proto__: null};
}

AutomationNodeImpl.prototype = {
  __proto__: null,
  treeID: -1,
  id: -1,
  isRootNode: false,

  detach: function() {
    this.rootImpl = null;
    this.hostNode_ = null;
    this.listeners = {__proto__: null};
  },

  get root() {
    return this.rootImpl && this.rootImpl.wrapper;
  },

  get parent() {
    if (!this.rootImpl)
      return undefined;
    if (this.hostNode_)
      return this.hostNode_;
    var parentID = GetParentID(this.treeID, this.id);
    return this.rootImpl.get(parentID);
  },

  get htmlAttributes() {
    return GetHtmlAttributes(this.treeID, this.id) || {};
  },

  get state() {
    return GetState(this.treeID, this.id) || {};
  },

  get role() {
    return GetRole(this.treeID, this.id);
  },

  get restriction() {
    return GetRestriction(this.treeID, this.id);
  },

  get checked() {
    return GetChecked(this.treeID, this.id);
  },

  get location() {
    return GetLocation(this.treeID, this.id);
  },

  boundsForRange: function(startIndex, endIndex) {
    return GetBoundsForRange(this.treeID, this.id, startIndex, endIndex);
  },

  get unclippedLocation() {
    var result = GetUnclippedLocation(this.treeID, this.id);
    if (result === undefined)
      result = GetLocation(this.treeID, this.id);
    return result;
  },

  get indexInParent() {
    return GetIndexInParent(this.treeID, this.id);
  },

  get lineStartOffsets() {
    return GetLineStartOffsets(this.treeID, this.id);
  },

  get childTree() {
    var childTreeID = GetIntAttribute(this.treeID, this.id, 'childTreeId');
    if (childTreeID)
      return AutomationRootNodeImpl.get(childTreeID);
  },

  get firstChild() {
    if (!this.rootImpl)
      return undefined;
    if (this.childTree)
      return this.childTree;
    if (!GetChildCount(this.treeID, this.id))
      return undefined;
    var firstChildID = GetChildIDAtIndex(this.treeID, this.id, 0);
    return this.rootImpl.get(firstChildID);
  },

  get lastChild() {
    if (!this.rootImpl)
      return undefined;
    if (this.childTree)
      return this.childTree;
    var count = GetChildCount(this.treeID, this.id);
    if (!count)
      return undefined;
    var lastChildID = GetChildIDAtIndex(this.treeID, this.id, count - 1);
    return this.rootImpl.get(lastChildID);
  },

  get children() {
    if (!this.rootImpl)
      return [];

    if (this.childTree)
      return [this.childTree];

    var children = [];
    var childIds = GetChildIds(this.treeID, this.id);
    for (var i = 0; i < childIds.length; ++i) {
      var childID = childIds[i];
      var child = this.rootImpl.get(childID);
      $Array.push(children, child);
    }
    return children;
  },

  get previousSibling() {
    var parent = this.parent;
    if (!parent)
      return undefined;
    parent = privates(parent).impl;
    var indexInParent = GetIndexInParent(this.treeID, this.id);
    return this.rootImpl.get(
        GetChildIDAtIndex(parent.treeID, parent.id, indexInParent - 1));
  },

  get nextSibling() {
    var parent = this.parent;
    if (!parent)
      return undefined;
    parent = privates(parent).impl;
    var indexInParent = GetIndexInParent(this.treeID, this.id);
    return this.rootImpl.get(
        GetChildIDAtIndex(parent.treeID, parent.id, indexInParent + 1));
  },

  get nameFrom() {
    return GetNameFrom(this.treeID, this.id);
  },

  get bold() {
    return GetBold(this.treeID, this.id);
  },

  get italic() {
    return GetItalic(this.treeID, this.id);
  },

  get underline() {
    return GetUnderline(this.treeID, this.id);
  },

  get lineThrough() {
    return GetLineThrough(this.treeID, this.id);
  },

  get customActions() {
    return GetCustomActions(this.treeID, this.id);
  },

  doDefault: function() {
    this.performAction_('doDefault');
  },

  focus: function() {
    this.performAction_('focus');
  },

  getImageData: function(maxWidth, maxHeight) {
    this.performAction_('getImageData',
                        { maxWidth: maxWidth,
                          maxHeight: maxHeight });
  },

  hitTest: function(x, y, eventToFire) {
    this.hitTestInternal(x, y, eventToFire);
  },

  hitTestWithReply: function(x, y, opt_callback) {
    this.hitTestInternal(x, y, 'hitTestResult', opt_callback);
  },

  hitTestInternal: function(x, y, eventToFire, opt_callback) {
    // Convert from global to tree-relative coordinates.
    var location = GetLocation(this.treeID, GetRootID(this.treeID));
    this.performAction_('hitTest',
                        { x: Math.floor(x - location.left),
                          y: Math.floor(y - location.top),
                          eventToFire: eventToFire },
                        opt_callback);
  },

  makeVisible: function() {
    this.performAction_('makeVisible');
  },

  performCustomAction: function(customActionId) {
    this.performAction_('customAction', { customActionID: customActionId });
  },

  resumeMedia: function() {
    this.performAction_('resumeMedia');
  },

  scrollBackward: function(opt_callback) {
    this.performAction_('scrollBackward', {}, opt_callback);
  },

  scrollForward: function(opt_callback) {
    this.performAction_('scrollForward', {}, opt_callback);
  },

  scrollUp: function(opt_callback) {
    this.performAction_('scrollUp', {}, opt_callback);
  },

  scrollDown: function(opt_callback) {
    this.performAction_('scrollDown', {}, opt_callback);
  },

  scrollLeft: function(opt_callback) {
    this.performAction_('scrollLeft', {}, opt_callback);
  },

  scrollRight: function(opt_callback) {
    this.performAction_('scrollRight', {}, opt_callback);
  },

  setSelection: function(startIndex, endIndex) {
    if (this.state.editable) {
      this.performAction_('setSelection',
                          { focusNodeID: this.id,
                            anchorOffset: startIndex,
                            focusOffset: endIndex });
    }
  },

  setSequentialFocusNavigationStartingPoint: function() {
    this.performAction_('setSequentialFocusNavigationStartingPoint');
  },

  showContextMenu: function() {
    this.performAction_('showContextMenu');
  },

  startDuckingMedia: function() {
    this.performAction_('startDuckingMedia');
  },

  stopDuckingMedia: function() {
    this.performAction_('stopDuckingMedia');
  },

  suspendMedia: function() {
    this.performAction_('suspendMedia');
  },

  domQuerySelector: function(selector, callback) {
    if (!this.rootImpl)
      callback();
    automationInternal.querySelector(
      { treeID: this.rootImpl.treeID,
        automationNodeID: this.id,
        selector: selector },
      $Function.bind(this.domQuerySelectorCallback_, this, callback));
  },

  find: function(params) {
    return this.findInternal_(params);
  },

  findAll: function(params) {
    return this.findInternal_(params, []);
  },

  matches: function(params) {
    return this.matchInternal_(params);
  },

  addEventListener: function(eventType, callback, capture) {
    this.removeEventListener(eventType, callback);
    if (!this.listeners[eventType])
      this.listeners[eventType] = [];
    $Array.push(this.listeners[eventType], {
      __proto__: null,
      callback: callback,
      capture: !!capture,
    });
  },

  // TODO(dtseng/aboxhall): Check this impl against spec.
  removeEventListener: function(eventType, callback) {
    if (this.listeners[eventType]) {
      var listeners = this.listeners[eventType];
      for (var i = 0; i < listeners.length; i++) {
        if (callback === listeners[i].callback)
          $Array.splice(listeners, i, 1);
      }
    }
  },

  toJSON: function() {
    return { treeID: this.treeID,
             id: this.id,
             role: this.role,
             attributes: this.attributes };
  },

  dispatchEvent: function(eventType, eventFrom, mouseX, mouseY) {
    var path = [];
    var parent = this.parent;
    while (parent) {
      $Array.push(path, parent);
      parent = parent.parent;
    }
    var event = new AutomationEvent(eventType, this.wrapper, eventFrom);
    event.mouseX = mouseX;
    event.mouseY = mouseY;

    // Dispatch the event through the propagation path in three phases:
    // - capturing: starting from the root and going down to the target's parent
    // - targeting: dispatching the event on the target itself
    // - bubbling: starting from the target's parent, going back up to the root.
    // At any stage, a listener may call stopPropagation() on the event, which
    // will immediately stop event propagation through this path.
    if (this.dispatchEventAtCapturing_(event, path)) {
      if (this.dispatchEventAtTargeting_(event, path))
        this.dispatchEventAtBubbling_(event, path);
    }
  },

  toString: function() {
    var parentID = GetParentID(this.treeID, this.id);
    var childTreeID = GetIntAttribute(this.treeID, this.id, 'childTreeId');
    var count = GetChildCount(this.treeID, this.id);
    var childIDs = [];
    for (var i = 0; i < count; ++i) {
      var childID = GetChildIDAtIndex(this.treeID, this.id, i);
      $Array.push(childIDs, childID);
    }

    var result = 'node id=' + this.id +
        ' role=' + this.role +
        ' state=' + $JSON.stringify(this.state) +
        ' parentID=' + parentID +
        ' childIds=' + $JSON.stringify(childIDs);
    if (this.hostNode_) {
      var hostNodeImpl = privates(this.hostNode_).impl;
      result += ' host treeID=' + hostNodeImpl.treeID +
          ' host nodeID=' + hostNodeImpl.id;
    }
    if (childTreeID)
      result += ' childTreeID=' + childTreeID;
    return result;
  },

  dispatchEventAtCapturing_: function(event, path) {
    privates(event).impl.eventPhase = Event.CAPTURING_PHASE;
    for (var i = path.length - 1; i >= 0; i--) {
      this.fireEventListeners_(path[i], event);
      if (privates(event).impl.propagationStopped)
        return false;
    }
    return true;
  },

  dispatchEventAtTargeting_: function(event) {
    privates(event).impl.eventPhase = Event.AT_TARGET;
    this.fireEventListeners_(this.wrapper, event);
    return !privates(event).impl.propagationStopped;
  },

  dispatchEventAtBubbling_: function(event, path) {
    privates(event).impl.eventPhase = Event.BUBBLING_PHASE;
    for (var i = 0; i < path.length; i++) {
      this.fireEventListeners_(path[i], event);
      if (privates(event).impl.propagationStopped)
        return false;
    }
    return true;
  },

  fireEventListeners_: function(node, event) {
    var nodeImpl = privates(node).impl;
    if (!nodeImpl.rootImpl)
      return;

    var listeners = nodeImpl.listeners[event.type];
    if (!listeners)
      return;
    var eventPhase = event.eventPhase;
    for (var i = 0; i < listeners.length; i++) {
      if (eventPhase == Event.CAPTURING_PHASE && !listeners[i].capture)
        continue;
      if (eventPhase == Event.BUBBLING_PHASE && listeners[i].capture)
        continue;

      try {
        listeners[i].callback(event);
      } catch (e) {
        exceptionHandler.handle('Error in event handler for ' + event.type +
            ' during phase ' + eventPhase, e);
      }
    }
  },

  performAction_: function(actionType, opt_args, opt_callback) {
    if (!this.rootImpl)
      return;

    // Not yet initialized.
    if (this.rootImpl.treeID === undefined ||
        this.id === undefined) {
      return;
    }

    // Check permissions.
    if (!IsInteractPermitted()) {
      throw new Error(actionType + ' requires {"desktop": true} or' +
          ' {"interact": true} in the "automation" manifest key.');
    }
    var requestID = -1;
    if (opt_callback) {
      requestID = this.rootImpl.addActionResultCallback(opt_callback);
    }

    automationInternal.performAction({ treeID: this.rootImpl.treeID,
                                       automationNodeID: this.id,
                                       actionType: actionType,
                                       requestID: requestID},
                                     opt_args || {});
  },

  domQuerySelectorCallback_: function(userCallback, resultAutomationNodeID) {
    // resultAutomationNodeID could be zero or undefined or (unlikely) null;
    // they all amount to the same thing here, which is that no node was
    // returned.
    if (!resultAutomationNodeID || !this.rootImpl) {
      userCallback(null);
      return;
    }
    var resultNode = this.rootImpl.get(resultAutomationNodeID);
    if (!resultNode) {
      logging.WARNING('Query selector result not in tree: ' +
                      resultAutomationNodeID);
      userCallback(null);
    }
    userCallback(resultNode);
  },

  findInternal_: function(params, opt_results) {
    var result = null;
    this.forAllDescendants_(function(node) {
      if (privates(node).impl.matchInternal_(params)) {
        if (opt_results)
          $Array.push(opt_results, node);
        else
          result = node;
        return !opt_results;
      }
    });
    if (opt_results)
      return opt_results;
    return result;
  },

  /**
   * Executes a closure for all of this node's descendants, in pre-order.
   * Early-outs if the closure returns true.
   * @param {Function(AutomationNode):boolean} closure Closure to be executed
   *     for each node. Return true to early-out the traversal.
   */
  forAllDescendants_: function(closure) {
    var stack = $Array.reverse(this.wrapper.children);
    while (stack.length > 0) {
      var node = $Array.pop(stack);
      if (closure(node))
        return;

      var children = node.children;
      for (var i = children.length - 1; i >= 0; i--)
        $Array.push(stack, children[i]);
    }
  },

  matchInternal_: function(params) {
    if ($Object.keys(params).length === 0)
      return false;

    if ('role' in params && this.role != params.role)
        return false;

    if ('state' in params) {
      for (var state in params.state) {
        if (params.state[state] != (state in this.state))
          return false;
      }
    }
    if ('attributes' in params) {
      for (var attribute in params.attributes) {
        var attrValue = params.attributes[attribute];
        if (typeof attrValue != 'object') {
          if (this[attribute] !== attrValue)
            return false;
        } else if (attrValue instanceof $RegExp.self) {
          if (typeof this[attribute] != 'string')
            return false;
          if (!attrValue.test(this[attribute]))
            return false;
        } else {
          // TODO(aboxhall): handle intlist case.
          return false;
        }
      }
    }
    return true;
  }
};

var stringAttributes = [
    'accessKey',
    'ariaInvalidValue',
    'autoComplete',
    'className',
    'containerLiveRelevant',
    'containerLiveStatus',
    'description',
    'display',
    'htmlTag',
    'imageDataUrl',
    'language',
    'liveRelevant',
    'liveStatus',
    'name',
    'placeholder',
    'roleDescription',
    'textInputType',
    'url',
    'value'];

var boolAttributes = [
    'busy',
    'clickable',
    'containerLiveAtomic',
    'containerLiveBusy',
    'liveAtomic',
    'scrollable'
];

var intAttributes = [
    'backgroundColor',
    'color',
    'colorValue',
    'hierarchicalLevel',
    'posInSet',
    'scrollX',
    'scrollXMax',
    'scrollXMin',
    'scrollY',
    'scrollYMax',
    'scrollYMin',
    'setSize',
    'tableCellColumnIndex',
    'ariaCellColumnIndex',
    'tableCellColumnSpan',
    'tableCellRowIndex',
    'ariaCellRowIndex',
    'tableCellRowSpan',
    'tableColumnCount',
    'ariaColumnCount',
    'tableColumnIndex',
    'tableRowCount',
    'ariaRowCount',
    'tableRowIndex',
    'textSelEnd',
    'textSelStart'];

var nodeRefAttributes = [
    ['activedescendantId', 'activeDescendant'],
    ['inPageLinkTargetId', 'inPageLinkTarget'],
    ['nextFocusId', 'nextFocus'],
    ['nextOnLineId', 'nextOnLine'],
    ['previousFocusId', 'previousFocus'],
    ['previousOnLineId', 'previousOnLine'],
    ['tableColumnHeaderId', 'tableColumnHeader'],
    ['tableHeaderId', 'tableHeader'],
    ['tableRowHeaderId', 'tableRowHeader']];

var intListAttributes = [
    'lineBreaks',
    'markerEnds',
    'markerStarts',
    'markerTypes',
    'wordEnds',
    'wordStarts'];

var nodeRefListAttributes = [
    ['controlsIds', 'controls'],
    ['describedbyIds', 'describedBy'],
    ['flowtoIds', 'flowTo'],
    ['labelledbyIds', 'labelledBy']];

var floatAttributes = [
    'valueForRange',
    'minValueForRange',
    'maxValueForRange'];

var htmlAttributes = [
    ['type', 'inputType']];

var publicAttributes = [];

$Array.forEach(stringAttributes, function(attributeName) {
  $Array.push(publicAttributes, attributeName);
  $Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
    __proto__: null,
    get: function() {
      return GetStringAttribute(this.treeID, this.id, attributeName);
    }
  });
});

$Array.forEach(boolAttributes, function(attributeName) {
  $Array.push(publicAttributes, attributeName);
  $Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
    __proto__: null,
    get: function() {
      return GetBoolAttribute(this.treeID, this.id, attributeName);
    }
  });
});

$Array.forEach(intAttributes, function(attributeName) {
  $Array.push(publicAttributes, attributeName);
  $Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
    __proto__: null,
    get: function() {
      return GetIntAttribute(this.treeID, this.id, attributeName);
    }
  });
});

$Array.forEach(nodeRefAttributes, function(params) {
  var srcAttributeName = params[0];
  var dstAttributeName = params[1];
  $Array.push(publicAttributes, dstAttributeName);
  $Object.defineProperty(AutomationNodeImpl.prototype, dstAttributeName, {
    __proto__: null,
    get: function() {
      var id = GetIntAttribute(this.treeID, this.id, srcAttributeName);
      if (id && this.rootImpl)
        return this.rootImpl.get(id);
      else
        return undefined;
    }
  });
});

$Array.forEach(intListAttributes, function(attributeName) {
  $Array.push(publicAttributes, attributeName);
  $Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
    __proto__: null,
    get: function() {
      return GetIntListAttribute(this.treeID, this.id, attributeName);
    }
  });
});

$Array.forEach(nodeRefListAttributes, function(params) {
  var srcAttributeName = params[0];
  var dstAttributeName = params[1];
  $Array.push(publicAttributes, dstAttributeName);
  $Object.defineProperty(AutomationNodeImpl.prototype, dstAttributeName, {
    __proto__: null,
    get: function() {
      var ids = GetIntListAttribute(this.treeID, this.id, srcAttributeName);
      if (!ids || !this.rootImpl)
        return undefined;
      var result = [];
      for (var i = 0; i < ids.length; ++i) {
        var node = this.rootImpl.get(ids[i]);
        if (node)
          $Array.push(result, node);
      }
      return result;
    }
  });
});

$Array.forEach(floatAttributes, function(attributeName) {
  $Array.push(publicAttributes, attributeName);
  $Object.defineProperty(AutomationNodeImpl.prototype, attributeName, {
    __proto__: null,
    get: function() {
      return GetFloatAttribute(this.treeID, this.id, attributeName);
    }
  });
});

$Array.forEach(htmlAttributes, function(params) {
  var srcAttributeName = params[0];
  var dstAttributeName = params[1];
  $Array.push(publicAttributes, dstAttributeName);
  $Object.defineProperty(AutomationNodeImpl.prototype, dstAttributeName, {
    __proto__: null,
    get: function() {
      return GetHtmlAttribute(this.treeID, this.id, srcAttributeName);
    }
  });
});

/**
 * AutomationRootNode.
 *
 * An AutomationRootNode is the javascript end of an AXTree living in the
 * browser. AutomationRootNode handles unserializing incremental updates from
 * the source AXTree. Each update contains node data that form a complete tree
 * after applying the update.
 *
 * A brief note about ids used through this class. The source AXTree assigns
 * unique ids per node and we use these ids to build a hash to the actual
 * AutomationNode object.
 * Thus, tree traversals amount to a lookup in our hash.
 *
 * The tree itself is identified by the accessibility tree id of the
 * renderer widget host.
 * @constructor
 */
function AutomationRootNodeImpl(treeID) {
  $Function.call(AutomationNodeImpl, this, this);
  this.treeID = treeID;
  this.axNodeDataCache_ = {__proto__: null};
  this.actionRequestIDToCallback_ = {__proto__: null};
}

utils.defineProperty(AutomationRootNodeImpl, 'idToAutomationRootNode_',
    {__proto__: null});

utils.defineProperty(AutomationRootNodeImpl, 'get', function(treeID) {
  var result = AutomationRootNodeImpl.idToAutomationRootNode_[treeID];
  return result || undefined;
});

utils.defineProperty(AutomationRootNodeImpl, 'getOrCreate', function(treeID) {
  if (AutomationRootNodeImpl.idToAutomationRootNode_[treeID])
    return AutomationRootNodeImpl.idToAutomationRootNode_[treeID];
  var result = new AutomationRootNode(treeID);
  AutomationRootNodeImpl.idToAutomationRootNode_[treeID] = result;
  return result;
});

utils.defineProperty(AutomationRootNodeImpl, 'destroy', function(treeID) {
  delete AutomationRootNodeImpl.idToAutomationRootNode_[treeID];
});

AutomationRootNodeImpl.prototype = {
  __proto__: AutomationNodeImpl.prototype,

  /**
   * @type {boolean}
   */
  isRootNode: true,

  /**
   * @type {number}
   */
  treeID: -1,

  /**
   * The parent of this node from a different tree.
   * @type {?AutomationNode}
   * @private
   */
  hostNode_: null,

  /**
   * A map from id to AutomationNode.
   * @type {Object.<number, AutomationNode>}
   * @private
   */
  axNodeDataCache_: null,

  actionRequestCounter_: 0,

  actionRequestIDToCallback_: null,

  get id() {
    var result = GetRootID(this.treeID);

    // Don't return undefined, because the id is often passed directly
    // as an argument to a native binding that expects only a valid number.
    if (result === undefined)
      return -1;

    return result;
  },

  get chromeChannel() {
    return GetStringAttribute(this.treeID, this.id, 'chromeChannel');
  },

  get docUrl() {
    return GetDocURL(this.treeID);
  },

  get docTitle() {
    return GetDocTitle(this.treeID);
  },

  get docLoaded() {
    return GetDocLoaded(this.treeID);
  },

  get docLoadingProgress() {
    return GetDocLoadingProgress(this.treeID);
  },

  get anchorObject() {
    var id = GetAnchorObjectID(this.treeID);
    if (id && id != -1)
      return this.get(id);
    else
      return undefined;
  },

  get anchorOffset() {
    var id = GetAnchorObjectID(this.treeID);
    if (id && id != -1)
      return GetAnchorOffset(this.treeID);
  },

  get anchorAffinity() {
    var id = GetAnchorObjectID(this.treeID);
    if (id && id != -1)
      return GetAnchorAffinity(this.treeID);
  },

  get focusObject() {
    var id = GetFocusObjectID(this.treeID);
    if (id && id != -1)
      return this.get(id);
    else
      return undefined;
  },

  get focusOffset() {
    var id = GetFocusObjectID(this.treeID);
    if (id && id != -1)
      return GetFocusOffset(this.treeID);
  },

  get focusAffinity() {
    var id = GetFocusObjectID(this.treeID);
    if (id && id != -1)
      return GetFocusAffinity(this.treeID);
  },

  get: function(id) {
    if (id == undefined)
      return undefined;

    if (id == this.id)
      return this.wrapper;

    var obj = this.axNodeDataCache_[id];
    if (obj)
      return obj;

    obj = new AutomationNode(this);
    privates(obj).impl.treeID = this.treeID;
    privates(obj).impl.id = id;
    this.axNodeDataCache_[id] = obj;

    return obj;
  },

  remove: function(id) {
    if (this.axNodeDataCache_[id])
      privates(this.axNodeDataCache_[id]).impl.detach();
    delete this.axNodeDataCache_[id];
  },

  destroy: function() {
    this.dispatchEvent('destroyed', 'none');
    for (var id in this.axNodeDataCache_)
      this.remove(id);
    this.detach();
  },

  setHostNode(hostNode) {
    this.hostNode_ = hostNode;
  },

  onAccessibilityEvent: function(eventParams) {
    var targetNode = this.get(eventParams.targetID);
    if (targetNode) {
      var targetNodeImpl = privates(targetNode).impl;
      targetNodeImpl.dispatchEvent(
          eventParams.eventType, eventParams.eventFrom,
          eventParams.mouseX, eventParams.mouseY);

      if (eventParams.actionRequestID != -1) {
        this.onActionResult(eventParams.actionRequestID, targetNode);
      }
    } else {
      logging.WARNING('Got ' + eventParams.eventType +
                      ' event on unknown node: ' + eventParams.targetID +
                      '; this: ' + this.id);
    }
    return true;
  },

  addActionResultCallback: function(callback) {
    this.actionRequestIDToCallback_[++this.actionRequestCounter_] = callback;
    return this.actionRequestCounter_;
  },

  onActionResult: function(requestID, result) {
    if (requestID in this.actionRequestIDToCallback_) {
      this.actionRequestIDToCallback_[requestID](result);
      delete this.actionRequestIDToCallback_[requestID];
    }
  },

  toString: function() {
    function toStringInternal(nodeImpl, indent) {
      if (!nodeImpl)
        return '';
      var output = '';
      if (nodeImpl.isRootNode)
        output += indent + 'tree id=' + nodeImpl.treeID + '\n';
      output += indent +
        $Function.call(AutomationNodeImpl.prototype.toString, nodeImpl) + '\n';
      indent += '  ';
      var children = nodeImpl.children;
      for (var i = 0; i < children.length; ++i)
        output += toStringInternal(privates(children[i]).impl, indent);
      return output;
    }
    return toStringInternal(this, '');
  },
};

function AutomationNode() {
  privates(AutomationNode).constructPrivate(this, arguments);
}
utils.expose(AutomationNode, AutomationNodeImpl, {
  functions: [
    'doDefault',
    'find',
    'findAll',
    'focus',
    'getImageData',
    'hitTest',
    'hitTestWithReply',
    'makeVisible',
    'matches',
    'performCustomAction',
    'resumeMedia',
    'scrollBackward',
    'scrollForward',
    'scrollUp',
    'scrollDown',
    'scrollLeft',
    'scrollRight',
    'setSelection',
    'setSequentialFocusNavigationStartingPoint',
    'showContextMenu',
    'startDuckingMedia',
    'stopDuckingMedia',
    'suspendMedia',
    'addEventListener',
    'removeEventListener',
    'domQuerySelector',
    'toString',
    'boundsForRange',
  ],
  readonly: $Array.concat(publicAttributes, [
      'parent',
      'firstChild',
      'lastChild',
      'children',
      'previousSibling',
      'nextSibling',
      'isRootNode',
      'role',
      'checked',
      'restriction',
      'state',
      'location',
      'indexInParent',
      'lineStartOffsets',
      'root',
      'htmlAttributes',
      'nameFrom',
      'bold',
      'italic',
      'underline',
      'lineThrough',
      'customActions',
      'unclippedLocation',
  ]),
});

function AutomationRootNode() {
  privates(AutomationRootNode).constructPrivate(this, arguments);
}
utils.expose(AutomationRootNode, AutomationRootNodeImpl, {
  superclass: AutomationNode,
  readonly: [
    'chromeChannel',
    'docTitle',
    'docUrl',
    'docLoaded',
    'docLoadingProgress',
    'anchorObject',
    'anchorOffset',
    'anchorAffinity',
    'focusObject',
    'focusOffset',
    'focusAffinity',
  ],
});

utils.defineProperty(AutomationRootNode, 'get', function(treeID) {
  return AutomationRootNodeImpl.get(treeID);
});

utils.defineProperty(AutomationRootNode, 'getOrCreate', function(treeID) {
  return AutomationRootNodeImpl.getOrCreate(treeID);
});

utils.defineProperty(AutomationRootNode, 'destroy', function(treeID) {
  AutomationRootNodeImpl.destroy(treeID);
});

exports.$set('AutomationNode', AutomationNode);
exports.$set('AutomationRootNode', AutomationRootNode);
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the browserAction API.

var binding = apiBridge || require('binding').Binding.create('browserAction');

var setIcon = require('setIcon').setIcon;
var getExtensionViews = requireNative('runtime').GetExtensionViews;
var sendRequest = bindingUtil ?
    $Function.bind(bindingUtil.sendRequest, bindingUtil) :
    require('sendRequest').sendRequest;

var jsLastError = bindingUtil ? undefined : require('lastError');
function hasLastError() {
  return bindingUtil ?
      bindingUtil.hasLastError() : jsLastError.hasError(chrome);
}

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('setIcon', function(details, callback) {
    setIcon(details, function(args) {
      sendRequest('browserAction.setIcon',
                  [args, callback],
                  apiBridge ? undefined : this.definition.parameters,
                  undefined);
    }.bind(this));
  });

  apiFunctions.setCustomCallback('openPopup',
      function(name, request, callback, response) {
    if (!callback)
      return;

    if (hasLastError()) {
      callback();
    } else {
      var views = getExtensionViews(-1, -1, 'POPUP');
      callback(views.length > 0 ? views[0] : null);
    }
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Cast Streaming RtpStream API.

var binding = apiBridge ||
              require('binding').Binding.create('cast.streaming.rtpStream');
var natives = requireNative('cast_streaming_natives');

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('destroy',
      function(transportId) {
        natives.DestroyCastRtpStream(transportId);
  });
  apiFunctions.setHandleRequest('getSupportedParams',
      function(transportId) {
        return natives.GetSupportedParamsCastRtpStream(transportId);
  });
  apiFunctions.setHandleRequest('start',
      function(transportId, params) {
        natives.StartCastRtpStream(transportId, params);
  });
  apiFunctions.setHandleRequest('stop',
      function(transportId) {
        natives.StopCastRtpStream(transportId);
  });
  apiFunctions.setHandleRequest('toggleLogging',
      function(transportId, enable) {
        natives.ToggleLogging(transportId, enable);
  });
  apiFunctions.setHandleRequest('getRawEvents',
      function(transportId, extraData, callback) {
        natives.GetRawEvents(transportId, extraData, callback);
  });
  apiFunctions.setHandleRequest('getStats',
      function(transportId, callback) {
        natives.GetStats(transportId, callback);
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Cast Streaming Session API.

var binding = apiBridge ||
              require('binding').Binding.create('cast.streaming.session');
var natives = requireNative('cast_streaming_natives');

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;
  apiFunctions.setHandleRequest('create',
      function(audioTrack, videoTrack, callback) {
        natives.CreateSession(audioTrack, videoTrack, callback);
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Cast Streaming UdpTransport API.

var binding = apiBridge ||
              require('binding').Binding.create('cast.streaming.udpTransport');
var natives = requireNative('cast_streaming_natives');

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('destroy', function(transportId) {
    natives.DestroyCastUdpTransport(transportId);
  });
  apiFunctions.setHandleRequest('setDestination',
    function(transportId, destination) {
      natives.SetDestinationCastUdpTransport(transportId, destination);
  });
  apiFunctions.setHandleRequest('setOptions',
    function(transportId, options) {
      natives.SetOptionsCastUdpTransport(transportId, options);
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Cast Streaming Session API.

var binding =
    apiBridge ||
    require('binding').Binding.create('cast.streaming.receiverSession');
var natives = requireNative('cast_streaming_natives');

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;
  apiFunctions.setHandleRequest(
      'createAndBind',
      function(ap, vp, local, weidgth, height, fr, url, cb, op) {
        natives.StartCastRtpReceiver(
            ap, vp, local, weidgth, height, fr, url, cb, op);
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var Event = require('event_bindings').Event;
var sendRequest = require('sendRequest').sendRequest;
var validate = require('schemaUtils').validate;

function extendSchema(schema) {
  var extendedSchema = $Array.slice(schema);
  $Array.unshift(extendedSchema, {'type': 'string'});
  return extendedSchema;
}

// TODO(devlin): Maybe find a way to combine this and ContentSetting.
function ChromeSetting(prefKey, valueSchema, schema) {
  var getFunctionParameters = function(name) {
    var f = $Array.filter(
                schema.functions, function(f) { return f.name === name; })[0];
    return f.parameters;
  };
  this.get = function(details, callback) {
    var getSchema = getFunctionParameters('get');
    validate([details, callback], getSchema);
    return sendRequest('types.ChromeSetting.get',
                       [prefKey, details, callback],
                       extendSchema(getSchema));
  };
  this.set = function(details, callback) {
    // The set schema included in the Schema object is generic, since it varies
    // per-setting. However, this is only ever for a single setting, so we can
    // enforce the types more thoroughly.
    var rawSetSchema = getFunctionParameters('set');
    var rawSettingParam = rawSetSchema[0];
    var props = $Object.assign({}, rawSettingParam.properties);
    props.value = valueSchema;
    var modSettingParam = {
      name: rawSettingParam.name,
      type: rawSettingParam.type,
      properties: props,
    };
    var modSetSchema = $Array.slice(rawSetSchema);
    modSetSchema[0] = modSettingParam;
    validate([details, callback], modSetSchema);
    return sendRequest('types.ChromeSetting.set',
                       [prefKey, details, callback],
                       extendSchema(modSetSchema));
  };
  this.clear = function(details, callback) {
    var clearSchema = getFunctionParameters('clear');
    validate([details, callback], clearSchema);
    return sendRequest('types.ChromeSetting.clear',
                       [prefKey, details, callback],
                       extendSchema(clearSchema));
  };
  this.onChange = new Event('types.ChromeSetting.' + prefKey + '.onChange');
};

exports.$set('ChromeSetting', ChromeSetting);
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var binding = apiBridge ||
              require('binding').Binding.create('chromeWebViewInternal');
var contextMenusHandlers = require('contextMenusHandlers');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  var handlers = contextMenusHandlers.create(true /* isWebview */);

  apiFunctions.setHandleRequest(
      'contextMenusCreate', handlers.requestHandlers.create);

  apiFunctions.setHandleRequest(
      'contextMenusUpdate', handlers.requestHandlers.update);

  apiFunctions.setHandleRequest(
      'contextMenusRemove', handlers.requestHandlers.remove);

  apiFunctions.setHandleRequest(
      'contextMenusRemoveAll', handlers.requestHandlers.removeAll);
});

if (!apiBridge)
  exports.$set('ChromeWebView', binding.generate());
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This module implements chrome-specific <webview> API.
// See web_view_api_methods.js for details.

var ChromeWebView = getInternalApi ?
    getInternalApi('chromeWebViewInternal') :
    require('chromeWebViewInternal').ChromeWebView;
var ChromeWebViewSchema =
    requireNative('schema_registry').GetSchema('chromeWebViewInternal');
var CreateEvent = require('guestViewEvents').CreateEvent;
var GuestViewInternalNatives = requireNative('guest_view_internal');
var idGeneratorNatives = requireNative('id_generator');
var utils = require('utils');
var WebViewImpl = require('webView').WebViewImpl;

// This is the only "webViewInternal.onClicked" named event for this renderer.
//
// Since we need an event per <webview>, we define events with suffix
// (subEventName) in each of the <webview>. Behind the scenes, this event is
// registered as a ContextMenusEvent, with filter set to the webview's
// |viewInstanceId|. Any time a ContextMenusEvent is dispatched, we re-dispatch
// it to the subEvent's listeners. This way
// <webview>.contextMenus.onClicked behave as a regular chrome Event type.
var ContextMenusEvent = CreateEvent('chromeWebViewInternal.onClicked');
// See comment above.
var ContextMenusHandlerEvent =
    CreateEvent('chromeWebViewInternal.onContextMenuShow');

var jsEvent;
function createCustomEvent(name, schema, options, webviewId) {
  if (bindingUtil)
    return bindingUtil.createCustomEvent(name, undefined, false, false);
  if (!jsEvent)
    jsEvent = require('event_bindings').Event;
  return new jsEvent(name, schema, options, webviewId);
}

// This event is exposed as <webview>.contextMenus.onClicked.
function createContextMenusOnClickedEvent(webViewInstanceId,
                                          opt_eventName,
                                          opt_argSchemas,
                                          opt_eventOptions) {
  var subEventName = GetUniqueSubEventName(opt_eventName);
  var newEvent = createCustomEvent(subEventName, opt_argSchemas,
                                   opt_eventOptions, webViewInstanceId);

  var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId);
  if (view) {
    view.events.addScopedListener(
        ContextMenusEvent,
        $Function.bind(function() {
          // Re-dispatch to subEvent's listeners.
          $Function.apply(newEvent.dispatch, newEvent, $Array.slice(arguments));
        }, newEvent),
        {instanceId: webViewInstanceId});
  }
  return newEvent;
}

// This event is exposed as <webview>.contextMenus.onShow.
function createContextMenusOnContextMenuEvent(webViewInstanceId,
                                              opt_eventName,
                                              opt_argSchemas,
                                              opt_eventOptions) {
  var subEventName = GetUniqueSubEventName(opt_eventName);
  var newEvent = createCustomEvent(subEventName, opt_argSchemas,
                                   opt_eventOptions, webViewInstanceId);

  var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId);
  if (view) {
    view.events.addScopedListener(
        ContextMenusHandlerEvent,
        $Function.bind(function(e) {
          var defaultPrevented = false;
          var event = {
            preventDefault: function() { defaultPrevented = true; }
          };

          // Re-dispatch to subEvent's listeners.
          $Function.apply(newEvent.dispatch, newEvent, [event]);

          if (!defaultPrevented) {
          // TODO(lazyboy): Remove |items| parameter completely from
          // ChromeWebView.showContextMenu as we don't do anything useful with
          // it currently.
          var items = [];
          var guestInstanceId = GuestViewInternalNatives.
              GetViewFromID(webViewInstanceId).guest.getId();
          ChromeWebView.showContextMenu(guestInstanceId, e.requestId, items);
        }
      }, newEvent),
      {instanceId: webViewInstanceId});
  }

  return newEvent;
}

// -----------------------------------------------------------------------------
// WebViewContextMenusImpl object.

// An instance of this class is exposed as <webview>.contextMenus.
function WebViewContextMenusImpl(viewInstanceId) {
  this.viewInstanceId_ = viewInstanceId;
}
$Object.setPrototypeOf(WebViewContextMenusImpl.prototype, null);

WebViewContextMenusImpl.prototype.create = function() {
  var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
  return $Function.apply(ChromeWebView.contextMenusCreate, null, args);
};

WebViewContextMenusImpl.prototype.remove = function() {
  var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
  return $Function.apply(ChromeWebView.contextMenusRemove, null, args);
};

WebViewContextMenusImpl.prototype.removeAll = function() {
  var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
  return $Function.apply(ChromeWebView.contextMenusRemoveAll, null, args);
};

WebViewContextMenusImpl.prototype.update = function() {
  var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
  return $Function.apply(ChromeWebView.contextMenusUpdate, null, args);
};

function WebViewContextMenus() {
  privates(WebViewContextMenus).constructPrivate(this, arguments);
}
utils.expose(WebViewContextMenus, WebViewContextMenusImpl, {
  functions: [
    'create',
    'remove',
    'removeAll',
    'update',
  ],
});

// -----------------------------------------------------------------------------

WebViewImpl.prototype.maybeSetupContextMenus = function() {
  if (!this.contextMenusOnContextMenuEvent_) {
    var eventName = 'chromeWebViewInternal.onContextMenuShow';
    var eventSchema =
        utils.lookup(ChromeWebViewSchema.events, 'name', 'onShow');
    var eventOptions = {supportsListeners: true, supportsLazyListeners: false};
    this.contextMenusOnContextMenuEvent_ = createContextMenusOnContextMenuEvent(
        this.viewInstanceId, eventName, eventSchema, eventOptions);
  }

  var createContextMenus = $Function.bind(function() {
    return this.weakWrapper(function() {
      if (this.contextMenus_) {
        return this.contextMenus_;
      }

      this.contextMenus_ = new WebViewContextMenus(this.viewInstanceId);

      // Define 'onClicked' event property on |this.contextMenus_|.
      var getOnClickedEvent = $Function.bind(function() {
        return this.weakWrapper(function() {
          if (!this.contextMenusOnClickedEvent_) {
            var eventName = 'chromeWebViewInternal.onClicked';
            var eventSchema =
                utils.lookup(ChromeWebViewSchema.events, 'name', 'onClicked');
            var eventOptions =
                {supportsListeners: true, supportsLazyListeners: false};
            var onClickedEvent = createContextMenusOnClickedEvent(
                this.viewInstanceId, eventName, eventSchema, eventOptions);
            this.contextMenusOnClickedEvent_ = onClickedEvent;
            return onClickedEvent;
          }
          return this.contextMenusOnClickedEvent_;
        });
      }, this);
      $Object.defineProperty(
          this.contextMenus_,
          'onClicked',
          {get: getOnClickedEvent(), enumerable: true});
      $Object.defineProperty(
          this.contextMenus_,
          'onShow',
          {
            get: this.weakWrapper(function() {
              return this.contextMenusOnContextMenuEvent_;
            }),
            enumerable: true
          });
      return this.contextMenus_;
    });
  }, this);

  // Expose <webview>.contextMenus object.
  $Object.defineProperty(
      this.element,
      'contextMenus',
      {
        get: createContextMenus(),
        enumerable: true
      });
};

function GetUniqueSubEventName(eventName) {
  return eventName + '/' + idGeneratorNatives.GetNextId();
}
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the contentSettings API.

var sendRequest = require('sendRequest').sendRequest;
var validate = require('schemaUtils').validate;

// Some content types have been removed and no longer correspond to a real
// content setting. Instead, these always return a fixed dummy value, and issue
// a warning when accessed. This maps the content type name to the dummy value.
var DEPRECATED_CONTENT_TYPES = {
  __proto__: null,

  fullscreen: 'allow',
  mouselock: 'allow',
};

function extendSchema(schema) {
  var extendedSchema = $Array.slice(schema);
  $Array.unshift(extendedSchema, {'type': 'string'});
  return extendedSchema;
}

function ContentSetting(contentType, settingSchema, schema) {
  var getFunctionParameters = function(name) {
    var f = $Array.filter(
                schema.functions, function(f) { return f.name === name; })[0];
    return f.parameters;
  };
  this.get = function(details, callback) {
    var getSchema = getFunctionParameters('get');
    validate([details, callback], getSchema);

    var dummySetting = DEPRECATED_CONTENT_TYPES[contentType];
    if (dummySetting !== undefined) {
      console.warn('contentSettings.' + contentType + ' is deprecated; it will '
                   + 'always return \'' + dummySetting + '\'.');
      $Function.apply(callback, undefined, [{setting: dummySetting}]);
      return;
    }

    return sendRequest('contentSettings.get',
                       [contentType, details, callback],
                       extendSchema(getSchema));
  };

  this.set = function(details, callback) {
    // We check if the setting is deprecated first, since the validation will
    // fail for deprecated types.
    if ($Object.hasOwnProperty(DEPRECATED_CONTENT_TYPES, contentType)) {
      console.warn('contentSettings.' + contentType + ' is deprecated; setting '
                   + 'it has no effect.');
      $Function.apply(callback, undefined, []);
      return;
    }

    // The set schema included in the Schema object is generic, since it varies
    // per-setting. However, this is only ever for a single setting, so we can
    // enforce the types more thoroughly.
    var rawSetSchema = getFunctionParameters('set');
    var rawSettingParam = rawSetSchema[0];
    var props = $Object.assign({}, rawSettingParam.properties);
    props.setting = settingSchema;
    var modSettingParam = {
      name: rawSettingParam.name,
      type: rawSettingParam.type,
      properties: props,
    };
    var modSetSchema = $Array.slice(rawSetSchema);
    modSetSchema[0] = modSettingParam;
    validate([details, callback], modSetSchema);

    return sendRequest('contentSettings.set',
                       [contentType, details, callback],
                       extendSchema(modSetSchema));
  };

  this.clear = function(details, callback) {
    var clearSchema = getFunctionParameters('clear');
    validate([details, callback], clearSchema);

    if ($Object.hasOwnProperty(DEPRECATED_CONTENT_TYPES, contentType)) {
      console.warn('contentSettings.' + contentType + ' is deprecated; '
                   + 'clearing it has no effect.');
      $Function.apply(callback, undefined, []);
      return;
    }

    return sendRequest('contentSettings.clear',
                       [contentType, details, callback],
                       extendSchema(clearSchema));
  };

  this.getResourceIdentifiers = function(callback) {
    var schema = getFunctionParameters('getResourceIdentifiers');
    validate([callback], schema);

    if ($Object.hasOwnProperty(DEPRECATED_CONTENT_TYPES, contentType)) {
      $Function.apply(callback, undefined, []);
      return;
    }

    return sendRequest(
        'contentSettings.getResourceIdentifiers',
        [contentType, callback],
        extendSchema(schema));
  };
}

exports.$set('ContentSetting', ContentSetting);
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the declarativeContent API.

var binding =
    apiBridge || require('binding').Binding.create('declarativeContent');

if (!apiBridge) {
  var utils = require('utils');
  var validate = require('schemaUtils').validate;
  var canonicalizeCompoundSelector =
      requireNative('css_natives').CanonicalizeCompoundSelector;
}

var setIcon = require('setIcon').setIcon;

binding.registerCustomHook(function(api) {
  var declarativeContent = api.compiledApi;

  if (apiBridge) {
    // Validation for most types is done in the native C++ with native bindings,
    // but setIcon is funny (and sadly broken). Ideally, we can move this
    // validation entirely into the native code, and this whole file can go
    // away.
    var nativeSetIcon = declarativeContent.SetIcon;
    declarativeContent.SetIcon = function(parameters) {
      // TODO(devlin): This is very, very wrong. setIcon() is potentially
      // asynchronous (in the case of a path being specified), which means this
      // becomes an "asynchronous constructor". Errors can be thrown *after* the
      // `new declarativeContent.SetIcon(...)` call, and in the async cases,
      // this wouldn't work when we immediately add the action via an API call
      // (e.g.,
      //   chrome.declarativeContent.onPageChange.addRules(
      //       [{conditions: ..., actions: [ new SetIcon(...) ]}]);
      // ). Some of this is tracked in http://crbug.com/415315.
      setIcon(parameters, $Function.bind(function(data) {
        // Fake calling the original function as a constructor.
        $Object.setPrototypeOf(this, nativeSetIcon.prototype);
        $Function.apply(nativeSetIcon, this, [data]);
      }, this));
    };
    return;
  }

  // Returns the schema definition of type |typeId| defined in |namespace|.
  function getSchema(typeId) {
    return utils.lookup(api.schema.types,
                        'id',
                        'declarativeContent.' + typeId);
  }

  // Helper function for the constructor of concrete datatypes of the
  // declarative content API.
  // Makes sure that |this| contains the union of parameters and
  // {'instanceType': 'declarativeContent.' + typeId} and validates the
  // generated union dictionary against the schema for |typeId|.
  function setupInstance(instance, parameters, typeId) {
    for (var key in parameters) {
      if ($Object.hasOwnProperty(parameters, key)) {
        instance[key] = parameters[key];
      }
    }
    instance.instanceType = 'declarativeContent.' + typeId;
    var schema = getSchema(typeId);
    validate([instance], [schema]);
  }

  function canonicalizeCssSelectors(selectors) {
    for (var i = 0; i < selectors.length; i++) {
      var canonicalizedSelector = canonicalizeCompoundSelector(selectors[i]);
      if (canonicalizedSelector == '') {
        throw new Error(
            'Element of \'css\' array must be a ' +
            'list of valid compound selectors: ' +
            selectors[i]);
      }
      selectors[i] = canonicalizedSelector;
    }
  }

  // Setup all data types for the declarative content API.
  declarativeContent.PageStateMatcher = function(parameters) {
    setupInstance(this, parameters, 'PageStateMatcher');
    if ($Object.hasOwnProperty(this, 'css')) {
      canonicalizeCssSelectors(this.css);
    }
  };
  declarativeContent.ShowPageAction = function(parameters) {
    setupInstance(this, parameters, 'ShowPageAction');
  };
  declarativeContent.RequestContentScript = function(parameters) {
    setupInstance(this, parameters, 'RequestContentScript');
  };
  // TODO(rockot): Do not expose this in M39 stable. Making this restriction
  // possible will take some extra work. See http://crbug.com/415315
  // Note: See also the SetIcon wrapper above for more issues.
  declarativeContent.SetIcon = function(parameters) {
    setIcon(parameters, $Function.bind(function(data) {
      setupInstance(this, data, 'SetIcon');
    }, this));
  };
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the desktopCapture API.

var binding = apiBridge || require('binding').Binding.create('desktopCapture');
var sendRequest = bindingUtil ?
    $Function.bind(bindingUtil.sendRequest, bindingUtil) :
    require('sendRequest').sendRequest;
var idGenerator = requireNative('id_generator');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  var pendingRequests = {};

  function onRequestResult(id, result, options) {
    if (id in pendingRequests) {
      var callback = pendingRequests[id];
      delete pendingRequests[id];
      callback(result, options);
    }
  }

  apiFunctions.setHandleRequest('chooseDesktopMedia',
                                function(sources, target_tab, callback) {
    // |target_tab| is an optional parameter.
    if (callback === undefined) {
      callback = target_tab;
      target_tab = undefined;
    }
    var id = idGenerator.GetNextId();
    pendingRequests[id] = callback;
    sendRequest('desktopCapture.chooseDesktopMedia',
                [id, sources, target_tab,
                 $Function.bind(onRequestResult, null, id)],
                apiBridge ? undefined : this.definition.parameters,
                undefined);
    return id;
  });

  apiFunctions.setHandleRequest('cancelChooseDesktopMedia', function(id) {
    if (id in pendingRequests) {
      delete pendingRequests[id];
      sendRequest('desktopCapture.cancelChooseDesktopMedia',
                  [id], apiBridge ? undefined : this.definition.parameters,
                  undefined);
    }
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the developerPrivate API.

var binding =
    apiBridge || require('binding').Binding.create('developerPrivate');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  // Converts the argument of |functionName| from DirectoryEntry to URL.
  function bindFileSystemFunction(functionName) {
    apiFunctions.setUpdateArgumentsPostValidate(
        functionName, function(directoryEntry, callback) {
          var fileSystemName = directoryEntry.filesystem.name;
          var relativePath = $String.slice(directoryEntry.fullPath, 1);
          var url = directoryEntry.toURL();
          return [fileSystemName, relativePath, url, callback];
    });
  }

  bindFileSystemFunction('loadDirectory');

  // developerPrivate.enable is the same as chrome.management.setEnabled.
  // TODO(devlin): Migrate callers off developerPrivate.enable.
  bindingsAPI.compiledApi.enable = chrome.management.setEnabled;

  apiFunctions.setHandleRequest('allowFileAccess',
                                function(id, allow, callback) {
    chrome.developerPrivate.updateExtensionConfiguration(
        {extensionId: id, fileAccess: allow}, callback);
  });

  apiFunctions.setHandleRequest('allowIncognito',
                                function(id, allow, callback) {
    chrome.developerPrivate.updateExtensionConfiguration(
        {extensionId: id, incognitoAccess: allow}, callback);
  });

  apiFunctions.setHandleRequest('inspect', function(options, callback) {
    var renderViewId = options.render_view_id;
    if (typeof renderViewId == 'string') {
      renderViewId = parseInt(renderViewId);
      if (isNaN(renderViewId))
        throw new Error('Invalid value for render_view_id');
    }
    var renderProcessId = options.render_process_id;
    if (typeof renderProcessId == 'string') {
      renderProcessId = parseInt(renderProcessId);
      if (isNaN(renderProcessId))
        throw new Error('Invalid value for render_process_id');
    }
    chrome.developerPrivate.openDevTools({
        extensionId: options.extension_id,
        renderProcessId: renderProcessId,
        renderViewId: renderViewId,
        incognito: options.incognito
    }, callback);
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom bindings for the downloads API.

var binding = apiBridge || require('binding').Binding.create('downloads');
var downloadsInternal =
    getInternalApi ?
        getInternalApi('downloadsInternal') :
        require('binding').Binding.create('downloadsInternal').generate();
var registerArgumentMassager = bindingUtil ?
    $Function.bind(bindingUtil.registerEventArgumentMassager, bindingUtil) :
    require('event_bindings').registerArgumentMassager;

registerArgumentMassager('downloads.onDeterminingFilename',
                         function(args, dispatch) {
  var downloadItem = args[0];
  // Copy the id so that extensions can't change it.
  var downloadId = downloadItem.id;
  var suggestable = true;
  function isValidResult(result) {
    if (result === undefined)
      return false;
    if (typeof(result) != 'object') {
      console.error('Error: Invocation of form suggest(' + typeof(result) +
                    ') doesn\'t match definition suggest({filename: string, ' +
                    'conflictAction: string})');
      return false;
    } else if ((typeof(result.filename) != 'string') ||
               (result.filename.length == 0)) {
      console.error('Error: "filename" parameter to suggest() must be a ' +
                    'non-empty string');
      return false;
    } else if ([undefined, 'uniquify', 'overwrite', 'prompt'].indexOf(
                 result.conflictAction) < 0) {
      console.error('Error: "conflictAction" parameter to suggest() must be ' +
                    'one of undefined, "uniquify", "overwrite", "prompt"');
      return false;
    }
    return true;
  }
  function suggestCallback(result) {
    if (!suggestable) {
      console.error('suggestCallback may not be called more than once.');
      return;
    }
    suggestable = false;
    if (isValidResult(result)) {
      downloadsInternal.determineFilename(
          downloadId, result.filename, result.conflictAction || "");
    } else {
      downloadsInternal.determineFilename(downloadId, "", "");
    }
  }
  try {
    var results = dispatch([downloadItem, suggestCallback]);
    var async = (results &&
                 results.results &&
                 (results.results.length != 0) &&
                 (results.results[0] === true));
    if (suggestable && !async)
      suggestCallback();
  } catch (e) {
    suggestCallback();
    throw e;
  }
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var Event = require('event_bindings').Event;

// The EasyUnlockProximityRequired object is just a stub that has an onChange
// event, which is never triggered.
// TODO(devlin): Remove this once the preferencesPrivate API is fully removed.
// https://crbug.com/593166
function EasyUnlockProximityRequired(prefKey, valueSchema, schema) {
  // Note: technically, extensions could intercept this through a setter on
  // Object.prototype(). We don't really care, because a) this is only for a
  // private API, so we shouldn't have to worry about untrusted code, and b)
  // this is an anonymous event, which exposes no attack surface and will be
  // exposed to the extension anyway.
  this.onChange = new Event();
};

exports.$set('EasyUnlockProximityRequired', EasyUnlockProximityRequired);
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom bindings for the feedbackPrivate API.

var binding = apiBridge || require('binding').Binding.create('feedbackPrivate');

var blobNatives = requireNative('blob_natives');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;
  apiFunctions.setUpdateArgumentsPostValidate(
      "sendFeedback", function(feedbackInfo, callback) {
    var attachedFileBlobUuid = '';
    var screenshotBlobUuid = '';

    if (feedbackInfo.attachedFile)
      attachedFileBlobUuid =
          blobNatives.GetBlobUuid(feedbackInfo.attachedFile.data);
    if (feedbackInfo.screenshot)
      screenshotBlobUuid =
          blobNatives.GetBlobUuid(feedbackInfo.screenshot);

    feedbackInfo.attachedFileBlobUuid = attachedFileBlobUuid;
    feedbackInfo.screenshotBlobUuid = screenshotBlobUuid;

    return [feedbackInfo, callback];
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the GCM API.

var binding = apiBridge || require('binding').Binding.create('gcm');
var forEach = require('utils').forEach;

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;
  var gcm = bindingsAPI.compiledApi;

  apiFunctions.setUpdateArgumentsPostValidate(
    'send', function(message, callback) {
      // Validate message.data.
      var payloadSize = 0;
      forEach(message.data, function(property, value) {
        if (property.length == 0)
          throw new Error("One of data keys is empty.");

        var lowerCasedProperty = property.toLowerCase();
        // Issue an error for forbidden prefixes of property names.
        if (lowerCasedProperty.startsWith("goog.") ||
            lowerCasedProperty.startsWith("google") ||
            property.startsWith("collapse_key")) {
          throw new Error("Invalid data key: " + property);
        }

        payloadSize += property.length + value.length;
      });

      if (payloadSize > gcm.MAX_MESSAGE_SIZE)
        throw new Error("Payload exceeded allowed size limit. Payload size is: "
            + payloadSize);

      if (payloadSize == 0)
        throw new Error("No data to send.");

      return arguments;
    });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Identity API.

var binding = apiBridge || require('binding').Binding.create('identity');

binding.registerCustomHook(function(binding, id, contextType) {
  var apiFunctions = binding.apiFunctions;

  apiFunctions.setHandleRequest('getRedirectURL', function(path) {
    if (path === null || path === undefined)
      path = '/';
    else
      path = String(path);
    if (path[0] != '/')
      path = '/' + path;
    return 'https://' + id + '.chromiumapp.org' + path;
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the image writer private API.

var binding =
    apiBridge || require('binding').Binding.create('imageWriterPrivate');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setUpdateArgumentsPostValidate(
      'writeFromFile', function(device, fileEntry, options, callback) {
    var fileSystemName = fileEntry.filesystem.name;
    var relativePath = $String.slice(fileEntry.fullPath, 1);
    return [device, fileSystemName, relativePath, callback];
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the input ime API. Only injected into the
// v8 contexts for extensions which have permission for the API.

var binding = apiBridge || require('binding').Binding.create('input.ime');
var appWindowNatives = requireNative('app_window_natives');
var registerArgumentMassager = bindingUtil ?
    $Function.bind(bindingUtil.registerEventArgumentMassager, bindingUtil) :
    require('event_bindings').registerArgumentMassager;

// TODO(crbug.com/733825): These bindings have some issues.

var inputIme;
registerArgumentMassager('input.ime.onKeyEvent',
                         function(args, dispatch) {
  var keyData = args[1];
  var result = false;
  try {
    // dispatch() is weird - it returns an object {results: array<results>} iff
    // there is at least one result value that !== undefined. Since onKeyEvent
    // has a maximum of one listener, we know that any result we find is the one
    // we're interested in.
    var dispatchResult = dispatch(args);
    if (dispatchResult && dispatchResult.results)
      result = dispatchResult.results[0];
  } catch (e) {
    console.error('Error in event handler for onKeyEvent: ' + e.stack);
  }
  if (!inputIme.onKeyEvent.async)
    inputIme.keyEventHandled(keyData.requestId, result);
});

binding.registerCustomHook(function(api) {
 inputIme = api.compiledApi;

  var originalAddListener = inputIme.onKeyEvent.addListener;
  inputIme.onKeyEvent.addListener = function(cb, opt_extraInfo) {
    inputIme.onKeyEvent.async = false;
    if (opt_extraInfo instanceof Array) {
      for (var i = 0; i < opt_extraInfo.length; ++i) {
        if (opt_extraInfo[i] == 'async') {
          inputIme.onKeyEvent.async = true;
        }
      }
    }
    $Function.call(originalAddListener, this, cb);
  };

  api.apiFunctions.setCustomCallback('createWindow',
      function(name, request, callback, windowParams) {
    if (!callback) {
      return;
    }
    var view;
    if (windowParams && windowParams.frameId) {
      view = appWindowNatives.GetFrame(
          windowParams.frameId, false /* notifyBrowser */);
      view.id = windowParams.frameId;
    }
    callback(view);
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Media Gallery API.

var binding = apiBridge || require('binding').Binding.create('mediaGalleries');
var blobNatives = requireNative('blob_natives');
var mediaGalleriesNatives = requireNative('mediaGalleries');
var sendRequest = bindingUtil ?
    $Function.bind(bindingUtil.sendRequest, bindingUtil) :
    require('sendRequest').sendRequest;

var blobsAwaitingMetadata = {};
var mediaGalleriesMetadata = {};

function createFileSystemObjectsAndUpdateMetadata(response) {
  var result = [];
  mediaGalleriesMetadata = {};  // Clear any previous metadata.
  if (response) {
    for (var i = 0; i < response.length; i++) {
      var filesystem = mediaGalleriesNatives.GetMediaFileSystemObject(
          response[i].fsid);
      $Array.push(result, filesystem);
      var metadata = response[i];
      delete metadata.fsid;
      mediaGalleriesMetadata[filesystem.name] = metadata;
    }
  }
  return result;
}

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;

  // getMediaFileSystems and addUserSelectedFolder use a custom callback so that
  // they can instantiate and return an array of file system objects.
  apiFunctions.setCustomCallback('getMediaFileSystems',
                                 function(name, request, callback, response) {
    var result = createFileSystemObjectsAndUpdateMetadata(response);
    if (callback)
      callback(result);
  });

  apiFunctions.setCustomCallback('addUserSelectedFolder',
      function(name, request, callback, response) {
    var fileSystems = [];
    var selectedFileSystemName = "";
    if (response && 'mediaFileSystems' in response &&
        'selectedFileSystemIndex' in response) {
      fileSystems = createFileSystemObjectsAndUpdateMetadata(
          response['mediaFileSystems']);
      var selectedFileSystemIndex = response['selectedFileSystemIndex'];
      if (selectedFileSystemIndex >= 0) {
        selectedFileSystemName = fileSystems[selectedFileSystemIndex].name;
      }
    }
    if (callback)
      callback(fileSystems, selectedFileSystemName);
  });

  apiFunctions.setHandleRequest('getMediaFileSystemMetadata',
                                function(filesystem) {
    if (filesystem && filesystem.name &&
        filesystem.name in mediaGalleriesMetadata) {
      return mediaGalleriesMetadata[filesystem.name];
    }
    return {
      'name': '',
      'galleryId': '',
      'isRemovable': false,
      'isMediaDevice': false,
      'isAvailable': false,
    };
  });

  function getMetadataCallback(uuid, name, request, callback, response) {
    if (response && response.attachedImagesBlobInfo) {
      for (var i = 0; i < response.attachedImagesBlobInfo.length; i++) {
        var blobInfo = response.attachedImagesBlobInfo[i];
        var blob = blobNatives.TakeBrowserProcessBlob(
            blobInfo.blobUUID, blobInfo.type, blobInfo.size);
        response.metadata.attachedImages.push(blob);
      }
    }

    if (callback)
      callback(response ? response.metadata : null);

    delete blobsAwaitingMetadata[uuid];
  }

  apiFunctions.setHandleRequest('getMetadata',
                                function(mediaFile, options, callback) {
    var blobUuid = blobNatives.GetBlobUuid(mediaFile)
    // Store the blob in a global object to keep its refcount nonzero -- this
    // prevents the object from being garbage collected before any metadata
    // parsing gets to occur (see crbug.com/415792).
    blobsAwaitingMetadata[blobUuid] = mediaFile;

    var optArgs = {
      __proto__: null,
      customCallback: $Function.bind(getMetadataCallback, null, blobUuid),
    };

    sendRequest('mediaGalleries.getMetadata', [blobUuid, options, callback],
                bindingUtil ? undefined : this.definition.parameters, optArgs);
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom bindings for the notifications API.
//
var binding = apiBridge || require('binding').Binding.create('notifications');

var sendRequest = bindingUtil ?
    $Function.bind(bindingUtil.sendRequest, bindingUtil) :
    require('sendRequest').sendRequest;
var exceptionHandler = require('uncaught_exception_handler');
var imageUtil = require('imageUtil');
var notificationsPrivate = requireNative('notifications_private');

var jsLastError = bindingUtil ? undefined : require('lastError');
function runCallbackWithLastError(name, message, stack, callback, args) {
  if (bindingUtil) {
    bindingUtil.runCallbackWithLastError(message, function() {
      $Function.apply(callback, null, args);
    });
  } else {
    jsLastError.run(name, message, stack, callback, args);
  }
}

function imageDataSetter(context, key) {
  var f = function(val) {
    this[key] = val;
  };
  return $Function.bind(f, context);
}

// A URL Spec is an object with the following keys:
//  path: The resource to be downloaded.
//  width: (optional) The maximum width of the image to be downloaded in device
//         pixels.
//  height: (optional) The maximum height of the image to be downloaded in
//          device pixels.
//  callback: A function to be called when the URL is complete. It
//    should accept an ImageData object and set the appropriate
//    field in |notificationDetails|.
function getUrlSpecs(imageSizes, notificationDetails) {
  var urlSpecs = [];

  // |iconUrl| might be optional for notification updates.
  if (notificationDetails.iconUrl) {
    $Array.push(urlSpecs, {
      path: notificationDetails.iconUrl,
      width: imageSizes.icon.width * imageSizes.scaleFactor,
      height: imageSizes.icon.height * imageSizes.scaleFactor,
      callback: imageDataSetter(notificationDetails, 'iconBitmap')
    });
  }

  // |appIconMaskUrl| is optional.
  if (notificationDetails.appIconMaskUrl) {
    $Array.push(urlSpecs, {
      path: notificationDetails.appIconMaskUrl,
      width: imageSizes.appIconMask.width * imageSizes.scaleFactor,
      height: imageSizes.appIconMask.height * imageSizes.scaleFactor,
      callback: imageDataSetter(notificationDetails, 'appIconMaskBitmap')
    });
  }

  // |imageUrl| is optional.
  if (notificationDetails.imageUrl) {
    $Array.push(urlSpecs, {
      path: notificationDetails.imageUrl,
      width: imageSizes.image.width * imageSizes.scaleFactor,
      height: imageSizes.image.height * imageSizes.scaleFactor,
      callback: imageDataSetter(notificationDetails, 'imageBitmap')
    });
  }

  // Each button has an optional icon.
  var buttonList = notificationDetails.buttons;
  if (buttonList && typeof buttonList.length === 'number') {
    var numButtons = buttonList.length;
    for (var i = 0; i < numButtons; i++) {
      if (buttonList[i].iconUrl) {
        $Array.push(urlSpecs, {
          path: buttonList[i].iconUrl,
          width: imageSizes.buttonIcon.width * imageSizes.scaleFactor,
          height: imageSizes.buttonIcon.height * imageSizes.scaleFactor,
          callback: imageDataSetter(buttonList[i], 'iconBitmap')
        });
      }
    }
  }

  return urlSpecs;
}

function replaceNotificationOptionURLs(notification_details, callback) {
  var imageSizes = notificationsPrivate.GetNotificationImageSizes();
  var url_specs = getUrlSpecs(imageSizes, notification_details);
  if (!url_specs.length) {
    callback(true);
    return;
  }

  var errors = 0;

  imageUtil.loadAllImages(url_specs, {
    onerror: function(index) {
      errors++;
    },
    oncomplete: function(imageData) {
      if (errors > 0) {
        callback(false);
        return;
      }
      for (var index = 0; index < url_specs.length; index++) {
        var url_spec = url_specs[index];
        url_spec.callback(imageData[index]);
      }
      callback(true);
    }
  });
}

function genHandle(name, failure_function) {
  return function(id, input_notification_details, callback) {
    // TODO(dewittj): Remove this hack. This is used as a way to deep
    // copy a complex JSON object.
    var notification_details = $JSON.parse(
        $JSON.stringify(input_notification_details));
    var that = this;
    var stack = exceptionHandler.getExtensionStackTrace();
    replaceNotificationOptionURLs(notification_details, function(success) {
      if (success) {
        sendRequest(
            name, [id, notification_details, callback],
            bindingUtil ? undefined : that.definition.parameters,
            bindingUtil ? undefined : {__proto__: null, stack: stack});
        return;
      }
      runCallbackWithLastError(
          name, 'Unable to download all specified images.',
          stack, failure_function, [callback || function() {}, id]);
    });
  };
}

var handleCreate = genHandle('notifications.create',
                             function(callback, id) { callback(id); });
var handleUpdate = genHandle('notifications.update',
                             function(callback, id) { callback(false); });

var notificationsCustomHook = function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;
  apiFunctions.setHandleRequest('create', handleCreate);
  apiFunctions.setHandleRequest('update', handleUpdate);
};

binding.registerCustomHook(notificationsCustomHook);

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the omnibox API. Only injected into the v8 contexts
// for extensions which have permission for the omnibox API.

var binding = apiBridge || require('binding').Binding.create('omnibox');

var registerArgumentMassager = bindingUtil ?
    $Function.bind(bindingUtil.registerEventArgumentMassager, bindingUtil) :
    require('event_bindings').registerArgumentMassager;

var sendRequest = bindingUtil ?
    $Function.bind(bindingUtil.sendRequest, bindingUtil) :
    require('sendRequest').sendRequest;

// Remove invalid characters from |text| so that it is suitable to use
// for |AutocompleteMatch::contents|.
function sanitizeString(text, shouldTrim) {
  // NOTE: This logic mirrors |AutocompleteMatch::SanitizeString()|.
  // 0x2028 = line separator; 0x2029 = paragraph separator.
  var kRemoveChars = /(\r|\n|\t|\u2028|\u2029)/gm;
  if (shouldTrim)
    text = text.trimLeft();
  return text.replace(kRemoveChars, '');
}

// Parses the xml syntax supported by omnibox suggestion results. Returns an
// object with two properties: 'description', which is just the text content,
// and 'descriptionStyles', which is an array of style objects in a format
// understood by the C++ backend.
function parseOmniboxDescription(input) {
  var domParser = new DOMParser();

  // The XML parser requires a single top-level element, but we want to
  // support things like 'hello, <match>world</match>!'. So we wrap the
  // provided text in generated root level element.
  var root = domParser.parseFromString(
      '<fragment>' + input + '</fragment>', 'text/xml');

  // DOMParser has a terrible error reporting facility. Errors come out nested
  // inside the returned document.
  var error = root.querySelector('parsererror div');
  if (error) {
    throw new Error(error.textContent);
  }

  // Otherwise, it's valid, so build up the result.
  var result = {
    description: '',
    descriptionStyles: []
  };

  // Recursively walk the tree.
  function walk(node) {
    for (var i = 0, child; child = node.childNodes[i]; i++) {
      // Append text nodes to our description.
      if (child.nodeType == Node.TEXT_NODE) {
        var shouldTrim = result.description.length == 0;
        result.description += sanitizeString(child.nodeValue, shouldTrim);
        continue;
      }

      // Process and descend into a subset of recognized tags.
      if (child.nodeType == Node.ELEMENT_NODE &&
          (child.nodeName == 'dim' || child.nodeName == 'match' ||
           child.nodeName == 'url')) {
        var style = {
          'type': child.nodeName,
          'offset': result.description.length
        };
        $Array.push(result.descriptionStyles, style);
        walk(child);
        style.length = result.description.length - style.offset;
        continue;
      }

      // Descend into all other nodes, even if they are unrecognized, for
      // forward compat.
      walk(child);
    }
  };
  walk(root);

  return result;
}

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setUpdateArgumentsPreValidate('setDefaultSuggestion',
                                             function(suggestResult) {
    if (suggestResult.content != undefined) {  // null, etc.
      throw new Error(
          'setDefaultSuggestion cannot contain the "content" field');
    }
    return [suggestResult];
  });

  apiFunctions.setHandleRequest('setDefaultSuggestion', function(details) {
    var parseResult = parseOmniboxDescription(details.description);
    sendRequest('omnibox.setDefaultSuggestion', [parseResult],
                bindingUtil ? undefined : this.definition.parameters,
                undefined);
  });

  apiFunctions.setUpdateArgumentsPostValidate(
      'sendSuggestions', function(requestId, userSuggestions) {
    var suggestions = [];
    for (var i = 0; i < userSuggestions.length; i++) {
      var parseResult = parseOmniboxDescription(
          userSuggestions[i].description);
      parseResult.content = userSuggestions[i].content;
      parseResult.deletable = userSuggestions[i].deletable;
      $Array.push(suggestions, parseResult);
    }
    return [requestId, suggestions];
  });
});

registerArgumentMassager('omnibox.onInputChanged', function(args, dispatch) {
  var text = args[0];
  var requestId = args[1];
  var suggestCallback = function(suggestions) {
    chrome.omnibox.sendSuggestions(requestId, suggestions);
  };
  dispatch([text, suggestCallback]);
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the pageAction API.

var binding = apiBridge || require('binding').Binding.create('pageAction');
var setIcon = require('setIcon').setIcon;
var sendRequest = bindingUtil ?
    $Function.bind(bindingUtil.sendRequest, bindingUtil) :
    require('sendRequest').sendRequest;

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('setIcon', function(details, callback) {
    setIcon(details, $Function.bind(function(args) {
      sendRequest('pageAction.setIcon', [args, callback],
                  bindingUtil ? undefined : this.definition.parameters,
                  undefined);
    }, this));
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the pageCapture API.

var binding = apiBridge || require('binding').Binding.create('pageCapture');

var handleUncaughtException = require('uncaught_exception_handler').handle;
var pageCaptureNatives = requireNative('page_capture');
var CreateBlob = pageCaptureNatives.CreateBlob;
var SendResponseAck = pageCaptureNatives.SendResponseAck;

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setCustomCallback('saveAsMHTML',
      function(name, request, callback, response) {
    if (response)
      response = CreateBlob(response.mhtmlFilePath, response.mhtmlFileLength);

    try {
      callback(response);
    } catch (e) {
      handleUncaughtException(
          'Error in chrome.pageCapture.saveAsMHTML callback', e, request.stack);
    } finally {
      // Notify the browser. Now that the blob is referenced from JavaScript,
      // the browser can drop its reference to it.
      SendResponseAck(request.id);
    }
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the syncFileSystem API.

var binding =
    apiBridge || require('binding').Binding.create('syncFileSystem');

var registerArgumentMassager = bindingUtil ?
    $Function.bind(bindingUtil.registerEventArgumentMassager, bindingUtil) :
    require('event_bindings').registerArgumentMassager;

var fileSystemNatives = requireNative('file_system_natives');
var syncFileSystemNatives = requireNative('sync_file_system');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  // Functions which take in an [instanceOf=FileEntry].
  function bindFileEntryFunction(functionName) {
    apiFunctions.setUpdateArgumentsPostValidate(
        functionName, function(entry, callback) {
      var fileSystemUrl = entry.toURL();
      return [fileSystemUrl, callback];
    });
  }
  $Array.forEach(['getFileStatus'], bindFileEntryFunction);

  // Functions which take in a FileEntry array.
  function bindFileEntryArrayFunction(functionName) {
    apiFunctions.setUpdateArgumentsPostValidate(
        functionName, function(entries, callback) {
      var fileSystemUrlArray = [];
      for (var i=0; i < entries.length; i++) {
        $Array.push(fileSystemUrlArray, entries[i].toURL());
      }
      return [fileSystemUrlArray, callback];
    });
  }
  $Array.forEach(['getFileStatuses'], bindFileEntryArrayFunction);

  // Functions which take in an [instanceOf=DOMFileSystem].
  function bindFileSystemFunction(functionName) {
    apiFunctions.setUpdateArgumentsPostValidate(
        functionName, function(filesystem, callback) {
      var fileSystemUrl = filesystem.root.toURL();
      return [fileSystemUrl, callback];
    });
  }
  $Array.forEach(['getUsageAndQuota'], bindFileSystemFunction);

  // Functions which return an [instanceOf=DOMFileSystem].
  apiFunctions.setCustomCallback('requestFileSystem',
      function(name, request, callback, response) {
    var result = null;
    if (response) {
      result = syncFileSystemNatives.GetSyncFileSystemObject(
          response.name, response.root);
    }
    if (callback)
      callback(result);
  });

  // Functions which return an array of FileStatusInfo object
  // which has [instanceOf=FileEntry].
  apiFunctions.setCustomCallback('getFileStatuses',
      function(name, request, callback, response) {
    var results = [];
    if (response) {
      for (var i = 0; i < response.length; i++) {
        var result = {};
        var entry = response[i].entry;
        result.fileEntry = fileSystemNatives.GetFileEntry(
            entry.fileSystemType,
            entry.fileSystemName,
            entry.rootUrl,
            entry.filePath,
            entry.isDirectory);
        result.status = response[i].status;
        result.error = response[i].error;
        $Array.push(results, result);
      }
    }
    if (callback)
      callback(results);
  });
});

registerArgumentMassager('syncFileSystem.onFileStatusChanged',
                         function(args, dispatch) {
  // Make FileEntry object using all the base string fields.
  var fileEntry = fileSystemNatives.GetFileEntry(
      args[0].fileSystemType,
      args[0].fileSystemName,
      args[0].rootUrl,
      args[0].filePath,
      args[0].isDirectory);

  // Combine into a single dictionary.
  var fileInfo = new Object();
  fileInfo.fileEntry = fileEntry;
  fileInfo.status = args[1];
  if (fileInfo.status == "synced") {
    fileInfo.action = args[2];
    fileInfo.direction = args[3];
  }
  dispatch([fileInfo]);
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the systemIndicator API.
// TODO(dewittj) Refactor custom binding to reduce redundancy between the
// extension action APIs.

var binding =
    apiBridge || require('binding').Binding.create('systemIndicator');

var setIcon = require('setIcon').setIcon;
var sendRequest = bindingUtil ?
    $Function.bind(bindingUtil.sendRequest, bindingUtil) :
    require('sendRequest').sendRequest;

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  apiFunctions.setHandleRequest('setIcon', function(details, callback) {
    setIcon(details, $Function.bind(function(args) {
      sendRequest('systemIndicator.setIcon', [args, callback],
                  bindingUtil ? undefined : this.definition.parameters,
                  undefined);
    }, this));
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the Tab Capture API.

var binding = apiBridge || require('binding').Binding.create('tabCapture');

var jsLastError = bindingUtil ? undefined : require('lastError');
function runCallbackWithLastError(name, message, stack, callback, args) {
  if (bindingUtil) {
    bindingUtil.runCallbackWithLastError(message, function() {
      $Function.apply(callback, null, args);
    });
  } else {
    jsLastError.run(name, message, stack, callback, args);
  }
}

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;

  function proxyToGetUserMedia(name, request, callback, response) {
    if (!callback)
      return;

    if (!response) {
      // When the response is missing, runtime.lastError has already been set.
      // See chrome/browser/extensions/api/tab_capture/tab_capture_api.cc.
      callback(null);
      return;
    }

    // Convenience function for processing webkitGetUserMedia() error objects to
    // provide runtime.lastError messages for the tab capture API.
    function getErrorMessage(error, fallbackMessage) {
      if (!error || (typeof error.message != 'string'))
        return fallbackMessage;
      return error.message.replace(/(navigator\.)?(webkit)?GetUserMedia/gi,
                                   name);
    }

    var options = {};
    if (response.audioConstraints)
      options.audio = response.audioConstraints;
    if (response.videoConstraints)
      options.video = response.videoConstraints;
    try {
      navigator.webkitGetUserMedia(
          options,
          function onSuccess(media_stream) {
            callback(media_stream);
          },
          function onError(error) {
            runCallbackWithLastError(
                name,
                getErrorMessage(error, "Failed to start MediaStream."),
                request.stack,
                function() { callback(null); });
          });
    } catch (error) {
      runCallbackWithLastError(
          name, getErrorMessage(error, "Invalid argument(s)."), request.stack,
          function() { callback(null); });
    }
  }

  apiFunctions.setCustomCallback('capture', proxyToGetUserMedia);
  apiFunctions.setCustomCallback('captureOffscreenTab', proxyToGetUserMedia);
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the tabs API.

var binding = apiBridge || require('binding').Binding.create('tabs');

var messaging = require('messaging');
var OpenChannelToTab = requireNative('messaging_natives').OpenChannelToTab;
var sendRequestIsDisabled = requireNative('process').IsSendRequestDisabled();
var forEach = require('utils').forEach;

binding.registerCustomHook(function(bindingsAPI, extensionId) {
  var apiFunctions = bindingsAPI.apiFunctions;
  var tabs = bindingsAPI.compiledApi;

  apiFunctions.setHandleRequest('connect', function(tabId, connectInfo) {
    var name = '';
    var frameId = -1;
    if (connectInfo) {
      name = connectInfo.name || name;
      frameId = connectInfo.frameId;
      if (typeof frameId == 'undefined' || frameId < 0)
        frameId = -1;
    }
    var portId = OpenChannelToTab(tabId, frameId, extensionId, name);
    return messaging.createPort(portId, name);
  });

  apiFunctions.setHandleRequest('sendRequest',
                                function(tabId, request, responseCallback) {
    if (sendRequestIsDisabled)
      throw new Error(sendRequestIsDisabled);
    var port = tabs.connect(tabId, {name: messaging.kRequestChannel});
    messaging.sendMessageImpl(port, request, responseCallback);
  });

  apiFunctions.setHandleRequest('sendMessage',
      function(tabId, message, options, responseCallback) {
    var connectInfo = {
      name: messaging.kMessageChannel
    };
    if (options) {
      forEach(options, function(k, v) {
        connectInfo[k] = v;
      });
    }

    var port = tabs.connect(tabId, connectInfo);
    messaging.sendMessageImpl(port, message, responseCallback);
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the tts API.

var binding = apiBridge || require('binding').Binding.create('tts');

var idGenerator = requireNative('id_generator');
var sendRequest = bindingUtil ?
    $Function.bind(bindingUtil.sendRequest, bindingUtil) :
    require('sendRequest').sendRequest;
var lazyBG = requireNative('lazy_background_page');

binding.registerCustomHook(function(api) {
  var apiFunctions = api.apiFunctions;
  var tts = api.compiledApi;
  var handlers = {};

  function ttsEventListener(event) {
    var eventHandler = handlers[event.srcId];
    if (eventHandler) {
      eventHandler({
                     type: event.type,
                     charIndex: event.charIndex,
                     errorMessage: event.errorMessage
                   });
      if (event.isFinalEvent) {
        delete handlers[event.srcId];
        // Balanced in 'speak' handler.
        lazyBG.DecrementKeepaliveCount();
      }
    }
  }

  // This file will get run if an extension needs the ttsEngine permission, but
  // it doesn't necessarily have the tts permission. If it doesn't, trying to
  // add a listener to chrome.tts.onEvent will fail.
  // See http://crbug.com/122474.
  try {
    tts.onEvent.addListener(ttsEventListener);
  } catch (e) {}

  apiFunctions.setHandleRequest('speak', function() {
    var args = $Array.from(arguments);
    if (args.length > 1 && args[1] && args[1].onEvent) {
      var id = idGenerator.GetNextId();
      args[1].srcId = id;
      handlers[id] = args[1].onEvent;
      // Keep the page alive until the event finishes.
      // Balanced in eventHandler.
      lazyBG.IncrementKeepaliveCount();
    }
    sendRequest('tts.speak', args,
                bindingUtil ? undefined : this.definition.parameters,
                undefined);
    return id;
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the ttsEngine API.

var binding = apiBridge || require('binding').Binding.create('ttsEngine');
var registerArgumentMassager = bindingUtil ?
    $Function.bind(bindingUtil.registerEventArgumentMassager, bindingUtil) :
    require('event_bindings').registerArgumentMassager;

registerArgumentMassager('ttsEngine.onSpeak', function(args, dispatch) {
  var text = args[0];
  var options = args[1];
  var requestId = args[2];
  var sendTtsEvent = function(event) {
    chrome.ttsEngine.sendTtsEvent(requestId, event);
  };
  dispatch([text, options, sendTtsEvent]);
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the webrtcDesktopCapturePrivate API.

var binding = apiBridge ||
              require('binding').Binding.create('webrtcDesktopCapturePrivate');
var sendRequest = bindingUtil ?
    $Function.bind(bindingUtil.sendRequest, bindingUtil) :
    require('sendRequest').sendRequest;
var idGenerator = requireNative('id_generator');

binding.registerCustomHook(function(bindingsAPI) {
  var apiFunctions = bindingsAPI.apiFunctions;

  var pendingRequests = {};

  function onRequestResult(id, result) {
    if (id in pendingRequests) {
      var callback = pendingRequests[id];
      delete pendingRequests[id];
      callback(result);
    }
  }

  apiFunctions.setHandleRequest('chooseDesktopMedia',
                                function(sources, request, callback) {
    var id = idGenerator.GetNextId();
    pendingRequests[id] = callback;
    sendRequest('webrtcDesktopCapturePrivate.chooseDesktopMedia',
                [id, sources, request,
                 $Function.bind(onRequestResult, null, id)],
                bindingUtil ? undefined : this.definition.parameters,
                undefined);
    return id;
  });

  apiFunctions.setHandleRequest('cancelChooseDesktopMedia', function(id) {
    if (id in pendingRequests) {
      delete pendingRequests[id];
      sendRequest('webrtcDesktopCapturePrivate.cancelChooseDesktopMedia', [id],
                  bindingUtil ? undefined : this.definition.parameters,
                  undefined);
    }
  });
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the webrtcLoggingPrivate API.

var binding = apiBridge ||
              require('binding').Binding.create('webrtcLoggingPrivate');

var getBindDirectoryEntryCallback =
    require('fileEntryBindingUtil').getBindDirectoryEntryCallback;

binding.registerCustomHook(function(binding, id, contextType) {
  var apiFunctions = binding.apiFunctions;
  apiFunctions.setCustomCallback('getLogsDirectory',
                                 getBindDirectoryEntryCallback());
});

if (!apiBridge)
  exports.$set('binding', binding.generate());
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Custom binding for the webstore API.

var webstoreNatives = requireNative('webstore');

var onInstallStageChanged;
var onDownloadProgress;

function Installer() {
  this._pendingInstall = null;
}

Installer.prototype.install = function(url, onSuccess, onFailure) {
  if (this._pendingInstall)
    throw new Error('A Chrome Web Store installation is already pending.');

  // With native bindings, these calls go through argument validation, which
  // sets optional/missing arguments to null. The native webstore bindings
  // expect either present or undefined, so transform null to undefined.
  if (url === null)
    url = undefined;
  if (onSuccess === null)
    onSuccess = undefined;
  if (onFailure === null)
    onFailure = undefined;

  if (url !== undefined && typeof url !== 'string') {
    throw new Error(
        'The Chrome Web Store item link URL parameter must be a string.');
  }
  if (onSuccess !== undefined && typeof onSuccess !== 'function') {
    throw new Error('The success callback parameter must be a function.');
  }
  if (onFailure !== undefined && typeof onFailure !== 'function') {
    throw new Error('The failure callback parameter must be a function.');
  }

  // Since we call Install() with a bool for if we have listeners, listeners
  // must be set prior to the inline installation starting (this is also
  // noted in the Event documentation in
  // chrome/common/extensions/api/webstore.json).
  var installId = webstoreNatives.Install(
      onInstallStageChanged.hasListeners(),
      onDownloadProgress.hasListeners(),
      url,
      onSuccess,
      onFailure);
  if (installId !== undefined) {
    this._pendingInstall = {
      installId: installId,
      onSuccess: onSuccess,
      onFailure: onFailure
    };
  }
};

Installer.prototype.onInstallResponse =
    function(installId, success, error, resultCode) {
  var pendingInstall = this._pendingInstall;
  if (!pendingInstall || pendingInstall.installId != installId) {
    // TODO(kalman): should this be an error?
    return;
  }

  try {
    if (success && pendingInstall.onSuccess)
      pendingInstall.onSuccess();
    else if (!success && pendingInstall.onFailure)
      pendingInstall.onFailure(error, resultCode);
  } catch (e) {
    console.error('Exception in chrome.webstore.install response handler: ' +
                  e.stack);
  } finally {
    this._pendingInstall = null;
  }
};

Installer.prototype.onInstallStageChanged = function(installStage) {
  onInstallStageChanged.dispatch(installStage);
};

Installer.prototype.onDownloadProgress = function(progress) {
  onDownloadProgress.dispatch(progress);
};

var installer = new Installer();


if (apiBridge) {
  apiBridge.registerCustomHook(function(api) {
    api.apiFunctions.setHandleRequest('install',
                                      function(url, onSuccess, onFailure) {
      installer.install(url, onSuccess, onFailure);
    });

    onInstallStageChanged = api.compiledApi.onInstallStageChanged;
    onDownloadProgress = api.compiledApi.onDownloadProgress;
  });
} else {
  var Event = require('event_bindings').Event;
  onInstallStageChanged =
      new Event(null, [{name: 'stage', type: 'string'}], {unmanaged: true});
  onDownloadProgress =
      new Event(null, [{name: 'progress', type: 'number'}], {unmanaged: true});

  var chromeWebstore = {
    install: function (url, onSuccess, onFailure) {
      installer.install(url, onSuccess, onFailure);
    },
    onInstallStageChanged: onInstallStageChanged,
    onDownloadProgress: onDownloadProgress,
  };
  exports.$set('binding', chromeWebstore);
}

// Called by webstore_bindings.cc.
exports.$set('onInstallResponse',
             $Function.bind(Installer.prototype.onInstallResponse, installer));
exports.$set('onInstallStageChanged',
             $Function.bind(Installer.prototype.onInstallStageChanged,
                            installer));
exports.$set('onDownloadProgress',
             $Function.bind(Installer.prototype.onDownloadProgress, installer));
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'chrome/common/media_router/mojo/media_controller.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('mediaRouter.mojom');
  var media_status$ =
      mojo.internal.exposeNamespace('mediaRouter.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'chrome/common/media_router/mojo/media_status.mojom', 'media_status.mojom.js');
  }
  var time$ =
      mojo.internal.exposeNamespace('mojo.common.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'mojo/common/time.mojom', '../../../../mojo/common/time.mojom.js');
  }



  function MediaController_Play_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaController_Play_Params.prototype.initDefaults_ = function() {
  };
  MediaController_Play_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaController_Play_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaController_Play_Params.encodedSize = codec.kStructHeaderSize + 0;

  MediaController_Play_Params.decode = function(decoder) {
    var packed;
    var val = new MediaController_Play_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  MediaController_Play_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaController_Play_Params.encodedSize);
    encoder.writeUint32(0);
  };
  function MediaController_Pause_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaController_Pause_Params.prototype.initDefaults_ = function() {
  };
  MediaController_Pause_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaController_Pause_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaController_Pause_Params.encodedSize = codec.kStructHeaderSize + 0;

  MediaController_Pause_Params.decode = function(decoder) {
    var packed;
    var val = new MediaController_Pause_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  MediaController_Pause_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaController_Pause_Params.encodedSize);
    encoder.writeUint32(0);
  };
  function MediaController_SetMute_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaController_SetMute_Params.prototype.initDefaults_ = function() {
    this.mute = false;
  };
  MediaController_SetMute_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaController_SetMute_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  MediaController_SetMute_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaController_SetMute_Params.decode = function(decoder) {
    var packed;
    var val = new MediaController_SetMute_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    packed = decoder.readUint8();
    val.mute = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaController_SetMute_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaController_SetMute_Params.encodedSize);
    encoder.writeUint32(0);
    packed = 0;
    packed |= (val.mute & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaController_SetVolume_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaController_SetVolume_Params.prototype.initDefaults_ = function() {
    this.volume = 0;
  };
  MediaController_SetVolume_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaController_SetVolume_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  MediaController_SetVolume_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaController_SetVolume_Params.decode = function(decoder) {
    var packed;
    var val = new MediaController_SetVolume_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.volume = decoder.decodeStruct(codec.Float);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaController_SetVolume_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaController_SetVolume_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Float, val.volume);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaController_Seek_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaController_Seek_Params.prototype.initDefaults_ = function() {
    this.time = null;
  };
  MediaController_Seek_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaController_Seek_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaController_Seek_Params.time
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, time$.TimeDelta, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaController_Seek_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaController_Seek_Params.decode = function(decoder) {
    var packed;
    var val = new MediaController_Seek_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.time = decoder.decodeStructPointer(time$.TimeDelta);
    return val;
  };

  MediaController_Seek_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaController_Seek_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(time$.TimeDelta, val.time);
  };
  function MediaController_ConnectHangoutsMediaRouteController_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaController_ConnectHangoutsMediaRouteController_Params.prototype.initDefaults_ = function() {
    this.controllerRequest = new bindings.InterfaceRequest();
  };
  MediaController_ConnectHangoutsMediaRouteController_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaController_ConnectHangoutsMediaRouteController_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaController_ConnectHangoutsMediaRouteController_Params.controllerRequest
    err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaController_ConnectHangoutsMediaRouteController_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaController_ConnectHangoutsMediaRouteController_Params.decode = function(decoder) {
    var packed;
    var val = new MediaController_ConnectHangoutsMediaRouteController_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.controllerRequest = decoder.decodeStruct(codec.InterfaceRequest);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaController_ConnectHangoutsMediaRouteController_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaController_ConnectHangoutsMediaRouteController_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.InterfaceRequest, val.controllerRequest);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function HangoutsMediaRouteController_SetLocalPresent_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  HangoutsMediaRouteController_SetLocalPresent_Params.prototype.initDefaults_ = function() {
    this.localPresent = false;
  };
  HangoutsMediaRouteController_SetLocalPresent_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  HangoutsMediaRouteController_SetLocalPresent_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  HangoutsMediaRouteController_SetLocalPresent_Params.encodedSize = codec.kStructHeaderSize + 8;

  HangoutsMediaRouteController_SetLocalPresent_Params.decode = function(decoder) {
    var packed;
    var val = new HangoutsMediaRouteController_SetLocalPresent_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    packed = decoder.readUint8();
    val.localPresent = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  HangoutsMediaRouteController_SetLocalPresent_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(HangoutsMediaRouteController_SetLocalPresent_Params.encodedSize);
    encoder.writeUint32(0);
    packed = 0;
    packed |= (val.localPresent & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  var kMediaController_Play_Name = 805768224;
  var kMediaController_Pause_Name = 1730431875;
  var kMediaController_SetMute_Name = 1350303890;
  var kMediaController_SetVolume_Name = 1058468242;
  var kMediaController_Seek_Name = 222187904;
  var kMediaController_ConnectHangoutsMediaRouteController_Name = 986560610;

  function MediaControllerPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(MediaController,
                                                   handleOrPtrInfo);
  }

  function MediaControllerAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        MediaController, associatedInterfacePtrInfo);
  }

  MediaControllerAssociatedPtr.prototype =
      Object.create(MediaControllerPtr.prototype);
  MediaControllerAssociatedPtr.prototype.constructor =
      MediaControllerAssociatedPtr;

  function MediaControllerProxy(receiver) {
    this.receiver_ = receiver;
  }
  MediaControllerPtr.prototype.play = function() {
    return MediaControllerProxy.prototype.play
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaControllerProxy.prototype.play = function() {
    var params = new MediaController_Play_Params();
    var builder = new codec.MessageV0Builder(
        kMediaController_Play_Name,
        codec.align(MediaController_Play_Params.encodedSize));
    builder.encodeStruct(MediaController_Play_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaControllerPtr.prototype.pause = function() {
    return MediaControllerProxy.prototype.pause
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaControllerProxy.prototype.pause = function() {
    var params = new MediaController_Pause_Params();
    var builder = new codec.MessageV0Builder(
        kMediaController_Pause_Name,
        codec.align(MediaController_Pause_Params.encodedSize));
    builder.encodeStruct(MediaController_Pause_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaControllerPtr.prototype.setMute = function() {
    return MediaControllerProxy.prototype.setMute
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaControllerProxy.prototype.setMute = function(mute) {
    var params = new MediaController_SetMute_Params();
    params.mute = mute;
    var builder = new codec.MessageV0Builder(
        kMediaController_SetMute_Name,
        codec.align(MediaController_SetMute_Params.encodedSize));
    builder.encodeStruct(MediaController_SetMute_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaControllerPtr.prototype.setVolume = function() {
    return MediaControllerProxy.prototype.setVolume
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaControllerProxy.prototype.setVolume = function(volume) {
    var params = new MediaController_SetVolume_Params();
    params.volume = volume;
    var builder = new codec.MessageV0Builder(
        kMediaController_SetVolume_Name,
        codec.align(MediaController_SetVolume_Params.encodedSize));
    builder.encodeStruct(MediaController_SetVolume_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaControllerPtr.prototype.seek = function() {
    return MediaControllerProxy.prototype.seek
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaControllerProxy.prototype.seek = function(time) {
    var params = new MediaController_Seek_Params();
    params.time = time;
    var builder = new codec.MessageV0Builder(
        kMediaController_Seek_Name,
        codec.align(MediaController_Seek_Params.encodedSize));
    builder.encodeStruct(MediaController_Seek_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaControllerPtr.prototype.connectHangoutsMediaRouteController = function() {
    return MediaControllerProxy.prototype.connectHangoutsMediaRouteController
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaControllerProxy.prototype.connectHangoutsMediaRouteController = function(controllerRequest) {
    var params = new MediaController_ConnectHangoutsMediaRouteController_Params();
    params.controllerRequest = controllerRequest;
    var builder = new codec.MessageV0Builder(
        kMediaController_ConnectHangoutsMediaRouteController_Name,
        codec.align(MediaController_ConnectHangoutsMediaRouteController_Params.encodedSize));
    builder.encodeStruct(MediaController_ConnectHangoutsMediaRouteController_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function MediaControllerStub(delegate) {
    this.delegate_ = delegate;
  }
  MediaControllerStub.prototype.play = function() {
    return this.delegate_ && this.delegate_.play && this.delegate_.play();
  }
  MediaControllerStub.prototype.pause = function() {
    return this.delegate_ && this.delegate_.pause && this.delegate_.pause();
  }
  MediaControllerStub.prototype.setMute = function(mute) {
    return this.delegate_ && this.delegate_.setMute && this.delegate_.setMute(mute);
  }
  MediaControllerStub.prototype.setVolume = function(volume) {
    return this.delegate_ && this.delegate_.setVolume && this.delegate_.setVolume(volume);
  }
  MediaControllerStub.prototype.seek = function(time) {
    return this.delegate_ && this.delegate_.seek && this.delegate_.seek(time);
  }
  MediaControllerStub.prototype.connectHangoutsMediaRouteController = function(controllerRequest) {
    return this.delegate_ && this.delegate_.connectHangoutsMediaRouteController && this.delegate_.connectHangoutsMediaRouteController(controllerRequest);
  }

  MediaControllerStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kMediaController_Play_Name:
      var params = reader.decodeStruct(MediaController_Play_Params);
      this.play();
      return true;
    case kMediaController_Pause_Name:
      var params = reader.decodeStruct(MediaController_Pause_Params);
      this.pause();
      return true;
    case kMediaController_SetMute_Name:
      var params = reader.decodeStruct(MediaController_SetMute_Params);
      this.setMute(params.mute);
      return true;
    case kMediaController_SetVolume_Name:
      var params = reader.decodeStruct(MediaController_SetVolume_Params);
      this.setVolume(params.volume);
      return true;
    case kMediaController_Seek_Name:
      var params = reader.decodeStruct(MediaController_Seek_Params);
      this.seek(params.time);
      return true;
    case kMediaController_ConnectHangoutsMediaRouteController_Name:
      var params = reader.decodeStruct(MediaController_ConnectHangoutsMediaRouteController_Params);
      this.connectHangoutsMediaRouteController(params.controllerRequest);
      return true;
    default:
      return false;
    }
  };

  MediaControllerStub.prototype.acceptWithResponder =
      function(message, responder) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    default:
      return false;
    }
  };

  function validateMediaControllerRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kMediaController_Play_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaController_Play_Params;
      break;
      case kMediaController_Pause_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaController_Pause_Params;
      break;
      case kMediaController_SetMute_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaController_SetMute_Params;
      break;
      case kMediaController_SetVolume_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaController_SetVolume_Params;
      break;
      case kMediaController_Seek_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaController_Seek_Params;
      break;
      case kMediaController_ConnectHangoutsMediaRouteController_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaController_ConnectHangoutsMediaRouteController_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  function validateMediaControllerResponse(messageValidator) {
    return validator.validationError.NONE;
  }

  var MediaController = {
    name: 'media_router::mojom::MediaController',
    kVersion: 0,
    ptrClass: MediaControllerPtr,
    proxyClass: MediaControllerProxy,
    stubClass: MediaControllerStub,
    validateRequest: validateMediaControllerRequest,
    validateResponse: null,
  };
  MediaControllerStub.prototype.validator = validateMediaControllerRequest;
  MediaControllerProxy.prototype.validator = null;
  var kHangoutsMediaRouteController_SetLocalPresent_Name = 203222817;

  function HangoutsMediaRouteControllerPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(HangoutsMediaRouteController,
                                                   handleOrPtrInfo);
  }

  function HangoutsMediaRouteControllerAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        HangoutsMediaRouteController, associatedInterfacePtrInfo);
  }

  HangoutsMediaRouteControllerAssociatedPtr.prototype =
      Object.create(HangoutsMediaRouteControllerPtr.prototype);
  HangoutsMediaRouteControllerAssociatedPtr.prototype.constructor =
      HangoutsMediaRouteControllerAssociatedPtr;

  function HangoutsMediaRouteControllerProxy(receiver) {
    this.receiver_ = receiver;
  }
  HangoutsMediaRouteControllerPtr.prototype.setLocalPresent = function() {
    return HangoutsMediaRouteControllerProxy.prototype.setLocalPresent
        .apply(this.ptr.getProxy(), arguments);
  };

  HangoutsMediaRouteControllerProxy.prototype.setLocalPresent = function(localPresent) {
    var params = new HangoutsMediaRouteController_SetLocalPresent_Params();
    params.localPresent = localPresent;
    var builder = new codec.MessageV0Builder(
        kHangoutsMediaRouteController_SetLocalPresent_Name,
        codec.align(HangoutsMediaRouteController_SetLocalPresent_Params.encodedSize));
    builder.encodeStruct(HangoutsMediaRouteController_SetLocalPresent_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function HangoutsMediaRouteControllerStub(delegate) {
    this.delegate_ = delegate;
  }
  HangoutsMediaRouteControllerStub.prototype.setLocalPresent = function(localPresent) {
    return this.delegate_ && this.delegate_.setLocalPresent && this.delegate_.setLocalPresent(localPresent);
  }

  HangoutsMediaRouteControllerStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kHangoutsMediaRouteController_SetLocalPresent_Name:
      var params = reader.decodeStruct(HangoutsMediaRouteController_SetLocalPresent_Params);
      this.setLocalPresent(params.localPresent);
      return true;
    default:
      return false;
    }
  };

  HangoutsMediaRouteControllerStub.prototype.acceptWithResponder =
      function(message, responder) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    default:
      return false;
    }
  };

  function validateHangoutsMediaRouteControllerRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kHangoutsMediaRouteController_SetLocalPresent_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = HangoutsMediaRouteController_SetLocalPresent_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  function validateHangoutsMediaRouteControllerResponse(messageValidator) {
    return validator.validationError.NONE;
  }

  var HangoutsMediaRouteController = {
    name: 'media_router::mojom::HangoutsMediaRouteController',
    kVersion: 0,
    ptrClass: HangoutsMediaRouteControllerPtr,
    proxyClass: HangoutsMediaRouteControllerProxy,
    stubClass: HangoutsMediaRouteControllerStub,
    validateRequest: validateHangoutsMediaRouteControllerRequest,
    validateResponse: null,
  };
  HangoutsMediaRouteControllerStub.prototype.validator = validateHangoutsMediaRouteControllerRequest;
  HangoutsMediaRouteControllerProxy.prototype.validator = null;
  exports.MediaController = MediaController;
  exports.MediaControllerPtr = MediaControllerPtr;
  exports.MediaControllerAssociatedPtr = MediaControllerAssociatedPtr;
  exports.HangoutsMediaRouteController = HangoutsMediaRouteController;
  exports.HangoutsMediaRouteControllerPtr = HangoutsMediaRouteControllerPtr;
  exports.HangoutsMediaRouteControllerAssociatedPtr = HangoutsMediaRouteControllerAssociatedPtr;
})();// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'chrome/common/media_router/mojo/media_router.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('mediaRouter.mojom');
  var media_controller$ =
      mojo.internal.exposeNamespace('mediaRouter.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'chrome/common/media_router/mojo/media_controller.mojom', 'media_controller.mojom.js');
  }
  var media_status$ =
      mojo.internal.exposeNamespace('mediaRouter.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'chrome/common/media_router/mojo/media_status.mojom', 'media_status.mojom.js');
  }
  var mirror_service_remoting$ =
      mojo.internal.exposeNamespace('media.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'media/mojo/interfaces/mirror_service_remoting.mojom', '../../../../media/mojo/interfaces/mirror_service_remoting.mojom.js');
  }
  var time$ =
      mojo.internal.exposeNamespace('mojo.common.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'mojo/common/time.mojom', '../../../../mojo/common/time.mojom.js');
  }
  var ip_address$ =
      mojo.internal.exposeNamespace('net.interfaces');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'net/interfaces/ip_address.mojom', '../../../../net/interfaces/ip_address.mojom.js');
  }
  var ip_endpoint$ =
      mojo.internal.exposeNamespace('net.interfaces');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'net/interfaces/ip_endpoint.mojom', '../../../../net/interfaces/ip_endpoint.mojom.js');
  }
  var origin$ =
      mojo.internal.exposeNamespace('url.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'url/mojo/origin.mojom', '../../../../url/mojo/origin.mojom.js');
  }
  var url$ =
      mojo.internal.exposeNamespace('url.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'url/mojo/url.mojom', '../../../../url/mojo/url.mojom.js');
  }


  var SinkIconType = {};
  SinkIconType.CAST = 0;
  SinkIconType.CAST_AUDIO_GROUP = SinkIconType.CAST + 1;
  SinkIconType.CAST_AUDIO = SinkIconType.CAST_AUDIO_GROUP + 1;
  SinkIconType.MEETING = SinkIconType.CAST_AUDIO + 1;
  SinkIconType.HANGOUT = SinkIconType.MEETING + 1;
  SinkIconType.EDUCATION = SinkIconType.HANGOUT + 1;
  SinkIconType.WIRED_DISPLAY = SinkIconType.EDUCATION + 1;
  SinkIconType.GENERIC = SinkIconType.WIRED_DISPLAY + 1;

  SinkIconType.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
      return true;
    }
    return false;
  };

  SinkIconType.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  var RouteControllerType = {};
  RouteControllerType.kNone = 0;
  RouteControllerType.kGeneric = RouteControllerType.kNone + 1;
  RouteControllerType.kHangouts = RouteControllerType.kGeneric + 1;
  RouteControllerType.kMirroring = RouteControllerType.kHangouts + 1;

  RouteControllerType.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
      return true;
    }
    return false;
  };

  RouteControllerType.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  var RouteRequestResultCode = {};
  RouteRequestResultCode.UNKNOWN_ERROR = 0;
  RouteRequestResultCode.OK = RouteRequestResultCode.UNKNOWN_ERROR + 1;
  RouteRequestResultCode.TIMED_OUT = RouteRequestResultCode.OK + 1;
  RouteRequestResultCode.ROUTE_NOT_FOUND = RouteRequestResultCode.TIMED_OUT + 1;
  RouteRequestResultCode.SINK_NOT_FOUND = RouteRequestResultCode.ROUTE_NOT_FOUND + 1;
  RouteRequestResultCode.INVALID_ORIGIN = RouteRequestResultCode.SINK_NOT_FOUND + 1;
  RouteRequestResultCode.INCOGNITO_MISMATCH = RouteRequestResultCode.INVALID_ORIGIN + 1;
  RouteRequestResultCode.NO_SUPPORTED_PROVIDER = RouteRequestResultCode.INCOGNITO_MISMATCH + 1;
  RouteRequestResultCode.CANCELLED = RouteRequestResultCode.NO_SUPPORTED_PROVIDER + 1;

  RouteRequestResultCode.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      return true;
    }
    return false;
  };

  RouteRequestResultCode.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };

  function MediaSink(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaSink.prototype.initDefaults_ = function() {
    this.sinkId = null;
    this.name = null;
    this.description = null;
    this.domain = null;
    this.iconType = 0;
    this.providerId = 0;
    this.extraData = null;
  };
  MediaSink.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaSink.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 64}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaSink.sinkId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaSink.name
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaSink.description
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, true)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaSink.domain
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, true)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaSink.iconType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 32, SinkIconType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaSink.providerId
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 36, MediaRouteProvider.Id);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaSink.extraData
    err = messageValidator.validateUnion(offset + codec.kStructHeaderSize + 40, MediaSinkExtraData, true);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaSink.encodedSize = codec.kStructHeaderSize + 56;

  MediaSink.decode = function(decoder) {
    var packed;
    var val = new MediaSink();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.sinkId = decoder.decodeStruct(codec.String);
    val.name = decoder.decodeStruct(codec.String);
    val.description = decoder.decodeStruct(codec.NullableString);
    val.domain = decoder.decodeStruct(codec.NullableString);
    val.iconType = decoder.decodeStruct(codec.Int32);
    val.providerId = decoder.decodeStruct(codec.Int32);
    val.extraData = decoder.decodeStruct(MediaSinkExtraData);
    return val;
  };

  MediaSink.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaSink.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.sinkId);
    encoder.encodeStruct(codec.String, val.name);
    encoder.encodeStruct(codec.NullableString, val.description);
    encoder.encodeStruct(codec.NullableString, val.domain);
    encoder.encodeStruct(codec.Int32, val.iconType);
    encoder.encodeStruct(codec.Int32, val.providerId);
    encoder.encodeStruct(MediaSinkExtraData, val.extraData);
  };
  function DialMediaSink(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  DialMediaSink.prototype.initDefaults_ = function() {
    this.ipAddress = null;
    this.modelName = null;
    this.appUrl = null;
  };
  DialMediaSink.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  DialMediaSink.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate DialMediaSink.ipAddress
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, ip_address$.IPAddress, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate DialMediaSink.modelName
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate DialMediaSink.appUrl
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, url$.Url, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  DialMediaSink.encodedSize = codec.kStructHeaderSize + 24;

  DialMediaSink.decode = function(decoder) {
    var packed;
    var val = new DialMediaSink();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.ipAddress = decoder.decodeStructPointer(ip_address$.IPAddress);
    val.modelName = decoder.decodeStruct(codec.String);
    val.appUrl = decoder.decodeStructPointer(url$.Url);
    return val;
  };

  DialMediaSink.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(DialMediaSink.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(ip_address$.IPAddress, val.ipAddress);
    encoder.encodeStruct(codec.String, val.modelName);
    encoder.encodeStructPointer(url$.Url, val.appUrl);
  };
  function CastMediaSink(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  CastMediaSink.prototype.initDefaults_ = function() {
    this.ipEndpoint = null;
    this.modelName = null;
    this.capabilities = 0;
    this.castChannelId = 0;
  };
  CastMediaSink.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  CastMediaSink.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate CastMediaSink.ipEndpoint
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, ip_endpoint$.IPEndPoint, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate CastMediaSink.modelName
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;



    return validator.validationError.NONE;
  };

  CastMediaSink.encodedSize = codec.kStructHeaderSize + 24;

  CastMediaSink.decode = function(decoder) {
    var packed;
    var val = new CastMediaSink();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.ipEndpoint = decoder.decodeStructPointer(ip_endpoint$.IPEndPoint);
    val.modelName = decoder.decodeStruct(codec.String);
    val.capabilities = decoder.decodeStruct(codec.Uint8);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.castChannelId = decoder.decodeStruct(codec.Int32);
    return val;
  };

  CastMediaSink.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(CastMediaSink.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(ip_endpoint$.IPEndPoint, val.ipEndpoint);
    encoder.encodeStruct(codec.String, val.modelName);
    encoder.encodeStruct(codec.Uint8, val.capabilities);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.Int32, val.castChannelId);
  };
  function MediaRoute(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRoute.prototype.initDefaults_ = function() {
    this.mediaRouteId = null;
    this.presentationId = null;
    this.mediaSource = null;
    this.mediaSinkId = null;
    this.description = null;
    this.isLocal = false;
    this.forDisplay = false;
    this.isIncognito = false;
    this.isLocalPresentation = false;
    this.controllerType = 0;
  };
  MediaRoute.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRoute.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 56}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRoute.mediaRouteId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRoute.presentationId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRoute.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, true)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRoute.mediaSinkId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRoute.description
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 32, false)
    if (err !== validator.validationError.NONE)
        return err;



    // validate MediaRoute.controllerType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 44, RouteControllerType);
    if (err !== validator.validationError.NONE)
        return err;




    return validator.validationError.NONE;
  };

  MediaRoute.encodedSize = codec.kStructHeaderSize + 48;

  MediaRoute.decode = function(decoder) {
    var packed;
    var val = new MediaRoute();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaRouteId = decoder.decodeStruct(codec.String);
    val.presentationId = decoder.decodeStruct(codec.String);
    val.mediaSource = decoder.decodeStruct(codec.NullableString);
    val.mediaSinkId = decoder.decodeStruct(codec.String);
    val.description = decoder.decodeStruct(codec.String);
    packed = decoder.readUint8();
    val.isLocal = (packed >> 0) & 1 ? true : false;
    val.forDisplay = (packed >> 1) & 1 ? true : false;
    val.isIncognito = (packed >> 2) & 1 ? true : false;
    val.isLocalPresentation = (packed >> 3) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.controllerType = decoder.decodeStruct(codec.Int32);
    return val;
  };

  MediaRoute.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRoute.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaRouteId);
    encoder.encodeStruct(codec.String, val.presentationId);
    encoder.encodeStruct(codec.NullableString, val.mediaSource);
    encoder.encodeStruct(codec.String, val.mediaSinkId);
    encoder.encodeStruct(codec.String, val.description);
    packed = 0;
    packed |= (val.isLocal & 1) << 0
    packed |= (val.forDisplay & 1) << 1
    packed |= (val.isIncognito & 1) << 2
    packed |= (val.isLocalPresentation & 1) << 3
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.Int32, val.controllerType);
  };
  function Issue(values) {
    this.initDefaults_();
    this.initFields_(values);
  }

  Issue.Severity = {};
  Issue.Severity.FATAL = 0;
  Issue.Severity.WARNING = Issue.Severity.FATAL + 1;
  Issue.Severity.NOTIFICATION = Issue.Severity.WARNING + 1;

  Issue.Severity.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    }
    return false;
  };

  Issue.Severity.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  Issue.ActionType = {};
  Issue.ActionType.DISMISS = 0;
  Issue.ActionType.LEARN_MORE = Issue.ActionType.DISMISS + 1;

  Issue.ActionType.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
      return true;
    }
    return false;
  };

  Issue.ActionType.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };

  Issue.prototype.initDefaults_ = function() {
    this.routeId = null;
    this.severity = 0;
    this.isBlocking = false;
    this.title = null;
    this.message = null;
    this.defaultAction = 0;
    this.helpPageId = 0;
    this.secondaryActions = null;
  };
  Issue.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  Issue.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 56}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate Issue.routeId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true)
    if (err !== validator.validationError.NONE)
        return err;


    // validate Issue.severity
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, Issue.Severity);
    if (err !== validator.validationError.NONE)
        return err;



    // validate Issue.title
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate Issue.message
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, true)
    if (err !== validator.validationError.NONE)
        return err;


    // validate Issue.defaultAction
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 32, Issue.ActionType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate Issue.secondaryActions
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 40, 4, new codec.Enum(Issue.ActionType), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  Issue.encodedSize = codec.kStructHeaderSize + 48;

  Issue.decode = function(decoder) {
    var packed;
    var val = new Issue();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.routeId = decoder.decodeStruct(codec.NullableString);
    val.severity = decoder.decodeStruct(codec.Int32);
    packed = decoder.readUint8();
    val.isBlocking = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.title = decoder.decodeStruct(codec.String);
    val.message = decoder.decodeStruct(codec.NullableString);
    val.defaultAction = decoder.decodeStruct(codec.Int32);
    val.helpPageId = decoder.decodeStruct(codec.Int32);
    val.secondaryActions = decoder.decodeArrayPointer(new codec.Enum(Issue.ActionType));
    return val;
  };

  Issue.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(Issue.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.NullableString, val.routeId);
    encoder.encodeStruct(codec.Int32, val.severity);
    packed = 0;
    packed |= (val.isBlocking & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.String, val.title);
    encoder.encodeStruct(codec.NullableString, val.message);
    encoder.encodeStruct(codec.Int32, val.defaultAction);
    encoder.encodeStruct(codec.Int32, val.helpPageId);
    encoder.encodeArrayPointer(new codec.Enum(Issue.ActionType), val.secondaryActions);
  };
  function RouteMessage(values) {
    this.initDefaults_();
    this.initFields_(values);
  }

  RouteMessage.Type = {};
  RouteMessage.Type.TEXT = 0;
  RouteMessage.Type.BINARY = RouteMessage.Type.TEXT + 1;

  RouteMessage.Type.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
      return true;
    }
    return false;
  };

  RouteMessage.Type.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };

  RouteMessage.prototype.initDefaults_ = function() {
    this.type = 0;
    this.message = null;
    this.data = null;
  };
  RouteMessage.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  RouteMessage.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate RouteMessage.type
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, RouteMessage.Type);
    if (err !== validator.validationError.NONE)
        return err;


    // validate RouteMessage.message
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, true)
    if (err !== validator.validationError.NONE)
        return err;


    // validate RouteMessage.data
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 1, codec.Uint8, true, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  RouteMessage.encodedSize = codec.kStructHeaderSize + 24;

  RouteMessage.decode = function(decoder) {
    var packed;
    var val = new RouteMessage();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.type = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.message = decoder.decodeStruct(codec.NullableString);
    val.data = decoder.decodeArrayPointer(codec.Uint8);
    return val;
  };

  RouteMessage.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(RouteMessage.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.type);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.NullableString, val.message);
    encoder.encodeArrayPointer(codec.Uint8, val.data);
  };
  function SinkSearchCriteria(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  SinkSearchCriteria.prototype.initDefaults_ = function() {
    this.input = null;
    this.domain = null;
  };
  SinkSearchCriteria.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  SinkSearchCriteria.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate SinkSearchCriteria.input
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate SinkSearchCriteria.domain
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  SinkSearchCriteria.encodedSize = codec.kStructHeaderSize + 16;

  SinkSearchCriteria.decode = function(decoder) {
    var packed;
    var val = new SinkSearchCriteria();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.input = decoder.decodeStruct(codec.String);
    val.domain = decoder.decodeStruct(codec.String);
    return val;
  };

  SinkSearchCriteria.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(SinkSearchCriteria.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.input);
    encoder.encodeStruct(codec.String, val.domain);
  };
  function MediaRouteProviderConfig(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProviderConfig.prototype.initDefaults_ = function() {
    this.enableDialDiscovery = false;
    this.enableCastDiscovery = false;
  };
  MediaRouteProviderConfig.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProviderConfig.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;



    return validator.validationError.NONE;
  };

  MediaRouteProviderConfig.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProviderConfig.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProviderConfig();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    packed = decoder.readUint8();
    val.enableDialDiscovery = (packed >> 0) & 1 ? true : false;
    val.enableCastDiscovery = (packed >> 1) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouteProviderConfig.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProviderConfig.encodedSize);
    encoder.writeUint32(0);
    packed = 0;
    packed |= (val.enableDialDiscovery & 1) << 0
    packed |= (val.enableCastDiscovery & 1) << 1
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouteProvider_CreateRoute_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_CreateRoute_Params.prototype.initDefaults_ = function() {
    this.mediaSource = null;
    this.sinkId = null;
    this.originalPresentationId = null;
    this.origin = null;
    this.tabId = 0;
    this.incognito = false;
    this.timeout = null;
  };
  MediaRouteProvider_CreateRoute_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_CreateRoute_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 56}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_CreateRoute_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_CreateRoute_Params.sinkId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_CreateRoute_Params.originalPresentationId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_CreateRoute_Params.origin
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, origin$.Origin, false);
    if (err !== validator.validationError.NONE)
        return err;



    // validate MediaRouteProvider_CreateRoute_Params.timeout
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 40, time$.TimeDelta, false);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  MediaRouteProvider_CreateRoute_Params.encodedSize = codec.kStructHeaderSize + 48;

  MediaRouteProvider_CreateRoute_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_CreateRoute_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaSource = decoder.decodeStruct(codec.String);
    val.sinkId = decoder.decodeStruct(codec.String);
    val.originalPresentationId = decoder.decodeStruct(codec.String);
    val.origin = decoder.decodeStructPointer(origin$.Origin);
    val.tabId = decoder.decodeStruct(codec.Int32);
    packed = decoder.readUint8();
    val.incognito = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.timeout = decoder.decodeStructPointer(time$.TimeDelta);
    return val;
  };

  MediaRouteProvider_CreateRoute_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_CreateRoute_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaSource);
    encoder.encodeStruct(codec.String, val.sinkId);
    encoder.encodeStruct(codec.String, val.originalPresentationId);
    encoder.encodeStructPointer(origin$.Origin, val.origin);
    encoder.encodeStruct(codec.Int32, val.tabId);
    packed = 0;
    packed |= (val.incognito & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStructPointer(time$.TimeDelta, val.timeout);
  };
  function MediaRouteProvider_CreateRoute_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_CreateRoute_ResponseParams.prototype.initDefaults_ = function() {
    this.route = null;
    this.errorText = null;
    this.resultCode = 0;
  };
  MediaRouteProvider_CreateRoute_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_CreateRoute_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_CreateRoute_ResponseParams.route
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, MediaRoute, true);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_CreateRoute_ResponseParams.errorText
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, true)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_CreateRoute_ResponseParams.resultCode
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 16, RouteRequestResultCode);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_CreateRoute_ResponseParams.encodedSize = codec.kStructHeaderSize + 24;

  MediaRouteProvider_CreateRoute_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_CreateRoute_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.route = decoder.decodeStructPointer(MediaRoute);
    val.errorText = decoder.decodeStruct(codec.NullableString);
    val.resultCode = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouteProvider_CreateRoute_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_CreateRoute_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(MediaRoute, val.route);
    encoder.encodeStruct(codec.NullableString, val.errorText);
    encoder.encodeStruct(codec.Int32, val.resultCode);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouteProvider_JoinRoute_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_JoinRoute_Params.prototype.initDefaults_ = function() {
    this.mediaSource = null;
    this.presentationId = null;
    this.origin = null;
    this.tabId = 0;
    this.incognito = false;
    this.timeout = null;
  };
  MediaRouteProvider_JoinRoute_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_JoinRoute_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 48}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_JoinRoute_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_JoinRoute_Params.presentationId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_JoinRoute_Params.origin
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, origin$.Origin, false);
    if (err !== validator.validationError.NONE)
        return err;



    // validate MediaRouteProvider_JoinRoute_Params.timeout
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 32, time$.TimeDelta, false);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  MediaRouteProvider_JoinRoute_Params.encodedSize = codec.kStructHeaderSize + 40;

  MediaRouteProvider_JoinRoute_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_JoinRoute_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaSource = decoder.decodeStruct(codec.String);
    val.presentationId = decoder.decodeStruct(codec.String);
    val.origin = decoder.decodeStructPointer(origin$.Origin);
    val.tabId = decoder.decodeStruct(codec.Int32);
    packed = decoder.readUint8();
    val.incognito = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.timeout = decoder.decodeStructPointer(time$.TimeDelta);
    return val;
  };

  MediaRouteProvider_JoinRoute_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_JoinRoute_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaSource);
    encoder.encodeStruct(codec.String, val.presentationId);
    encoder.encodeStructPointer(origin$.Origin, val.origin);
    encoder.encodeStruct(codec.Int32, val.tabId);
    packed = 0;
    packed |= (val.incognito & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStructPointer(time$.TimeDelta, val.timeout);
  };
  function MediaRouteProvider_JoinRoute_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_JoinRoute_ResponseParams.prototype.initDefaults_ = function() {
    this.route = null;
    this.errorText = null;
    this.resultCode = 0;
  };
  MediaRouteProvider_JoinRoute_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_JoinRoute_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_JoinRoute_ResponseParams.route
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, MediaRoute, true);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_JoinRoute_ResponseParams.errorText
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, true)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_JoinRoute_ResponseParams.resultCode
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 16, RouteRequestResultCode);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_JoinRoute_ResponseParams.encodedSize = codec.kStructHeaderSize + 24;

  MediaRouteProvider_JoinRoute_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_JoinRoute_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.route = decoder.decodeStructPointer(MediaRoute);
    val.errorText = decoder.decodeStruct(codec.NullableString);
    val.resultCode = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouteProvider_JoinRoute_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_JoinRoute_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(MediaRoute, val.route);
    encoder.encodeStruct(codec.NullableString, val.errorText);
    encoder.encodeStruct(codec.Int32, val.resultCode);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouteProvider_ConnectRouteByRouteId_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_ConnectRouteByRouteId_Params.prototype.initDefaults_ = function() {
    this.mediaSource = null;
    this.routeId = null;
    this.presentationId = null;
    this.origin = null;
    this.tabId = 0;
    this.incognito = false;
    this.timeout = null;
  };
  MediaRouteProvider_ConnectRouteByRouteId_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_ConnectRouteByRouteId_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 56}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_ConnectRouteByRouteId_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_ConnectRouteByRouteId_Params.routeId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_ConnectRouteByRouteId_Params.presentationId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_ConnectRouteByRouteId_Params.origin
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, origin$.Origin, false);
    if (err !== validator.validationError.NONE)
        return err;



    // validate MediaRouteProvider_ConnectRouteByRouteId_Params.timeout
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 40, time$.TimeDelta, false);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  MediaRouteProvider_ConnectRouteByRouteId_Params.encodedSize = codec.kStructHeaderSize + 48;

  MediaRouteProvider_ConnectRouteByRouteId_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_ConnectRouteByRouteId_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaSource = decoder.decodeStruct(codec.String);
    val.routeId = decoder.decodeStruct(codec.String);
    val.presentationId = decoder.decodeStruct(codec.String);
    val.origin = decoder.decodeStructPointer(origin$.Origin);
    val.tabId = decoder.decodeStruct(codec.Int32);
    packed = decoder.readUint8();
    val.incognito = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.timeout = decoder.decodeStructPointer(time$.TimeDelta);
    return val;
  };

  MediaRouteProvider_ConnectRouteByRouteId_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_ConnectRouteByRouteId_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaSource);
    encoder.encodeStruct(codec.String, val.routeId);
    encoder.encodeStruct(codec.String, val.presentationId);
    encoder.encodeStructPointer(origin$.Origin, val.origin);
    encoder.encodeStruct(codec.Int32, val.tabId);
    packed = 0;
    packed |= (val.incognito & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStructPointer(time$.TimeDelta, val.timeout);
  };
  function MediaRouteProvider_ConnectRouteByRouteId_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.prototype.initDefaults_ = function() {
    this.route = null;
    this.errorText = null;
    this.resultCode = 0;
  };
  MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.route
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, MediaRoute, true);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.errorText
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, true)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.resultCode
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 16, RouteRequestResultCode);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.encodedSize = codec.kStructHeaderSize + 24;

  MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_ConnectRouteByRouteId_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.route = decoder.decodeStructPointer(MediaRoute);
    val.errorText = decoder.decodeStruct(codec.NullableString);
    val.resultCode = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(MediaRoute, val.route);
    encoder.encodeStruct(codec.NullableString, val.errorText);
    encoder.encodeStruct(codec.Int32, val.resultCode);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouteProvider_TerminateRoute_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_TerminateRoute_Params.prototype.initDefaults_ = function() {
    this.routeId = null;
  };
  MediaRouteProvider_TerminateRoute_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_TerminateRoute_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_TerminateRoute_Params.routeId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_TerminateRoute_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_TerminateRoute_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_TerminateRoute_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.routeId = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_TerminateRoute_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_TerminateRoute_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.routeId);
  };
  function MediaRouteProvider_TerminateRoute_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_TerminateRoute_ResponseParams.prototype.initDefaults_ = function() {
    this.errorText = null;
    this.resultCode = 0;
  };
  MediaRouteProvider_TerminateRoute_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_TerminateRoute_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_TerminateRoute_ResponseParams.errorText
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_TerminateRoute_ResponseParams.resultCode
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, RouteRequestResultCode);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_TerminateRoute_ResponseParams.encodedSize = codec.kStructHeaderSize + 16;

  MediaRouteProvider_TerminateRoute_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_TerminateRoute_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.errorText = decoder.decodeStruct(codec.NullableString);
    val.resultCode = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouteProvider_TerminateRoute_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_TerminateRoute_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.NullableString, val.errorText);
    encoder.encodeStruct(codec.Int32, val.resultCode);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouteProvider_SendRouteMessage_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_SendRouteMessage_Params.prototype.initDefaults_ = function() {
    this.mediaRouteId = null;
    this.message = null;
  };
  MediaRouteProvider_SendRouteMessage_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_SendRouteMessage_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_SendRouteMessage_Params.mediaRouteId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_SendRouteMessage_Params.message
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_SendRouteMessage_Params.encodedSize = codec.kStructHeaderSize + 16;

  MediaRouteProvider_SendRouteMessage_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_SendRouteMessage_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaRouteId = decoder.decodeStruct(codec.String);
    val.message = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_SendRouteMessage_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_SendRouteMessage_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaRouteId);
    encoder.encodeStruct(codec.String, val.message);
  };
  function MediaRouteProvider_SendRouteMessage_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_SendRouteMessage_ResponseParams.prototype.initDefaults_ = function() {
    this.sent = false;
  };
  MediaRouteProvider_SendRouteMessage_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_SendRouteMessage_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  MediaRouteProvider_SendRouteMessage_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_SendRouteMessage_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_SendRouteMessage_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    packed = decoder.readUint8();
    val.sent = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouteProvider_SendRouteMessage_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_SendRouteMessage_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    packed = 0;
    packed |= (val.sent & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouteProvider_SendRouteBinaryMessage_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_SendRouteBinaryMessage_Params.prototype.initDefaults_ = function() {
    this.mediaRouteId = null;
    this.data = null;
  };
  MediaRouteProvider_SendRouteBinaryMessage_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_SendRouteBinaryMessage_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_SendRouteBinaryMessage_Params.mediaRouteId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_SendRouteBinaryMessage_Params.data
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_SendRouteBinaryMessage_Params.encodedSize = codec.kStructHeaderSize + 16;

  MediaRouteProvider_SendRouteBinaryMessage_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_SendRouteBinaryMessage_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaRouteId = decoder.decodeStruct(codec.String);
    val.data = decoder.decodeArrayPointer(codec.Uint8);
    return val;
  };

  MediaRouteProvider_SendRouteBinaryMessage_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_SendRouteBinaryMessage_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaRouteId);
    encoder.encodeArrayPointer(codec.Uint8, val.data);
  };
  function MediaRouteProvider_SendRouteBinaryMessage_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_SendRouteBinaryMessage_ResponseParams.prototype.initDefaults_ = function() {
    this.sent = false;
  };
  MediaRouteProvider_SendRouteBinaryMessage_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_SendRouteBinaryMessage_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  MediaRouteProvider_SendRouteBinaryMessage_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_SendRouteBinaryMessage_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_SendRouteBinaryMessage_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    packed = decoder.readUint8();
    val.sent = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouteProvider_SendRouteBinaryMessage_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_SendRouteBinaryMessage_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    packed = 0;
    packed |= (val.sent & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouteProvider_StartObservingMediaSinks_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_StartObservingMediaSinks_Params.prototype.initDefaults_ = function() {
    this.mediaSource = null;
  };
  MediaRouteProvider_StartObservingMediaSinks_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_StartObservingMediaSinks_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_StartObservingMediaSinks_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_StartObservingMediaSinks_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_StartObservingMediaSinks_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_StartObservingMediaSinks_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaSource = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_StartObservingMediaSinks_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_StartObservingMediaSinks_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaSource);
  };
  function MediaRouteProvider_StopObservingMediaSinks_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_StopObservingMediaSinks_Params.prototype.initDefaults_ = function() {
    this.mediaSource = null;
  };
  MediaRouteProvider_StopObservingMediaSinks_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_StopObservingMediaSinks_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_StopObservingMediaSinks_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_StopObservingMediaSinks_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_StopObservingMediaSinks_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_StopObservingMediaSinks_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaSource = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_StopObservingMediaSinks_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_StopObservingMediaSinks_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaSource);
  };
  function MediaRouteProvider_StartObservingMediaRoutes_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_StartObservingMediaRoutes_Params.prototype.initDefaults_ = function() {
    this.mediaSource = null;
  };
  MediaRouteProvider_StartObservingMediaRoutes_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_StartObservingMediaRoutes_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_StartObservingMediaRoutes_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_StartObservingMediaRoutes_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_StartObservingMediaRoutes_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_StartObservingMediaRoutes_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaSource = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_StartObservingMediaRoutes_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_StartObservingMediaRoutes_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaSource);
  };
  function MediaRouteProvider_StopObservingMediaRoutes_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_StopObservingMediaRoutes_Params.prototype.initDefaults_ = function() {
    this.mediaSource = null;
  };
  MediaRouteProvider_StopObservingMediaRoutes_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_StopObservingMediaRoutes_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_StopObservingMediaRoutes_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_StopObservingMediaRoutes_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_StopObservingMediaRoutes_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_StopObservingMediaRoutes_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaSource = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_StopObservingMediaRoutes_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_StopObservingMediaRoutes_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaSource);
  };
  function MediaRouteProvider_StartListeningForRouteMessages_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_StartListeningForRouteMessages_Params.prototype.initDefaults_ = function() {
    this.routeId = null;
  };
  MediaRouteProvider_StartListeningForRouteMessages_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_StartListeningForRouteMessages_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_StartListeningForRouteMessages_Params.routeId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_StartListeningForRouteMessages_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_StartListeningForRouteMessages_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_StartListeningForRouteMessages_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.routeId = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_StartListeningForRouteMessages_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_StartListeningForRouteMessages_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.routeId);
  };
  function MediaRouteProvider_StopListeningForRouteMessages_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_StopListeningForRouteMessages_Params.prototype.initDefaults_ = function() {
    this.routeId = null;
  };
  MediaRouteProvider_StopListeningForRouteMessages_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_StopListeningForRouteMessages_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_StopListeningForRouteMessages_Params.routeId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_StopListeningForRouteMessages_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_StopListeningForRouteMessages_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_StopListeningForRouteMessages_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.routeId = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_StopListeningForRouteMessages_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_StopListeningForRouteMessages_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.routeId);
  };
  function MediaRouteProvider_DetachRoute_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_DetachRoute_Params.prototype.initDefaults_ = function() {
    this.routeId = null;
  };
  MediaRouteProvider_DetachRoute_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_DetachRoute_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_DetachRoute_Params.routeId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_DetachRoute_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_DetachRoute_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_DetachRoute_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.routeId = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_DetachRoute_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_DetachRoute_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.routeId);
  };
  function MediaRouteProvider_EnableMdnsDiscovery_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_EnableMdnsDiscovery_Params.prototype.initDefaults_ = function() {
  };
  MediaRouteProvider_EnableMdnsDiscovery_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_EnableMdnsDiscovery_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_EnableMdnsDiscovery_Params.encodedSize = codec.kStructHeaderSize + 0;

  MediaRouteProvider_EnableMdnsDiscovery_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_EnableMdnsDiscovery_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  MediaRouteProvider_EnableMdnsDiscovery_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_EnableMdnsDiscovery_Params.encodedSize);
    encoder.writeUint32(0);
  };
  function MediaRouteProvider_UpdateMediaSinks_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_UpdateMediaSinks_Params.prototype.initDefaults_ = function() {
    this.mediaSource = null;
  };
  MediaRouteProvider_UpdateMediaSinks_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_UpdateMediaSinks_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_UpdateMediaSinks_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_UpdateMediaSinks_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_UpdateMediaSinks_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_UpdateMediaSinks_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.mediaSource = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_UpdateMediaSinks_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_UpdateMediaSinks_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.mediaSource);
  };
  function MediaRouteProvider_SearchSinks_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_SearchSinks_Params.prototype.initDefaults_ = function() {
    this.sinkId = null;
    this.mediaSource = null;
    this.searchCriteria = null;
  };
  MediaRouteProvider_SearchSinks_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_SearchSinks_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_SearchSinks_Params.sinkId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_SearchSinks_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_SearchSinks_Params.searchCriteria
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, SinkSearchCriteria, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_SearchSinks_Params.encodedSize = codec.kStructHeaderSize + 24;

  MediaRouteProvider_SearchSinks_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_SearchSinks_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.sinkId = decoder.decodeStruct(codec.String);
    val.mediaSource = decoder.decodeStruct(codec.String);
    val.searchCriteria = decoder.decodeStructPointer(SinkSearchCriteria);
    return val;
  };

  MediaRouteProvider_SearchSinks_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_SearchSinks_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.sinkId);
    encoder.encodeStruct(codec.String, val.mediaSource);
    encoder.encodeStructPointer(SinkSearchCriteria, val.searchCriteria);
  };
  function MediaRouteProvider_SearchSinks_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_SearchSinks_ResponseParams.prototype.initDefaults_ = function() {
    this.sinkId = null;
  };
  MediaRouteProvider_SearchSinks_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_SearchSinks_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_SearchSinks_ResponseParams.sinkId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_SearchSinks_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_SearchSinks_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_SearchSinks_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.sinkId = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouteProvider_SearchSinks_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_SearchSinks_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.sinkId);
  };
  function MediaRouteProvider_ProvideSinks_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_ProvideSinks_Params.prototype.initDefaults_ = function() {
    this.providerName = null;
    this.sinks = null;
  };
  MediaRouteProvider_ProvideSinks_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_ProvideSinks_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_ProvideSinks_Params.providerName
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_ProvideSinks_Params.sinks
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.PointerTo(MediaSink), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_ProvideSinks_Params.encodedSize = codec.kStructHeaderSize + 16;

  MediaRouteProvider_ProvideSinks_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_ProvideSinks_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.providerName = decoder.decodeStruct(codec.String);
    val.sinks = decoder.decodeArrayPointer(new codec.PointerTo(MediaSink));
    return val;
  };

  MediaRouteProvider_ProvideSinks_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_ProvideSinks_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.providerName);
    encoder.encodeArrayPointer(new codec.PointerTo(MediaSink), val.sinks);
  };
  function MediaRouteProvider_CreateMediaRouteController_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_CreateMediaRouteController_Params.prototype.initDefaults_ = function() {
    this.routeId = null;
    this.mediaController = new bindings.InterfaceRequest();
    this.observer = new media_status$.MediaStatusObserverPtr();
  };
  MediaRouteProvider_CreateMediaRouteController_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_CreateMediaRouteController_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_CreateMediaRouteController_Params.routeId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_CreateMediaRouteController_Params.mediaController
    err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouteProvider_CreateMediaRouteController_Params.observer
    err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 12, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouteProvider_CreateMediaRouteController_Params.encodedSize = codec.kStructHeaderSize + 24;

  MediaRouteProvider_CreateMediaRouteController_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_CreateMediaRouteController_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.routeId = decoder.decodeStruct(codec.String);
    val.mediaController = decoder.decodeStruct(codec.InterfaceRequest);
    val.observer = decoder.decodeStruct(new codec.Interface(media_status$.MediaStatusObserverPtr));
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouteProvider_CreateMediaRouteController_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_CreateMediaRouteController_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.routeId);
    encoder.encodeStruct(codec.InterfaceRequest, val.mediaController);
    encoder.encodeStruct(new codec.Interface(media_status$.MediaStatusObserverPtr), val.observer);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouteProvider_CreateMediaRouteController_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouteProvider_CreateMediaRouteController_ResponseParams.prototype.initDefaults_ = function() {
    this.success = false;
  };
  MediaRouteProvider_CreateMediaRouteController_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouteProvider_CreateMediaRouteController_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  MediaRouteProvider_CreateMediaRouteController_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouteProvider_CreateMediaRouteController_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MediaRouteProvider_CreateMediaRouteController_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    packed = decoder.readUint8();
    val.success = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouteProvider_CreateMediaRouteController_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouteProvider_CreateMediaRouteController_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    packed = 0;
    packed |= (val.success & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouter_RegisterMediaRouteProvider_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouter_RegisterMediaRouteProvider_Params.prototype.initDefaults_ = function() {
    this.providerId = 0;
    this.mediaRouterProvider = new MediaRouteProviderPtr();
  };
  MediaRouter_RegisterMediaRouteProvider_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouter_RegisterMediaRouteProvider_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_RegisterMediaRouteProvider_Params.providerId
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MediaRouteProvider.Id);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_RegisterMediaRouteProvider_Params.mediaRouterProvider
    err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 4, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouter_RegisterMediaRouteProvider_Params.encodedSize = codec.kStructHeaderSize + 16;

  MediaRouter_RegisterMediaRouteProvider_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouter_RegisterMediaRouteProvider_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.providerId = decoder.decodeStruct(codec.Int32);
    val.mediaRouterProvider = decoder.decodeStruct(new codec.Interface(MediaRouteProviderPtr));
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouter_RegisterMediaRouteProvider_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouter_RegisterMediaRouteProvider_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.providerId);
    encoder.encodeStruct(new codec.Interface(MediaRouteProviderPtr), val.mediaRouterProvider);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouter_RegisterMediaRouteProvider_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouter_RegisterMediaRouteProvider_ResponseParams.prototype.initDefaults_ = function() {
    this.instanceId = null;
    this.config = null;
  };
  MediaRouter_RegisterMediaRouteProvider_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouter_RegisterMediaRouteProvider_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_RegisterMediaRouteProvider_ResponseParams.instanceId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_RegisterMediaRouteProvider_ResponseParams.config
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, MediaRouteProviderConfig, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouter_RegisterMediaRouteProvider_ResponseParams.encodedSize = codec.kStructHeaderSize + 16;

  MediaRouter_RegisterMediaRouteProvider_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MediaRouter_RegisterMediaRouteProvider_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.instanceId = decoder.decodeStruct(codec.String);
    val.config = decoder.decodeStructPointer(MediaRouteProviderConfig);
    return val;
  };

  MediaRouter_RegisterMediaRouteProvider_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouter_RegisterMediaRouteProvider_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.instanceId);
    encoder.encodeStructPointer(MediaRouteProviderConfig, val.config);
  };
  function MediaRouter_OnSinksReceived_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouter_OnSinksReceived_Params.prototype.initDefaults_ = function() {
    this.providerId = 0;
    this.mediaSource = null;
    this.sinks = null;
    this.origins = null;
  };
  MediaRouter_OnSinksReceived_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouter_OnSinksReceived_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 40}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnSinksReceived_Params.providerId
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MediaRouteProvider.Id);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnSinksReceived_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnSinksReceived_Params.sinks
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 8, new codec.PointerTo(MediaSink), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnSinksReceived_Params.origins
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 24, 8, new codec.PointerTo(origin$.Origin), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouter_OnSinksReceived_Params.encodedSize = codec.kStructHeaderSize + 32;

  MediaRouter_OnSinksReceived_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouter_OnSinksReceived_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.providerId = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.mediaSource = decoder.decodeStruct(codec.String);
    val.sinks = decoder.decodeArrayPointer(new codec.PointerTo(MediaSink));
    val.origins = decoder.decodeArrayPointer(new codec.PointerTo(origin$.Origin));
    return val;
  };

  MediaRouter_OnSinksReceived_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouter_OnSinksReceived_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.providerId);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.String, val.mediaSource);
    encoder.encodeArrayPointer(new codec.PointerTo(MediaSink), val.sinks);
    encoder.encodeArrayPointer(new codec.PointerTo(origin$.Origin), val.origins);
  };
  function MediaRouter_OnIssue_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouter_OnIssue_Params.prototype.initDefaults_ = function() {
    this.issue = null;
  };
  MediaRouter_OnIssue_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouter_OnIssue_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnIssue_Params.issue
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, Issue, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouter_OnIssue_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouter_OnIssue_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouter_OnIssue_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.issue = decoder.decodeStructPointer(Issue);
    return val;
  };

  MediaRouter_OnIssue_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouter_OnIssue_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(Issue, val.issue);
  };
  function MediaRouter_OnRoutesUpdated_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouter_OnRoutesUpdated_Params.prototype.initDefaults_ = function() {
    this.providerId = 0;
    this.routes = null;
    this.mediaSource = null;
    this.joinableRouteIds = null;
  };
  MediaRouter_OnRoutesUpdated_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouter_OnRoutesUpdated_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 40}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnRoutesUpdated_Params.providerId
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MediaRouteProvider.Id);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnRoutesUpdated_Params.routes
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.PointerTo(MediaRoute), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnRoutesUpdated_Params.mediaSource
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnRoutesUpdated_Params.joinableRouteIds
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 24, 8, codec.String, false, [0, 0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouter_OnRoutesUpdated_Params.encodedSize = codec.kStructHeaderSize + 32;

  MediaRouter_OnRoutesUpdated_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouter_OnRoutesUpdated_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.providerId = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.routes = decoder.decodeArrayPointer(new codec.PointerTo(MediaRoute));
    val.mediaSource = decoder.decodeStruct(codec.String);
    val.joinableRouteIds = decoder.decodeArrayPointer(codec.String);
    return val;
  };

  MediaRouter_OnRoutesUpdated_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouter_OnRoutesUpdated_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.providerId);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeArrayPointer(new codec.PointerTo(MediaRoute), val.routes);
    encoder.encodeStruct(codec.String, val.mediaSource);
    encoder.encodeArrayPointer(codec.String, val.joinableRouteIds);
  };
  function MediaRouter_OnSinkAvailabilityUpdated_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouter_OnSinkAvailabilityUpdated_Params.prototype.initDefaults_ = function() {
    this.providerId = 0;
    this.availability = 0;
  };
  MediaRouter_OnSinkAvailabilityUpdated_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouter_OnSinkAvailabilityUpdated_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnSinkAvailabilityUpdated_Params.providerId
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MediaRouteProvider.Id);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnSinkAvailabilityUpdated_Params.availability
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 4, MediaRouter.SinkAvailability);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouter_OnSinkAvailabilityUpdated_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaRouter_OnSinkAvailabilityUpdated_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouter_OnSinkAvailabilityUpdated_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.providerId = decoder.decodeStruct(codec.Int32);
    val.availability = decoder.decodeStruct(codec.Int32);
    return val;
  };

  MediaRouter_OnSinkAvailabilityUpdated_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouter_OnSinkAvailabilityUpdated_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.providerId);
    encoder.encodeStruct(codec.Int32, val.availability);
  };
  function MediaRouter_OnPresentationConnectionStateChanged_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouter_OnPresentationConnectionStateChanged_Params.prototype.initDefaults_ = function() {
    this.routeId = null;
    this.state = 0;
  };
  MediaRouter_OnPresentationConnectionStateChanged_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouter_OnPresentationConnectionStateChanged_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnPresentationConnectionStateChanged_Params.routeId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnPresentationConnectionStateChanged_Params.state
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, MediaRouter.PresentationConnectionState);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouter_OnPresentationConnectionStateChanged_Params.encodedSize = codec.kStructHeaderSize + 16;

  MediaRouter_OnPresentationConnectionStateChanged_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouter_OnPresentationConnectionStateChanged_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.routeId = decoder.decodeStruct(codec.String);
    val.state = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MediaRouter_OnPresentationConnectionStateChanged_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouter_OnPresentationConnectionStateChanged_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.routeId);
    encoder.encodeStruct(codec.Int32, val.state);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaRouter_OnPresentationConnectionClosed_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouter_OnPresentationConnectionClosed_Params.prototype.initDefaults_ = function() {
    this.routeId = null;
    this.reason = 0;
    this.message = null;
  };
  MediaRouter_OnPresentationConnectionClosed_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouter_OnPresentationConnectionClosed_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnPresentationConnectionClosed_Params.routeId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnPresentationConnectionClosed_Params.reason
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, MediaRouter.PresentationConnectionCloseReason);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnPresentationConnectionClosed_Params.message
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouter_OnPresentationConnectionClosed_Params.encodedSize = codec.kStructHeaderSize + 24;

  MediaRouter_OnPresentationConnectionClosed_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouter_OnPresentationConnectionClosed_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.routeId = decoder.decodeStruct(codec.String);
    val.reason = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.message = decoder.decodeStruct(codec.String);
    return val;
  };

  MediaRouter_OnPresentationConnectionClosed_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouter_OnPresentationConnectionClosed_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.routeId);
    encoder.encodeStruct(codec.Int32, val.reason);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.String, val.message);
  };
  function MediaRouter_OnRouteMessagesReceived_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouter_OnRouteMessagesReceived_Params.prototype.initDefaults_ = function() {
    this.routeId = null;
    this.messages = null;
  };
  MediaRouter_OnRouteMessagesReceived_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouter_OnRouteMessagesReceived_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnRouteMessagesReceived_Params.routeId
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnRouteMessagesReceived_Params.messages
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.PointerTo(RouteMessage), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouter_OnRouteMessagesReceived_Params.encodedSize = codec.kStructHeaderSize + 16;

  MediaRouter_OnRouteMessagesReceived_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouter_OnRouteMessagesReceived_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.routeId = decoder.decodeStruct(codec.String);
    val.messages = decoder.decodeArrayPointer(new codec.PointerTo(RouteMessage));
    return val;
  };

  MediaRouter_OnRouteMessagesReceived_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouter_OnRouteMessagesReceived_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.routeId);
    encoder.encodeArrayPointer(new codec.PointerTo(RouteMessage), val.messages);
  };
  function MediaRouter_OnMediaRemoterCreated_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaRouter_OnMediaRemoterCreated_Params.prototype.initDefaults_ = function() {
    this.tabId = 0;
    this.remoter = new mirror_service_remoting$.MirrorServiceRemoterPtr();
    this.remotingSource = new bindings.InterfaceRequest();
  };
  MediaRouter_OnMediaRemoterCreated_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaRouter_OnMediaRemoterCreated_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;



    // validate MediaRouter_OnMediaRemoterCreated_Params.remoter
    err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 4, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaRouter_OnMediaRemoterCreated_Params.remotingSource
    err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 12, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaRouter_OnMediaRemoterCreated_Params.encodedSize = codec.kStructHeaderSize + 16;

  MediaRouter_OnMediaRemoterCreated_Params.decode = function(decoder) {
    var packed;
    var val = new MediaRouter_OnMediaRemoterCreated_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.tabId = decoder.decodeStruct(codec.Int32);
    val.remoter = decoder.decodeStruct(new codec.Interface(mirror_service_remoting$.MirrorServiceRemoterPtr));
    val.remotingSource = decoder.decodeStruct(codec.InterfaceRequest);
    return val;
  };

  MediaRouter_OnMediaRemoterCreated_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaRouter_OnMediaRemoterCreated_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.tabId);
    encoder.encodeStruct(new codec.Interface(mirror_service_remoting$.MirrorServiceRemoterPtr), val.remoter);
    encoder.encodeStruct(codec.InterfaceRequest, val.remotingSource);
  };

  function MediaSinkExtraData(value) {
    this.initDefault_();
    this.initValue_(value);
  }
  
  
  MediaSinkExtraData.Tags = {
    dialMediaSink: 0,
    castMediaSink: 1,
  };
  
  MediaSinkExtraData.prototype.initDefault_ = function() {
    this.$data = null;
    this.$tag = undefined;
  }
  
  MediaSinkExtraData.prototype.initValue_ = function(value) {
    if (value == undefined) {
      return;
    }
  
    var keys = Object.keys(value);
    if (keys.length == 0) {
      return;
    }
  
    if (keys.length > 1) {
      throw new TypeError("You may set only one member on a union.");
    }
  
    var fields = [
        "dialMediaSink",
        "castMediaSink",
    ];
  
    if (fields.indexOf(keys[0]) < 0) {
      throw new ReferenceError(keys[0] + " is not a MediaSinkExtraData member.");
  
    }
  
    this[keys[0]] = value[keys[0]];
  }
  Object.defineProperty(MediaSinkExtraData.prototype, "dialMediaSink", {
    get: function() {
      if (this.$tag != MediaSinkExtraData.Tags.dialMediaSink) {
        throw new ReferenceError(
            "MediaSinkExtraData.dialMediaSink is not currently set.");
      }
      return this.$data;
    },
  
    set: function(value) {
      this.$tag = MediaSinkExtraData.Tags.dialMediaSink;
      this.$data = value;
    }
  });
  Object.defineProperty(MediaSinkExtraData.prototype, "castMediaSink", {
    get: function() {
      if (this.$tag != MediaSinkExtraData.Tags.castMediaSink) {
        throw new ReferenceError(
            "MediaSinkExtraData.castMediaSink is not currently set.");
      }
      return this.$data;
    },
  
    set: function(value) {
      this.$tag = MediaSinkExtraData.Tags.castMediaSink;
      this.$data = value;
    }
  });
  
  
    MediaSinkExtraData.encode = function(encoder, val) {
      if (val == null) {
        encoder.writeUint64(0);
        encoder.writeUint64(0);
        return;
      }
      if (val.$tag == undefined) {
        throw new TypeError("Cannot encode unions with an unknown member set.");
      }
    
      encoder.writeUint32(16);
      encoder.writeUint32(val.$tag);
      switch (val.$tag) {
        case MediaSinkExtraData.Tags.dialMediaSink:
          encoder.encodeStructPointer(DialMediaSink, val.dialMediaSink);
          break;
        case MediaSinkExtraData.Tags.castMediaSink:
          encoder.encodeStructPointer(CastMediaSink, val.castMediaSink);
          break;
      }
      encoder.align();
    };
  
  
    MediaSinkExtraData.decode = function(decoder) {
      var size = decoder.readUint32();
      if (size == 0) {
        decoder.readUint32();
        decoder.readUint64();
        return null;
      }
    
      var result = new MediaSinkExtraData();
      var tag = decoder.readUint32();
      switch (tag) {
        case MediaSinkExtraData.Tags.dialMediaSink:
          result.dialMediaSink = decoder.decodeStructPointer(DialMediaSink);
          break;
        case MediaSinkExtraData.Tags.castMediaSink:
          result.castMediaSink = decoder.decodeStructPointer(CastMediaSink);
          break;
      }
      decoder.align();
    
      return result;
    };
  
  
    MediaSinkExtraData.validate = function(messageValidator, offset) {
      var size = messageValidator.decodeUnionSize(offset);
      if (size != 16) {
        return validator.validationError.INVALID_UNION_SIZE;
      }
    
      var tag = messageValidator.decodeUnionTag(offset);
      var data_offset = offset + 8;
      var err;
      switch (tag) {
        case MediaSinkExtraData.Tags.dialMediaSink:
          
    
    // validate MediaSinkExtraData.dialMediaSink
    err = messageValidator.validateStructPointer(data_offset, DialMediaSink, false);
    if (err !== validator.validationError.NONE)
        return err;
          break;
        case MediaSinkExtraData.Tags.castMediaSink:
          
    
    // validate MediaSinkExtraData.castMediaSink
    err = messageValidator.validateStructPointer(data_offset, CastMediaSink, false);
    if (err !== validator.validationError.NONE)
        return err;
          break;
      }
    
      return validator.validationError.NONE;
    };
  
  MediaSinkExtraData.encodedSize = 16;
  var kMediaRouteProvider_CreateRoute_Name = 532762503;
  var kMediaRouteProvider_JoinRoute_Name = 2106021236;
  var kMediaRouteProvider_ConnectRouteByRouteId_Name = 1337330625;
  var kMediaRouteProvider_TerminateRoute_Name = 1446798134;
  var kMediaRouteProvider_SendRouteMessage_Name = 165525264;
  var kMediaRouteProvider_SendRouteBinaryMessage_Name = 1573256505;
  var kMediaRouteProvider_StartObservingMediaSinks_Name = 541421523;
  var kMediaRouteProvider_StopObservingMediaSinks_Name = 837606112;
  var kMediaRouteProvider_StartObservingMediaRoutes_Name = 135291614;
  var kMediaRouteProvider_StopObservingMediaRoutes_Name = 1922660390;
  var kMediaRouteProvider_StartListeningForRouteMessages_Name = 1098695957;
  var kMediaRouteProvider_StopListeningForRouteMessages_Name = 1641046848;
  var kMediaRouteProvider_DetachRoute_Name = 1832892794;
  var kMediaRouteProvider_EnableMdnsDiscovery_Name = 1287884081;
  var kMediaRouteProvider_UpdateMediaSinks_Name = 2013107007;
  var kMediaRouteProvider_SearchSinks_Name = 636267362;
  var kMediaRouteProvider_ProvideSinks_Name = 338192070;
  var kMediaRouteProvider_CreateMediaRouteController_Name = 1740134779;

  function MediaRouteProviderPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(MediaRouteProvider,
                                                   handleOrPtrInfo);
  }

  function MediaRouteProviderAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        MediaRouteProvider, associatedInterfacePtrInfo);
  }

  MediaRouteProviderAssociatedPtr.prototype =
      Object.create(MediaRouteProviderPtr.prototype);
  MediaRouteProviderAssociatedPtr.prototype.constructor =
      MediaRouteProviderAssociatedPtr;

  function MediaRouteProviderProxy(receiver) {
    this.receiver_ = receiver;
  }
  MediaRouteProviderPtr.prototype.createRoute = function() {
    return MediaRouteProviderProxy.prototype.createRoute
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.createRoute = function(mediaSource, sinkId, originalPresentationId, origin, tabId, timeout, incognito) {
    var params = new MediaRouteProvider_CreateRoute_Params();
    params.mediaSource = mediaSource;
    params.sinkId = sinkId;
    params.originalPresentationId = originalPresentationId;
    params.origin = origin;
    params.tabId = tabId;
    params.timeout = timeout;
    params.incognito = incognito;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMediaRouteProvider_CreateRoute_Name,
          codec.align(MediaRouteProvider_CreateRoute_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MediaRouteProvider_CreateRoute_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MediaRouteProvider_CreateRoute_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };
  MediaRouteProviderPtr.prototype.joinRoute = function() {
    return MediaRouteProviderProxy.prototype.joinRoute
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.joinRoute = function(mediaSource, presentationId, origin, tabId, timeout, incognito) {
    var params = new MediaRouteProvider_JoinRoute_Params();
    params.mediaSource = mediaSource;
    params.presentationId = presentationId;
    params.origin = origin;
    params.tabId = tabId;
    params.timeout = timeout;
    params.incognito = incognito;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMediaRouteProvider_JoinRoute_Name,
          codec.align(MediaRouteProvider_JoinRoute_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MediaRouteProvider_JoinRoute_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MediaRouteProvider_JoinRoute_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };
  MediaRouteProviderPtr.prototype.connectRouteByRouteId = function() {
    return MediaRouteProviderProxy.prototype.connectRouteByRouteId
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.connectRouteByRouteId = function(mediaSource, routeId, presentationId, origin, tabId, timeout, incognito) {
    var params = new MediaRouteProvider_ConnectRouteByRouteId_Params();
    params.mediaSource = mediaSource;
    params.routeId = routeId;
    params.presentationId = presentationId;
    params.origin = origin;
    params.tabId = tabId;
    params.timeout = timeout;
    params.incognito = incognito;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMediaRouteProvider_ConnectRouteByRouteId_Name,
          codec.align(MediaRouteProvider_ConnectRouteByRouteId_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MediaRouteProvider_ConnectRouteByRouteId_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MediaRouteProvider_ConnectRouteByRouteId_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };
  MediaRouteProviderPtr.prototype.terminateRoute = function() {
    return MediaRouteProviderProxy.prototype.terminateRoute
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.terminateRoute = function(routeId) {
    var params = new MediaRouteProvider_TerminateRoute_Params();
    params.routeId = routeId;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMediaRouteProvider_TerminateRoute_Name,
          codec.align(MediaRouteProvider_TerminateRoute_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MediaRouteProvider_TerminateRoute_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MediaRouteProvider_TerminateRoute_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };
  MediaRouteProviderPtr.prototype.sendRouteMessage = function() {
    return MediaRouteProviderProxy.prototype.sendRouteMessage
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.sendRouteMessage = function(mediaRouteId, message) {
    var params = new MediaRouteProvider_SendRouteMessage_Params();
    params.mediaRouteId = mediaRouteId;
    params.message = message;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMediaRouteProvider_SendRouteMessage_Name,
          codec.align(MediaRouteProvider_SendRouteMessage_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MediaRouteProvider_SendRouteMessage_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MediaRouteProvider_SendRouteMessage_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };
  MediaRouteProviderPtr.prototype.sendRouteBinaryMessage = function() {
    return MediaRouteProviderProxy.prototype.sendRouteBinaryMessage
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.sendRouteBinaryMessage = function(mediaRouteId, data) {
    var params = new MediaRouteProvider_SendRouteBinaryMessage_Params();
    params.mediaRouteId = mediaRouteId;
    params.data = data;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMediaRouteProvider_SendRouteBinaryMessage_Name,
          codec.align(MediaRouteProvider_SendRouteBinaryMessage_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MediaRouteProvider_SendRouteBinaryMessage_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MediaRouteProvider_SendRouteBinaryMessage_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };
  MediaRouteProviderPtr.prototype.startObservingMediaSinks = function() {
    return MediaRouteProviderProxy.prototype.startObservingMediaSinks
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.startObservingMediaSinks = function(mediaSource) {
    var params = new MediaRouteProvider_StartObservingMediaSinks_Params();
    params.mediaSource = mediaSource;
    var builder = new codec.MessageV0Builder(
        kMediaRouteProvider_StartObservingMediaSinks_Name,
        codec.align(MediaRouteProvider_StartObservingMediaSinks_Params.encodedSize));
    builder.encodeStruct(MediaRouteProvider_StartObservingMediaSinks_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouteProviderPtr.prototype.stopObservingMediaSinks = function() {
    return MediaRouteProviderProxy.prototype.stopObservingMediaSinks
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.stopObservingMediaSinks = function(mediaSource) {
    var params = new MediaRouteProvider_StopObservingMediaSinks_Params();
    params.mediaSource = mediaSource;
    var builder = new codec.MessageV0Builder(
        kMediaRouteProvider_StopObservingMediaSinks_Name,
        codec.align(MediaRouteProvider_StopObservingMediaSinks_Params.encodedSize));
    builder.encodeStruct(MediaRouteProvider_StopObservingMediaSinks_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouteProviderPtr.prototype.startObservingMediaRoutes = function() {
    return MediaRouteProviderProxy.prototype.startObservingMediaRoutes
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.startObservingMediaRoutes = function(mediaSource) {
    var params = new MediaRouteProvider_StartObservingMediaRoutes_Params();
    params.mediaSource = mediaSource;
    var builder = new codec.MessageV0Builder(
        kMediaRouteProvider_StartObservingMediaRoutes_Name,
        codec.align(MediaRouteProvider_StartObservingMediaRoutes_Params.encodedSize));
    builder.encodeStruct(MediaRouteProvider_StartObservingMediaRoutes_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouteProviderPtr.prototype.stopObservingMediaRoutes = function() {
    return MediaRouteProviderProxy.prototype.stopObservingMediaRoutes
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.stopObservingMediaRoutes = function(mediaSource) {
    var params = new MediaRouteProvider_StopObservingMediaRoutes_Params();
    params.mediaSource = mediaSource;
    var builder = new codec.MessageV0Builder(
        kMediaRouteProvider_StopObservingMediaRoutes_Name,
        codec.align(MediaRouteProvider_StopObservingMediaRoutes_Params.encodedSize));
    builder.encodeStruct(MediaRouteProvider_StopObservingMediaRoutes_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouteProviderPtr.prototype.startListeningForRouteMessages = function() {
    return MediaRouteProviderProxy.prototype.startListeningForRouteMessages
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.startListeningForRouteMessages = function(routeId) {
    var params = new MediaRouteProvider_StartListeningForRouteMessages_Params();
    params.routeId = routeId;
    var builder = new codec.MessageV0Builder(
        kMediaRouteProvider_StartListeningForRouteMessages_Name,
        codec.align(MediaRouteProvider_StartListeningForRouteMessages_Params.encodedSize));
    builder.encodeStruct(MediaRouteProvider_StartListeningForRouteMessages_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouteProviderPtr.prototype.stopListeningForRouteMessages = function() {
    return MediaRouteProviderProxy.prototype.stopListeningForRouteMessages
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.stopListeningForRouteMessages = function(routeId) {
    var params = new MediaRouteProvider_StopListeningForRouteMessages_Params();
    params.routeId = routeId;
    var builder = new codec.MessageV0Builder(
        kMediaRouteProvider_StopListeningForRouteMessages_Name,
        codec.align(MediaRouteProvider_StopListeningForRouteMessages_Params.encodedSize));
    builder.encodeStruct(MediaRouteProvider_StopListeningForRouteMessages_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouteProviderPtr.prototype.detachRoute = function() {
    return MediaRouteProviderProxy.prototype.detachRoute
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.detachRoute = function(routeId) {
    var params = new MediaRouteProvider_DetachRoute_Params();
    params.routeId = routeId;
    var builder = new codec.MessageV0Builder(
        kMediaRouteProvider_DetachRoute_Name,
        codec.align(MediaRouteProvider_DetachRoute_Params.encodedSize));
    builder.encodeStruct(MediaRouteProvider_DetachRoute_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouteProviderPtr.prototype.enableMdnsDiscovery = function() {
    return MediaRouteProviderProxy.prototype.enableMdnsDiscovery
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.enableMdnsDiscovery = function() {
    var params = new MediaRouteProvider_EnableMdnsDiscovery_Params();
    var builder = new codec.MessageV0Builder(
        kMediaRouteProvider_EnableMdnsDiscovery_Name,
        codec.align(MediaRouteProvider_EnableMdnsDiscovery_Params.encodedSize));
    builder.encodeStruct(MediaRouteProvider_EnableMdnsDiscovery_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouteProviderPtr.prototype.updateMediaSinks = function() {
    return MediaRouteProviderProxy.prototype.updateMediaSinks
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.updateMediaSinks = function(mediaSource) {
    var params = new MediaRouteProvider_UpdateMediaSinks_Params();
    params.mediaSource = mediaSource;
    var builder = new codec.MessageV0Builder(
        kMediaRouteProvider_UpdateMediaSinks_Name,
        codec.align(MediaRouteProvider_UpdateMediaSinks_Params.encodedSize));
    builder.encodeStruct(MediaRouteProvider_UpdateMediaSinks_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouteProviderPtr.prototype.searchSinks = function() {
    return MediaRouteProviderProxy.prototype.searchSinks
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.searchSinks = function(sinkId, mediaSource, searchCriteria) {
    var params = new MediaRouteProvider_SearchSinks_Params();
    params.sinkId = sinkId;
    params.mediaSource = mediaSource;
    params.searchCriteria = searchCriteria;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMediaRouteProvider_SearchSinks_Name,
          codec.align(MediaRouteProvider_SearchSinks_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MediaRouteProvider_SearchSinks_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MediaRouteProvider_SearchSinks_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };
  MediaRouteProviderPtr.prototype.provideSinks = function() {
    return MediaRouteProviderProxy.prototype.provideSinks
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.provideSinks = function(providerName, sinks) {
    var params = new MediaRouteProvider_ProvideSinks_Params();
    params.providerName = providerName;
    params.sinks = sinks;
    var builder = new codec.MessageV0Builder(
        kMediaRouteProvider_ProvideSinks_Name,
        codec.align(MediaRouteProvider_ProvideSinks_Params.encodedSize));
    builder.encodeStruct(MediaRouteProvider_ProvideSinks_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouteProviderPtr.prototype.createMediaRouteController = function() {
    return MediaRouteProviderProxy.prototype.createMediaRouteController
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouteProviderProxy.prototype.createMediaRouteController = function(routeId, mediaController, observer) {
    var params = new MediaRouteProvider_CreateMediaRouteController_Params();
    params.routeId = routeId;
    params.mediaController = mediaController;
    params.observer = observer;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMediaRouteProvider_CreateMediaRouteController_Name,
          codec.align(MediaRouteProvider_CreateMediaRouteController_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MediaRouteProvider_CreateMediaRouteController_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MediaRouteProvider_CreateMediaRouteController_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };

  function MediaRouteProviderStub(delegate) {
    this.delegate_ = delegate;
  }
  MediaRouteProviderStub.prototype.createRoute = function(mediaSource, sinkId, originalPresentationId, origin, tabId, timeout, incognito) {
    return this.delegate_ && this.delegate_.createRoute && this.delegate_.createRoute(mediaSource, sinkId, originalPresentationId, origin, tabId, timeout, incognito);
  }
  MediaRouteProviderStub.prototype.joinRoute = function(mediaSource, presentationId, origin, tabId, timeout, incognito) {
    return this.delegate_ && this.delegate_.joinRoute && this.delegate_.joinRoute(mediaSource, presentationId, origin, tabId, timeout, incognito);
  }
  MediaRouteProviderStub.prototype.connectRouteByRouteId = function(mediaSource, routeId, presentationId, origin, tabId, timeout, incognito) {
    return this.delegate_ && this.delegate_.connectRouteByRouteId && this.delegate_.connectRouteByRouteId(mediaSource, routeId, presentationId, origin, tabId, timeout, incognito);
  }
  MediaRouteProviderStub.prototype.terminateRoute = function(routeId) {
    return this.delegate_ && this.delegate_.terminateRoute && this.delegate_.terminateRoute(routeId);
  }
  MediaRouteProviderStub.prototype.sendRouteMessage = function(mediaRouteId, message) {
    return this.delegate_ && this.delegate_.sendRouteMessage && this.delegate_.sendRouteMessage(mediaRouteId, message);
  }
  MediaRouteProviderStub.prototype.sendRouteBinaryMessage = function(mediaRouteId, data) {
    return this.delegate_ && this.delegate_.sendRouteBinaryMessage && this.delegate_.sendRouteBinaryMessage(mediaRouteId, data);
  }
  MediaRouteProviderStub.prototype.startObservingMediaSinks = function(mediaSource) {
    return this.delegate_ && this.delegate_.startObservingMediaSinks && this.delegate_.startObservingMediaSinks(mediaSource);
  }
  MediaRouteProviderStub.prototype.stopObservingMediaSinks = function(mediaSource) {
    return this.delegate_ && this.delegate_.stopObservingMediaSinks && this.delegate_.stopObservingMediaSinks(mediaSource);
  }
  MediaRouteProviderStub.prototype.startObservingMediaRoutes = function(mediaSource) {
    return this.delegate_ && this.delegate_.startObservingMediaRoutes && this.delegate_.startObservingMediaRoutes(mediaSource);
  }
  MediaRouteProviderStub.prototype.stopObservingMediaRoutes = function(mediaSource) {
    return this.delegate_ && this.delegate_.stopObservingMediaRoutes && this.delegate_.stopObservingMediaRoutes(mediaSource);
  }
  MediaRouteProviderStub.prototype.startListeningForRouteMessages = function(routeId) {
    return this.delegate_ && this.delegate_.startListeningForRouteMessages && this.delegate_.startListeningForRouteMessages(routeId);
  }
  MediaRouteProviderStub.prototype.stopListeningForRouteMessages = function(routeId) {
    return this.delegate_ && this.delegate_.stopListeningForRouteMessages && this.delegate_.stopListeningForRouteMessages(routeId);
  }
  MediaRouteProviderStub.prototype.detachRoute = function(routeId) {
    return this.delegate_ && this.delegate_.detachRoute && this.delegate_.detachRoute(routeId);
  }
  MediaRouteProviderStub.prototype.enableMdnsDiscovery = function() {
    return this.delegate_ && this.delegate_.enableMdnsDiscovery && this.delegate_.enableMdnsDiscovery();
  }
  MediaRouteProviderStub.prototype.updateMediaSinks = function(mediaSource) {
    return this.delegate_ && this.delegate_.updateMediaSinks && this.delegate_.updateMediaSinks(mediaSource);
  }
  MediaRouteProviderStub.prototype.searchSinks = function(sinkId, mediaSource, searchCriteria) {
    return this.delegate_ && this.delegate_.searchSinks && this.delegate_.searchSinks(sinkId, mediaSource, searchCriteria);
  }
  MediaRouteProviderStub.prototype.provideSinks = function(providerName, sinks) {
    return this.delegate_ && this.delegate_.provideSinks && this.delegate_.provideSinks(providerName, sinks);
  }
  MediaRouteProviderStub.prototype.createMediaRouteController = function(routeId, mediaController, observer) {
    return this.delegate_ && this.delegate_.createMediaRouteController && this.delegate_.createMediaRouteController(routeId, mediaController, observer);
  }

  MediaRouteProviderStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kMediaRouteProvider_StartObservingMediaSinks_Name:
      var params = reader.decodeStruct(MediaRouteProvider_StartObservingMediaSinks_Params);
      this.startObservingMediaSinks(params.mediaSource);
      return true;
    case kMediaRouteProvider_StopObservingMediaSinks_Name:
      var params = reader.decodeStruct(MediaRouteProvider_StopObservingMediaSinks_Params);
      this.stopObservingMediaSinks(params.mediaSource);
      return true;
    case kMediaRouteProvider_StartObservingMediaRoutes_Name:
      var params = reader.decodeStruct(MediaRouteProvider_StartObservingMediaRoutes_Params);
      this.startObservingMediaRoutes(params.mediaSource);
      return true;
    case kMediaRouteProvider_StopObservingMediaRoutes_Name:
      var params = reader.decodeStruct(MediaRouteProvider_StopObservingMediaRoutes_Params);
      this.stopObservingMediaRoutes(params.mediaSource);
      return true;
    case kMediaRouteProvider_StartListeningForRouteMessages_Name:
      var params = reader.decodeStruct(MediaRouteProvider_StartListeningForRouteMessages_Params);
      this.startListeningForRouteMessages(params.routeId);
      return true;
    case kMediaRouteProvider_StopListeningForRouteMessages_Name:
      var params = reader.decodeStruct(MediaRouteProvider_StopListeningForRouteMessages_Params);
      this.stopListeningForRouteMessages(params.routeId);
      return true;
    case kMediaRouteProvider_DetachRoute_Name:
      var params = reader.decodeStruct(MediaRouteProvider_DetachRoute_Params);
      this.detachRoute(params.routeId);
      return true;
    case kMediaRouteProvider_EnableMdnsDiscovery_Name:
      var params = reader.decodeStruct(MediaRouteProvider_EnableMdnsDiscovery_Params);
      this.enableMdnsDiscovery();
      return true;
    case kMediaRouteProvider_UpdateMediaSinks_Name:
      var params = reader.decodeStruct(MediaRouteProvider_UpdateMediaSinks_Params);
      this.updateMediaSinks(params.mediaSource);
      return true;
    case kMediaRouteProvider_ProvideSinks_Name:
      var params = reader.decodeStruct(MediaRouteProvider_ProvideSinks_Params);
      this.provideSinks(params.providerName, params.sinks);
      return true;
    default:
      return false;
    }
  };

  MediaRouteProviderStub.prototype.acceptWithResponder =
      function(message, responder) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kMediaRouteProvider_CreateRoute_Name:
      var params = reader.decodeStruct(MediaRouteProvider_CreateRoute_Params);
      this.createRoute(params.mediaSource, params.sinkId, params.originalPresentationId, params.origin, params.tabId, params.timeout, params.incognito).then(function(response) {
        var responseParams =
            new MediaRouteProvider_CreateRoute_ResponseParams();
        responseParams.route = response.route;
        responseParams.errorText = response.errorText;
        responseParams.resultCode = response.resultCode;
        var builder = new codec.MessageV1Builder(
            kMediaRouteProvider_CreateRoute_Name,
            codec.align(MediaRouteProvider_CreateRoute_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MediaRouteProvider_CreateRoute_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    case kMediaRouteProvider_JoinRoute_Name:
      var params = reader.decodeStruct(MediaRouteProvider_JoinRoute_Params);
      this.joinRoute(params.mediaSource, params.presentationId, params.origin, params.tabId, params.timeout, params.incognito).then(function(response) {
        var responseParams =
            new MediaRouteProvider_JoinRoute_ResponseParams();
        responseParams.route = response.route;
        responseParams.errorText = response.errorText;
        responseParams.resultCode = response.resultCode;
        var builder = new codec.MessageV1Builder(
            kMediaRouteProvider_JoinRoute_Name,
            codec.align(MediaRouteProvider_JoinRoute_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MediaRouteProvider_JoinRoute_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    case kMediaRouteProvider_ConnectRouteByRouteId_Name:
      var params = reader.decodeStruct(MediaRouteProvider_ConnectRouteByRouteId_Params);
      this.connectRouteByRouteId(params.mediaSource, params.routeId, params.presentationId, params.origin, params.tabId, params.timeout, params.incognito).then(function(response) {
        var responseParams =
            new MediaRouteProvider_ConnectRouteByRouteId_ResponseParams();
        responseParams.route = response.route;
        responseParams.errorText = response.errorText;
        responseParams.resultCode = response.resultCode;
        var builder = new codec.MessageV1Builder(
            kMediaRouteProvider_ConnectRouteByRouteId_Name,
            codec.align(MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MediaRouteProvider_ConnectRouteByRouteId_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    case kMediaRouteProvider_TerminateRoute_Name:
      var params = reader.decodeStruct(MediaRouteProvider_TerminateRoute_Params);
      this.terminateRoute(params.routeId).then(function(response) {
        var responseParams =
            new MediaRouteProvider_TerminateRoute_ResponseParams();
        responseParams.errorText = response.errorText;
        responseParams.resultCode = response.resultCode;
        var builder = new codec.MessageV1Builder(
            kMediaRouteProvider_TerminateRoute_Name,
            codec.align(MediaRouteProvider_TerminateRoute_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MediaRouteProvider_TerminateRoute_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    case kMediaRouteProvider_SendRouteMessage_Name:
      var params = reader.decodeStruct(MediaRouteProvider_SendRouteMessage_Params);
      this.sendRouteMessage(params.mediaRouteId, params.message).then(function(response) {
        var responseParams =
            new MediaRouteProvider_SendRouteMessage_ResponseParams();
        responseParams.sent = response.sent;
        var builder = new codec.MessageV1Builder(
            kMediaRouteProvider_SendRouteMessage_Name,
            codec.align(MediaRouteProvider_SendRouteMessage_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MediaRouteProvider_SendRouteMessage_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    case kMediaRouteProvider_SendRouteBinaryMessage_Name:
      var params = reader.decodeStruct(MediaRouteProvider_SendRouteBinaryMessage_Params);
      this.sendRouteBinaryMessage(params.mediaRouteId, params.data).then(function(response) {
        var responseParams =
            new MediaRouteProvider_SendRouteBinaryMessage_ResponseParams();
        responseParams.sent = response.sent;
        var builder = new codec.MessageV1Builder(
            kMediaRouteProvider_SendRouteBinaryMessage_Name,
            codec.align(MediaRouteProvider_SendRouteBinaryMessage_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MediaRouteProvider_SendRouteBinaryMessage_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    case kMediaRouteProvider_SearchSinks_Name:
      var params = reader.decodeStruct(MediaRouteProvider_SearchSinks_Params);
      this.searchSinks(params.sinkId, params.mediaSource, params.searchCriteria).then(function(response) {
        var responseParams =
            new MediaRouteProvider_SearchSinks_ResponseParams();
        responseParams.sinkId = response.sinkId;
        var builder = new codec.MessageV1Builder(
            kMediaRouteProvider_SearchSinks_Name,
            codec.align(MediaRouteProvider_SearchSinks_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MediaRouteProvider_SearchSinks_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    case kMediaRouteProvider_CreateMediaRouteController_Name:
      var params = reader.decodeStruct(MediaRouteProvider_CreateMediaRouteController_Params);
      this.createMediaRouteController(params.routeId, params.mediaController, params.observer).then(function(response) {
        var responseParams =
            new MediaRouteProvider_CreateMediaRouteController_ResponseParams();
        responseParams.success = response.success;
        var builder = new codec.MessageV1Builder(
            kMediaRouteProvider_CreateMediaRouteController_Name,
            codec.align(MediaRouteProvider_CreateMediaRouteController_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MediaRouteProvider_CreateMediaRouteController_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    default:
      return false;
    }
  };

  function validateMediaRouteProviderRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kMediaRouteProvider_CreateRoute_Name:
        if (message.expectsResponse())
          paramsClass = MediaRouteProvider_CreateRoute_Params;
      break;
      case kMediaRouteProvider_JoinRoute_Name:
        if (message.expectsResponse())
          paramsClass = MediaRouteProvider_JoinRoute_Params;
      break;
      case kMediaRouteProvider_ConnectRouteByRouteId_Name:
        if (message.expectsResponse())
          paramsClass = MediaRouteProvider_ConnectRouteByRouteId_Params;
      break;
      case kMediaRouteProvider_TerminateRoute_Name:
        if (message.expectsResponse())
          paramsClass = MediaRouteProvider_TerminateRoute_Params;
      break;
      case kMediaRouteProvider_SendRouteMessage_Name:
        if (message.expectsResponse())
          paramsClass = MediaRouteProvider_SendRouteMessage_Params;
      break;
      case kMediaRouteProvider_SendRouteBinaryMessage_Name:
        if (message.expectsResponse())
          paramsClass = MediaRouteProvider_SendRouteBinaryMessage_Params;
      break;
      case kMediaRouteProvider_StartObservingMediaSinks_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouteProvider_StartObservingMediaSinks_Params;
      break;
      case kMediaRouteProvider_StopObservingMediaSinks_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouteProvider_StopObservingMediaSinks_Params;
      break;
      case kMediaRouteProvider_StartObservingMediaRoutes_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouteProvider_StartObservingMediaRoutes_Params;
      break;
      case kMediaRouteProvider_StopObservingMediaRoutes_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouteProvider_StopObservingMediaRoutes_Params;
      break;
      case kMediaRouteProvider_StartListeningForRouteMessages_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouteProvider_StartListeningForRouteMessages_Params;
      break;
      case kMediaRouteProvider_StopListeningForRouteMessages_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouteProvider_StopListeningForRouteMessages_Params;
      break;
      case kMediaRouteProvider_DetachRoute_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouteProvider_DetachRoute_Params;
      break;
      case kMediaRouteProvider_EnableMdnsDiscovery_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouteProvider_EnableMdnsDiscovery_Params;
      break;
      case kMediaRouteProvider_UpdateMediaSinks_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouteProvider_UpdateMediaSinks_Params;
      break;
      case kMediaRouteProvider_SearchSinks_Name:
        if (message.expectsResponse())
          paramsClass = MediaRouteProvider_SearchSinks_Params;
      break;
      case kMediaRouteProvider_ProvideSinks_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouteProvider_ProvideSinks_Params;
      break;
      case kMediaRouteProvider_CreateMediaRouteController_Name:
        if (message.expectsResponse())
          paramsClass = MediaRouteProvider_CreateMediaRouteController_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  function validateMediaRouteProviderResponse(messageValidator) {
   var message = messageValidator.message;
   var paramsClass = null;
   switch (message.getName()) {
      case kMediaRouteProvider_CreateRoute_Name:
        if (message.isResponse())
          paramsClass = MediaRouteProvider_CreateRoute_ResponseParams;
        break;
      case kMediaRouteProvider_JoinRoute_Name:
        if (message.isResponse())
          paramsClass = MediaRouteProvider_JoinRoute_ResponseParams;
        break;
      case kMediaRouteProvider_ConnectRouteByRouteId_Name:
        if (message.isResponse())
          paramsClass = MediaRouteProvider_ConnectRouteByRouteId_ResponseParams;
        break;
      case kMediaRouteProvider_TerminateRoute_Name:
        if (message.isResponse())
          paramsClass = MediaRouteProvider_TerminateRoute_ResponseParams;
        break;
      case kMediaRouteProvider_SendRouteMessage_Name:
        if (message.isResponse())
          paramsClass = MediaRouteProvider_SendRouteMessage_ResponseParams;
        break;
      case kMediaRouteProvider_SendRouteBinaryMessage_Name:
        if (message.isResponse())
          paramsClass = MediaRouteProvider_SendRouteBinaryMessage_ResponseParams;
        break;
      case kMediaRouteProvider_SearchSinks_Name:
        if (message.isResponse())
          paramsClass = MediaRouteProvider_SearchSinks_ResponseParams;
        break;
      case kMediaRouteProvider_CreateMediaRouteController_Name:
        if (message.isResponse())
          paramsClass = MediaRouteProvider_CreateMediaRouteController_ResponseParams;
        break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  var MediaRouteProvider = {
    name: 'media_router::mojom::MediaRouteProvider',
    kVersion: 0,
    ptrClass: MediaRouteProviderPtr,
    proxyClass: MediaRouteProviderProxy,
    stubClass: MediaRouteProviderStub,
    validateRequest: validateMediaRouteProviderRequest,
    validateResponse: validateMediaRouteProviderResponse,
  };
  MediaRouteProvider.Id = {};
  MediaRouteProvider.Id.EXTENSION = 0;
  MediaRouteProvider.Id.WIRED_DISPLAY = MediaRouteProvider.Id.EXTENSION + 1;

  MediaRouteProvider.Id.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
      return true;
    }
    return false;
  };

  MediaRouteProvider.Id.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  MediaRouteProviderStub.prototype.validator = validateMediaRouteProviderRequest;
  MediaRouteProviderProxy.prototype.validator = validateMediaRouteProviderResponse;
  var kMediaRouter_RegisterMediaRouteProvider_Name = 1633404846;
  var kMediaRouter_OnSinksReceived_Name = 2015856829;
  var kMediaRouter_OnIssue_Name = 1759034049;
  var kMediaRouter_OnRoutesUpdated_Name = 2003346426;
  var kMediaRouter_OnSinkAvailabilityUpdated_Name = 2056392117;
  var kMediaRouter_OnPresentationConnectionStateChanged_Name = 1154951203;
  var kMediaRouter_OnPresentationConnectionClosed_Name = 426891386;
  var kMediaRouter_OnRouteMessagesReceived_Name = 1939797999;
  var kMediaRouter_OnMediaRemoterCreated_Name = 1740078423;

  function MediaRouterPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(MediaRouter,
                                                   handleOrPtrInfo);
  }

  function MediaRouterAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        MediaRouter, associatedInterfacePtrInfo);
  }

  MediaRouterAssociatedPtr.prototype =
      Object.create(MediaRouterPtr.prototype);
  MediaRouterAssociatedPtr.prototype.constructor =
      MediaRouterAssociatedPtr;

  function MediaRouterProxy(receiver) {
    this.receiver_ = receiver;
  }
  MediaRouterPtr.prototype.registerMediaRouteProvider = function() {
    return MediaRouterProxy.prototype.registerMediaRouteProvider
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouterProxy.prototype.registerMediaRouteProvider = function(providerId, mediaRouterProvider) {
    var params = new MediaRouter_RegisterMediaRouteProvider_Params();
    params.providerId = providerId;
    params.mediaRouterProvider = mediaRouterProvider;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMediaRouter_RegisterMediaRouteProvider_Name,
          codec.align(MediaRouter_RegisterMediaRouteProvider_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MediaRouter_RegisterMediaRouteProvider_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MediaRouter_RegisterMediaRouteProvider_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };
  MediaRouterPtr.prototype.onSinksReceived = function() {
    return MediaRouterProxy.prototype.onSinksReceived
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouterProxy.prototype.onSinksReceived = function(providerId, mediaSource, sinks, origins) {
    var params = new MediaRouter_OnSinksReceived_Params();
    params.providerId = providerId;
    params.mediaSource = mediaSource;
    params.sinks = sinks;
    params.origins = origins;
    var builder = new codec.MessageV0Builder(
        kMediaRouter_OnSinksReceived_Name,
        codec.align(MediaRouter_OnSinksReceived_Params.encodedSize));
    builder.encodeStruct(MediaRouter_OnSinksReceived_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouterPtr.prototype.onIssue = function() {
    return MediaRouterProxy.prototype.onIssue
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouterProxy.prototype.onIssue = function(issue) {
    var params = new MediaRouter_OnIssue_Params();
    params.issue = issue;
    var builder = new codec.MessageV0Builder(
        kMediaRouter_OnIssue_Name,
        codec.align(MediaRouter_OnIssue_Params.encodedSize));
    builder.encodeStruct(MediaRouter_OnIssue_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouterPtr.prototype.onRoutesUpdated = function() {
    return MediaRouterProxy.prototype.onRoutesUpdated
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouterProxy.prototype.onRoutesUpdated = function(providerId, routes, mediaSource, joinableRouteIds) {
    var params = new MediaRouter_OnRoutesUpdated_Params();
    params.providerId = providerId;
    params.routes = routes;
    params.mediaSource = mediaSource;
    params.joinableRouteIds = joinableRouteIds;
    var builder = new codec.MessageV0Builder(
        kMediaRouter_OnRoutesUpdated_Name,
        codec.align(MediaRouter_OnRoutesUpdated_Params.encodedSize));
    builder.encodeStruct(MediaRouter_OnRoutesUpdated_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouterPtr.prototype.onSinkAvailabilityUpdated = function() {
    return MediaRouterProxy.prototype.onSinkAvailabilityUpdated
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouterProxy.prototype.onSinkAvailabilityUpdated = function(providerId, availability) {
    var params = new MediaRouter_OnSinkAvailabilityUpdated_Params();
    params.providerId = providerId;
    params.availability = availability;
    var builder = new codec.MessageV0Builder(
        kMediaRouter_OnSinkAvailabilityUpdated_Name,
        codec.align(MediaRouter_OnSinkAvailabilityUpdated_Params.encodedSize));
    builder.encodeStruct(MediaRouter_OnSinkAvailabilityUpdated_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouterPtr.prototype.onPresentationConnectionStateChanged = function() {
    return MediaRouterProxy.prototype.onPresentationConnectionStateChanged
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouterProxy.prototype.onPresentationConnectionStateChanged = function(routeId, state) {
    var params = new MediaRouter_OnPresentationConnectionStateChanged_Params();
    params.routeId = routeId;
    params.state = state;
    var builder = new codec.MessageV0Builder(
        kMediaRouter_OnPresentationConnectionStateChanged_Name,
        codec.align(MediaRouter_OnPresentationConnectionStateChanged_Params.encodedSize));
    builder.encodeStruct(MediaRouter_OnPresentationConnectionStateChanged_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouterPtr.prototype.onPresentationConnectionClosed = function() {
    return MediaRouterProxy.prototype.onPresentationConnectionClosed
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouterProxy.prototype.onPresentationConnectionClosed = function(routeId, reason, message) {
    var params = new MediaRouter_OnPresentationConnectionClosed_Params();
    params.routeId = routeId;
    params.reason = reason;
    params.message = message;
    var builder = new codec.MessageV0Builder(
        kMediaRouter_OnPresentationConnectionClosed_Name,
        codec.align(MediaRouter_OnPresentationConnectionClosed_Params.encodedSize));
    builder.encodeStruct(MediaRouter_OnPresentationConnectionClosed_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouterPtr.prototype.onRouteMessagesReceived = function() {
    return MediaRouterProxy.prototype.onRouteMessagesReceived
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouterProxy.prototype.onRouteMessagesReceived = function(routeId, messages) {
    var params = new MediaRouter_OnRouteMessagesReceived_Params();
    params.routeId = routeId;
    params.messages = messages;
    var builder = new codec.MessageV0Builder(
        kMediaRouter_OnRouteMessagesReceived_Name,
        codec.align(MediaRouter_OnRouteMessagesReceived_Params.encodedSize));
    builder.encodeStruct(MediaRouter_OnRouteMessagesReceived_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MediaRouterPtr.prototype.onMediaRemoterCreated = function() {
    return MediaRouterProxy.prototype.onMediaRemoterCreated
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaRouterProxy.prototype.onMediaRemoterCreated = function(tabId, remoter, remotingSource) {
    var params = new MediaRouter_OnMediaRemoterCreated_Params();
    params.tabId = tabId;
    params.remoter = remoter;
    params.remotingSource = remotingSource;
    var builder = new codec.MessageV0Builder(
        kMediaRouter_OnMediaRemoterCreated_Name,
        codec.align(MediaRouter_OnMediaRemoterCreated_Params.encodedSize));
    builder.encodeStruct(MediaRouter_OnMediaRemoterCreated_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function MediaRouterStub(delegate) {
    this.delegate_ = delegate;
  }
  MediaRouterStub.prototype.registerMediaRouteProvider = function(providerId, mediaRouterProvider) {
    return this.delegate_ && this.delegate_.registerMediaRouteProvider && this.delegate_.registerMediaRouteProvider(providerId, mediaRouterProvider);
  }
  MediaRouterStub.prototype.onSinksReceived = function(providerId, mediaSource, sinks, origins) {
    return this.delegate_ && this.delegate_.onSinksReceived && this.delegate_.onSinksReceived(providerId, mediaSource, sinks, origins);
  }
  MediaRouterStub.prototype.onIssue = function(issue) {
    return this.delegate_ && this.delegate_.onIssue && this.delegate_.onIssue(issue);
  }
  MediaRouterStub.prototype.onRoutesUpdated = function(providerId, routes, mediaSource, joinableRouteIds) {
    return this.delegate_ && this.delegate_.onRoutesUpdated && this.delegate_.onRoutesUpdated(providerId, routes, mediaSource, joinableRouteIds);
  }
  MediaRouterStub.prototype.onSinkAvailabilityUpdated = function(providerId, availability) {
    return this.delegate_ && this.delegate_.onSinkAvailabilityUpdated && this.delegate_.onSinkAvailabilityUpdated(providerId, availability);
  }
  MediaRouterStub.prototype.onPresentationConnectionStateChanged = function(routeId, state) {
    return this.delegate_ && this.delegate_.onPresentationConnectionStateChanged && this.delegate_.onPresentationConnectionStateChanged(routeId, state);
  }
  MediaRouterStub.prototype.onPresentationConnectionClosed = function(routeId, reason, message) {
    return this.delegate_ && this.delegate_.onPresentationConnectionClosed && this.delegate_.onPresentationConnectionClosed(routeId, reason, message);
  }
  MediaRouterStub.prototype.onRouteMessagesReceived = function(routeId, messages) {
    return this.delegate_ && this.delegate_.onRouteMessagesReceived && this.delegate_.onRouteMessagesReceived(routeId, messages);
  }
  MediaRouterStub.prototype.onMediaRemoterCreated = function(tabId, remoter, remotingSource) {
    return this.delegate_ && this.delegate_.onMediaRemoterCreated && this.delegate_.onMediaRemoterCreated(tabId, remoter, remotingSource);
  }

  MediaRouterStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kMediaRouter_OnSinksReceived_Name:
      var params = reader.decodeStruct(MediaRouter_OnSinksReceived_Params);
      this.onSinksReceived(params.providerId, params.mediaSource, params.sinks, params.origins);
      return true;
    case kMediaRouter_OnIssue_Name:
      var params = reader.decodeStruct(MediaRouter_OnIssue_Params);
      this.onIssue(params.issue);
      return true;
    case kMediaRouter_OnRoutesUpdated_Name:
      var params = reader.decodeStruct(MediaRouter_OnRoutesUpdated_Params);
      this.onRoutesUpdated(params.providerId, params.routes, params.mediaSource, params.joinableRouteIds);
      return true;
    case kMediaRouter_OnSinkAvailabilityUpdated_Name:
      var params = reader.decodeStruct(MediaRouter_OnSinkAvailabilityUpdated_Params);
      this.onSinkAvailabilityUpdated(params.providerId, params.availability);
      return true;
    case kMediaRouter_OnPresentationConnectionStateChanged_Name:
      var params = reader.decodeStruct(MediaRouter_OnPresentationConnectionStateChanged_Params);
      this.onPresentationConnectionStateChanged(params.routeId, params.state);
      return true;
    case kMediaRouter_OnPresentationConnectionClosed_Name:
      var params = reader.decodeStruct(MediaRouter_OnPresentationConnectionClosed_Params);
      this.onPresentationConnectionClosed(params.routeId, params.reason, params.message);
      return true;
    case kMediaRouter_OnRouteMessagesReceived_Name:
      var params = reader.decodeStruct(MediaRouter_OnRouteMessagesReceived_Params);
      this.onRouteMessagesReceived(params.routeId, params.messages);
      return true;
    case kMediaRouter_OnMediaRemoterCreated_Name:
      var params = reader.decodeStruct(MediaRouter_OnMediaRemoterCreated_Params);
      this.onMediaRemoterCreated(params.tabId, params.remoter, params.remotingSource);
      return true;
    default:
      return false;
    }
  };

  MediaRouterStub.prototype.acceptWithResponder =
      function(message, responder) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kMediaRouter_RegisterMediaRouteProvider_Name:
      var params = reader.decodeStruct(MediaRouter_RegisterMediaRouteProvider_Params);
      this.registerMediaRouteProvider(params.providerId, params.mediaRouterProvider).then(function(response) {
        var responseParams =
            new MediaRouter_RegisterMediaRouteProvider_ResponseParams();
        responseParams.instanceId = response.instanceId;
        responseParams.config = response.config;
        var builder = new codec.MessageV1Builder(
            kMediaRouter_RegisterMediaRouteProvider_Name,
            codec.align(MediaRouter_RegisterMediaRouteProvider_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MediaRouter_RegisterMediaRouteProvider_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    default:
      return false;
    }
  };

  function validateMediaRouterRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kMediaRouter_RegisterMediaRouteProvider_Name:
        if (message.expectsResponse())
          paramsClass = MediaRouter_RegisterMediaRouteProvider_Params;
      break;
      case kMediaRouter_OnSinksReceived_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouter_OnSinksReceived_Params;
      break;
      case kMediaRouter_OnIssue_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouter_OnIssue_Params;
      break;
      case kMediaRouter_OnRoutesUpdated_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouter_OnRoutesUpdated_Params;
      break;
      case kMediaRouter_OnSinkAvailabilityUpdated_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouter_OnSinkAvailabilityUpdated_Params;
      break;
      case kMediaRouter_OnPresentationConnectionStateChanged_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouter_OnPresentationConnectionStateChanged_Params;
      break;
      case kMediaRouter_OnPresentationConnectionClosed_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouter_OnPresentationConnectionClosed_Params;
      break;
      case kMediaRouter_OnRouteMessagesReceived_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouter_OnRouteMessagesReceived_Params;
      break;
      case kMediaRouter_OnMediaRemoterCreated_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaRouter_OnMediaRemoterCreated_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  function validateMediaRouterResponse(messageValidator) {
   var message = messageValidator.message;
   var paramsClass = null;
   switch (message.getName()) {
      case kMediaRouter_RegisterMediaRouteProvider_Name:
        if (message.isResponse())
          paramsClass = MediaRouter_RegisterMediaRouteProvider_ResponseParams;
        break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  var MediaRouter = {
    name: 'media_router::mojom::MediaRouter',
    kVersion: 0,
    ptrClass: MediaRouterPtr,
    proxyClass: MediaRouterProxy,
    stubClass: MediaRouterStub,
    validateRequest: validateMediaRouterRequest,
    validateResponse: validateMediaRouterResponse,
  };
  MediaRouter.SinkAvailability = {};
  MediaRouter.SinkAvailability.UNAVAILABLE = 0;
  MediaRouter.SinkAvailability.PER_SOURCE = MediaRouter.SinkAvailability.UNAVAILABLE + 1;
  MediaRouter.SinkAvailability.AVAILABLE = MediaRouter.SinkAvailability.PER_SOURCE + 1;

  MediaRouter.SinkAvailability.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    }
    return false;
  };

  MediaRouter.SinkAvailability.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  MediaRouter.PresentationConnectionState = {};
  MediaRouter.PresentationConnectionState.CONNECTING = 0;
  MediaRouter.PresentationConnectionState.CONNECTED = MediaRouter.PresentationConnectionState.CONNECTING + 1;
  MediaRouter.PresentationConnectionState.CLOSED = MediaRouter.PresentationConnectionState.CONNECTED + 1;
  MediaRouter.PresentationConnectionState.TERMINATED = MediaRouter.PresentationConnectionState.CLOSED + 1;

  MediaRouter.PresentationConnectionState.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
      return true;
    }
    return false;
  };

  MediaRouter.PresentationConnectionState.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  MediaRouter.PresentationConnectionCloseReason = {};
  MediaRouter.PresentationConnectionCloseReason.CONNECTION_ERROR = 0;
  MediaRouter.PresentationConnectionCloseReason.CLOSED = MediaRouter.PresentationConnectionCloseReason.CONNECTION_ERROR + 1;
  MediaRouter.PresentationConnectionCloseReason.WENT_AWAY = MediaRouter.PresentationConnectionCloseReason.CLOSED + 1;

  MediaRouter.PresentationConnectionCloseReason.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    }
    return false;
  };

  MediaRouter.PresentationConnectionCloseReason.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  MediaRouterStub.prototype.validator = validateMediaRouterRequest;
  MediaRouterProxy.prototype.validator = validateMediaRouterResponse;
  exports.SinkIconType = SinkIconType;
  exports.RouteControllerType = RouteControllerType;
  exports.RouteRequestResultCode = RouteRequestResultCode;
  exports.MediaSink = MediaSink;
  exports.DialMediaSink = DialMediaSink;
  exports.CastMediaSink = CastMediaSink;
  exports.MediaRoute = MediaRoute;
  exports.Issue = Issue;
  exports.RouteMessage = RouteMessage;
  exports.SinkSearchCriteria = SinkSearchCriteria;
  exports.MediaRouteProviderConfig = MediaRouteProviderConfig;
  exports.MediaSinkExtraData = MediaSinkExtraData;
  exports.MediaRouteProvider = MediaRouteProvider;
  exports.MediaRouteProviderPtr = MediaRouteProviderPtr;
  exports.MediaRouteProviderAssociatedPtr = MediaRouteProviderAssociatedPtr;
  exports.MediaRouter = MediaRouter;
  exports.MediaRouterPtr = MediaRouterPtr;
  exports.MediaRouterAssociatedPtr = MediaRouterAssociatedPtr;
})();// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

if ((typeof mojo === 'undefined') || !mojo.bindingsLibraryInitialized) {
  loadScript('mojo_bindings');
}
mojo.config.autoLoadMojomDeps = false;

loadScript('chrome/common/media_router/mojo/media_controller.mojom');
loadScript('chrome/common/media_router/mojo/media_router.mojom');
loadScript('chrome/common/media_router/mojo/media_status.mojom');
loadScript('extensions/common/mojo/keep_alive.mojom');
loadScript('media/mojo/interfaces/mirror_service_remoting.mojom');
loadScript('media/mojo/interfaces/remoting_common.mojom');
loadScript('mojo/common/time.mojom');
loadScript('net/interfaces/ip_address.mojom');
loadScript('net/interfaces/ip_endpoint.mojom');
loadScript('url/mojo/origin.mojom');
loadScript('url/mojo/url.mojom');

// The following adapter classes preserve backward compatibility for the media
// router component extension.
// TODO(crbug.com/787128): Remove these adapters.

function assignFields(object, fields) {
  for(var field in fields) {
    if (object.hasOwnProperty(field))
      object[field] = fields[field];
  }
}

/**
 * Adapter for mediaRouter.mojom.DialMediaSink.
 * @constructor
 */
function DialMediaSinkAdapter(fields) {
  this.ip_address = null;
  this.model_name = null;
  this.app_url = null;

  assignFields(this, fields);
}

DialMediaSinkAdapter.fromNewVersion = function(other) {
  return new DialMediaSinkAdapter({
    'ip_address': IPAddressAdapter.fromNewVersion(other.ipAddress),
    'model_name': other.modelName,
    'app_url': other.appUrl,
  });
};

DialMediaSinkAdapter.prototype.toNewVersion = function() {
  return new mediaRouter.mojom.DialMediaSink({
    'ipAddress' : this.ip_address.toNewVersion(),
    'modelName' : this.model_name,
    'appUrl' : this.app_url,
  });
};

/**
 * Adapter for mediaRouter.mojom.CastMediaSink.
 * @constructor
 */
function CastMediaSinkAdapter(fields) {
  this.ip_endpoint = null;
  this.model_name = null;
  this.capabilities = 0;
  this.cast_channel_id = 0;

  assignFields(this, fields);
}

CastMediaSinkAdapter.fromNewVersion = function(other) {
  return new CastMediaSinkAdapter({
    'ip_endpoint': IPEndpointAdapter.fromNewVersion(other.ipEndpoint),
    'model_name': other.modelName,
    'capabilities': other.capabilities,
    'cast_channel_id': other.castChannelId,
  });
};

CastMediaSinkAdapter.prototype.toNewVersion = function() {
  return new mediaRouter.mojom.CastMediaSink({
    'ipEndpoint': this.ip_endpoint.toNewVersion(),
    'modelName': this.model_name,
    'capabilities': this.capabilities,
    'castChannelId': this.cast_channel_id,
  });
};

/**
 * Adapter for mediaRouter.mojom.HangoutsMediaStatusExtraData.
 * @constructor
 */
function HangoutsMediaStatusExtraDataAdapter(fields) {
  this.local_present = false;

  assignFields(this, fields);
}

HangoutsMediaStatusExtraDataAdapter.prototype.toNewVersion = function() {
  return new mediaRouter.mojom.HangoutsMediaStatusExtraData({
    'localPresent': this.local_present,
  });
};

/**
 * Adapter for net.interfaces.IPAddress.
 * @constructor
 */
function IPAddressAdapter(fields) {
  this.address_bytes = null;

  assignFields(this, fields);
}

IPAddressAdapter.fromNewVersion = function(other) {
  return new IPAddressAdapter({
    'address_bytes': other.addressBytes,
  });
};

IPAddressAdapter.prototype.toNewVersion = function() {
  return new net.interfaces.IPAddress({
    'addressBytes': this.address_bytes,
  });
};

/**
 * Adapter for net.interfaces.IPEndpoint.
 * @constructor
 */
function IPEndpointAdapter(fields) {
  this.address = null;
  this.port = 0;

  assignFields(this, fields);
}

IPEndpointAdapter.fromNewVersion = function(other) {
  return new IPEndpointAdapter({
    'address': IPAddressAdapter.fromNewVersion(other.address),
    'port': other.port,
  });
};

IPEndpointAdapter.prototype.toNewVersion = function() {
  return new net.interfaces.IPEndpoint({
    'address': this.address.toNewVersion(),
    'port': this.port,
  });
};

/**
 * Adapter for mediaRouter.mojom.MediaStatus.
 * @constructor
 */
function MediaStatusAdapter(fields) {
  this.title = null;
  this.description = null;
  this.can_play_pause = false;
  this.can_mute = false;
  this.can_set_volume = false;
  this.can_seek = false;
  this.is_muted = false;
  this.play_state = 0;
  this.volume = 0;
  this.duration = null;
  this.current_time = null;
  this.hangouts_extra_data = null;

  assignFields(this, fields);
}

MediaStatusAdapter.PlayState = mediaRouter.mojom.MediaStatus.PlayState;

MediaStatusAdapter.prototype.toNewVersion = function() {
  return new mediaRouter.mojom.MediaStatus({
    'title': this.title,
    'description': this.description,
    'canPlayPause': this.can_play_pause,
    'canMute': this.can_mute,
    'canSetVolume': this.can_set_volume,
    'canSeek': this.can_seek,
    'isMuted': this.is_muted,
    'playState': this.play_state,
    'volume': this.volume,
    'duration': this.duration,
    'currentTime': this.current_time,
    'hangoutsExtraData':
        this.hangouts_extra_data && this.hangouts_extra_data.toNewVersion(),
  });
};

/**
 * Adapter for media.mojom.RemotingSinkMetadata.
 * @constructor
 */
function RemotingSinkMetadataAdapter(fields) {
  this.features = null;
  this.audio_capabilities = null;
  this.video_capabilities = null;
  this.friendly_name = null;

  assignFields(this, fields);
}

RemotingSinkMetadataAdapter.fromNewVersion = function(other) {
  return new RemotingSinkMetadataAdapter({
    'features': other.features,
    'audio_capabilities': other.audioCapabilities,
    'video_capabilities': other.videoCapabilities,
    'friendly_name': other.friendlyName,
  });
};

RemotingSinkMetadataAdapter.prototype.toNewVersion = function() {
  return new media.mojom.RemotingSinkMetadata({
    'features': this.features,
    'audioCapabilities': this.audio_capabilities,
    'videoCapabilities': this.video_capabilities,
    'friendlyName': this.friendly_name,
  });
};

/**
 * Adapter for mediaRouter.mojom.MediaSink.
 * @constructor
 */
function MediaSinkAdapter(fields) {
  this.sink_id = null;
  this.name = null;
  this.description = null;
  this.domain = null;
  this.icon_type = 0;
  this.extra_data = null;

  assignFields(this, fields);
}

MediaSinkAdapter.fromNewVersion = function(other) {
  return new MediaSinkAdapter({
    'sink_id': other.sinkId,
    'name': other.name,
    'description': other.description,
    'domain': other.domain,
    'icon_type': other.iconType,
    'extra_data': other.extraData &&
        MediaSinkExtraDataAdapter.fromNewVersion(other.extraData),
  });
};

MediaSinkAdapter.prototype.toNewVersion = function() {
  return new mediaRouter.mojom.MediaSink({
    'sinkId': this.sink_id,
    'name': this.name,
    'description': this.description,
    'domain': this.domain,
    'iconType': this.icon_type,
    'extraData': this.extra_data && this.extra_data.toNewVersion(),
  });
};

/**
 * Adapter for mediaRouter.mojom.MediaSinkExtraData.
 * @constructor
 */
function MediaSinkExtraDataAdapter(value) {
  this.$data = null;
  this.$tag = undefined;

  if (value == undefined) {
    return;
  }

  var keys = Object.keys(value);
  if (keys.length == 0) {
    return;
  }

  if (keys.length > 1) {
    throw new TypeError('You may set only one member on a union.');
  }

  var fields = [
    'dial_media_sink',
    'cast_media_sink',
  ];

  if (fields.indexOf(keys[0]) < 0) {
    throw new ReferenceError(keys[0] +
        ' is not a MediaSinkExtraDataAdapter member.');
  }

  this[keys[0]] = value[keys[0]];
}

MediaSinkExtraDataAdapter.Tags = {
  dial_media_sink: 0,
  cast_media_sink: 1,
};

Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'dial_media_sink', {
  get: function() {
    if (this.$tag != MediaSinkExtraDataAdapter.Tags.dial_media_sink) {
      throw new ReferenceError(
          'MediaSinkExtraDataAdapter.dial_media_sink is not currently set.');
    }
    return this.$data;
  },

  set: function(value) {
    this.$tag = MediaSinkExtraDataAdapter.Tags.dial_media_sink;
    this.$data = value;
  }
});

Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'cast_media_sink', {
  get: function() {
    if (this.$tag != MediaSinkExtraDataAdapter.Tags.cast_media_sink) {
      throw new ReferenceError(
          'MediaSinkExtraDataAdapter.cast_media_sink is not currently set.');
    }
    return this.$data;
  },

  set: function(value) {
    this.$tag = MediaSinkExtraDataAdapter.Tags.cast_media_sink;
    this.$data = value;
  }
});

MediaSinkExtraDataAdapter.fromNewVersion = function(other) {
  if (other.$tag == mediaRouter.mojom.MediaSinkExtraData.Tags.dialMediaSink) {
    return new MediaSinkExtraDataAdapter({
      'dial_media_sink':
          DialMediaSinkAdapter.fromNewVersion(other.dialMediaSink),
    });
  } else {
    return new MediaSinkExtraDataAdapter({
      'cast_media_sink':
          CastMediaSinkAdapter.fromNewVersion(other.castMediaSink),
    });
  }
};

MediaSinkExtraDataAdapter.prototype.toNewVersion = function() {
  if (this.$tag == MediaSinkExtraDataAdapter.Tags.dial_media_sink) {
    return new mediaRouter.mojom.MediaSinkExtraData({
      'dialMediaSink': this.dial_media_sink.toNewVersion(),
    });
  } else {
    return new mediaRouter.mojom.MediaSinkExtraData({
      'castMediaSink': this.cast_media_sink.toNewVersion(),
    });
  }
};

/**
 * Adapter for media.mojom.MirrorServiceRemoterPtr.
 * @constructor
 */
function MirrorServiceRemoterPtrAdapter(handleOrPtrInfo) {
  this.ptr = new mojo.InterfacePtrController(MirrorServiceRemoterAdapter,
                                             handleOrPtrInfo);
}

MirrorServiceRemoterPtrAdapter.prototype =
    Object.create(media.mojom.MirrorServiceRemoterPtr.prototype);
MirrorServiceRemoterPtrAdapter.prototype.constructor =
    MirrorServiceRemoterPtrAdapter;

MirrorServiceRemoterPtrAdapter.prototype.startDataStreams = function() {
  return MirrorServiceRemoterProxy.prototype.startDataStreams
      .apply(this.ptr.getProxy(), arguments).then(function(response) {
    return Promise.resolve({
      'audio_stream_id': response.audioStreamId,
      'video_stream_id': response.videoStreamId,
    });
  });
};

/**
 * Adapter for media.mojom.MirrorServiceRemoter.stubclass.
 * @constructor
 */
function MirrorServiceRemoterStubAdapter(delegate) {
  this.delegate_ = delegate;
}

MirrorServiceRemoterStubAdapter.prototype = Object.create(
    media.mojom.MirrorServiceRemoter.stubClass.prototype);
MirrorServiceRemoterStubAdapter.prototype.constructor =
    MirrorServiceRemoterStubAdapter;

MirrorServiceRemoterStubAdapter.prototype.startDataStreams =
    function(hasAudio, hasVideo) {
  return this.delegate_ && this.delegate_.startDataStreams &&
      this.delegate_.startDataStreams(hasAudio, hasVideo).then(
          function(response) {
            return {
              'audioStreamId': response.audio_stream_id,
              'videoStreamId': response.video_stream_id,
            };
          });
};

/**
 * Adapter for media.mojom.MirrorServiceRemoter.
 */
var MirrorServiceRemoterAdapter = {
    name: 'media::mojom::MirrorServiceRemoter',
    kVersion: 0,
    ptrClass: MirrorServiceRemoterPtrAdapter,
    proxyClass: media.mojom.MirrorServiceRemoter.proxyClass,
    stubClass: MirrorServiceRemoterStubAdapter,
    validateRequest: media.mojom.MirrorServiceRemoter.validateRequest,
    validateResponse: media.mojom.MirrorServiceRemoter.validateResponse,
};

/**
 * Adapter for media.mojom.MirrorServiceRemotingSourcePtr.
 * @constructor
 */
function MirrorServiceRemotingSourcePtrAdapter(handleOrPtrInfo) {
  this.ptr = new mojo.InterfacePtrController(MirrorServiceRemotingSourceAdapter,
                                             handleOrPtrInfo);
}

MirrorServiceRemotingSourcePtrAdapter.prototype =
    Object.create(media.mojom.MirrorServiceRemotingSourcePtr.prototype);
MirrorServiceRemotingSourcePtrAdapter.prototype.constructor =
    MirrorServiceRemotingSourcePtrAdapter;

MirrorServiceRemotingSourcePtrAdapter.prototype.onSinkAvailable =
    function(metadata) {
  return this.ptr.getProxy().onSinkAvailable(metadata.toNewVersion());
};

/**
 * Adapter for media.mojom.MirrorServiceRemotingSource.
 */
var MirrorServiceRemotingSourceAdapter = {
    name: 'media::mojom::MirrorServiceRemotingSource',
    kVersion: 0,
    ptrClass: MirrorServiceRemotingSourcePtrAdapter,
    proxyClass: media.mojom.MirrorServiceRemotingSource.proxyClass,
    stubClass: null,
    validateRequest: media.mojom.MirrorServiceRemotingSource.validateRequest,
    validateResponse: null,
};

/**
 * Adapter for mediaRouter.mojom.MediaStatusObserver.
 * @constructor
 */
function MediaStatusObserverPtrAdapter(handleOrPtrInfo) {
  this.ptr = new mojo.InterfacePtrController(MediaStatusObserverAdapter,
                                             handleOrPtrInfo);
}

MediaStatusObserverPtrAdapter.prototype =
    Object.create(mediaRouter.mojom.MediaStatusObserverPtr.prototype);
MediaStatusObserverPtrAdapter.prototype.constructor =
    MediaStatusObserverPtrAdapter;

MediaStatusObserverPtrAdapter.prototype.onMediaStatusUpdated =
    function(status) {
  return this.ptr.getProxy().onMediaStatusUpdated(status.toNewVersion());
};

/**
 * Adapter for mediaRouter.mojom.MediaStatusObserver.
 */
var MediaStatusObserverAdapter = {
  name: 'mediaRouter::mojom::MediaStatusObserver',
  kVersion: 0,
  ptrClass: MediaStatusObserverPtrAdapter,
  proxyClass: mediaRouter.mojom.MediaStatusObserver.proxyClass,
  stubClass: null,
  validateRequest: mediaRouter.mojom.MediaStatusObserver.validateRequest,
  validateResponse: null,
};

/**
 * Converts a media sink to a MediaSink Mojo object.
 * @param {!MediaSink} sink A media sink.
 * @return {!mediaRouter.mojom.MediaSink} A Mojo MediaSink object.
 */
function sinkToMojo_(sink) {
  return new mediaRouter.mojom.MediaSink({
    'name': sink.friendlyName,
    'description': sink.description,
    'domain': sink.domain,
    'sinkId': sink.id,
    'iconType': sinkIconTypeToMojo(sink.iconType),
    'providerId': mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION,
  });
}

/**
 * Converts a media sink's icon type to a MediaSink.IconType Mojo object.
 * @param {!MediaSink.IconType} type A media sink's icon type.
 * @return {!mediaRouter.mojom.MediaSink.IconType} A Mojo MediaSink.IconType
 *     object.
 */
function sinkIconTypeToMojo(type) {
  switch (type) {
    case 'cast':
      return mediaRouter.mojom.SinkIconType.CAST;
    case 'cast_audio_group':
      return mediaRouter.mojom.SinkIconType.CAST_AUDIO_GROUP;
    case 'cast_audio':
      return mediaRouter.mojom.SinkIconType.CAST_AUDIO;
    case 'meeting':
      return mediaRouter.mojom.SinkIconType.MEETING;
    case 'hangout':
      return mediaRouter.mojom.SinkIconType.HANGOUT;
    case 'education':
      return mediaRouter.mojom.SinkIconType.EDUCATION;
    case 'generic':
      return mediaRouter.mojom.SinkIconType.GENERIC;
    default:
      console.error('Unknown sink icon type : ' + type);
      return mediaRouter.mojom.SinkIconType.GENERIC;
  }
}

/**
 * Returns a Mojo MediaRoute object given a MediaRoute and a
 * media sink name.
 * @param {!MediaRoute} route
 * @return {!mediaRouter.mojom.MediaRoute}
 */
function routeToMojo_(route) {
  return new mediaRouter.mojom.MediaRoute({
    'mediaRouteId': route.id,
    'mediaSource': route.mediaSource,
    'mediaSinkId': route.sinkId,
    'description': route.description,
    'iconUrl': route.iconUrl,
    'isLocal': route.isLocal,
    'forDisplay': route.forDisplay,
    'isIncognito': route.offTheRecord,
    'isLocalPresentation': route.isOffscreenPresentation,
    'controllerType': route.controllerType,
    // Begin newly added properties, followed by the milestone they were
    // added.  The guard should be safe to remove N+2 milestones later.
    'presentationId': route.presentationId || ''  // M64
  });
}

/**
 * Converts a route message to a RouteMessage Mojo object.
 * @param {!RouteMessage} message
 * @return {!mediaRouter.mojom.RouteMessage} A Mojo RouteMessage object.
 */
function messageToMojo_(message) {
  if ("string" == typeof message.message) {
    return new mediaRouter.mojom.RouteMessage({
      'type': mediaRouter.mojom.RouteMessage.Type.TEXT,
      'message': message.message,
    });
  } else {
    return new mediaRouter.mojom.RouteMessage({
      'type': mediaRouter.mojom.RouteMessage.Type.BINARY,
      'data': message.message,
    });
  }
}

/**
 * Converts presentation connection state to Mojo enum value.
 * @param {!string} state
 * @return {!mediaRouter.mojom.MediaRouter.PresentationConnectionState}
 */
function presentationConnectionStateToMojo_(state) {
  var PresentationConnectionState =
      mediaRouter.mojom.MediaRouter.PresentationConnectionState;
  switch (state) {
    case 'connecting':
      return PresentationConnectionState.CONNECTING;
    case 'connected':
      return PresentationConnectionState.CONNECTED;
    case 'closed':
      return PresentationConnectionState.CLOSED;
    case 'terminated':
      return PresentationConnectionState.TERMINATED;
    default:
      console.error('Unknown presentation connection state: ' + state);
      return PresentationConnectionState.TERMINATED;
  }
}

/**
 * Converts presentation connection close reason to Mojo enum value.
 * @param {!string} reason
 * @return {!mediaRouter.mojom.MediaRouter.PresentationConnectionCloseReason}
 */
function presentationConnectionCloseReasonToMojo_(reason) {
  var PresentationConnectionCloseReason =
      mediaRouter.mojom.MediaRouter.PresentationConnectionCloseReason;
  switch (reason) {
    case 'error':
      return PresentationConnectionCloseReason.CONNECTION_ERROR;
    case 'closed':
      return PresentationConnectionCloseReason.CLOSED;
    case 'went_away':
      return PresentationConnectionCloseReason.WENT_AWAY;
    default:
      console.error('Unknown presentation connection close reason : ' +
          reason);
      return PresentationConnectionCloseReason.CONNECTION_ERROR;
  }
}

/**
 * Converts string to Mojo origin.
 * @param {string|!url.mojom.Origin} origin
 * @return {!url.mojom.Origin}
 */
function stringToMojoOrigin_(origin) {
  if (origin instanceof url.mojom.Origin) {
    return origin;
  }
  var originUrl = new URL(origin);
  var mojoOrigin = {};
  mojoOrigin.scheme = originUrl.protocol.replace(':', '');
  mojoOrigin.host = originUrl.hostname;
  var port = originUrl.port ? Number.parseInt(originUrl.port) : 0;
  switch (mojoOrigin.scheme) {
    case 'http':
      mojoOrigin.port = port || 80;
      break;
    case 'https':
      mojoOrigin.port = port || 443;
      break;
    default:
      throw new Error('Scheme must be http or https');
  }
  mojoOrigin.suborigin = '';
  return new url.mojom.Origin(mojoOrigin);
}

/**
 * Parses the given route request Error object and converts it to the
 * corresponding result code.
 * @param {!Error} error
 * @return {!mediaRouter.mojom.RouteRequestResultCode}
 */
function getRouteRequestResultCode_(error) {
  return error.errorCode ? error.errorCode :
    mediaRouter.mojom.RouteRequestResultCode.UNKNOWN_ERROR;
}

/**
 * Creates and returns a successful route response from given route.
 * @param {!MediaRoute} route
 * @return {!Object}
 */
function toSuccessRouteResponse_(route) {
  return {
      route: routeToMojo_(route),
      resultCode: mediaRouter.mojom.RouteRequestResultCode.OK
  };
}

/**
 * Creates and returns a error route response from given Error object.
 * @param {!Error} error
 * @return {!Object}
 */
function toErrorRouteResponse_(error) {
  return {
      errorText: error.message,
      resultCode: getRouteRequestResultCode_(error)
  };
}

/**
 * Creates a new MediaRouter.
 * Converts a route struct to its Mojo form.
 * @param {!mediaRouter.mojom.MediaRouterPtr} service
 * @constructor
 */
function MediaRouter(service) {
  /**
   * The Mojo service proxy. Allows extension code to call methods that reside
   * in the browser.
   * @type {!mediaRouter.mojom.MediaRouterPtr}
   */
  this.service_ = service;

  /**
   * The provider manager service delegate. Its methods are called by the
   * browser-resident Mojo service.
   * @type {!MediaRouter}
   */
  this.mrpm_ = new MediaRouteProvider(this);

  /**
   * Handle to a KeepAlive service object, which prevents the extension from
   * being suspended as long as it remains in scope.
   * @type {boolean}
   */
  this.keepAlive_ = null;

  /**
   * The bindings to bind the service delegate to the Mojo interface.
   * Object must remain in scope for the lifetime of the connection to
   * prevent the connection from closing automatically.
   * @type {!mojo.Binding}
   */
  this.mediaRouteProviderBinding_ = new mojo.Binding(
      mediaRouter.mojom.MediaRouteProvider, this.mrpm_);
}

/**
 * Returns definitions of Mojo core and generated Mojom classes that can be
 * used directly by the component.
 * @return {!Object}
 * TODO(imcheng): We should export these along with MediaRouter. This requires
 * us to modify the component to handle multiple exports. When that logic is
 * baked in for a couple of milestones, we should be able to remove this
 * method.
 * TODO(imcheng): We should stop exporting mojo bindings classes that the
 * Media Router extension doesn't directly use, such as
 * mojo.AssociatedInterfacePtrInfo, mojo.InterfacePtrController and
 * mojo.interfaceControl.
 */
MediaRouter.prototype.getMojoExports = function() {
  return {
    AssociatedInterfacePtrInfo: mojo.AssociatedInterfacePtrInfo,
    Binding: mojo.Binding,
    DialMediaSink: DialMediaSinkAdapter,
    CastMediaSink: CastMediaSinkAdapter,
    HangoutsMediaRouteController:
        mediaRouter.mojom.HangoutsMediaRouteController,
    HangoutsMediaStatusExtraData: HangoutsMediaStatusExtraDataAdapter,
    IPAddress: IPAddressAdapter,
    IPEndpoint: IPEndpointAdapter,
    InterfacePtrController: mojo.InterfacePtrController,
    InterfacePtrInfo: mojo.InterfacePtrInfo,
    InterfaceRequest: mojo.InterfaceRequest,
    MediaController: mediaRouter.mojom.MediaController,
    MediaStatus: MediaStatusAdapter,
    MediaStatusObserverPtr: mediaRouter.mojom.MediaStatusObserverPtr,
    MirrorServiceRemoter: MirrorServiceRemoterAdapter,
    MirrorServiceRemoterPtr: MirrorServiceRemoterPtrAdapter,
    MirrorServiceRemotingSourcePtr: MirrorServiceRemotingSourcePtrAdapter,
    RemotingStopReason: media.mojom.RemotingStopReason,
    RemotingStartFailReason: media.mojom.RemotingStartFailReason,
    RemotingSinkFeature: media.mojom.RemotingSinkFeature,
    RemotingSinkAudioCapability:
        media.mojom.RemotingSinkAudioCapability,
    RemotingSinkVideoCapability:
        media.mojom.RemotingSinkVideoCapability,
    RemotingSinkMetadata: RemotingSinkMetadataAdapter,
    RouteControllerType: mediaRouter.mojom.RouteControllerType,
    Origin: url.mojom.Origin,
    Sink: MediaSinkAdapter,
    SinkExtraData: MediaSinkExtraDataAdapter,
    TimeDelta: mojo.common.mojom.TimeDelta,
    Url: url.mojom.Url,
    interfaceControl: mojo.interfaceControl,
    makeRequest: mojo.makeRequest,
  };
};

/**
 * Registers the Media Router Provider Manager with the Media Router.
 * @return {!Promise<Object>} Instance ID and config for the Media Router.
 */
MediaRouter.prototype.start = function() {
  return this.service_.registerMediaRouteProvider(
      mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION,
      this.mediaRouteProviderBinding_.createInterfacePtrAndBind()).then(
          function(response) {
            return {
              'instance_id': response.instanceId,
              'config': {
                'enable_dial_discovery': response.config.enableDialDiscovery,
                'enable_cast_discovery': response.config.enableCastDiscovery,
              }
            };
          });
}

/**
 * Sets the service delegate methods.
 * @param {Object} handlers
 */
MediaRouter.prototype.setHandlers = function(handlers) {
  this.mrpm_.setHandlers(handlers);
}

/**
 * The keep alive status.
 * @return {boolean}
 */
MediaRouter.prototype.getKeepAlive = function() {
  return this.keepAlive_ != null;
};

/**
 * Called by the provider manager when a sink list for a given source is
 * updated.
 * @param {!string} sourceUrn
 * @param {!Array<!MediaSink>} sinks
 * @param {!Array<string|!url.mojom.Origin>} origins
 */
MediaRouter.prototype.onSinksReceived = function(sourceUrn, sinks, origins) {
  // |origins| is a string array if the Media Router component extension version
  // is 59 or older. Without the stringToMojoOrigin_() conversion, clients using
  // those extension versions would see a crash shown in
  // https://crbug.com/787427.
  this.service_.onSinksReceived(
      mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, sourceUrn,
      sinks.map(sinkToMojo_), origins.map(stringToMojoOrigin_));
};

/**
 * Called by the provider manager when a sink is found to notify the MR of the
 * sink's ID. The actual sink will be returned through the normal sink list
 * update process, so this helps the MR identify the search result in the
 * list.
 * @param {string} pseudoSinkId  ID of the pseudo sink that started the
 *     search.
 * @param {string} sinkId ID of the newly-found sink.
 */
MediaRouter.prototype.onSearchSinkIdReceived = function(
    pseudoSinkId, sinkId) {
  this.service_.onSearchSinkIdReceived(pseudoSinkId, sinkId);
};

/**
 * Called by the provider manager to keep the extension from suspending
 * if it enters a state where suspension is undesirable (e.g. there is an
 * active MediaRoute.)
 * If keepAlive is true, the extension is kept alive.
 * If keepAlive is false, the extension is allowed to suspend.
 * @param {boolean} keepAlive
 */
MediaRouter.prototype.setKeepAlive = function(keepAlive) {
  if (keepAlive === false && this.keepAlive_) {
    this.keepAlive_.ptr.reset();
    this.keepAlive_ = null;
  } else if (keepAlive === true && !this.keepAlive_) {
    this.keepAlive_ = new extensions.KeepAlivePtr;
    Mojo.bindInterface(extensions.KeepAlive.name,
                       mojo.makeRequest(this.keepAlive_).handle);
  }
};

/**
 * Called by the provider manager to send an issue from a media route
 * provider to the Media Router, to show the user.
 * @param {!Object} issue The issue object.
 */
MediaRouter.prototype.onIssue = function(issue) {
  function issueSeverityToMojo_(severity) {
    switch (severity) {
      case 'fatal':
        return mediaRouter.mojom.Issue.Severity.FATAL;
      case 'warning':
        return mediaRouter.mojom.Issue.Severity.WARNING;
      case 'notification':
        return mediaRouter.mojom.Issue.Severity.NOTIFICATION;
      default:
        console.error('Unknown issue severity: ' + severity);
        return mediaRouter.mojom.Issue.Severity.NOTIFICATION;
    }
  }

  function issueActionToMojo_(action) {
    switch (action) {
      case 'dismiss':
        return mediaRouter.mojom.Issue.ActionType.DISMISS;
      case 'learn_more':
        return mediaRouter.mojom.Issue.ActionType.LEARN_MORE;
      default:
        console.error('Unknown issue action type : ' + action);
        return mediaRouter.mojom.Issue.ActionType.OK;
    }
  }

  var secondaryActions = (issue.secondaryActions || []).map(issueActionToMojo_);
  this.service_.onIssue(new mediaRouter.mojom.Issue({
    'routeId': issue.routeId || '',
    'severity': issueSeverityToMojo_(issue.severity),
    'title': issue.title,
    'message': issue.message || '',
    'defaultAction': issueActionToMojo_(issue.defaultAction),
    'secondaryActions': secondaryActions,
    'helpPageId': issue.helpPageId,
    'isBlocking': issue.isBlocking
  }));
};

/**
 * Called by the provider manager when the set of active routes
 * has been updated.
 * @param {!Array<MediaRoute>} routes The active set of media routes.
 * @param {string=} sourceUrn The sourceUrn associated with this route
 *     query.
 * @param {Array<string>=} joinableRouteIds The active set of joinable
 *     media routes.
 */
MediaRouter.prototype.onRoutesUpdated = function(
    routes, sourceUrn = '', joinableRouteIds = []) {
  this.service_.onRoutesUpdated(
      mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION,
      routes.map(routeToMojo_), sourceUrn, joinableRouteIds);
};

/**
 * Called by the provider manager when sink availability has been updated.
 * @param {!mediaRouter.mojom.MediaRouter.SinkAvailability} availability
 *     The new sink availability.
 */
MediaRouter.prototype.onSinkAvailabilityUpdated = function(availability) {
  this.service_.onSinkAvailabilityUpdated(
      mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, availability);
};

/**
 * Called by the provider manager when the state of a presentation connected
 * to a route has changed.
 * @param {string} routeId
 * @param {string} state
 */
MediaRouter.prototype.onPresentationConnectionStateChanged =
    function(routeId, state) {
  this.service_.onPresentationConnectionStateChanged(
      routeId, presentationConnectionStateToMojo_(state));
};

/**
 * Called by the provider manager when the state of a presentation connected
 * to a route has closed.
 * @param {string} routeId
 * @param {string} reason
 * @param {string} message
 */
MediaRouter.prototype.onPresentationConnectionClosed =
    function(routeId, reason, message) {
  this.service_.onPresentationConnectionClosed(
      routeId, presentationConnectionCloseReasonToMojo_(reason), message);
};

/**
 * @param {string} routeId
 * @param {!Array<!RouteMessage>} mesages
 */
MediaRouter.prototype.onRouteMessagesReceived = function(routeId, messages) {
  this.service_.onRouteMessagesReceived(
      routeId, messages.map(messageToMojo_));
};

/**
 * @param {number} tabId
 * @param {!media.mojom.MirrorServiceRemoterPtr} remoter
 * @param {!mojo.InterfaceRequest} remotingSource
 */
MediaRouter.prototype.onMediaRemoterCreated = function(tabId, remoter,
    remotingSource) {
  this.service_.onMediaRemoterCreated(
      tabId,
      new media.mojom.MirrorServiceRemoterPtr(remoter.ptr.passInterface()),
      remotingSource);
}

/**
 * Object containing callbacks set by the provider manager.
 *
 * @constructor
 * @struct
 */
function MediaRouterHandlers() {
  /**
   * @type {function(!string, !string, !string, !string, !number)}
   */
  this.createRoute = null;

  /**
   * @type {function(!string, !string, !string, !number)}
   */
  this.joinRoute = null;

  /**
   * @type {function(string): Promise}
   */
  this.terminateRoute = null;

  /**
   * @type {function(string)}
   */
  this.startObservingMediaSinks = null;

  /**
   * @type {function(string)}
   */
  this.stopObservingMediaSinks = null;

  /**
   * @type {function(string, string): Promise}
   */
  this.sendRouteMessage = null;

  /**
   * @type {function(string, Uint8Array): Promise}
   */
  this.sendRouteBinaryMessage = null;

  /**
   * @type {function(string)}
   */
  this.startListeningForRouteMessages = null;

  /**
   * @type {function(string)}
   */
  this.stopListeningForRouteMessages = null;

  /**
   * @type {function(string)}
   */
  this.detachRoute = null;

  /**
   * @type {function()}
   */
  this.startObservingMediaRoutes = null;

  /**
   * @type {function()}
   */
  this.stopObservingMediaRoutes = null;

  /**
   * @type {function()}
   */
  this.connectRouteByRouteId = null;

  /**
   * @type {function()}
   */
  this.enableMdnsDiscovery = null;

  /**
   * @type {function()}
   */
  this.updateMediaSinks = null;

  /**
   * @type {function(string, string, !SinkSearchCriteria): string}
   */
  this.searchSinks = null;

  /**
   * @type {function()}
   */
  this.provideSinks = null;

  /**
   * @type {function(string, !mojo.InterfaceRequest,
   *            !mediaRouter.mojom.MediaStatusObserverPtr): !Promise<void>}
   */
  this.createMediaRouteController = null;
};

/**
 * Routes calls from Media Router to the provider manager extension.
 * Registered with the MediaRouter stub.
 * @param {!MediaRouter} MediaRouter proxy to call into the
 * Media Router mojo interface.
 * @constructor
 */
function MediaRouteProvider(mediaRouter) {
  /**
   * Object containing JS callbacks into Provider Manager code.
   * @type {!MediaRouterHandlers}
   */
  this.handlers_ = new MediaRouterHandlers();

  /**
   * Proxy class to the browser's Media Router Mojo service.
   * @type {!MediaRouter}
   */
  this.mediaRouter_ = mediaRouter;
}

/*
 * Sets the callback handler used to invoke methods in the provider manager.
 *
 * @param {!MediaRouterHandlers} handlers
 */
MediaRouteProvider.prototype.setHandlers = function(handlers) {
  this.handlers_ = handlers;
  var requiredHandlers = [
    'stopObservingMediaRoutes',
    'startObservingMediaRoutes',
    'sendRouteMessage',
    'sendRouteBinaryMessage',
    'startListeningForRouteMessages',
    'stopListeningForRouteMessages',
    'detachRoute',
    'terminateRoute',
    'joinRoute',
    'createRoute',
    'stopObservingMediaSinks',
    'startObservingMediaRoutes',
    'connectRouteByRouteId',
    'enableMdnsDiscovery',
    'updateMediaSinks',
    'searchSinks',
    'provideSinks',
    'createMediaRouteController',
    'onBeforeInvokeHandler'
  ];
  requiredHandlers.forEach(function(nextHandler) {
    if (handlers[nextHandler] === undefined) {
      console.error(nextHandler + ' handler not registered.');
    }
  });
}

/**
 * Starts querying for sinks capable of displaying the media source
 * designated by |sourceUrn|.  Results are returned by calling
 * OnSinksReceived.
 * @param {!string} sourceUrn
 */
MediaRouteProvider.prototype.startObservingMediaSinks =
    function(sourceUrn) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.startObservingMediaSinks(sourceUrn);
};

/**
 * Stops querying for sinks capable of displaying |sourceUrn|.
 * @param {!string} sourceUrn
 */
MediaRouteProvider.prototype.stopObservingMediaSinks =
    function(sourceUrn) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.stopObservingMediaSinks(sourceUrn);
};

/**
 * Requests that |sinkId| render the media referenced by |sourceUrn|. If the
 * request is from the Presentation API, then origin and tabId will
 * be populated.
 * @param {!string} sourceUrn Media source to render.
 * @param {!string} sinkId Media sink ID.
 * @param {!string} presentationId Presentation ID from the site
 *     requesting presentation. TODO(mfoltz): Remove.
 * @param {!url.mojom.Origin} origin Origin of site requesting presentation.
 * @param {!number} tabId ID of tab requesting presentation.
 * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout
 *     duration for the request. Otherwise, the default duration will be used.
 * @param {!boolean} incognito If true, the route is being requested by
 *     an incognito profile.
 * @return {!Promise.<!Object>} A Promise resolving to an object describing
 *     the newly created media route, or rejecting with an error message on
 *     failure.
 */
MediaRouteProvider.prototype.createRoute =
    function(sourceUrn, sinkId, presentationId, origin, tabId,
             timeout, incognito) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.createRoute(
      sourceUrn, sinkId, presentationId, origin, tabId,
      Math.floor(timeout.microseconds / 1000), incognito)
      .then(function(route) {
        return toSuccessRouteResponse_(route);
      },
      function(err) {
        return toErrorRouteResponse_(err);
      });
};

/**
 * Handles a request via the Presentation API to join an existing route given
 * by |sourceUrn| and |presentationId|. |origin| and |tabId| are used for
 * validating same-origin/tab scope.
 * @param {!string} sourceUrn Media source to render.
 * @param {!string} presentationId Presentation ID to join.
 * @param {!url.mojom.Origin} origin Origin of site requesting join.
 * @param {!number} tabId ID of tab requesting join.
 * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout
 *     duration for the request. Otherwise, the default duration will be used.
 * @param {!boolean} incognito If true, the route is being requested by
 *     an incognito profile.
 * @return {!Promise.<!Object>} A Promise resolving to an object describing
 *     the newly created media route, or rejecting with an error message on
 *     failure.
 */
MediaRouteProvider.prototype.joinRoute =
    function(sourceUrn, presentationId, origin, tabId, timeout,
             incognito) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.joinRoute(
      sourceUrn, presentationId, origin, tabId,
      Math.floor(timeout.microseconds / 1000), incognito)
      .then(function(route) {
        return toSuccessRouteResponse_(route);
      },
      function(err) {
        return toErrorRouteResponse_(err);
      });
};

/**
 * Handles a request via the Presentation API to join an existing route given
 * by |sourceUrn| and |routeId|. |origin| and |tabId| are used for
 * validating same-origin/tab scope.
 * @param {!string} sourceUrn Media source to render.
 * @param {!string} routeId Route ID to join.
 * @param {!string} presentationId Presentation ID to join.
 * @param {!url.mojom.Origin} origin Origin of site requesting join.
 * @param {!number} tabId ID of tab requesting join.
 * @param {!mojo.common.mojom.TimeDelta} timeout If positive, the timeout
 *     duration for the request. Otherwise, the default duration will be used.
 * @param {!boolean} incognito If true, the route is being requested by
 *     an incognito profile.
 * @return {!Promise.<!Object>} A Promise resolving to an object describing
 *     the newly created media route, or rejecting with an error message on
 *     failure.
 */
MediaRouteProvider.prototype.connectRouteByRouteId =
    function(sourceUrn, routeId, presentationId, origin, tabId,
             timeout, incognito) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.connectRouteByRouteId(
      sourceUrn, routeId, presentationId, origin, tabId,
      Math.floor(timeout.microseconds / 1000), incognito)
      .then(function(route) {
        return toSuccessRouteResponse_(route);
      },
      function(err) {
        return toErrorRouteResponse_(err);
      });
};

/**
 * Terminates the route specified by |routeId|.
 * @param {!string} routeId
 * @return {!Promise<!Object>} A Promise resolving to an object describing
 *    the result of the terminate operation, or rejecting with an error
 *    message and code if the operation failed.
 */
MediaRouteProvider.prototype.terminateRoute = function(routeId) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.terminateRoute(routeId).then(
      () => ({resultCode: mediaRouter.mojom.RouteRequestResultCode.OK}),
      (err) => toErrorRouteResponse_(err));
};

/**
 * Posts a message to the route designated by |routeId|.
 * @param {!string} routeId
 * @param {!string} message
 * @return {!Promise.<boolean>} Resolved with true if the message was sent,
 *    or false on failure.
 */
MediaRouteProvider.prototype.sendRouteMessage = function(
  routeId, message) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.sendRouteMessage(routeId, message)
      .then(function() {
        return {'sent': true};
      }, function() {
        return {'sent': false};
      });
};

/**
 * Sends a binary message to the route designated by |routeId|.
 * @param {!string} routeId
 * @param {!Array<number>} data
 * @return {!Promise.<boolean>} Resolved with true if the data was sent,
 *    or false on failure.
 */
MediaRouteProvider.prototype.sendRouteBinaryMessage = function(
  routeId, data) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.sendRouteBinaryMessage(routeId, new Uint8Array(data))
      .then(function() {
        return {'sent': true};
      }, function() {
        return {'sent': false};
      });
};

/**
 * Listen for messages from a route.
 * @param {!string} routeId
 */
MediaRouteProvider.prototype.startListeningForRouteMessages = function(
    routeId) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.startListeningForRouteMessages(routeId);
};

/**
 * @param {!string} routeId
 */
MediaRouteProvider.prototype.stopListeningForRouteMessages = function(
    routeId) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.stopListeningForRouteMessages(routeId);
};

/**
 * Indicates that the presentation connection that was connected to |routeId|
 * is no longer connected to it.
 * @param {!string} routeId
 */
MediaRouteProvider.prototype.detachRoute = function(
    routeId) {
  this.handlers_.detachRoute(routeId);
};

/**
 * Requests that the provider manager start sending information about active
 * media routes to the Media Router.
 * @param {!string} sourceUrn
 */
MediaRouteProvider.prototype.startObservingMediaRoutes = function(sourceUrn) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.startObservingMediaRoutes(sourceUrn);
};

/**
 * Requests that the provider manager stop sending information about active
 * media routes to the Media Router.
 * @param {!string} sourceUrn
 */
MediaRouteProvider.prototype.stopObservingMediaRoutes = function(sourceUrn) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.stopObservingMediaRoutes(sourceUrn);
};

/**
 * Enables mDNS device discovery.
 */
MediaRouteProvider.prototype.enableMdnsDiscovery = function() {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.enableMdnsDiscovery();
};

/**
 * Requests that the provider manager update media sinks.
 * @param {!string} sourceUrn
 */
MediaRouteProvider.prototype.updateMediaSinks = function(sourceUrn) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.updateMediaSinks(sourceUrn);
};

/**
 * Requests that the provider manager search its providers for a sink matching
 * |searchCriteria| that is compatible with |sourceUrn|. If a sink is found
 * that can be used immediately for route creation, its ID is returned.
 * Otherwise the empty string is returned.
 *
 * @param {string} sinkId Sink ID of the pseudo sink generating the request.
 * @param {string} sourceUrn Media source to be used with the sink.
 * @param {!SinkSearchCriteria} searchCriteria Search criteria for the route
 *     providers.
 * @return {!Promise.<!{sink_id: !string}>} A Promise resolving to either the
 *     sink ID of the sink found by the search that can be used for route
 *     creation, or the empty string if no route can be immediately created.
 */
MediaRouteProvider.prototype.searchSinks = function(
    sinkId, sourceUrn, searchCriteria) {
  this.handlers_.onBeforeInvokeHandler();
 return this.handlers_.searchSinks(sinkId, sourceUrn, searchCriteria).then(
      sinkId => {
        return { 'sinkId': sinkId };
      },
      () => {
        return { 'sinkId': '' };
      });
};

/**
 * Notifies the provider manager that MediaRouter has discovered a list of
 * sinks.
 * @param {string} providerName
 * @param {!Array<!mediaRouter.mojom.MediaSink>} sinks
 */
MediaRouteProvider.prototype.provideSinks = function(providerName, sinks) {
  this.handlers_.onBeforeInvokeHandler();
  this.handlers_.provideSinks(providerName,
                              sinks.map(MediaSinkAdapter.fromNewVersion));
};

/**
 * Creates a controller for the given route and binds the given
 * InterfaceRequest to it, and registers an observer for media status updates
 * for the route.
 * @param {string} routeId
 * @param {!mojo.InterfaceRequest} controllerRequest
 * @param {!mediaRouter.mojom.MediaStatusObserverPtr} observer
 * @return {!Promise<!{success: boolean}>} Resolves to true if a controller
 *     is created. Resolves to false if a controller cannot be created, or if
 *     the controller is already bound.
 */
MediaRouteProvider.prototype.createMediaRouteController = function(
    routeId, controllerRequest, observer) {
  this.handlers_.onBeforeInvokeHandler();
  return this.handlers_.createMediaRouteController(
      routeId, controllerRequest,
      new MediaStatusObserverPtrAdapter(observer.ptr.passInterface())).then(
          () => ({success: true}), e => ({success: false}));
};

var ptr = new mediaRouter.mojom.MediaRouterPtr;
Mojo.bindInterface(mediaRouter.mojom.MediaRouter.name,
                   mojo.makeRequest(ptr).handle);
exports.$set('returnValue', new MediaRouter(ptr));
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'chrome/common/media_router/mojo/media_status.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('mediaRouter.mojom');
  var time$ =
      mojo.internal.exposeNamespace('mojo.common.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'mojo/common/time.mojom', '../../../../mojo/common/time.mojom.js');
  }



  function MediaStatus(values) {
    this.initDefaults_();
    this.initFields_(values);
  }

  MediaStatus.PlayState = {};
  MediaStatus.PlayState.PLAYING = 0;
  MediaStatus.PlayState.PAUSED = MediaStatus.PlayState.PLAYING + 1;
  MediaStatus.PlayState.BUFFERING = MediaStatus.PlayState.PAUSED + 1;

  MediaStatus.PlayState.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    }
    return false;
  };

  MediaStatus.PlayState.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };

  MediaStatus.prototype.initDefaults_ = function() {
    this.title = null;
    this.description = null;
    this.canPlayPause = false;
    this.canMute = false;
    this.canSetVolume = false;
    this.canSeek = false;
    this.isMuted = false;
    this.playState = 0;
    this.volume = 0;
    this.duration = null;
    this.currentTime = null;
    this.hangoutsExtraData = null;
  };
  MediaStatus.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaStatus.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 64}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaStatus.title
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaStatus.description
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;






    // validate MediaStatus.playState
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 20, MediaStatus.PlayState);
    if (err !== validator.validationError.NONE)
        return err;




    // validate MediaStatus.duration
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 32, time$.TimeDelta, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaStatus.currentTime
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 40, time$.TimeDelta, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaStatus.hangoutsExtraData
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 48, HangoutsMediaStatusExtraData, true);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaStatus.encodedSize = codec.kStructHeaderSize + 56;

  MediaStatus.decode = function(decoder) {
    var packed;
    var val = new MediaStatus();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.title = decoder.decodeStruct(codec.String);
    val.description = decoder.decodeStruct(codec.String);
    packed = decoder.readUint8();
    val.canPlayPause = (packed >> 0) & 1 ? true : false;
    val.canMute = (packed >> 1) & 1 ? true : false;
    val.canSetVolume = (packed >> 2) & 1 ? true : false;
    val.canSeek = (packed >> 3) & 1 ? true : false;
    val.isMuted = (packed >> 4) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.playState = decoder.decodeStruct(codec.Int32);
    val.volume = decoder.decodeStruct(codec.Float);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.duration = decoder.decodeStructPointer(time$.TimeDelta);
    val.currentTime = decoder.decodeStructPointer(time$.TimeDelta);
    val.hangoutsExtraData = decoder.decodeStructPointer(HangoutsMediaStatusExtraData);
    return val;
  };

  MediaStatus.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaStatus.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.title);
    encoder.encodeStruct(codec.String, val.description);
    packed = 0;
    packed |= (val.canPlayPause & 1) << 0
    packed |= (val.canMute & 1) << 1
    packed |= (val.canSetVolume & 1) << 2
    packed |= (val.canSeek & 1) << 3
    packed |= (val.isMuted & 1) << 4
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.Int32, val.playState);
    encoder.encodeStruct(codec.Float, val.volume);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStructPointer(time$.TimeDelta, val.duration);
    encoder.encodeStructPointer(time$.TimeDelta, val.currentTime);
    encoder.encodeStructPointer(HangoutsMediaStatusExtraData, val.hangoutsExtraData);
  };
  function HangoutsMediaStatusExtraData(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  HangoutsMediaStatusExtraData.prototype.initDefaults_ = function() {
    this.localPresent = false;
  };
  HangoutsMediaStatusExtraData.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  HangoutsMediaStatusExtraData.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  HangoutsMediaStatusExtraData.encodedSize = codec.kStructHeaderSize + 8;

  HangoutsMediaStatusExtraData.decode = function(decoder) {
    var packed;
    var val = new HangoutsMediaStatusExtraData();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    packed = decoder.readUint8();
    val.localPresent = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  HangoutsMediaStatusExtraData.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(HangoutsMediaStatusExtraData.encodedSize);
    encoder.writeUint32(0);
    packed = 0;
    packed |= (val.localPresent & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MediaStatusObserver_OnMediaStatusUpdated_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MediaStatusObserver_OnMediaStatusUpdated_Params.prototype.initDefaults_ = function() {
    this.status = null;
  };
  MediaStatusObserver_OnMediaStatusUpdated_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MediaStatusObserver_OnMediaStatusUpdated_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MediaStatusObserver_OnMediaStatusUpdated_Params.status
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, MediaStatus, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MediaStatusObserver_OnMediaStatusUpdated_Params.encodedSize = codec.kStructHeaderSize + 8;

  MediaStatusObserver_OnMediaStatusUpdated_Params.decode = function(decoder) {
    var packed;
    var val = new MediaStatusObserver_OnMediaStatusUpdated_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.status = decoder.decodeStructPointer(MediaStatus);
    return val;
  };

  MediaStatusObserver_OnMediaStatusUpdated_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MediaStatusObserver_OnMediaStatusUpdated_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(MediaStatus, val.status);
  };
  var kMediaStatusObserver_OnMediaStatusUpdated_Name = 1718512640;

  function MediaStatusObserverPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(MediaStatusObserver,
                                                   handleOrPtrInfo);
  }

  function MediaStatusObserverAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        MediaStatusObserver, associatedInterfacePtrInfo);
  }

  MediaStatusObserverAssociatedPtr.prototype =
      Object.create(MediaStatusObserverPtr.prototype);
  MediaStatusObserverAssociatedPtr.prototype.constructor =
      MediaStatusObserverAssociatedPtr;

  function MediaStatusObserverProxy(receiver) {
    this.receiver_ = receiver;
  }
  MediaStatusObserverPtr.prototype.onMediaStatusUpdated = function() {
    return MediaStatusObserverProxy.prototype.onMediaStatusUpdated
        .apply(this.ptr.getProxy(), arguments);
  };

  MediaStatusObserverProxy.prototype.onMediaStatusUpdated = function(status) {
    var params = new MediaStatusObserver_OnMediaStatusUpdated_Params();
    params.status = status;
    var builder = new codec.MessageV0Builder(
        kMediaStatusObserver_OnMediaStatusUpdated_Name,
        codec.align(MediaStatusObserver_OnMediaStatusUpdated_Params.encodedSize));
    builder.encodeStruct(MediaStatusObserver_OnMediaStatusUpdated_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function MediaStatusObserverStub(delegate) {
    this.delegate_ = delegate;
  }
  MediaStatusObserverStub.prototype.onMediaStatusUpdated = function(status) {
    return this.delegate_ && this.delegate_.onMediaStatusUpdated && this.delegate_.onMediaStatusUpdated(status);
  }

  MediaStatusObserverStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kMediaStatusObserver_OnMediaStatusUpdated_Name:
      var params = reader.decodeStruct(MediaStatusObserver_OnMediaStatusUpdated_Params);
      this.onMediaStatusUpdated(params.status);
      return true;
    default:
      return false;
    }
  };

  MediaStatusObserverStub.prototype.acceptWithResponder =
      function(message, responder) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    default:
      return false;
    }
  };

  function validateMediaStatusObserverRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kMediaStatusObserver_OnMediaStatusUpdated_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MediaStatusObserver_OnMediaStatusUpdated_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  function validateMediaStatusObserverResponse(messageValidator) {
    return validator.validationError.NONE;
  }

  var MediaStatusObserver = {
    name: 'media_router::mojom::MediaStatusObserver',
    kVersion: 0,
    ptrClass: MediaStatusObserverPtr,
    proxyClass: MediaStatusObserverProxy,
    stubClass: MediaStatusObserverStub,
    validateRequest: validateMediaStatusObserverRequest,
    validateResponse: null,
  };
  MediaStatusObserverStub.prototype.validator = validateMediaStatusObserverRequest;
  MediaStatusObserverProxy.prototype.validator = null;
  exports.MediaStatus = MediaStatus;
  exports.HangoutsMediaStatusExtraData = HangoutsMediaStatusExtraData;
  exports.MediaStatusObserver = MediaStatusObserver;
  exports.MediaStatusObserverPtr = MediaStatusObserverPtr;
  exports.MediaStatusObserverAssociatedPtr = MediaStatusObserverAssociatedPtr;
})();// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'mojo/common/time.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('mojo.common.mojom');



  function Time(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  Time.prototype.initDefaults_ = function() {
    this.internalValue = 0;
  };
  Time.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  Time.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  Time.encodedSize = codec.kStructHeaderSize + 8;

  Time.decode = function(decoder) {
    var packed;
    var val = new Time();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.internalValue = decoder.decodeStruct(codec.Int64);
    return val;
  };

  Time.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(Time.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int64, val.internalValue);
  };
  function TimeDelta(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  TimeDelta.prototype.initDefaults_ = function() {
    this.microseconds = 0;
  };
  TimeDelta.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  TimeDelta.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  TimeDelta.encodedSize = codec.kStructHeaderSize + 8;

  TimeDelta.decode = function(decoder) {
    var packed;
    var val = new TimeDelta();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.microseconds = decoder.decodeStruct(codec.Int64);
    return val;
  };

  TimeDelta.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(TimeDelta.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int64, val.microseconds);
  };
  function TimeTicks(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  TimeTicks.prototype.initDefaults_ = function() {
    this.internalValue = 0;
  };
  TimeTicks.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  TimeTicks.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  TimeTicks.encodedSize = codec.kStructHeaderSize + 8;

  TimeTicks.decode = function(decoder) {
    var packed;
    var val = new TimeTicks();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.internalValue = decoder.decodeStruct(codec.Int64);
    return val;
  };

  TimeTicks.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(TimeTicks.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int64, val.internalValue);
  };
  exports.Time = Time;
  exports.TimeDelta = TimeDelta;
  exports.TimeTicks = TimeTicks;
})();// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'net/interfaces/ip_address.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('net.interfaces');



  function IPAddress(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  IPAddress.prototype.initDefaults_ = function() {
    this.addressBytes = null;
  };
  IPAddress.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  IPAddress.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate IPAddress.addressBytes
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 1, codec.Uint8, false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  IPAddress.encodedSize = codec.kStructHeaderSize + 8;

  IPAddress.decode = function(decoder) {
    var packed;
    var val = new IPAddress();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.addressBytes = decoder.decodeArrayPointer(codec.Uint8);
    return val;
  };

  IPAddress.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(IPAddress.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(codec.Uint8, val.addressBytes);
  };
  exports.IPAddress = IPAddress;
})();// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'net/interfaces/ip_endpoint.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('net.interfaces');
  var ip_address$ =
      mojo.internal.exposeNamespace('net.interfaces');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'net/interfaces/ip_address.mojom', 'ip_address.mojom.js');
  }



  function IPEndPoint(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  IPEndPoint.prototype.initDefaults_ = function() {
    this.address = null;
    this.port = 0;
  };
  IPEndPoint.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  IPEndPoint.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate IPEndPoint.address
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, ip_address$.IPAddress, false);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  IPEndPoint.encodedSize = codec.kStructHeaderSize + 16;

  IPEndPoint.decode = function(decoder) {
    var packed;
    var val = new IPEndPoint();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.address = decoder.decodeStructPointer(ip_address$.IPAddress);
    val.port = decoder.decodeStruct(codec.Uint16);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  IPEndPoint.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(IPEndPoint.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(ip_address$.IPAddress, val.address);
    encoder.encodeStruct(codec.Uint16, val.port);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  exports.IPEndPoint = IPEndPoint;
})();// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'url/mojo/origin.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('url.mojom');



  function Origin(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  Origin.prototype.initDefaults_ = function() {
    this.scheme = null;
    this.host = null;
    this.port = 0;
    this.unique = false;
    this.suborigin = null;
  };
  Origin.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  Origin.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 40}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate Origin.scheme
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate Origin.host
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;



    // validate Origin.suborigin
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  Origin.encodedSize = codec.kStructHeaderSize + 32;

  Origin.decode = function(decoder) {
    var packed;
    var val = new Origin();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.scheme = decoder.decodeStruct(codec.String);
    val.host = decoder.decodeStruct(codec.String);
    val.port = decoder.decodeStruct(codec.Uint16);
    packed = decoder.readUint8();
    val.unique = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.suborigin = decoder.decodeStruct(codec.String);
    return val;
  };

  Origin.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(Origin.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.scheme);
    encoder.encodeStruct(codec.String, val.host);
    encoder.encodeStruct(codec.Uint16, val.port);
    packed = 0;
    packed |= (val.unique & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.String, val.suborigin);
  };
  exports.Origin = Origin;
})();// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'url/mojo/url.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('url.mojom');



  function Url(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  Url.prototype.initDefaults_ = function() {
    this.url = null;
  };
  Url.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  Url.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate Url.url
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  Url.encodedSize = codec.kStructHeaderSize + 8;

  Url.decode = function(decoder) {
    var packed;
    var val = new Url();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.url = decoder.decodeStruct(codec.String);
    return val;
  };

  Url.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(Url.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.url);
  };
  exports.Url = Url;
})();// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'media/mojo/interfaces/mirror_service_remoting.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('media.mojom');
  var remoting_common$ =
      mojo.internal.exposeNamespace('media.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'media/mojo/interfaces/remoting_common.mojom', 'remoting_common.mojom.js');
  }



  function MirrorServiceRemoter_Start_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemoter_Start_Params.prototype.initDefaults_ = function() {
  };
  MirrorServiceRemoter_Start_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemoter_Start_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MirrorServiceRemoter_Start_Params.encodedSize = codec.kStructHeaderSize + 0;

  MirrorServiceRemoter_Start_Params.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemoter_Start_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  MirrorServiceRemoter_Start_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemoter_Start_Params.encodedSize);
    encoder.writeUint32(0);
  };
  function MirrorServiceRemoter_StartDataStreams_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemoter_StartDataStreams_Params.prototype.initDefaults_ = function() {
    this.hasAudio = false;
    this.hasVideo = false;
  };
  MirrorServiceRemoter_StartDataStreams_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemoter_StartDataStreams_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;



    return validator.validationError.NONE;
  };

  MirrorServiceRemoter_StartDataStreams_Params.encodedSize = codec.kStructHeaderSize + 8;

  MirrorServiceRemoter_StartDataStreams_Params.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemoter_StartDataStreams_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    packed = decoder.readUint8();
    val.hasAudio = (packed >> 0) & 1 ? true : false;
    val.hasVideo = (packed >> 1) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MirrorServiceRemoter_StartDataStreams_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemoter_StartDataStreams_Params.encodedSize);
    encoder.writeUint32(0);
    packed = 0;
    packed |= (val.hasAudio & 1) << 0
    packed |= (val.hasVideo & 1) << 1
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MirrorServiceRemoter_StartDataStreams_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemoter_StartDataStreams_ResponseParams.prototype.initDefaults_ = function() {
    this.audioStreamId = 0;
    this.videoStreamId = 0;
  };
  MirrorServiceRemoter_StartDataStreams_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemoter_StartDataStreams_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;



    return validator.validationError.NONE;
  };

  MirrorServiceRemoter_StartDataStreams_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;

  MirrorServiceRemoter_StartDataStreams_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemoter_StartDataStreams_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.audioStreamId = decoder.decodeStruct(codec.Int32);
    val.videoStreamId = decoder.decodeStruct(codec.Int32);
    return val;
  };

  MirrorServiceRemoter_StartDataStreams_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemoter_StartDataStreams_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.audioStreamId);
    encoder.encodeStruct(codec.Int32, val.videoStreamId);
  };
  function MirrorServiceRemoter_Stop_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemoter_Stop_Params.prototype.initDefaults_ = function() {
    this.reason = 0;
  };
  MirrorServiceRemoter_Stop_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemoter_Stop_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MirrorServiceRemoter_Stop_Params.reason
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, remoting_common$.RemotingStopReason);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MirrorServiceRemoter_Stop_Params.encodedSize = codec.kStructHeaderSize + 8;

  MirrorServiceRemoter_Stop_Params.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemoter_Stop_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.reason = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MirrorServiceRemoter_Stop_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemoter_Stop_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.reason);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MirrorServiceRemoter_SendMessageToSink_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemoter_SendMessageToSink_Params.prototype.initDefaults_ = function() {
    this.message = null;
  };
  MirrorServiceRemoter_SendMessageToSink_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemoter_SendMessageToSink_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MirrorServiceRemoter_SendMessageToSink_Params.message
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 1, codec.Uint8, false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MirrorServiceRemoter_SendMessageToSink_Params.encodedSize = codec.kStructHeaderSize + 8;

  MirrorServiceRemoter_SendMessageToSink_Params.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemoter_SendMessageToSink_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.message = decoder.decodeArrayPointer(codec.Uint8);
    return val;
  };

  MirrorServiceRemoter_SendMessageToSink_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemoter_SendMessageToSink_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(codec.Uint8, val.message);
  };
  function MirrorServiceRemoter_EstimateTransmissionCapacity_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemoter_EstimateTransmissionCapacity_Params.prototype.initDefaults_ = function() {
  };
  MirrorServiceRemoter_EstimateTransmissionCapacity_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemoter_EstimateTransmissionCapacity_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MirrorServiceRemoter_EstimateTransmissionCapacity_Params.encodedSize = codec.kStructHeaderSize + 0;

  MirrorServiceRemoter_EstimateTransmissionCapacity_Params.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemoter_EstimateTransmissionCapacity_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  MirrorServiceRemoter_EstimateTransmissionCapacity_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemoter_EstimateTransmissionCapacity_Params.encodedSize);
    encoder.writeUint32(0);
  };
  function MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.prototype.initDefaults_ = function() {
    this.rate = 0;
  };
  MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;

  MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.rate = decoder.decodeStruct(codec.Double);
    return val;
  };

  MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Double, val.rate);
  };
  function MirrorServiceRemotingSource_OnSinkAvailable_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemotingSource_OnSinkAvailable_Params.prototype.initDefaults_ = function() {
    this.metadata = null;
  };
  MirrorServiceRemotingSource_OnSinkAvailable_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemotingSource_OnSinkAvailable_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MirrorServiceRemotingSource_OnSinkAvailable_Params.metadata
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, remoting_common$.RemotingSinkMetadata, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MirrorServiceRemotingSource_OnSinkAvailable_Params.encodedSize = codec.kStructHeaderSize + 8;

  MirrorServiceRemotingSource_OnSinkAvailable_Params.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemotingSource_OnSinkAvailable_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.metadata = decoder.decodeStructPointer(remoting_common$.RemotingSinkMetadata);
    return val;
  };

  MirrorServiceRemotingSource_OnSinkAvailable_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemotingSource_OnSinkAvailable_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(remoting_common$.RemotingSinkMetadata, val.metadata);
  };
  function MirrorServiceRemotingSource_OnMessageFromSink_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemotingSource_OnMessageFromSink_Params.prototype.initDefaults_ = function() {
    this.message = null;
  };
  MirrorServiceRemotingSource_OnMessageFromSink_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemotingSource_OnMessageFromSink_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MirrorServiceRemotingSource_OnMessageFromSink_Params.message
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 1, codec.Uint8, false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MirrorServiceRemotingSource_OnMessageFromSink_Params.encodedSize = codec.kStructHeaderSize + 8;

  MirrorServiceRemotingSource_OnMessageFromSink_Params.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemotingSource_OnMessageFromSink_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.message = decoder.decodeArrayPointer(codec.Uint8);
    return val;
  };

  MirrorServiceRemotingSource_OnMessageFromSink_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemotingSource_OnMessageFromSink_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(codec.Uint8, val.message);
  };
  function MirrorServiceRemotingSource_OnStopped_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemotingSource_OnStopped_Params.prototype.initDefaults_ = function() {
    this.reason = 0;
  };
  MirrorServiceRemotingSource_OnStopped_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemotingSource_OnStopped_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MirrorServiceRemotingSource_OnStopped_Params.reason
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, remoting_common$.RemotingStopReason);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MirrorServiceRemotingSource_OnStopped_Params.encodedSize = codec.kStructHeaderSize + 8;

  MirrorServiceRemotingSource_OnStopped_Params.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemotingSource_OnStopped_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.reason = decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  MirrorServiceRemotingSource_OnStopped_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemotingSource_OnStopped_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.reason);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function MirrorServiceRemotingSource_OnError_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MirrorServiceRemotingSource_OnError_Params.prototype.initDefaults_ = function() {
  };
  MirrorServiceRemotingSource_OnError_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MirrorServiceRemotingSource_OnError_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MirrorServiceRemotingSource_OnError_Params.encodedSize = codec.kStructHeaderSize + 0;

  MirrorServiceRemotingSource_OnError_Params.decode = function(decoder) {
    var packed;
    var val = new MirrorServiceRemotingSource_OnError_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  MirrorServiceRemotingSource_OnError_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MirrorServiceRemotingSource_OnError_Params.encodedSize);
    encoder.writeUint32(0);
  };
  var kMirrorServiceRemoter_Start_Name = 81813800;
  var kMirrorServiceRemoter_StartDataStreams_Name = 1868370921;
  var kMirrorServiceRemoter_Stop_Name = 1544600824;
  var kMirrorServiceRemoter_SendMessageToSink_Name = 161806593;
  var kMirrorServiceRemoter_EstimateTransmissionCapacity_Name = 189629937;

  function MirrorServiceRemoterPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(MirrorServiceRemoter,
                                                   handleOrPtrInfo);
  }

  function MirrorServiceRemoterAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        MirrorServiceRemoter, associatedInterfacePtrInfo);
  }

  MirrorServiceRemoterAssociatedPtr.prototype =
      Object.create(MirrorServiceRemoterPtr.prototype);
  MirrorServiceRemoterAssociatedPtr.prototype.constructor =
      MirrorServiceRemoterAssociatedPtr;

  function MirrorServiceRemoterProxy(receiver) {
    this.receiver_ = receiver;
  }
  MirrorServiceRemoterPtr.prototype.start = function() {
    return MirrorServiceRemoterProxy.prototype.start
        .apply(this.ptr.getProxy(), arguments);
  };

  MirrorServiceRemoterProxy.prototype.start = function() {
    var params = new MirrorServiceRemoter_Start_Params();
    var builder = new codec.MessageV0Builder(
        kMirrorServiceRemoter_Start_Name,
        codec.align(MirrorServiceRemoter_Start_Params.encodedSize));
    builder.encodeStruct(MirrorServiceRemoter_Start_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MirrorServiceRemoterPtr.prototype.startDataStreams = function() {
    return MirrorServiceRemoterProxy.prototype.startDataStreams
        .apply(this.ptr.getProxy(), arguments);
  };

  MirrorServiceRemoterProxy.prototype.startDataStreams = function(hasAudio, hasVideo) {
    var params = new MirrorServiceRemoter_StartDataStreams_Params();
    params.hasAudio = hasAudio;
    params.hasVideo = hasVideo;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMirrorServiceRemoter_StartDataStreams_Name,
          codec.align(MirrorServiceRemoter_StartDataStreams_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MirrorServiceRemoter_StartDataStreams_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MirrorServiceRemoter_StartDataStreams_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };
  MirrorServiceRemoterPtr.prototype.stop = function() {
    return MirrorServiceRemoterProxy.prototype.stop
        .apply(this.ptr.getProxy(), arguments);
  };

  MirrorServiceRemoterProxy.prototype.stop = function(reason) {
    var params = new MirrorServiceRemoter_Stop_Params();
    params.reason = reason;
    var builder = new codec.MessageV0Builder(
        kMirrorServiceRemoter_Stop_Name,
        codec.align(MirrorServiceRemoter_Stop_Params.encodedSize));
    builder.encodeStruct(MirrorServiceRemoter_Stop_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MirrorServiceRemoterPtr.prototype.sendMessageToSink = function() {
    return MirrorServiceRemoterProxy.prototype.sendMessageToSink
        .apply(this.ptr.getProxy(), arguments);
  };

  MirrorServiceRemoterProxy.prototype.sendMessageToSink = function(message) {
    var params = new MirrorServiceRemoter_SendMessageToSink_Params();
    params.message = message;
    var builder = new codec.MessageV0Builder(
        kMirrorServiceRemoter_SendMessageToSink_Name,
        codec.align(MirrorServiceRemoter_SendMessageToSink_Params.encodedSize));
    builder.encodeStruct(MirrorServiceRemoter_SendMessageToSink_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MirrorServiceRemoterPtr.prototype.estimateTransmissionCapacity = function() {
    return MirrorServiceRemoterProxy.prototype.estimateTransmissionCapacity
        .apply(this.ptr.getProxy(), arguments);
  };

  MirrorServiceRemoterProxy.prototype.estimateTransmissionCapacity = function() {
    var params = new MirrorServiceRemoter_EstimateTransmissionCapacity_Params();
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kMirrorServiceRemoter_EstimateTransmissionCapacity_Name,
          codec.align(MirrorServiceRemoter_EstimateTransmissionCapacity_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(MirrorServiceRemoter_EstimateTransmissionCapacity_Params, params);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };

  function MirrorServiceRemoterStub(delegate) {
    this.delegate_ = delegate;
  }
  MirrorServiceRemoterStub.prototype.start = function() {
    return this.delegate_ && this.delegate_.start && this.delegate_.start();
  }
  MirrorServiceRemoterStub.prototype.startDataStreams = function(hasAudio, hasVideo) {
    return this.delegate_ && this.delegate_.startDataStreams && this.delegate_.startDataStreams(hasAudio, hasVideo);
  }
  MirrorServiceRemoterStub.prototype.stop = function(reason) {
    return this.delegate_ && this.delegate_.stop && this.delegate_.stop(reason);
  }
  MirrorServiceRemoterStub.prototype.sendMessageToSink = function(message) {
    return this.delegate_ && this.delegate_.sendMessageToSink && this.delegate_.sendMessageToSink(message);
  }
  MirrorServiceRemoterStub.prototype.estimateTransmissionCapacity = function() {
    return this.delegate_ && this.delegate_.estimateTransmissionCapacity && this.delegate_.estimateTransmissionCapacity();
  }

  MirrorServiceRemoterStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kMirrorServiceRemoter_Start_Name:
      var params = reader.decodeStruct(MirrorServiceRemoter_Start_Params);
      this.start();
      return true;
    case kMirrorServiceRemoter_Stop_Name:
      var params = reader.decodeStruct(MirrorServiceRemoter_Stop_Params);
      this.stop(params.reason);
      return true;
    case kMirrorServiceRemoter_SendMessageToSink_Name:
      var params = reader.decodeStruct(MirrorServiceRemoter_SendMessageToSink_Params);
      this.sendMessageToSink(params.message);
      return true;
    default:
      return false;
    }
  };

  MirrorServiceRemoterStub.prototype.acceptWithResponder =
      function(message, responder) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kMirrorServiceRemoter_StartDataStreams_Name:
      var params = reader.decodeStruct(MirrorServiceRemoter_StartDataStreams_Params);
      this.startDataStreams(params.hasAudio, params.hasVideo).then(function(response) {
        var responseParams =
            new MirrorServiceRemoter_StartDataStreams_ResponseParams();
        responseParams.audioStreamId = response.audioStreamId;
        responseParams.videoStreamId = response.videoStreamId;
        var builder = new codec.MessageV1Builder(
            kMirrorServiceRemoter_StartDataStreams_Name,
            codec.align(MirrorServiceRemoter_StartDataStreams_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MirrorServiceRemoter_StartDataStreams_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    case kMirrorServiceRemoter_EstimateTransmissionCapacity_Name:
      var params = reader.decodeStruct(MirrorServiceRemoter_EstimateTransmissionCapacity_Params);
      this.estimateTransmissionCapacity().then(function(response) {
        var responseParams =
            new MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams();
        responseParams.rate = response.rate;
        var builder = new codec.MessageV1Builder(
            kMirrorServiceRemoter_EstimateTransmissionCapacity_Name,
            codec.align(MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    default:
      return false;
    }
  };

  function validateMirrorServiceRemoterRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kMirrorServiceRemoter_Start_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MirrorServiceRemoter_Start_Params;
      break;
      case kMirrorServiceRemoter_StartDataStreams_Name:
        if (message.expectsResponse())
          paramsClass = MirrorServiceRemoter_StartDataStreams_Params;
      break;
      case kMirrorServiceRemoter_Stop_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MirrorServiceRemoter_Stop_Params;
      break;
      case kMirrorServiceRemoter_SendMessageToSink_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MirrorServiceRemoter_SendMessageToSink_Params;
      break;
      case kMirrorServiceRemoter_EstimateTransmissionCapacity_Name:
        if (message.expectsResponse())
          paramsClass = MirrorServiceRemoter_EstimateTransmissionCapacity_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  function validateMirrorServiceRemoterResponse(messageValidator) {
   var message = messageValidator.message;
   var paramsClass = null;
   switch (message.getName()) {
      case kMirrorServiceRemoter_StartDataStreams_Name:
        if (message.isResponse())
          paramsClass = MirrorServiceRemoter_StartDataStreams_ResponseParams;
        break;
      case kMirrorServiceRemoter_EstimateTransmissionCapacity_Name:
        if (message.isResponse())
          paramsClass = MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams;
        break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  var MirrorServiceRemoter = {
    name: 'media::mojom::MirrorServiceRemoter',
    kVersion: 0,
    ptrClass: MirrorServiceRemoterPtr,
    proxyClass: MirrorServiceRemoterProxy,
    stubClass: MirrorServiceRemoterStub,
    validateRequest: validateMirrorServiceRemoterRequest,
    validateResponse: validateMirrorServiceRemoterResponse,
  };
  MirrorServiceRemoterStub.prototype.validator = validateMirrorServiceRemoterRequest;
  MirrorServiceRemoterProxy.prototype.validator = validateMirrorServiceRemoterResponse;
  var kMirrorServiceRemotingSource_OnSinkAvailable_Name = 354805125;
  var kMirrorServiceRemotingSource_OnMessageFromSink_Name = 1263719888;
  var kMirrorServiceRemotingSource_OnStopped_Name = 1994824442;
  var kMirrorServiceRemotingSource_OnError_Name = 1852939234;

  function MirrorServiceRemotingSourcePtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(MirrorServiceRemotingSource,
                                                   handleOrPtrInfo);
  }

  function MirrorServiceRemotingSourceAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        MirrorServiceRemotingSource, associatedInterfacePtrInfo);
  }

  MirrorServiceRemotingSourceAssociatedPtr.prototype =
      Object.create(MirrorServiceRemotingSourcePtr.prototype);
  MirrorServiceRemotingSourceAssociatedPtr.prototype.constructor =
      MirrorServiceRemotingSourceAssociatedPtr;

  function MirrorServiceRemotingSourceProxy(receiver) {
    this.receiver_ = receiver;
  }
  MirrorServiceRemotingSourcePtr.prototype.onSinkAvailable = function() {
    return MirrorServiceRemotingSourceProxy.prototype.onSinkAvailable
        .apply(this.ptr.getProxy(), arguments);
  };

  MirrorServiceRemotingSourceProxy.prototype.onSinkAvailable = function(metadata) {
    var params = new MirrorServiceRemotingSource_OnSinkAvailable_Params();
    params.metadata = metadata;
    var builder = new codec.MessageV0Builder(
        kMirrorServiceRemotingSource_OnSinkAvailable_Name,
        codec.align(MirrorServiceRemotingSource_OnSinkAvailable_Params.encodedSize));
    builder.encodeStruct(MirrorServiceRemotingSource_OnSinkAvailable_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MirrorServiceRemotingSourcePtr.prototype.onMessageFromSink = function() {
    return MirrorServiceRemotingSourceProxy.prototype.onMessageFromSink
        .apply(this.ptr.getProxy(), arguments);
  };

  MirrorServiceRemotingSourceProxy.prototype.onMessageFromSink = function(message) {
    var params = new MirrorServiceRemotingSource_OnMessageFromSink_Params();
    params.message = message;
    var builder = new codec.MessageV0Builder(
        kMirrorServiceRemotingSource_OnMessageFromSink_Name,
        codec.align(MirrorServiceRemotingSource_OnMessageFromSink_Params.encodedSize));
    builder.encodeStruct(MirrorServiceRemotingSource_OnMessageFromSink_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MirrorServiceRemotingSourcePtr.prototype.onStopped = function() {
    return MirrorServiceRemotingSourceProxy.prototype.onStopped
        .apply(this.ptr.getProxy(), arguments);
  };

  MirrorServiceRemotingSourceProxy.prototype.onStopped = function(reason) {
    var params = new MirrorServiceRemotingSource_OnStopped_Params();
    params.reason = reason;
    var builder = new codec.MessageV0Builder(
        kMirrorServiceRemotingSource_OnStopped_Name,
        codec.align(MirrorServiceRemotingSource_OnStopped_Params.encodedSize));
    builder.encodeStruct(MirrorServiceRemotingSource_OnStopped_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MirrorServiceRemotingSourcePtr.prototype.onError = function() {
    return MirrorServiceRemotingSourceProxy.prototype.onError
        .apply(this.ptr.getProxy(), arguments);
  };

  MirrorServiceRemotingSourceProxy.prototype.onError = function() {
    var params = new MirrorServiceRemotingSource_OnError_Params();
    var builder = new codec.MessageV0Builder(
        kMirrorServiceRemotingSource_OnError_Name,
        codec.align(MirrorServiceRemotingSource_OnError_Params.encodedSize));
    builder.encodeStruct(MirrorServiceRemotingSource_OnError_Params, params);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function MirrorServiceRemotingSourceStub(delegate) {
    this.delegate_ = delegate;
  }
  MirrorServiceRemotingSourceStub.prototype.onSinkAvailable = function(metadata) {
    return this.delegate_ && this.delegate_.onSinkAvailable && this.delegate_.onSinkAvailable(metadata);
  }
  MirrorServiceRemotingSourceStub.prototype.onMessageFromSink = function(message) {
    return this.delegate_ && this.delegate_.onMessageFromSink && this.delegate_.onMessageFromSink(message);
  }
  MirrorServiceRemotingSourceStub.prototype.onStopped = function(reason) {
    return this.delegate_ && this.delegate_.onStopped && this.delegate_.onStopped(reason);
  }
  MirrorServiceRemotingSourceStub.prototype.onError = function() {
    return this.delegate_ && this.delegate_.onError && this.delegate_.onError();
  }

  MirrorServiceRemotingSourceStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kMirrorServiceRemotingSource_OnSinkAvailable_Name:
      var params = reader.decodeStruct(MirrorServiceRemotingSource_OnSinkAvailable_Params);
      this.onSinkAvailable(params.metadata);
      return true;
    case kMirrorServiceRemotingSource_OnMessageFromSink_Name:
      var params = reader.decodeStruct(MirrorServiceRemotingSource_OnMessageFromSink_Params);
      this.onMessageFromSink(params.message);
      return true;
    case kMirrorServiceRemotingSource_OnStopped_Name:
      var params = reader.decodeStruct(MirrorServiceRemotingSource_OnStopped_Params);
      this.onStopped(params.reason);
      return true;
    case kMirrorServiceRemotingSource_OnError_Name:
      var params = reader.decodeStruct(MirrorServiceRemotingSource_OnError_Params);
      this.onError();
      return true;
    default:
      return false;
    }
  };

  MirrorServiceRemotingSourceStub.prototype.acceptWithResponder =
      function(message, responder) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    default:
      return false;
    }
  };

  function validateMirrorServiceRemotingSourceRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kMirrorServiceRemotingSource_OnSinkAvailable_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MirrorServiceRemotingSource_OnSinkAvailable_Params;
      break;
      case kMirrorServiceRemotingSource_OnMessageFromSink_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MirrorServiceRemotingSource_OnMessageFromSink_Params;
      break;
      case kMirrorServiceRemotingSource_OnStopped_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MirrorServiceRemotingSource_OnStopped_Params;
      break;
      case kMirrorServiceRemotingSource_OnError_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MirrorServiceRemotingSource_OnError_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  function validateMirrorServiceRemotingSourceResponse(messageValidator) {
    return validator.validationError.NONE;
  }

  var MirrorServiceRemotingSource = {
    name: 'media::mojom::MirrorServiceRemotingSource',
    kVersion: 0,
    ptrClass: MirrorServiceRemotingSourcePtr,
    proxyClass: MirrorServiceRemotingSourceProxy,
    stubClass: MirrorServiceRemotingSourceStub,
    validateRequest: validateMirrorServiceRemotingSourceRequest,
    validateResponse: null,
  };
  MirrorServiceRemotingSourceStub.prototype.validator = validateMirrorServiceRemotingSourceRequest;
  MirrorServiceRemotingSourceProxy.prototype.validator = null;
  exports.MirrorServiceRemoter = MirrorServiceRemoter;
  exports.MirrorServiceRemoterPtr = MirrorServiceRemoterPtr;
  exports.MirrorServiceRemoterAssociatedPtr = MirrorServiceRemoterAssociatedPtr;
  exports.MirrorServiceRemotingSource = MirrorServiceRemotingSource;
  exports.MirrorServiceRemotingSourcePtr = MirrorServiceRemotingSourcePtr;
  exports.MirrorServiceRemotingSourceAssociatedPtr = MirrorServiceRemotingSourceAssociatedPtr;
})();// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

(function() {
  var mojomId = 'media/mojo/interfaces/remoting_common.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('media.mojom');


  var RemotingStopReason = {};
  RemotingStopReason.ROUTE_TERMINATED = 0;
  RemotingStopReason.LOCAL_PLAYBACK = RemotingStopReason.ROUTE_TERMINATED + 1;
  RemotingStopReason.SOURCE_GONE = RemotingStopReason.LOCAL_PLAYBACK + 1;
  RemotingStopReason.MESSAGE_SEND_FAILED = RemotingStopReason.SOURCE_GONE + 1;
  RemotingStopReason.DATA_SEND_FAILED = RemotingStopReason.MESSAGE_SEND_FAILED + 1;
  RemotingStopReason.UNEXPECTED_FAILURE = RemotingStopReason.DATA_SEND_FAILED + 1;
  RemotingStopReason.SERVICE_GONE = RemotingStopReason.UNEXPECTED_FAILURE + 1;
  RemotingStopReason.USER_DISABLED = RemotingStopReason.SERVICE_GONE + 1;

  RemotingStopReason.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
      return true;
    }
    return false;
  };

  RemotingStopReason.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  var RemotingStartFailReason = {};
  RemotingStartFailReason.CANNOT_START_MULTIPLE = 0;
  RemotingStartFailReason.ROUTE_TERMINATED = RemotingStartFailReason.CANNOT_START_MULTIPLE + 1;
  RemotingStartFailReason.SERVICE_NOT_CONNECTED = RemotingStartFailReason.ROUTE_TERMINATED + 1;

  RemotingStartFailReason.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    }
    return false;
  };

  RemotingStartFailReason.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  var RemotingSinkFeature = {};
  RemotingSinkFeature.RENDERING = 0;
  RemotingSinkFeature.CONTENT_DECRYPTION = RemotingSinkFeature.RENDERING + 1;

  RemotingSinkFeature.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
      return true;
    }
    return false;
  };

  RemotingSinkFeature.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  var RemotingSinkAudioCapability = {};
  RemotingSinkAudioCapability.CODEC_BASELINE_SET = 0;
  RemotingSinkAudioCapability.CODEC_AAC = RemotingSinkAudioCapability.CODEC_BASELINE_SET + 1;
  RemotingSinkAudioCapability.CODEC_OPUS = RemotingSinkAudioCapability.CODEC_AAC + 1;

  RemotingSinkAudioCapability.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    }
    return false;
  };

  RemotingSinkAudioCapability.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  var RemotingSinkVideoCapability = {};
  RemotingSinkVideoCapability.SUPPORT_4K = 0;
  RemotingSinkVideoCapability.CODEC_BASELINE_SET = RemotingSinkVideoCapability.SUPPORT_4K + 1;
  RemotingSinkVideoCapability.CODEC_H264 = RemotingSinkVideoCapability.CODEC_BASELINE_SET + 1;
  RemotingSinkVideoCapability.CODEC_VP8 = RemotingSinkVideoCapability.CODEC_H264 + 1;
  RemotingSinkVideoCapability.CODEC_VP9 = RemotingSinkVideoCapability.CODEC_VP8 + 1;
  RemotingSinkVideoCapability.CODEC_HEVC = RemotingSinkVideoCapability.CODEC_VP9 + 1;

  RemotingSinkVideoCapability.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
      return true;
    }
    return false;
  };

  RemotingSinkVideoCapability.validate = function(enumValue) {
    var isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };

  function RemotingSinkMetadata(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  RemotingSinkMetadata.prototype.initDefaults_ = function() {
    this.features = null;
    this.audioCapabilities = null;
    this.videoCapabilities = null;
    this.friendlyName = null;
  };
  RemotingSinkMetadata.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  RemotingSinkMetadata.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 40}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate RemotingSinkMetadata.features
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 4, new codec.Enum(RemotingSinkFeature), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;


    // validate RemotingSinkMetadata.audioCapabilities
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 4, new codec.Enum(RemotingSinkAudioCapability), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;


    // validate RemotingSinkMetadata.videoCapabilities
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 4, new codec.Enum(RemotingSinkVideoCapability), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;


    // validate RemotingSinkMetadata.friendlyName
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  RemotingSinkMetadata.encodedSize = codec.kStructHeaderSize + 32;

  RemotingSinkMetadata.decode = function(decoder) {
    var packed;
    var val = new RemotingSinkMetadata();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.features = decoder.decodeArrayPointer(new codec.Enum(RemotingSinkFeature));
    val.audioCapabilities = decoder.decodeArrayPointer(new codec.Enum(RemotingSinkAudioCapability));
    val.videoCapabilities = decoder.decodeArrayPointer(new codec.Enum(RemotingSinkVideoCapability));
    val.friendlyName = decoder.decodeStruct(codec.String);
    return val;
  };

  RemotingSinkMetadata.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(RemotingSinkMetadata.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(new codec.Enum(RemotingSinkFeature), val.features);
    encoder.encodeArrayPointer(new codec.Enum(RemotingSinkAudioCapability), val.audioCapabilities);
    encoder.encodeArrayPointer(new codec.Enum(RemotingSinkVideoCapability), val.videoCapabilities);
    encoder.encodeStruct(codec.String, val.friendlyName);
  };
  exports.RemotingStopReason = RemotingStopReason;
  exports.RemotingStartFailReason = RemotingStartFailReason;
  exports.RemotingSinkFeature = RemotingSinkFeature;
  exports.RemotingSinkAudioCapability = RemotingSinkAudioCapability;
  exports.RemotingSinkVideoCapability = RemotingSinkVideoCapability;
  exports.RemotingSinkMetadata = RemotingSinkMetadata;
})();‰PNG


IHDRTTaøR	PLTEÿÿÿƒÝÏÒtRNS@æØf`IDATx^íÕ1
€0ƒaïç’%÷˒Sºd‘ZDÈ Å(ozÐám;Ǝ‰⮙zìYE;CQÌÐÑþ¾Ÿû!ÑbWàۚVU`]æ-jÌñ–^ëšқ&úæžj¯5ʄ<oIEND®B`‚‰PNG


IHDR”‚RüaPLTEÿÿÿmHtçIDATx^íÙÑ1„áiËÞÏCõý_©75ԔXbŒ8ÿU,ù¬ŽœÜÄom”ª¡ÈzŠ%¢†B	ÔS(¡d9Ef)’KJtŠÒ6I†‘yj]3… Å3©¡ÖÒP	øšˆR¸G‰ÍQ|MAuU€Z}v¤ äÅ%ÓËSª˜B7xî£^=ö½ðÞ4ª\û(q®ÔQ><Ÿ	jý7Å)(–¥rJe)IBK(A²J¨ÿnrë—. ÕRC¡š2$£Ü2×GC–RN©Uy	0׃C
å†Z%h;•oš>8üܪ+VÅMIEND®B`‚‰PNG


IHDR@(NÎüésRGB®Îé¨IDAThíZiL\Uþfc†mXf€™aXʎe+XZcƒˆ­bš¸T+¨MüeӤ&&556F[kÜBâ/cSI·TS£Q­XE´-„²o-0ìËÌ0žsYª„I æyïÝûî½ï|ç|÷œ3̓€¤³³ÓhµZߖH$÷Ùív÷¹«ÆnÂxI.—¿l4;%Þf³]¡Î`w½.2ĀL&K—³çi@°J¥‚F£Yf©ñnÓGxa2™`6›ƒ»”,±ѭðŒ“ÌXY»œ¨¯çƝz>ôÀw<ý‘Tƒ?*÷f;ýìy¬Œ]êôl7›à1€›9Ôi88m27›àa€›9Ôi88m27›àrá¿A㍻#„YLãSÐøz‰ëoú‘®†Öo¶íÈnC“ÓPʤðö’áƈ¾töWÝRëŸköM!dn½Ë-CŽ–tªßå-ðúöxùȱɨƉâ4h}HÑûá±8X¹T‚’\ü”2q=ßæ³B&Ar˜mCò£])HÖùA)—bw¶^ŒcG¼˜Ïã%ˆþ»´ȊT;ÔÑà[¦v4â6ý¬l‹iåöcgzÎ]¹	5yðìóx§²ì©ÍñŽxwg’XÍ4>³ûó£±ÿ\=J|s­íƒfèéúÙÜp¼Vވ¨`oû©iTóÿØ2ˆabËý‰´
˜o£Õ¿í2Ž]î´ՐçOÔt‹'?wo]hÆo#x iö›—uƎ¯ëzŇU·á¥ÏëÑA 3ˆ=,7G-(HÒ
f\íƒ^­ę_{0f±á‘ÔP°á*Lbìr\6@cßv¤„bÏf#ʪ»`# OféPAݝ™D"tå“J!Ëô
’µøø©áÑڎ1桍!Â(/~úŠsb;Ü„3µ=ÐßÑGQQ¿¼´¶¶ÚùéQQQB	gu=£øàbBµˆìiTfɠyïªRàè–öì$ÝoêŸ@¬Ö*ÚF9ŽY¬˜¶Ù!£y{ɧJÒÑKÁOKUÂAÒO)ǑóMè²ÜÑ×aV¢­­MèârÈ/ýE,ôåÕ^q^îÖ÷«.ÉÿpU\6€#ªöå`hbzá6ӿ´ª/l‰Xèã³uFx—=όž´"<P…Q
’,
J‘f«M0‰Ûìýža‹È*|]•3€è¾çT2#f\sÿ$N–¤aßg×`±Í`bʆð•ˆüÏÐ~/û¹ÑõëzÆð*¥Ï7+šÀN
óc«[‡©ÆPP\1àPùućú"È[§©트—zø\܃y/”âv¸`¼Rƒ­DgNcEѹnxl“ƒĒqŠò~+<¥ ýïMŒá¹:%ú)úsªܨ÷_(´"‚TˆñYêñNõ­ˆæ5Щ½ðx¦¹сøª®y1ø¡ySV»¨|Yqªð,×Dý)bR®x.åðÃ	àÔÚÐ;ŽZJ­eTpåQmñ	eWeE¶ӟ+¿`Šܥ—څŽ\$°!~ïÅ™z\l4¡êúJrÂQHi‘Ë袴PøÒ>ç,Às‰ê¼VMû0Uœ
üðùfJ¯Z“`¥ŽS—DÊÏïù¼÷ª±+K¥Atrú4y<!dv\û`"ƒ¼QÓ6ü¯¹¼E¸dætx¶ö†¸7CVæÂÈUY°R~?ëùÅ
_‚¶ŽÆ.ž»¸½ipEcÀb…×bÛc€µè•ÕÔÉÀմöZ|–‡kÑ+«©Ӻg€œ^èáßÉù͉ùß͝ñ@ï‘|g†¯‰±Œ•…±K	|7øµ‘ùÜvWaŒŒ•…±¯û—¤¤üª¿-E9͔¦qãÃÆӌ™±ÿ
oügʍé{IEND®B`‚‰PNG


IHDR@(NÎüésRGB®Îé
‡IDAThåZ{xMWÿåäA"!ïWiHh‚øâ2SA$
A=¢Ú2F™èiUÐ~D•~UžÑÉM
zţÞꑐw"!oò¼÷&‘睵NzNNâJBoú‡®ï»÷¬½ÎÞû¬µözí}ŽÂÃÃ
W­Zµ´[·n3ôôô0íe…†††»•••û֭[·966¶V‡…ŠŠJÕÕÕu~Y…Ö$Wccc֊+Üu>033[ollKKKèëëkêÿÒÐêëëQRR‚'Ož@¡P¬Ô%³ŸÅÒý„g9yYV–]Ÿ|ރ¹ò‰˰ï\ÎÆç£AÝȏÃãòjä<V¡¾Q-´-La߳üÚbÊWøyôèñ'Êʲëdgg899iýYeªZ,ÞqÙEJ,ˆ±Þöèjl =§LYƒ£×`Cìm$ç”KtFü<m°ý=?x8öhA×VãCÂT¦€Œ‚#ÿ‡åa¯áqîmòÝÐЈu1·°vßM4ÙCSwVÖ?ÿìð‘®mŽ‘›¢t_dp{cxåCÖü€­F´+<ϥ§§‹șC°c‘_‹©«žÔaægq8q+·]›NQÀßö^ÇÛ¯"€L^„+Ʌˆý1Sl
םß'!%§L¢Íìy­¬¥®¾³7š¢ªVê§MDë
È~¤B\|.Þõ”øŒŽKÈeG]*щKÈà?Äù»ùýÓ9Caڥ9NðÇÕ'îH}´‰h]‡.gaÎë}a ¯'ð™žW¹[εðm¹յ
ûä$?¯°•yLá"ï"àÑqéϜã©ÎÏAкÎ&ä#pˆ£Ä¦ÿÄK©N"¶BJU5ØõC²D?ØAÂE$·XõT¦ïý’«ÖWR	gkS‰§i$¼-京ŸK/3]>Rj¤ÿ¢Ö ª®ƒ±a“ù3cŠªºñ§”��V=©—7µ‚k]6]QPZ%1×ϡ»„·…¸ËúÉÇËÇØYv•7µ‚k]^®–¸”T(1×^Äuè7—Ҧòñ"ÍØPžNbSkW­+ l¸b.dH†ú:ãaÎR[²lòkàܴAi¤½w­êäãøTzÔ4×óҴ®€QTÃW?‹«¨££ƒ˜c°0¨?ôuy­›¡«‘>ÖÍ‚oûJÄoΤ!•R§¸R\=s°œ¤5¼Sö·ï—`ÆÆ3¸¸1–fƳ\Չõ[·SsËá»ôÊ+[V}½9XP”4‘NÝxSXCµýø¿çoäÂ3MÞNÈ*Á؏Ž?%ü[֒•ttÚñÏT?WX˜ȧÇñ~ˆ'ޥ_.°(P%mx6J@•º•5ÍiÎÐ@ŸF¶ÑbßθvŠÈåMÌgãÁ%²—‹%8Ýõ01êûxZõS·óP%¼)D>œ6NÖ&򩴊‹.Ðé
¹æ}þ]Úe*Q¬x‚FuóΟâ$,H)V&äÖz­‚%ϡ¦þ?ž¿ßaÃ`hd(N+\«««qãú
Œ=ª½­†¨€¹˜ìÿ÷>üñ½…ÂabnNfϙ:LÅí[·‘’œŒ7gÎhëyB®èlþµ™™8yâ^éÓ*•éié˜>֯Ǿ1O) ° [>ÿü¹ ñÀGbükJKKգGŽ”ºöÔAãՊ
…DÓ’—›«~kv„šNo¥)KŠ‹Õ7úI=ÿwÕeee]Ž„‡…ɛíâ¢Ü²Îårptt$mƞݻ1Úß

õpvvÆÕ+Wacg‹›7n lòdXö쉳qq‚հéVWU!''>Àȑ#‘˜˜zI???Xü|RûÍ޽@§DÍû	¾'ÞW*•ˆ;}¡oLB2Y^A~Æì?{III˜6}šÔ_η&ü…!777¤¦¦ --׮^%!k°eófØØØÀÉÉ»ÿ±c¿„w …­X¶\è·mëV˜˜˜ ##´
ÄüXäæ6yeÝÏBo›gŸ›ššâø±£|¦¾}ú‚çcP)Uðä
{{{üaÞ<M²j¤½°
Ї|´w¯&fíìí`aÑCPûnii	NŸ:[[[áÁ+V®„‹«úõï‡À	à=hŽù/¾üâôéÛWbÎÅÕ©))R[b`Ð96™˜šÀÜÜCCPWW/MMc[Ó:¤r(p.ù!.]¼„9sçŠ$W#c#”—•ÃÓÓ¶ärPTTà»ÇPW[‡ûc¤[³#æ ö7(¥·7"°B8Øʡ¦¦Fh2_ô¾µ5ÍÕ#[ak·••ãŠG¿:‹ٿ_¸–—`Ǯ¿Y +ë>¸’œB/W—›‡ŒôtÁô#(SD­߀[·nÁo”233¡T()<DñãÇ8uò$Å	K>Lâ‰-éë;±1*
>>CѽGw\¹|³#f«ÊÏñÿýï°qÃ!V°ðiii՘qäða²C,]¾Lš¯=äW«Úcä׾ÿ\u»Cmm-ŒŒŒÈÁ/9‚‹¯™¸173§•Ðî³	ªÉ<Ù
Ødy,ÏÃã荴0Ï'B#½$á9ÉÏy,¯p]2‘ò•ÇñÜ<g
þ©T*!°2yŸ#ÎÙֵC.ð׿,ÃØñã°/:ã1!(۷mƒ‡‡'²éS¹€»G?Ü!?íïÑÐÕÑCbR"ååX¹_}¹5µ5X½fP´,\´ˆâÈE\¦X2!8Hhõ™!øóå+—,¸Š™YwÄÇ߁‹‹Ž?†»va¹IȤI¸O֬ÅÞèáôÉS¸ví*>ŽŒDB|¼hÛžïu(ZY[ÃÞÁS§Mǵ+רì¼/oo‡LD¿~îpruFøԩ°²¶¢ô¤rpoÛÞM+FQZŸâ3Ô4Ç×_mÆr:ӡÇgSM0ÄÇG¨+Ä(î1ÀVVVØC©têôé?a<îݽ+¤ÇАP|@)ÕÍíJ·N¸Ÿq_°_¬{YÚxe«à,Óèĉt©FڴQˆÚT±‰äWh®T#°)ÚP>/,,\‚Ûó,€R©ÀªéËÉ2233`Gi’‹%MЭk©FàځÝÀÏ4FùûcϞÝžƒS�G[¤>®:zK–,‰äŽݻ?ûð’+.3Z±Œô¸S;nŠ
ŠàN«ŸxïØÿ½¼¼Èì„ڝûw¡LPààÁԙ!k² ‰I)àú«C¶Š$ªÙʲ³ÐÊy#7/OHƒ/ÆÙ3q(.~,Tœ……{êðzÀr“4R|0¥ýȰáÃÉ2¯¢'UžEEE("¥›“<mÉTAi˜A‡L癌‡Є;/ñð<R2ØD]ŠäÑ,+6Â7^v`YV–ý·ü‘T6}$õªížòóó·ûúúVQ޵¡Ülý2[›=Õ
[è³ü™Üÿì#Ðƨ[çIEND®B`‚‰PNG


IHDR@(NÎüéŒIDATx횃“cMÅ÷¯Xc­m۶m۶m۶mï&™$c{‚KÎ÷nWu*o?¯k^NÕ}ÖùõíÛ=(DŠŒŒTGGGŸ#IðH"¯äY·ù,1 ³È$HNN†ÝnGy$¯Âi,†ÌK pÉr÷íààà////€oUvv6„|ág^999ð”S<žþñ%bnž‚%Îø{
†¿ڇ­[4m†U+V¸
=r„{÷ö-2ÒÓѥc'¶äçaƒ‡Àl2ƒDsîÆ!40ˆγõÙ3g@нuw;”ÆãfEð¼MQ<j_Ϧ¶€)F‹í[·²ëïݹO6œ=#-5
!ì3¦NÃõ«×ÜûeK–BŸž½`0¾½¨K‡Ž8zø0fNŸÁ^شQ#äææJ̞9“m>x÷ïÝÇÒŋÝQ£JU”+U[7oÁí[·°rùrì޹ÉOoã^ã¢д-Šèn%ßOØA
è+ðdly¤ÆE",8ƒWJJ
‚ý0iüè{ºvêŒçÎS°oá6o܄=»v3mZ¶üzƎץ‹ÙÃ׬Z-0dà Öò/ž?‡§æ͞ƒ_¼~õ
žr8xЯ4í‹!¡W	¤‰Æ3Fª1N…”I*|£€æÐtL›2¾~HLHiýÚuì?~ä8·8€»wî€D€äWw€«J…Šèѵ›3§Ϩ•Ù~§öíqÿî=š7iŠ捛àK٬fÜoYQ=J u°£TȚ †iº2gû f¦
oW·‚泆=sõʕZõÊUXW#qeÂJ¢^­Ú,öïÝ˰îºfÕ*Ö0ƒúø~*—¯€Þ=zJðt§ԮS³;þðÁ4kԘՎ/%X²ñ¨C1Ä(ŒÑ*dOòi†,ó}aZ䃸>x»®HÝ:wAÕJ•YŠÓs¯^¹"Ъy1Ý7²xùâ…@¹ÒehM¨¼P–0™Lp¹\ }üðÁýâ™ӦSð”•èɘZ0Q m‚`†–¾°,ñEÖ
_ª~fHW._fÏ+_¦jר	§Ó	®ê§NœD•Š•йC‡o )‚T:¶kA8F
ã¸1cXêӚŽ_ºp‘*5˘Jåʳ‚ôèáClٴ™¥jҋkx>H¨‰J¤ÏQ#K4Ÿ!šYæƒ×ËÊC°¦»ëE­jÕÙ3wlÛ.€ºÄùsç(¨1$5€Š.m/˜;ïëð¡«Qý¬‚[Ìæ?
ƒ”–<å(¦Nž,yIß^½Y1ãÃä‰ãÇAŠxϧ”Æû)Jhç¨ð~ž
o77ƒ9^š1­TH(Ë4ýã0ȋ ã
òC'BÔŒ#›ü•hèԇ‡³Zá)‡‹tÝCÄ?;SÜ{ü•¬V+tZ-¾·¼Sáϯ¡ßÒ[†\8žïnZtòà4ÜAþ–FÈ]àKæåðîdœB>\IŸ!ÌMËkñãC¸YùpF<€p°'7)Ž7ǐ¿µ	7'®Œ(Øo.AÞÊòܔPkºáPoä-ôãf
>güØ.ÏDފ²€+é췖!Cmɇ`.8c_Ц—"Sý¯3ö~í?Häeá¹ÛùIÈ[Uñ‡›æažëÃÌg—süÜ‘±çÃýö;+‘¿«­XÈü’i©ù¨)* nc‡˜ûORÚwˆ¼}ÆC“¾¢t“xêýú0Ìu¦Ÿ›]µ¸ðü7¹ä¯6«yƒÈ{Ga<¹úÍ=>¯½è·ãì²jy2OÞÿÍÿxeÔi°£IEND®B`‚‰PNG


IHDR@(yÛhPLTEUUUÒÒÒÝÝÝÞÞÞÝÝÝÞÞÞÿÿÿàààÎÎÎ~~~ÀÀÀ&&&888¿¿¿ûûûAAA«««ÞÞÞ'''


ÿÕÉÿð¦àìììèèè)))>>>GGGÍÍͅ~///ãã㨨¨ÕÕÕÅÅÅððð,,,555ZzööövvváááQQQ
ÇÇÇ_€sm1/òòò".›››---^p2uuu???Œ¼›ÒrorrrÌÌ̵µµùùù€€€"""OOO'4i޽²¹¹¹„„„hhh­ÈÍ
———QMæÙØØØÏÏÏíí�³ƻÝÝ݉¸Ô~wjdŠŠŠSSSÒÒÒNôâ’¢¥1tRNSxÔßÒÞù£IDATx½–×ÜPEßð¼Ø£S{úٶU۶þ~_jn’ÕÙÁbv|îa)–ÈHÉ$Äá,-Å ËXBªY<"VMJ°¤dñÈXR’I$ýW¬8ZÞÖEŽ$p}üÄwC< {ᦁ¿0Ì0³Ž¨›tg †Gèh‰N¸hƒKøøÉ9õ8~áÓGñ‹#ü0~C&	^®:qRû.¸w¿xl…$p<{Àž¶Μ
ãç/_)–ž\à€ëüroøÕ@ðüExUz
@#	lƒOú¸Ú/å!Ã#£bo“òX³91	ÁTyÀÌìœØçɷ0/-4°–°¼RVë4úCÌmlnmï`—Wö.^ºy«pûù!*¸û¨òøðöؽÿðñÓgúk”Ñ™ü)·Əý3Åý{(\mij˜PUÿ
Uµ·±N,„ÑfGm=žαF슳d¥YPó’RD’¢æ}ê3mYÂÛIEND®B`‚‰PNG


IHDR@(NÎüégAMA±üasRGB®Îé cHRMz&€„ú€èu0ê`:˜pœºQ<×IDAThÞíÚ1ja„ágWI'XJнBÀ6ÇQ<“÷°ö†´!)c™ºb¿ß|˜—ù~nš`…ÞÑã4’믞vWSÿô‚È?º7,óÏø(d~¸Otlñªžfè|a¡¦Žðs'"›ÝÜ{
­âjÑT 
«Á/žÒyé€$  PP}¾Ãé€t@H ÒI@@-5øƼ¨ÿc‹}áì¡s™‹”œÈ$–.á’#©AS¬&·ög&w‰݃Ç&‰~"IEND®B`‚‰PNG


IHDR@(NÎüé†IDATxíšt]Äk۶ÝØIm۶m۶۵Ý&¯±m×HæÛû6»ç¾ܗSoÎ×dª$=º¿3ÿ™ÿ»»ùˆ†RD&“-”…„„à_þCÎHÎJÎÌýáLþ37ý	âDΞÐ ?ˆ‰‰Áׯ_񯋜‘œ•œ™œ=g	òM.8<
A|‚%r›„sÿ2s'wtzU»îC¹îQºïq”|ÅF\F‘qf(8Ùùg:!«<laÜwN×ÓÄåjª°¬¤çòê¸[ZÏKh#ˆ&‚
j!«Ì<\ÑýÒ$4>d€¦G´Ñæ„&4Îj@ï’::«¡§¹
ڴ—Àò­6¨ª¹•õ·¢B§Ý(Kô!Îf0E¡)6Ûõ[±µA{¨«‚“µTq‰`QIN€;€gϢ,€yŽ{Qa›>ªïÖC½ý:hzXK@¸¨†N×Tы0@
vÎn¨¡²R ’þTè¸KÁÅG\˜%€›“Ö4i'°¿N{œ¨©‚ËrjrwËhàYqÖf·Qr£@µ]º¨KPп¤NHç€csV ªÖzÁ€³Ô8BÐáQãå¶5äÔ$ Ð#P@‚OÏTç(s@çÌ`Ýîïhª±ÕۯF@t@™¾'Pr€•jÚXݘw 822
€r›{ €耶'µ .d€”#P«Õ"2"€Š$䎣 øHù0!¸¨y[Îí|TÍPN¹48šTp¡Üå·ê):€ F@2Âð€R,jÑN’'©`@(´ÖH!êñȹ¬Ùr‘8•ô¶ðЃÀ8`!ç€ÕT²ØPâ;:S5(©ø #p@lÖôÐ!¨BF@Üî°@[ƒ'Iä”T¾ãºh”Î4ԆY‹ΰkÔΕ´Ø`3 û Z@ò2@e†1܃á’·Ðd¼KUØ–¶V…ù’Õð¿uïã¡ Œ|
AªË#„^ƒ`ʯ£ýáíYŒÞÄúÁ3Î^ñ¾ðNð…{¬;Œ½®` e'iG€dÁ¤tæ™!«èˆôö­±ñ¸b
߃qÉïd~ J¹ì¨tvñ…“ÿ=¸ރbhy'¾‘²©̬Aâ]€àFN·p¶‘³ÈZ
Døà%J̲ß*Ö`«ãúˆ{Zƒ¬u1Pª !H-B$¿ëAß>Æñ6FBò-PN-34™4Ûa›‚Zgz ís¥H—5©ïŠø.€(™×¤Uyˆ5È/Bžòd$}HEDZ"¹?¿~QzF:î…ÝÆHÛÞ91|Tü~((ZæIZ€l‚¬ÄM‡an¸"³ƒ±‡-œnÉOô%ýì,ÐÏRS*‹É0-Ð}¥-h}ü’þÝøÞ}“T
šxšƒÖÙ7¤ɀU›-ÑXo½€ßÁò~ hÝðŠc(† s ›Â"äèïZ®ÁÖÒ8€èÓ篸û4'͟ã¨ÙÈ9ùý´[[¡"½kð}L<®*©Á+NJø'†áq¸žFºÁ'ÁYµöÁipÁø!^ʐœú´ÒÓ3à™ŠCN>h°ÚéEhnÝDŽ$¥‹PŠóC²	-ð½Eˆáƒûáw±âî\éZ€Þjv܁F£ސ“(?à”Òûz¦ïN7ЂyËN°oL¯ÂìgBkóîòîòîòîþŸ÷%æ»dw@2€s€šR„”4ü¥û€ávZ9w@B´y. Ðßû$ûT¸æCPm0M¹hBP!¸êD»à ´ÀXþHéËh:I
R!HZ€}0B>½3»I‡ Ìs}ªFºæÜ}qýhlÎUPhGB®Aæ>€Ô`ô¼] UˆÆT}½´$¿ (;ì<ôW;áڣ0¢[`
€¾p©¬…WFãhìJن`“LhŸ×Á§q¸âôËO‡óçö$ò^‘ÉÅ/I“³ôkr¹à59ú5¹ÿ16lÄNIEND®B`‚‰PNG


IHDR@(NÎüésRGB®Îé
IDAThåZ{LUuÿœsîåq¹¼"Þ8žH4L͈­‡2››Ф´©U[MdÜÄlæЍȹ6©´­-uÍØtTK֋ÕÂYh"²9ã!)0¸p_çÑïwô"xϹçžsqþþ¸÷œïë÷ý|ßßû0 ¥¼¼<¨®®ngXXØËÇ-£´…ZA¸<55ub߾}§Nr1üC¯²,›¶PA+áE±¯¦¦&‡éì쬍ˆˆ¨		ALLL&“’ü‚¡ñ<±±18LLLìbIÚo¦èð'm`Š•Š%}~	}y`-?í\nZ…¾"	oק㧴+Å>ïù.üÞ
ç_Âõõ÷{ ŽOÈn±ÑQ0=¹æu…Ùú˜ØGæºë¶Aèi†xãˆ#çmH’Æƚ6¹\j1˜¸ü¹z¾1ýýýµ‘šš)áj/¦köÃy欦†Œ7!¯mAػՀÅ¡óð]BrMjêr‰Oô²LL`“Õõë×åºæ%®Ï[0¹µX��ñ­¶@àûô¨a9˜žz\îv]z³…=`g<;‚Ɋ7tƒçÂX³;ank;ÅëªZ¸ÏíÿÛ~]zJÂÀ}¶
S;ߑûª’q5ÃIˆ\7
ÖJ€ó‚:GxD5qU:ù„?N©òýa€4aÃäæ7!	d´ÖY,OL‚˜Õê.æžqVîˆó�©ACºTÉpì
MGÿÒ]±‰}Ìæ¥Çޚ÷·ˋ®Exø‹
Zbª|cpó }ßH	Κ&a—'/unxʋæNŸpŒù#ê%c(î¶s3ó»—E†ð‚ÓÕ7숌¨fAEáÆw¾DTyÆðíOª}1X2òËŸš(‚™4°j$öÄAƒ>©ùâ‹.þilÐa­Ú&ãԖQòM28ÊqxDÉMkÑÇ8´e+²ôIјÑ¢%¡Ìçé( Q8?d”Lp¡JTMš¡`ã5
+	6N‰<‡&…hËÌQ¸ûÂXâ”Ț4C0-ÍÖ4¬$ ÚÈæSôÝÂRˆ±
*mÌ'C*}Q	Ÿ&Mt3p«ÊIdg(†·ȘO†&/‚yÕ
U ¾Î>õ¾*Īó|Ùd¬Éäœ`¥/Už¡Pkº—7Pœ}ˆ
­lf!$…°HN³–Wì‘
éÓ"U™_xÁŠtW*‘MŸ­=ÚKψ„¤ß6v9¸Ì2/{þô×8˲õÓC0åd͢ø÷肽3|FXŒ³€O°̼ûû@Gþ ç>6Üú´ž€ÀDXñÍq˜–聧.FÀÞ
ޝëZA`¬IZwœôÅ-QŸü€@-³©Ɉüå‚ËK|Vt?“	&³F=ä?Yïgû|ç’H÷+ù
Lt®O9˜ór&詈ÿùWLï}îÛUJèhð«e°T¿6óîA¬ýø+A¸z\õ`”ar’¼¦¼·&<ï©Òð¿çLp^àñF½
Wk۝cñÁaÒÂf°q”ÿ8Ì«Hڪ,¥E7¤‘ˆ·.@¢k{lCÉ
‹sÉÏ¡ÆV ¿fÿ?Ð̮è¿úì	@Àc€^€7oÞĕ+Wôª©ÊS 'NœPåk1V$Z*÷ømmmèèè€ÓéDff&®]»†ÊÊJP§Ž;†”””••áҥKhooǦM›dzoo/vì؁„„=z%%%ÈÎÎÆɓ'ÜÜ\´´´ ¨¨QQQ²µµqãF´¶¶¢¯¯UUUhll”‰ŒŒ¼ç”Χ€2àüùóÈÈȀËåÂèè(âââpúôikg ¹yÆÐКšš°fÍ$&&¢¸¸¥¥¥(,,D}}=


pàÀc``@Òîݻ±}ûv$%%¡ººZ¶ÕÕՅÁÁA;}ÔÖւÜïËJKKÓ	y®x@ ¦rrr••5óO¯žém‹åÎâ†ìéé‘
»ÝzMÝßßòÁ***ä÷ŋƒ\XÊÀi°¨,-äú~ÆVrr2¬V+Ün·\Gxø½•,¬ó‡#©¸—êÐTÓ[ȗò"u:66Vv444ëׯ—[—fÄêիåVǶmÛ@AÒ,¡h—hnn–äççË7Ôééé2†4í4S¨­µkׂN‡yyy ò‡‚Íf“ŸiÔS¨?´<iP#ÿ–ìÌ,@RP’iJ>,ѕbgIFӾëa,ä@PŒ+-ûÃü‘T?™­²¹îînL/GÈ`5M>I$_‹;]üŸ¤
M{2p¾O>|…~&÷ۦ{ÚW‚…IEND®B`‚‰PNG


IHDR@(NÎüésRGB®Îé§IDAThíZoh[Uÿ½$m³®³MÒvµI·é\SKªàdT×?£2‡øaCÄ2E‚¢”!‚úE±ü E?ø­-Ûcĭ®]7ö·u+t&˜´Î6ý³µY’¾$Þóæ}ë{Í[ßËÊJ“Hî=çžsîûýî¹÷å…'€I p‰¢Ø!Bc2™¬$[¦
Ã8Â0öX,–v—Ë|<`F{¦‚N…‹1a6›½Zyæ`·Z­p8`̤òÏËP(„H$b'ì&ÆD¡Ëð„“˜°’v+ý»IÉô•'Œ\8VÂnâÆlmsdëÊsܹ
àLdk›«€l]yŽ;ë+@ówï£ß?ÂI’Z“`Â=ÅëðÚC¯ãáŠ͊1R¾þýKì¿ԍÉȄbìeï«x¾öÄâ1´t=¦{g˻ؾn‡l;óÏi|rîcø¦}H$²ýàÎÃ(ʷ!ÿ‡!٦èÌŁÐ,0–ÌwY-Øì\ƒ7ª°ý^›ÂU­è®º ËSÃØÛóB×Çyÿu_|¶¼ÂieüúÞ>ÞÎ測ÏÃòL\…y\MÑ&eÛՈˆ_†'ñÄ7ƒxï¨_¶§êè&€GãQñÿÌU©=4|P¡§£|÷ǷÏÝXA­ø½µ·x`„”aïõ¡Ç?rŒŒ†	  Á^j$¹»†ßƹšV;ÄOÃ?.»ç¾ìª^“Ú/y³Ô_¿¢6ÉzZŽ
`fnFJrr´ñۃ·!];#‹f 5îl¨D»‡=¶³-¡µ~sôâ;4DóTû—–c"’
	§Fú±Í݊¾àqٵ¼p-h/Ï?ÀäAUЁ¡ýòègúƒ}²®îä1œ՗⍎ŒÎâÏéhÏ'fWá˜Ú]Ò7:V¥´“Q7ÞòzLE&A'5IßH/šª[$"$ûjóìƧöéZMs`¨›íý+´É^ƒV÷ãšÐaKñ|q2řϾè£qà7V5³Aû,ÝPhsõ6™€“¬.ü{´‚$ìÏ4±‰ˆ½Ãè¾Ô%»·yžƒ˜˜“uu§7ð+zþ>¦6ßR¯X]ë^Òô1tlu5‚~\N£ãÔrâJëPºªLÖõtèÖIyH*‹œzâôúxJk±¯õsZØöÐC`³ÚQ_þ Î]9+¥Îå´Íl;^=÷̦gerµò¨Ïy³Ɍ¶šÝÜmVîgÛÉ[V¿`Lm0DӾçðdTþUÆ	àñÅÅxrÃS\ÕlÕç¼Y0ãïM=†¶%¤…o>ÇQ‹µì®ìÜø4
Ìé†ßVœaVêʼŠI©*ҕ¢ü"ìb,—&€.´…Ý
æKsåOU´¾d>Üځ’‚’ùéîh_ðù|ÒÙâv»ïèÄË=™ßï—.!­
Xî‹_Êùs,%›+1W®Vâª-å5ç*`)Ù\‰¹rÀdFiåè͉lŽ•°ÓÇ8½6Â2™ÂHXI{ֿ$e¢WÅèm)FH'ß=úõ?ÆNÂLØÿŸ¦xûâ,žIEND®B`‚‰PNG


IHDR@(NÎüésRGB®Îé	UIDAThåZ	p“Çþ,ɲlY2¶|ߨØsûà0PŠH 0Rh’0ÍEÓÉÚ2MK‡„¡!M¦HÉÑvMB´!)…”r™Ãcllˆ,[¶B’-ë–Üݕ¡L,ë—<édÌÎHÿþï½ÝßÛ}ï}»³! eåʕâ­[·¾(•J
……”6Z‹Óé¬ïïï߿m۶]°…PåwìØñµ@ È­J¥—Ëåjۼys^H]]ÝËr¹üU‰D…B‘H4”ü¨¡9hµZX,ôööneÿ8Õî~PžêI'˜êJÕ]@|¾€¾Œö™§:r…ӕê.àˆ÷ësÄïìè‚þw‚åt\†>Ÿv´†‡cOÅÃøXgG‡ÖèSΛ1½(
æX I§…Ãåòfù¬!(ˆû.FqJ²O9Ž1"¸4Zh–>
‡ZÃõçó¹éÁåø¢ſ×AñÌt\ri0 å(üž.×ê»5xêð—¨}fƒßF#r¾=ûy)_]R‚/Zù+ôȬð;~Ÿ=Æ~Ÿ<oƈ`þ÷ï¾|ֿJë“7#;+*½a(oZ~<ñ%h¸´:Øo¶óøpÁØT&gŽáÕïpBs2҆c{xAÀz񪧓á*i$êÔúáD¾ÅsI¿E
˜ðÝ ŠŸê&òŽܖ*S/W
ê)03-•W۠³€mÐ	Çÿ†›
šÅpb,_U°}7@ub
ÐÂߟdèèíÃoÌź©…€h!ðõ|{'žùü(úív¿ŠMNL@¤8ԯÊÌØê› ÊÉDhAœƒiP”KÞó²ao¹ªœüvlŽ;x•ËVNùûѠ¹͌1+߬ò]þAÀVӀ2+aE“ظ­•—Ù3lÚÄÁ÷j T„1Qh3;B¨“³ñì#%ŒOÿbdáÐBey§¿pE(ÄB¦&%â¬êš´wa²9˜1ê{î¥R!iC‹L,fOúÆÍúœ~†¢
ƒr.Š‹ÜG–Aˆ§O„³]
ab’.„ÃlE«4?ÞyQÒ0¤ÄF!=.
³ÙÉ10šm(y~š?ø9ìNäaø¨®ö*ÂDBLJŒÇÙ'ס$5¿<þ_¼ýpdeéEAG›[ñÆC嘳÷¯8º~
~øþ‡¸Ôم9™ü25@P.`ôñ”|X¬p4+i_̙ËɋÌ-@ѡ÷0:UôåÕs‘+ÇöŸ–#2\ŒÇ_û”DŽÙů‚™Ì4õÿy™¬Ýg
7°»ê2Òv¾EV…ædaÊÛ{Խp«š~7Øٵ¨T–*Ÿ¤ÈH֞Ï_à+€`r[u=ë[ —!$Léê%”aZŒûC¶am·ÐÅäZÔZ$ÅÈpöš
Ï.-Amk7*Šr Ñ÷C!`2ª=ÂÅ"TutâÉSqÇdÂöSç<:”¦¥€ºÅù´Pˆñi¡ gهX=ÿ§
^ö†f¸úMìcúWÞdƐm\Qr<n¯zökM(¢a9vfIÎ5´“™B£JƒJRÿ˱+(Ÿ‚iã’ñè+û‘F\âDíMč‘By×@fQ
ED8þy½™}ƒûûüF3Rår¼úÀÐIVIº›¹åo?U‰îAè¨B”J%ƒiîeÇ}Ð×ÓøÞ'Ðýz—/¶‡ޑ•…YÒlÏ;Ÿʔ%¨Õôðe2?+žŽ—ÊJ‘÷Ç=°:ŒÖøÂFLˆsxבJ¥bì€]€€ÃuNy59ãµçØ"â4&ìýññ89V͛„óèÂó¥E‹8ÞÒÆöOMÅÕ.
2HF‘’ÜN3Ǒ-КÌø}ù<†
8åÈ㡼÷ 7OxIM¾sÛû[žúвüyÓRXHÐûÕcó‰[Ôà'‹¦#¢¶©Q2¦¶¼‹‡rÇaëü2¼vú¶-œ‡·Î_†SPFp~^\,*Uø;É\™Mҟ;9rÿπ@Sœ³çŽÿ^‰ą>߈­(7ï½̂ FoÄÆ%Å0„·xü8䯯֡Wɞ~ËÜÙ,ÒÓh#K¼Ý`ÀZ•7ÐtGKV‰òc	Ôÿi。 ßåo ³óu·ï
PÁ¿X1ôð¢ßbC1	Šb±Álw`ç™%i´"7{ªj>qS‰˝ÝDñ»˜?6ï\º‚C×oüŸ
Àsù_)p#ÂoŒnð¥|Z66-ŸÅޞ[VŠ’¼4èŒl?]‰®>#>m¸Žֻ:ÌÍL‡<,k'OÄòü<œ¼IRhé¼8»×4F§‘+‚<§''q¯¼Ÿ­ž¨ŽIô9€ã5­hîÔb×g•ÈüÑëÈIQàdƒr\M_}÷mœlSá‘	9,×?qè= ÂÇ× £Ì1c°æ“ÃК͞ï§&3í!ð¬ðŽ.]¯ñùëû‚Ÿ)FÁ]òRI(V”u`T,ÉnòN“1$ʤ,›0žíNoXÇ\à1ol:Qü¯]‰Յùø¨þ^Æÿéyã˱3¸½þ¥!•ò&ZI*ÊÏ-cØޛî]ÏNŠ&CIÐ_t¤óçâ-MH ÊëÈNS3´h›ô(9œ$VPp¤ÔëÑkµ!E&ƒÎb&1ãž|¹~5åðÇã¾°¡°vÓðGح]:=zMVœìl‡Þje?c°ÒN2-}÷Žܽë”GÂùn•©¼wá¸
wã¡êÕI©C‘}Òbc#G|:1>Q$`SxÀެäÕ³ °$§º7L¼:÷!´,?×Ç?™·DÉ	þ{#Ipcr^ÂDH¯#«ÁÃ
¾m¼årcxaf±7) :ï,óæVè¶섽©
 AÉWyºênÍ\ˆSj,vÿƸ«1¡<?ÍN1x–èp	*HУ9†ԃ-¼³@°ø¾¶ã²oø¾*2Òq	ȝ™Ú	½9q¿NWª»€\ÚG§×F8Æh6wE†êHu¿Ÿ/I)É%©ñÂÆÆF§Z­Þ]ZZj"WG’Èm±øѼè²7okké5¹ÿ…(Œ\ƒ‡šPIEND®B`‚‰PNG


IHDR@(NÎüésRGB®ÎéäIDAThíZ}LUe¸|ˆ"W􊀄|DMÄ9&\M§I¦–𫙥6³2­´-RÃrÎ5+?ꏬ-g,ÃMRü*tÕæWӜÊå*HD>/
/ÈǽÐû;xï{8‚‰KàÙà¼ÏÇûžó<çyÏsî^'b´hÑ"·ÄÄÄu‹ÇBÖSÉn·_­©©I޲eˎ”””'8¿m۶NÔSÖ򫩩éfBBÂ('³Ùü¡^¯ÿÔÝݝ¹¸¸hÙ÷™Íf£ÊÊJª««£êêêõ:–öKà]op~âÃW|ױ=?LOóðQ&ÙWø®“…½õÚ€Þúæe¿û2@ŽDo½öúøßv=e•VºQTEv{ùy{҈á^äêâüÐÕaÞÝz”NœÍ!<ˆšü¼õ´áÍi´dÞµJâ£|EyE•ŠîWãh󚙴aç	ڝ|^‘¿8ûIúfó…/¯ª¡{ÏPòqU[ë9ýÝhᬱôåÆy‚Lº¥˜VmN¥ì¼2E736Œì’z<E¦5pùFÍEôý¡K”rò*Ùlvi’òjJø<âá4t°‡°BÁy'''Zú|´dcbÊÓøˆá
›v&‡Vlü‰jë?¨¹ß@·+îñ"e¼rÓAÊ-¨PxLY%ïˆé& ¯?™O?|ö’°ô|z¡ óã±tAD!C¨¹¹™Ì9âCEö—l-7ÊheâA‡ÎËÊö2ëé‹ymœ‡¼¼ÊJÅeÕ¶K3@=+Þ8’B‡
7ËÌ-¥¹Ó#ÓںF:ük¦Âc°|ÁD‰ÏÎ+'¼E™œu4.ÜWb×oO#km½¬’²jÝr#	õ¥ûõdɽMÇOeŸ1²ñ^–ŽȔ]BÇé©%ù¬§Lpíúmañ#¿g¶qdδ–™²Äôö¦þý\ÉÆ@îÜå|aoM§eó[Ŭ¸‘´v™Q°Sq§†~9­ȁ|3Ø=gO	WôZƒ·?	éÌS&{3<%3ñ,-ž¥ wº*r:ßgYþͅyH릦fA¦Å`»5>À%èW/™,˜©ƒ.(0
Àä	A·î(/,¾K\ÉWô<øA˜n¹¥è0ˆz€žý(ø‰!‚îðo™4mé·tÞÔcxäÔË
«èNk^‰%w–U2™²Ŭ“åüµSð1”p@^ÀfÉm)=ÉÇÓ% “uF¶]~ ¤¹z»Dn­Øïj2³ý;ûõ=ôƦCôÏ=±$ÂYróï*eڳSGI¥22ÌG‘¡„—”kW٨S$XUAûYíæiÙüh…ÍbAªc`&šȰ„ýz-:–Añ+öHû׫Á=H
”mƒ. Êd@xöÒM*,¹«ÈÑÈàaz–˜þ£C}ÈÍUìêÐ(%o_LAªí€ùhp>ÚuC‰Ð0ñàgðò §&…Hºñ£Z3‚Œ¶A$ÝHþ‡¨k?~°k€âCÊk=ÃûÏ«iÓÛ3ð”u©¬¼¢-©ÁO6ô‘#[3¶e@§Ê D]hÉûïÚõRåÖG
~˜sÅB§&dJ^wWB SC£J+¬ä¤íà}Rê%éO¶å¯èڣNg‹åÊ὚z¡ƒãÁ¶
vðÑÒ¢É)â¶oÓÏM|7ìg{2x
 Süò9ðãçhÑ>—:h¡a/ÞEk
€pߑ+b
L+øÁÂ×j”©ˆÐaÒÜË×nÑs«’hæäPšÊö°¿Ï ªo°ÑVþöÿ,‚ªqb+q.Òw‰æÛâ» Þè©iÑåh­¦?ØàK'”)փР	:yî/鏷ãǨñ_|0‡õ÷"øÁ潥Fòһóæ0§œ0+2!Zy-êR|Ñ?/ù±¸ü k€-鯥ƒLMpþ»­/°þÃ@»’Î	Ù` WÏPO‘z>ía—0wŒ‹n¬~0pÔB3~„Ô`®š|‡zÒû¯M!óѵl‹„Ij5ø-|:R=Mâ#B¼ŎPՆó“œòóó¥¦;0P¬ï¼Qw”¥¬c+a`…Ö8È0
`U ;©  @Z¾K[àa?J~òÂߣ¦.oGý Ýu¿¾tWd—uû2àqySÝõœ:vfFú''zɾÂw;0´Žã؈¬èɁÈÀGøޛIå³CRá΋Å^\\¼;&&¦–ñcŸ-Ÿj=4
öV«u';ø2ŽÉý¸d›¹
IEND®B`‚‰PNG


IHDRL(#õ,ñsRGB®Îé²IDAThÞíZ}leŸÀ6¡|ˆà¢"‰@Ö°YÛf B»¡ÓdíîZî®+n8!CMjBǂԀd?þX7‡"A BŒ "ȇ	®³çó^ス½Þu-+2²¾ɓ»¾÷Þ{¿{î}žç÷<o¢iõ:	þ]@s‡5ëÝÍtn¡¹ƒèÈqÜÃuÐl`’Ô*“€„¼]„ÎEnhâ%Œi&ñEº?ØØÓ2Üþõ&
ø%¤AàAÕÕÕ}à=æ|fÅ9ñB¡͑׉©(=dÖÈðÒøFCÚø„î´+e£!7·¯ÖuÕbc_DG«/µ°ţNg2cu:‡‹'G·ß'(¿¬¡ÜwN9™øÞ{dQÃU"Xö
êá® :ùÈûѾ™ÅÆÛîŒvuö´¡Ôëݞ۝Òþ°µ ;DGš.v"]ânåÊÉÈs´ÔÁ^Ýè·Ý^ü¾&ž#ñ×%•‘ƎíE¶c†ûŽ7,<?Òbãˆw£sz¡c†8Øç½û¼Ò('q7÷Ãñ@ÐìY`µ£#,سZ“Á"ý‰ìGG»Ý9F¹`KÁâOÌÝjÍǻ9/ 5ÃzzoC~QiXꍺ<M§x¦A>Œ	 äÖH—³§Ž–¯åNë_¯םìjqîSúÆç‘Ít2N$m5ƒB4˜ÁÛj!°³¨ßJó%’ýA$ç.Iý‹lÜvîÙ[µqKƒ€çتF”¢ØÁ_聢0Ü'dpPÅ|jDíµØQ¸\®>èG8è»÷z剙-†Øi¤zL¾>S²V6OŠDcÁ׸œPÇ]”.ºA‡ãQ	h€¿ªúIØr BÀ9‹fɡ»¨èÁ€€f+H`ˆË-©‹E£Yvro½·ÕtÙõzê#•ßS҈•õÚi÷\P¬šfeX}AQíZI㬏¨Ýge8k'Óåã¤
@þÖ}zm È,Â@íl¤–73Fi݋‘}‡cêcْ‡ºÄw&@éuû£½W
˜v AŒaõV†_UÀð4Ií-Åѕ÷¡~1óõ×%gã N˜]Ñ6AYä”ûf·/½WL`¤8(<Ï!hߟüÓP⎂½Ôç÷&½©ÌènÉScÆ-&5`(g…æ~ÄDöt Gfç=±†kÂZe˜¢ǂµÌUŠ?ڽIùÑ3¸[35¿HyÜ~ÍÏÅ×KKKÂõ½¨`Áõ•r*Ãp'@“
äº!ŠÏWg#Q¡ZÆY離ÅŴÖ
iáD¡Ï(°±&‘sIãyžO!@Gã‚ó­*sS'½1ї™k¥„#‰á€ˆÕ!ëˆæ?Vä¾H“ëEê´dÉ 5.¦à`æf|žöY™ꙕÍ#£m^Àm°÷K5™éؔe%D½UÍ~æW?ӡEӪsÇGã.ÈRI­4W –“,tÂú%]mþãðikÌH§÷é<ysoe´0ެIŸ‘_ѣ@¡`œVÇ[¼ÅۭkbÕL܆¡ê MéÐΨ3@ȗÕçÎL镊•dÐù¥La%Ê݇N¦ٵ@êµSÞ"ºݭiÖ􉠨fÕ°žòÃqKƒZܐE½Ô`L³ƒbÖAÚwAg N…Kó"Q˜VfىÀ׎Šûü¶*«msÊüƗÇ_
Q”úHp¹úti¾99É7ûìHÖIÝطˆÂäí)«uƒ†ù½‰í8k^3\hÈNm‡•”ú<?…)/“	:ý‚³
´›®nÂ\$‡Ѷ<Ë0¯ŽÀ9äc§\aƒ¸•O³­¸cûI	e²+Kû®Ä´&Òʂµ$ËÝjè¶IÒüÒÖ$VD-*n í5¢o
¹ç)î62ÜÏĊ|WTðBçS„i£É÷îWI±-Aµþ]ɥJ…ù½IËc¥0cyËüØ9}n?Ã8Ž.ë4c›Í1É=•$}qτ`“ܛ4ŽTÖeï€%›3þÉؖ?D
À«…ÁƾÉj¢/÷ý¢°ŠÖQ±2IeC//|&R…+6bœJó¬,ö5¹_Q¤’Ûño‡V~¹mŒî™Gì™ü#îÚ#ô3¸}ûB”å��Z6ÞB˜Öwv»k€FI§XMagó«ä9lü¤B;ŸI”…@yLl˜-·íTyNú–ÂA˜ÔR›Œ¥ªsë6-¸0½r½é¾\Ù+÷ÕÄÚé+ª4ïÈ/§؅UБëZ
“J›_HJ÷qM*ƒ¾ˆÜêܤÔ*óWZŠëJt
;ž^}¨q–»m⭈’düÁmt`_Ä^C¾½,ôïAûð’:NaRAçÂO~}Sá~jՂ)`–;R=¦]+Ëܐê1/‹ö)PϏ³Ò|
£½Â}Ð
^t;˜ÑI´Ç¼[d±=‰ç'£¨Âlÿˆ·p¦Íp^IY—JJJúÇ5.pÐÜ&‰kù£¥+½®‰ça¸£Hɍk$ÞâíŽkÿŸÆås®½×ðIEND®B`‚‰PNG


IHDR@(NÎüéìIDATx^íšÁJQ…}™°•‚†.zß=¸ÈZ»IÐGЕÕN!ÛÔÎ6ãÊ6.Dg …Ù¦ƒcHº9Í!bˆ6¦.º3¿ppüïüÂù`î=Wo`44MÛstíhæ׌^é™Þi>Øjµ¬~¿áp§èiÑ#½Ò3½HƒúI½^ôN3RñÇ3Ì	€_ŠÞ	ù|ޗ@ €! ”ùøˆ·«+ع©>ŽŽ°
‡)^³Æ1LªU˜†áf§ûìËhó“L./ñªi0ù;Æó3ÅkÖ8ûô”÷򝽛ø7¯›àð¨Vårý>ÞËö6Š(—ós@×7h@¡«TRÀÃppL§[säwpžßÝ) “š͝ñ×jxO§H‹ůr¥R¡Öüìêåé	ËXL!Çǀeù@6Üßïî¨×{ÚíÝM‚–õ5	ÞÞ*¸
\ʶ_‹E5ƒCÃ..þ„V+ö¸AHñ(ìÆÛ\΍ºÎq¼0»]7
36G"nöÐfˆÝÍP<ŽU(D0øH&n†Öø¿S¶Ã@@9 !Gdö}|Hjÿû˜\4َàqÙôJÏôþ	g‰W«,}ëÅIEND®B`‚‰PNG


IHDR@(yÛÆPLTEÂÂÂÂÂÂÂÂÂÃÃÃåååÂÂÂÂÂÂÂÂÂÂÂÂø==öQQퟟååå휜ãããÖÖÖòrrÂÂÂçÕÕókkçÛÛéÀÀú//çÔԉ‰‰æÜÜòssæÛÛæÚÚójj뵵æààöSSèÍÍçÏÏ~~~ô``÷GG�çÖÖù66ø::ø;;æßß흝ø<<쨨좢붶÷EEòttçØØ꾾éÁÁÕÕÕ봴ú..ù33ø??�ôbb짧l%d	tRNS­'ñïó%(òœ
·ñIDATx^í–ŎÄ@Dݙ4†™a™áÿjµ§ÌLïÅñm•’|©ÓÚ.µ
Ì^EÐ25[U”í4€£z0l
Àn‚§Hòp€޸‚'	®|¨˜ÝoûÖSºߧ±ìo‹pàQ^yÄ-`$&—Æd<Ânïz×Vo9@+Ý[-€M÷×Ȳr”ên€ãšøúֽæ	ƒåK|Eq¬ñ$‹Oσ4å:ÊÅ.8Äþpè?ËåRá§+voï•ëúGÒóùù ,
à-±½â´i%«
&ƒŽWQ`æÓQ‰“VIEND®B`‚‰PNG


IHDRðð	‹ úPLTEUªÿÿÿÿ?ƒÅAƒÅ@ŒÌ?‚Å@¿ÿAƒÅf™Ì@ƒÄ@ƒŀÿÿA„Å?ƒÅ?‚Å@‚ÄI’ÛUªÕ@Ÿß@„Ä@‚Ä?‚Å@ƒÄ@ƒÅ?ƒÅN‰ÄGŽÆDˆÌ@•ÕF‹Ñ@‡Ç@ƒÅ?ƒÅ@ƒÆDƒÇC…È@ƒÅ@‚Ä@‚ÄUŽÆ@ƒÄM™Ì@ƒÅ?‚Å@ƒÅK‡Ò@ŠÊ@ƒÄF„ÊAƒÄ@‚ÆBƒÅ?„ÆB…ÇI’È@ƒÅ?ƒÄ?‚Ä?ƒÄ?ƒÅ?ƒÅ@ƒÄE‰ÄEƒÈ@‚Å?ƒÄD‡ËB„Æ?ƒÆ@‚ÄI†Î@ƒÅA„Å?ƒÅ?‚Ä?ƒÅ@„Ç@†ÆG…Ì@ƒÅ@ƒÅA„Å@ƒÄ@ƒÆ@ƒÄ@ƒÅA„Ä?ƒÄ?ƒÅ@ƒÅA†ÇAƒÄAƒÅ?ƒÅ?ƒÄ@‚ÅF‹Å?‚Å?‚Å@ƒÅ@ƒÅAƒÄ@‚Ä?ƒÅA„Ä@ƒÅ@ƒÄC…È@Ï@ƒÆB„ÆC†É@‚Ä?‚ÅB„Å?ƒÆ?‚Ä@‚Å?‚Å@„È@ƒÅC‡Å?ƒÅ@ƒÄ@‰È@…ÅB„Å@‚ÅA‚ÉC†Ä?‚ÄA…Æ?‚ÄA‚Ê@…Å?ƒÅ@ƒÇ@„Ä?‚Å@ƒÄ@ƒÅB„Æ@‚Å@„Æ@‚Ä@‚ÅC†ÅA…ÆDˆÌA…Å@„Ä?ƒÄ@‚Å@ƒÆ@‚Å?ƒÅ?ƒÅ@‚ÅA‚Ç@‚Ä?„Å?ƒÅA‚Æ?ƒÄD‚Æ@„ÄBƒÅA„Å@ƒÅ@ƒÆAƒÄC†ÈA‚ÆB„ÆC…ÄBƒÅ@‚Å?‚Ä?‚ÅA„ÅAƒÄ@„Æ@ƒÅ@ƒÅ?‚Å?ƒÄ@ƒÅFƒÉ?ƒÄ?‚Å@‡ÆB„Ç@ƒÅ?‚Å?‚Å?‚Ä@„ÆAƒÅAƒÇ@„Æ?ƒÅ@„Å@ƒÅ?ƒÅ?‚Å@ƒÅ@‚Å?ƒÄ@ƒÇ?‚ÅAƒÅ@‚ÄA‚Æ@ƒÆC†É@‚Å@ƒÄ@„Å@‚Ä?‚Ä@‚Ä@ƒÄ?‚Å@‚Ä@ƒÄ?ƒÄA„Å@ƒÆAƒÆAƒÆ@„Å?ƒÄB…ÇA‚Æ@‚Ä?„Å@„ÈD‚Æ?„Æ?ƒÅA†Æ?‚Æ@ƒÄAƒÅC…È?ƒÅA†ÇA‚È@ƒÅ?ƒÅ@‚Å@ƒÅ?‚ÄîގýtRNSҦýšüŒvþùûW÷ñø„ö
 ìúP)ðëó	ô
ÓƤ»J—#YIàî²ÞÍòœ%ã­"6}ïˆSµá½_(¯Ür·H èz¥±§7'–¹æßå³T†çÎ~ؿ.kQ&íy¶´é<€5֔,>¸/=ÝGº+0a@[õÇÏÛp“ƒ9CKh©\g¬ÅÚ×Vĝªbâ-4FOwo‚*Z:AB¼ՙnNt«u£!q•$M‘ÊÙx¢RlɟËe¾äXêD‰’‡fc`Л‹®Ș…dÔÑjLŽŠ|¡2^Ì]81Ui?ÞEm;3{p¨Š'ó[MIDATxìA€ ý©©€¹·ï()«4
àOXh;;g:ÐtCӄ¦»‘’ˆÉ%ƒ€€QPƒŽ9ë˜%+æ̎aÌ:Î섙<³a÷9gÏÙãÙóޯê~U]õݯªüýÛ=}î½ß}ß÷V¬ª­:ùǭÍÙßÜ|˃O^:a/~¨֞zî³E›hQ·|Ö%}[‚–Â5×÷(§{g½ӂ†‚æní>†bì[¸q.ëO‹ÓÙûNT!ny7'V³ÓÒÇdg!MükÃTý٥ˆ7¥çç1s·"ž̙žÎH-ºñâʻ}tÂÛˆ…_ùè”E[뼻ºÓAéŸ#¦]y6d	bWɺdÚK½w{Ÿgüóçç<ðþš߭~õëëÇLNfۆ!FÝwmԌ¹ {g=üd>ºfã­e´ё˜ôN>urÆýçÁØðîœrqµúd!æt¥FÞ󧲂„Ý?ʥƾH1;og`·Y…Õöš̀:~‚˜rgٳ®Ô4B³ŸåEìXíc¹KG!%Ï-c ç%!V<ÂÊF¬B˜²VeÛJ<‰��Hzuý½yb@Ö$ú»m%"T4‰þ.,BÔeö¢Ÿî÷x¹›ÚègHÔ§¦Ÿ[áˆÚèçŽO]—Ó*ï
8¦b$­¾,A4 ÕäßÂA¥oÒjj¢ç­îî;)Ãúè3tûÞoÇøvïö¡}N4·x`'éW´:æE´Tøhq	ôê}:~Òڻ5@o|:->G”œì Ê÷gè4MY”F­ô½3Š sS>-þ„¨ÈXNUÞVû“‹’DêŠ{t»áñVªr[
çSÕñ$ú䆑ɞ®@@¡ª=ªºá¤éó:†,-±”.¤êz¸îd.å× €ú¥9ì”ä§‘T—%-§"õ1ðìvZÙÇ^øۜOEõ¸ëLªÀ_ïKÃ}ð÷l2‹áªÞuTŒ†¿S릜›áïcª„›†RÑ+VI݁Ãýá§êáž~TÌ[«ý_2"׭„UÖ>*–Â5Y“)ùž€Մ±´ãË}oÀúrÚÉÝ
«Á”ÒæÀ-¥âX
/£Ɛž3ÎÙRŒÿ“q|ÚÃ}º¤2°¼×a՗ŠÃ%ò)KÅ5u$}ñ‘Áð3êοç2ßX%RÑîM)§»ó@û3£ ¿k§2€{`Ñ¥»àŠÆû½3—þÞ=[•ǒé'ùÙ ‹z7Üð/”®ˀjØ2ú¹í ‚j™E?ù›a1ŽR/¸ `=¥k j¼ŽVÝwyŠCÒjä¨&¤Qšíú¥òyX̤լB„(ó,-ºÔBµ”Ò@—u.…äaP EÎGè„l¢E"TÅeRW´lJ¯A5¼œªù+Ñ)hѪ.ÆSðUBQÒFU—‰è¤ú‹©ª)…bU.…îI0«*Ýn¦jÑ*tZÂo¨š	ÕRW‹¦”þEe9
õƒ·'U¿„bÔ
CaÖr
Aõ.—",Iۨh«…â
i0i¥
»óŒïõF˜J~oÛÞßAéf˜ô¯Ê2!¥\F)y3ÂV:’Rî*(Ú)4À$%ÓKP,¡b#"°†Š_Cñ0…Ô3`N“ݽn9¥í^ǰe%¤SXs£ð
͔r†!")Mb1…óaÎ 
# ˜Jégotm^ý/„9WS©)™ÂäDêǔ®‚Tè£p6LÙ@¡Úi
¥ñˆؿQJ´9/n)»l*³O)ÌO@äÆQ™©…¹³…†´ÅùËԟÅÍîlâ»(¬„t”Bn-œЃÂ HÅòԞCº˺Ìé"
ƒôV®†¢Â˜Q¨ï‚'ÔPØ
Gì÷Qؠ4=3êS¸×gŒ£°K»<
3~NáHœšQ˜išÇô‡úölO
×Â!—RxÒq7&_è·ÔÛFn>žjyôCJɑ(LPOÆ|/¤yë€c¶ShÒ³<0¢‡¶TšHaó3
ÑwOo„òIÎï!m¥ð2³šÂ7ºR¸FȡÒ
H¾ƒcާp&¤§)Tˆ4méð
p̣їÃaB&…ó }GáӛÂ:ýÐöLø„ÂWÎ4ôïnÔßЧ¨‹ʄR
Ý Ý`hC%P8é#ó-€³)üүպÑ1Yú]ô…l˜P¬¿Ù>£¶ŸS¥ïNÎ0ÿœÇ+«µ/ §p³–Âhý òßaDµ¶^Cá1ÀHõ°Qÿÿ>!âŸַŸÀ17QX­¯Ï6§´³z@s­~øÐ#öÊ´jåö~Žé©ÿ¾ÿ…1WC3 ÉÇYu^8årJXi¾¬UaÆ1
WBšDa-’!oïmJRå[q˜1ƒB_ýUë
8dš~Òq?…©0£‚ÂYúqÞ\#¿Õ]ªÿò¿3ÖR˜¤/kҊጱ^׿½øfx䖺Š~Eu%…òþÆP83”TÉY>0°¦_¢°ŠjKːÞ€ô
©à€k(Õo¡…î<
ÿRB5…Ëနv@zǝgâ~as)ªiDÄ®¶UiSV%ëWÑáVí3”6ڬ§~0¦Â=6çtúD¨°•BÚý7¯îl⻡øŽÒG‡<НÍnaÍ˚‘™
jèà·øþtJ›õEŸƒ9žV›ÖÙ˔Z‹‚ɔöAñ”îƒAwSxŠ5”îòD^kÚd‰ædohS^@ŇÛ.*VÀfóL‡Ig'SèEÉ2*þŒ0=PN)õ~(n¦ô:ŒH¡,Š#TøîDX.­£bTû(lJ‚Q§hӑMh§"mÂPٝŠºR(fSúfyRè’EeåãÑi˨úª™”ðh7Å:@‹KÐIæSµªÇ-ç™i¥©Ú2¡ðŽ£Å-è”Ù>ª~ZÕ"J}aÜ\Jÿ„ª¨•ŠD/)~üU¨UP5SZŸãΡ´©ª'ʃçM‘Frèþ?•÷SJë`žçû7Œš7kî÷«uGÐÄÇ`q-¥¼ÞpÁJùƒañH¼Ûø½MI¼"ªÂy”ÖÁ
ÞvJ
)°èiŸw*ÿ߹•¶‰/k„EWJ5£àŠ~T<‹„×ìò^D†˜¸ÇDûóƒ7À%£”·Þ˵y3ÇP±l‚6ñÞFXŒú)¥Öᒫ¨hO€Õ׺¼ÓbÙMâ^%°ºU³´̛JÅYðÓ/pށô3o-Ÿ	«ßQ±¬®™“C)5!IšÉFHfçPÑ.:JEÎìòþ7~â¢s©˜7y¾¤âܢòN¢Æ{'Tñ§T¬o‚«*ó¨èR4ïÔ҂ RfRu-\ö*Uc’`+a(m{/R5nóœ¦j`†mÞ[ië^ûģ©j×íȧªW½MÞçÄØãÐ{QZЊlZü­¿6ïa5¶ޯhñ2¢â,Zœ.D@žÿah§¼E‹^D…w-VÎ;‹!™¿ü’·7"JŠ»h®˜
OW†h~‘æť¢z¢¦´{yÏcÈÚBHìë‡(ښ,oJOvÂսƒ&ž‚¨jÎ’÷5vÊä+‚$¾Q6-Ç6ïoHG@Ô=o“w:;íºý6‰g Ê׿}‹a¸ýlm⇞Ø8¯÷ïË+ºÄÏ!FœwÃôÊDr?bš÷3†íÂ&Äo"#pGÜ%ö>͈\Vgyû0BOÅUbïùŒØS?^¢¾…xñ"ѣ?âÃn:äićqtHjâB+2
ñÀ[G§¼¸Ð@‡øÎ@\XC‡\81ŽèR€8áéêHÞ3€øOÿyM%þ_òí˜@ b K„¢3?C×íÇÁ
H^]œ÷&q^_œ—Þľ7±ïÝÅy}q^_¬xûÞĸwçõÅy}±çMì{ï^Kœ×çõŲ7±ïM¼{q^_œWûÞĀwûÞľ7ñ]޶W÷Ö÷œó·ÇD€0À~dffA*"ð[½k’»~9oh
(ԵT>T¨ìFIEND®B`‚‰PNG


IHDR  szzôsRGB®ÎéVIDATX	c`逯ÆƬjjj­ŒŒŒñ@11˜8ýéï߿+W®¼Ž$F1“	f‚ªªj-ÐòR ›å e|ÌÌ̛BCC…`z¨AÃÀÄÄò9! Â²ÚÁA…Bbåáj#F0”œ$$$&£–5ð4õŸ
”¨ùÿÿÿ; üøñ#gݺuÏAfQ-(‰qÐrPú	âàà)ÈQâÓCÂfр8`7ˆ`¾ÑCÇ˖-cad×cc«¦wè„ÌÅԦ<àqJ’9ô`éiÀC`Ô$WF°¸CŽOd6©ii#€è€ùœ‰UµÑr`#î`3é1,aКF¶î`3i!­-†™l3L툰°0PR(Æ
§2ý
èûi·nݪþüù?*›=D@%RP3Š•ÊIEND®B`‚‰PNG


IHDR  szzôbKGDÿÿÿ ½§“	pHYs
×
×B(›x„IDATXÃݖ]ˆUÇçvj²%Ҹµ…‹´¶°„6‚֏ë‹Äq`æÎÎV\?߅
6RD…"_ê>,¸ìN"bQÈ>è¢OV­•6«üq+.º»“ÌõÁBÉÇ$f_<Osï=ó?ÿ{ιÎ6º˜ã8ûr¹Ü#ÕjõCZ±XT™L¦˜Ëå>«V«|T§M­õ}J©ρS®ëæ†%P«Õ<cÌsƘ/|ß?‹€ÖÚÞvJD^&x>ŸO'›ËýFã}ÇqŽö$ µ¾X¶·ci­
J N?ÜжµK)Uñ}GZëC@lë€÷2 qƒ
…´ˆïptm£Ñ8kÛöؕ˜vv|Õó<7.ÍÍÍg›%ìdG,Ëj•æß[yž÷°1¦Ü÷ÛT*•
{9MMMeêõú
0ÖÃ-TJYXX¸¨‰¢èDŒ‹\[[{²ŸS†/ô	°=Š¢g¤Ù`Ë1³ûk†ËåòZ§CÏó²Ƙ/»ôѕ¶nYÖõ
°hî÷€FÚÿ|+†á¢µþØ㇠¯Ÿ“mÛc–e}("7ÅÀ<kÅ	."¿$‰ÇÛ÷|ßßS¯×o‘d2y~nnîO€r¹ü·ëºðu7¥m™1樊“+cÌë­ÍZ?Úh4¾‘
°¼¾¾~ÑuÝ{[ç¥RéB³\ý.–‰E@)µÔúžœœ¼ËsØÑæ²WDÞpçº6ÒKq°-àR?§z½þ]°×%µ׈ˆ¼Ò\Û
‚àÆA4>Š¢½"Ò-S»ÛʰôÅVh"Òë™}<(ÞÀÂ0<
¬t8zgqqñ­-'ÐTÁÛEä5àG fŒ9‘J¥ÿ{›™™ÙÑmþ+
Ɂ{jÐ!³V«þ2Ƽ©”ªÉ(в"âïAðĖp]÷19Óë•·Aðéțжí"r²ž1æԖ¼˲Ž»cèÄ=®ë>8Ò4֯€«bâ^Z]]ÍV*•QeàÅ‚z$ÐZß
|0ċ½lŒ9T*•~:ÅbQ§‡”Œ´RêùÿT‚•••[€Ãʖ1ƞžž¾º—OÏéµZ­þ”ÍfI‰È ®Òý¼
èùùù?F"Dù|>‘N§)¥î4ÆÜd€=Mñ¹\>Š¢hybbâ\±XŒâàþО/„iÄN¸IEND®B`‚‰PNG


IHDR݈pûPLTESSS¨i'ÿtRNS@æØfRIDATx^íÑÁ
€0CÑpbFéhéhŒÂPÅX àâ
ùK9ä]rÎ9ÜZ*Þznû­K‰)RN`ZzÊIȔ(9µËÐově.óW4¥ ƒðvIEND®B`‚‰PNG


IHDRV@AW_±@IDATxÚì{tÕ}Çw»«ÕÒ,ÛòۖÃÃ.\^Å.Ž¥„„òø£vI)à4 §é)1!BO9-9¶0y•ÖjNJhBzì<hNÛA¥JClCjêGŒ`DzY#ËZíÎãöޙ;«ÑìÌî̮,­´¿¯Ïxwçy��ùÝß}J) P(jü$¡	P(
JB¡P-Ż‚2îùx÷‘öq¹"ÃE”B›D`‘I!	jÙåT
f߇Ø÷“†	o7‡GŒŸÿ×cËßï´`è…Bk/hƬëî=4·.)odg»‘ý\5’1ã]\ËuIêÿ`ڏ²LÞe;<?¢Ñ'SgôçûvþNÙTD°¢P¨)ÖOt^S“þR7àڳC᧧ù<Íý >Àóî¯*’qé]æÍ~+«™;þãÑÏ XQ(Դëu÷¾ª.)=–ÎÐ+2š9>*øÀÖíµúíË=Ùdœb?¿9ҾÄ<Ø‚…BM;°þþæƒM3äºAîHgLbsæ•–VÏþ°u5rV§ÞûÈÏ XQ(ԴëÇï;´&—ž:›6çS~\~>Åú°ú……â*áË7OœÖ?ϼW
JB¡¦4Xoºÿ`7+ðÿõH–ª!’–´0X}aIC‡œ}[ÓP+÷
›×ÿ÷חÿv2ÁÚ}ÿƒQvobK»ëwŠ-}øH¢¦ª¶m} TR;֛»ßøšfЭ#YSÍAŽÿG&þ0ÙeOíµ	é•5Ÿ;xÞ²=‡ês®e>ŽÓBž&
Áªž`^êݯ ²‰jy–/9‰ÅìÁacI\%/1¸ž·5	â%}â%É?w¢I¬¡tý~ñ•tƼÃ0M»°/<U:¹LÍihĜW¥g¯¹û`+ÞZÔk½ÇSíbKšÁZPûܫŸ1ó:ƒ*µ`:¦>ß­9ù„JK’	é™öMoÄñö¢&Øcõ
J`
ÖÚϼ²RQ¤Ç4ݴKü9žº`ênà!à:>»øÃõ¬qIsƒòÞ^Ôª×ó+#¬=ÕXMRýq:c$˜Žê

O֧c@YðŒHX¾{:cþٵ÷ºo1j‚Ä!ºAv7[:\QÖ|-¾`鿩ŠÒ¹â?ÍUZå¼V:êµÒ\E–t“Ð
2¿mßôF
ÞfÔÉêôV¬ºý««jkëæ,šF63¶ÄOyS'3R:괊ýh$Ç3LûҨ|>›16ÖÊâmF¡P)¥ÐƺÚÄYH¬¶ZZêáäÉ!b¢NˆŒ¥µš]Ùë­&­Äq\É׵>nÂE‹c°`–
Íõ2Ô'ÌÓZֈŸԵ_ɾs"£™”ˆsûhþ›äàk7˜•œo儝bíaÅW‰ª
¹õæûö÷<ýåUoãíF¡P“
ÖÛ;µ,WVj†
­ÙKCjà504Æ45‘åé0–ÐÑ!£Þ%±ºb7^ÕW]<ƒè¾T£ø´Šì©Á,ì;‚=NC†ç%"Ù»¬Î]H±€Ë?%¶’wøâÿIláëø>²$޳ÓSÈ=Oloãußÿ o^Óùµ¿}b)7ÆÆÏÛî9Êuþ(òöôê
Øo½çzý¢ˆ;Ñé
›f¾½ÃÇþ½!ÓÛckôK½wQzҵùظ?âõ¼sïdۑå‡<;nÛúpUƙ»´nê9ӫ(Ê:·Ùz÷7ðNÿ»ÌkM€¤¨659Üù(w#ݿ٩g$)Üõ‰&Xû»yÅú3iM¨¯áð›°3g5xæåpä×ikÔ"ÎK¬ïHdEY’Yz$k½“~{;‰ª"¿?œÖænùä‚l¹]ZÅÃÓáÚ)ò‡«G,~ã9ÏÃÞé‚[—σž̸=àÜâz—¹2¾ó7müfC}bßB™6Œ=R®ô¦JLs§+£;ém+p½qMïõœôê!Å_&Ý€Wè~zÅÓíîi×-ÒEÞ™T²`û«	¬k\•¯1\uTü¶5/˜§Þ;Ù¬µʆ+µŠ"»3>€øQ‡î˜sfÚáƒ,ƒè‹G^9JáÈqöÛÈE uÀʅëVXÒÂ`[«Âú·—_?/¾6hÓ{£ 
‡)[$Y΁Ôòd©SaE`Ks}C⦞WT9ðv‚›EðÖG€ˆów…ôœ}K©nrgW̑*ò÷í‚pí5›Lx&ÞTâ½hçÙ)ìZìz[T6@†=Öy¹u”‘ÖJքۑåM®»«¬Ÿþ»n1ĽïG^ŸwþR8úú05Í™¤ª¹0€=
º…M¶޵ëmøîe·ãÛ/Q8=ì*Ðþ<þÀ1¶<{€Âêó>µ†@KÁÕ+›AQØs8ªªæ<W' ky°¶‹jÇ\%Çcµ¡j…Ø?E–þ¤œÂŒ.(­›âî2¡ê.–¶û@݁[g‰™k_‘EPQ°=z=ékòdÔ]X=Ó엡ÝEn¿°ŒcŸËÄgPºÉçåâ\¯¯„¢z%kRìÈòP_µx®¾­˜Gx—I¨Oy£vF#4Ϊ·¡h0¸:ØUW£ͮjU¸­5Õï¿Badz6TÔk^b^í–]ŽŸ¶×^¾¼–/N0Àò"¿lÅPeÙñZYñ_ëœmŠ”Xß.‘5O¼˜‘J„j{D8:ÙÃBø"Šc—‰¢Ýîˆ`mwAµ_€Ç9_§XšÅgŸOQ¯£„̵Ë=§øÛéZúҺÍ'4᤹Ó'ͽ>/‘õӼÅuL¯°M³ëZËÄÒë“Þ}.õï˝Vç\Û<¶é¤sbG–øRMvŒæ±*’´Š@Ÿ·t	|ðþÿ²ï²å¹î)*ª¨¼§pËGaq«Ý|ôG,[þd9h0aú€­И¸æâ:8þÒdM)ç±ھ*qB½¶§*Ù눳= `èWÄ~V‚vùùCÔW-µ¢ÆyÐ7(‚;±»}¯¢ÂU4¸3W“+ÍÝŽ÷†CúŠ„#zÅâõÈwŠõ©ˆ6êŠ=;öi÷@¡XZSÂàÀúכªë9³£¨°êÃhNg;†÷Xo|X"2i,4°Šœ¨Öùsr±W, ºfÐ:ƒÀM״X›¾ðƒ=´(Tƒ¿>5ðøó"æ«X¹Tµc­Âcå1Vs•ÅoEÄ]e×vYx²|aý½CÞbQTËUªTÝûm÷ñZKÉ\}%´—f™ªד†®ˆéîwo‚ÂaÒêçmM·¡'Ŏ¢ôW}`•ÁXh£5Œ®NUc`8sѐUbumµº	˜®†»|œ}øw^5 (T<äýoSxí×ö÷ãìÜԮ¼²àiÅN8%Òъ-9°¿+ª|a	6ò«çAÕyˆSöõeTm‚h_>éˆ7Ûîêsa£Ýë¤5åó¢išfyÿœÛQx®ÓݎáÀ
`žW¸‡”#‘aÁÒE®-Ċ·®¾Ď¿>ðöÉü8m T©ߵì•ÿþû“ƒta³ÝÔ* ²u¾;ۉhß*b*ÁFëC¾ÁÇC½÷ï/Ókí)!l±>DÆ+ö7ºÓÝ1Ýam”
ӔjÛéæi¡'¬ÒܰϘÕÂ{g1o•á˜y®³›˜7Ë«eï[ùc\…ªÔ_ £Ûßg7J¹
,IÀ3XI´ouڰæ_qÄ0@‡Ï[¸¯��¯¥ï½ÔœúÊÈlåؿom[éB;N$X™—X¶	=o90ÿüű8ÌÎIŒZóDyPu7ä7¸ß:)`^KF㦲Ý+hž.šÿ».¢}ÚÊ_¥¦@æj§ÌÙW伕d£é(´ã„{¬„$(Q(>ðI<Y-sš­Xkcƒ:zç†=¡ƒ¡J=çK¨N«¦’¬šèѐÊi¹0Þj«P¡·Š'դ’Ÿç´ð±ZÛ°bø˜áV¬ð€·UA©Pu{¼Eü¢ުåùê”àY^flTՅ†¢ÎaEdæ.žœÑsëkóÁ\ª… <CŒªšÑÊú{‡𖏫zÑ(T¸P0Û»4Ïk…A#wš%3B	 J\Oî¥.id¡c¼ְު,öL™öÂiÇÇhÇòԄ&˜j`5Íã¥Ì6Åb‘êgCJx­«ÿxB@ñß7 ¾,ŸŒÙßO-½4ÏN÷›)T\®DõŸ£ޏ¦ÅӴ«nң¹©|?ZÚKMcì9tÖÚÂGªšßä-à¥úõºîb"˜ðÛ3r‰ު¥#eføj ÇËíVôX«
¬J,þ«Âc–·à‡í¯FDn½’rZCAõ‚V€«D³þwN1ä@¨õXMz(Êþ۶>œ×k¤ZºäÈ;t©]=Û}Î[Íj;Çû£&¬O~6iš&êÊê,×~LJb°ÿ-jÅ.[ʽM z‹þ~På`ßýQ{M3áȀlœž"Þ*oïúR	6òö,êªògÆk¨#Tu@þÕV	VN	|§"X¹Ã|­<‹A÷Çû‰2˜¶á¹q55†ðR} úÅÌi°¿ڟ…¡¬"ò£­Ôuã¬$K{K°‘7ÓwU¹×Úã“ɣxPÞá·W¡
S>`
kÃôX§(X™ËúýrN:8ðOÿC@7í¦üŸý®æ#TÑ0€ûÇE¾òG>4[¼Þ§áxºÖ>&l\5?ñŸ×Äõ¨˶­û
2ò\¸N·LÐçñZýÆu
ÒNÈ«§
óßÀÙÛB†Pv!¶¦(X¿óÏ<<½œÿò87^ ¹>þ<$ðøí6\N`^S>õ1€+—<x#‡n&Ð"úH½rpúO«`P-®ê­03é÷Êøs¼cH6	¸nóOŽ…CäÍŠÊSAÞ±œ»
xYÏùlï†êmyÑãR	šæÆ$ú9ñ=Øb¥¢8畡{E¾:ÊɼÜ;tà«?%ðÇWRXØ̊÷	öô|˜/†³gìšþd€OJ ¹êºF²~òó4~7+WÌÝ(-@í0 Sž.ÕH¼‹ÏÙcgpö-b@ßj+Êvº2ºã™ï„ÑkÝÐõóf»«Ô[uƒÕFY/÷¬­~ӤtÃèœ\¨©â±r难Ù0̂ÝY5Ärô^ʆ뮽ĚÓÊo—ºx&ÀÒY`ÅQ¨f4^8¿Ù=?íKÃÅ4EƒªßvJÿaãšøH9†!¨c—N÷âlÐÔ-®¥ÉÊ܎۫Ü~…osٯͧ´PÊp¨JðX¿÷ù–½w|ãô›19¶,êI½EvƗüì—1˜ž7`n…ú¸
Ôa杞b¯èw²ðï0œ6Ù1&\¼,g‚µ$Ušçy(ªòèx‹Õy§»…§ÚÅ㊻az×x;Sc‡™ى§F{º¿œxþÚ&<Ц"îv—íð_Á"ÞZz÷|·îX¯I¼ÈÇ:oyákèé4O˜|
#°z6h&)	ª4çyk߸s]Ýݣץãö7ˆ
,¿¢®3ïUµ=üm_݂Òç«6u€ß)ñ,1Çï`°rÝöµ÷_fp½z¼.T«od3`hºõÃ0t¸fE“…GÈ*U-«ŸPcÊù×Ä?8`E¡P(?:3œ¹^ÏdËj!ÔæÕ›¥†Ý6ˤ&ÔÇM˜Ù\STMÓ使îuC…B¡*¬»îŸ{:›պLØzêx‘¦ÕËìÕCÖ ûƒªÈêÿ|çºÚïâ-F¡PV®§îõّì¿òy­Â#S¿a©å]Ú}U4$kâŽÔPei=KÄîÂۋB¡*¬\߽gæ
z&s8J+ý‚M±\8XùԃzVƒK/lÍ(ªm@’åë7®‰ã Ö(ª²ÁjIM¬вÙcàÓß?T»ր<Ì`.YÆÛ_IÅçÚ
€ª–ÕeE¾îÎuɣxkQ(Ԕ+ùjøÌðÒL&ó¶…Cb ­5g¯&H¦Kç×[ã=—ñÿ$óT×~zmͫx[Q(ÔÔñX™~ðÅùIM´éé‘}yZ!ÜVï&«5€iÂ+’ Öç'¯øIgŽJŠt5B…BU‚жc-¤[wœܡÄÔͲ¢’%÷¼
º–…HÃÚ7C`£®/•7©bžêÉħ6®‰‡šÏ
۱¢P¨Š«
ׁլþ#YU[$IŽ4[£–†ÎUµ ©J$/•WR±´Þ×ÕY÷D”ô"XQ(TŃÕÑ-|9¦*›%UU‰"Â.kè:´&3péò¹–A.®³*›ÉfM“~;Q€y©‘»ù!XQ(Ԕ+×Íկ&¾.«òÌ{­‘”À1^øà( ŒÀõWփNIA ZžmFcE}úd¼&ñ%Ôc¥¦JB¡¦XÝúä#·Yz@"҅’,©6dGjè,Ÿo¢Ö$øuêÒ8x³ú0ûú;þ©X\ý!jºÜt!XQ(Ԕë˜0c'/gg½Lz)cëBhÕ3êÚKêuFºA¶Kš2Ā{‚Hä(Û÷ ¬({Ԙ²§”éT¬(ª¢
B¡P¨ò$¡	P(
JB¡PV
…B°¢P(ªdý¿AãèÐã$âIEND®B`‚‰PNG


IHDR  szzôsRGB®ÎégIDATX	í–MHTQÇç+u-Z8’2PŴs•A‘&3Mm,ÚIHË"ÆYè:²v›šÑ÷B‹
Šh‘…äªRw•.Dyö;ã½Ã}3Ž8;½ð޽÷|üÏÿž{ïyÏç;l=þ½$ ¯¯ïxSSSO ¸º½½}ß6å¿ä÷û-˚ÝÜܜžššúU/n]R©T²€öÓkC¬„~Œ>3>>¾TËVt» øuVüۈ¼ÈxžGLtB.¤mè×ÈÈmHÌ2װ&‚ßô	OَÀ Œ¬¯¯O
…¿&ZooïÑp8܃ì!æJgá3˜ÏçGM[s\•€ZùŒ€Hˮ¬¬ÏÍÍÉ꫶®®®Pkkë#Hdqaݨ–	O²ç¤ý;Q"™þ«ÈW꡸ICüJ‘í8íu&¾>œ²ÈË{.+÷
.7"N'’ÉdÜC|ÄWé"
Óeê" ÀXõ‹%’v—‚–––Kt¯ƒÁà/½ÈÄW0”¾_aÛÌ]äžÃV_µ‘Ýö܆æ˜(ߦ`;L|.RdÄæE9íN‡½Î	<#X⧱MŒ¥ÂI›w^µñÞ޹\î`‰—]q@S)¯«ý̂eCq’‡dlR&¤î
:¹‚ÒVK¥R÷ÄÄÄû©í}Ž›pÝ›´ÎI€
a«¯‹—›g𭭭ϤT‚žbo?Q;F¥z «šÕòÔ ±J¹ìµòÉÉÉÅbñ<ú²µ
‰JñDîЯ‰(R2ÇnQËu_9N¬îŸ§z}ÐÆÎ%ôϱíàyþDž%‰vm+ß—?RàÍj¹î+Lµ@Î`ƒ<ݵ‚k{³ç,\€@Œ"8&rù.D£ѯ‚¥Îq$íÿ)ãý4p2ÉÄî9ñ*[`*œÁIéYS_ϘàiV®o×ôØæ®K®MhNdK¨÷ùX,v¤¹¹ùíòò²eêcI{<Lð§<’a¶ÞJ²¨N[™{n6$øEÆïxʙbrЇÁ-¨
§M}
ÿ!ÑȬkd ÇÜöK‰oú­ìäž7þ—L“à3%ýYæw\sÛ Õ؟RMBzùž7ú·ÜÄ?Ìü‰9™Ë}ÃIEND®B`‚‰PNG


IHDR µBñIDATx^½–ËkQ‡w2IÚZk-ânÄî»q'¢+uÕԊE»qᅨ ¶M‹J•ªpa)Š¥*i¥Q|”mMҦÉ4™L昙ݡ¶Iüàp¹“!ßüΜK"ºº„’Íf›ΞXxâd3L*ہǽH&“„§T%"¤2„L¶8aЦ¥åÂá®ÑG½MgZ%©ÊmÈ–u³¸„Š«Cz·S’*Dâ
UÆÚç¥-¨ = %´t%†¥ápؑ”²HªÍU
;ýط;PXy"CDŽ
…B+I‰ÀCcùÔnPP¿Õ‹Š€à=ÍfOÉ• ÑÜBOO÷hä^g£
wlVáÆöüõXR‡|$ò_/„£œ°€µnªâdð«nTj*5gÊLÆÀác§óŸ+pïúð$r¶¼Ê2¾g|*
ëh©¾ –séüÅBXװ+ȲUòTç(_Á¿J¶1ٺ*ºA˜šÕùþµÂB€=ì{?F¹ 0Ò;,'vKÙIå–ÙBËþ?Š¡Y~ŸøŸ-RKÍ2âú4#† ¯uz(B]Uæz,@&¼Ș)LÆ#øèg™EP©Æޚ£Ø_w
•¾ZW™ç±0=|ÓÚ†æ®@ËÅ\$‰‰…>&žâЖسñˆS&ý{èÆX¼ý?Û%™›xpî2†£ÈUb!qBâ„Në›X7&b-LæÓA¬kuõÙ	Z©ñ…û,[âÝbŸ–XaKÀB8wÔ+ŒÄo­Kfm^GobÉøåœ·¡I?ðâ÷U´^cP/ç¯ãø¶‹™£¥93‹ç󗠛©"d6ßÓcô99XpI-H<@TÿR¬ÌÑƑ…ž`9ÿGÓ3ya_)eŒ–‹b8~úh'|6s
&%”Ù|M
a\»
=§ñ^´µµ“¦i%–ɐ TTðŸºV8…3áIEND®B`‚‰PNG


IHDRr
ߔcsClÁ0`M¯IDATx^•ÓQgäPÇáw3Weo‡!ÃÊÐ/0„Ñ|‚¥,ý"ÛS–~‰ÚzWÊ0��«a˜Û6çœýɾœLŽé^<BþoßÿœÖw¹¬ïþôýäݤõËGî!hwÜBú¢oÎI˶nñ¸ـp£®Àw¯;EQH‘ºс	¦Zº
ËWxÄTwÝã¦+ñ˜@Ô9V/Z!Ç¢&xÐ
»>)3)r\B@Č_6Rz<c+Ž`„.(p‰±\4+Nʜg‹g
í‘0ðCSähK}6Ñl
	xA†c¤Á
$`®×&• ÀÌŸi½`CN‡-ìJ³a©ó´¥•;gg0ïc~‹G(ôÈH¶€r{%^i»cƒº,r}à€[È	ӊ٨-2ò¤C9ÓÈ)³G†4;Oïa?2£'·Ç;/saÖÚ6؃¬OOh)ëJ_! ó9¨Wk›
öˆó|6ïrƾCÎ`æã2Jçô„MÈOÌÌ!g´³˜C0:鑦>#ˆQ8cæýnœ‡Yý{}ÌDÆ|ÄzÞc<aa̻w¬ÏϘÅbÍ<c…1
, oJ(³hp×1
,!P
”iސª7ÍÆ,uWÜÛÓûÇ'@Ž¥#(‘¢V)e°Ô4Käˆÿuè7Ä9H@‰5jˆª-ïPBäÚўpî»I %RÔ#§¨5+!	
Ì"Ž9á'Þ7sž
©>É}Î5‚
©>Êt,‘5&øQaÍLiÙөàÏoˆ®H¯†«úHQATï]#_T!Õççž
)j2‰ôȰÒöim5JWþ?J¤¨uO
v۶‡BB(E‰T•sX4¦Ě‚%DÔ_@ëqo°¾˜FIEND®B`‚‰PNG


IHDRr
ߔcsClÁ0`MÀIDATx^•ÔAg\QÆñÿÛ{7!«RB(a(eh•î†a4Ÿ ”ÒU¿V颺(ýá2dJ¡”B	e¶mç>5¯‡ã^s2ͳ™ÅÜûþÎûÞsNûüý@”ðâ8@b•<#˜Ÿ(¡
)A›À/àØè0€uNŒì
Š7ÆàQ¾‚‹ÿ€©ß}„À5_D	¾F|NÌ1Ú%ŠÑ ±Îïb°¬½¾¶¬õŠÐgT0TP"Ñ9pi‘Jž&Æ
XPXµHgHçÀK¶EY`YPհ¥ÇXËÆ8kéûqGñ¢2¶2Þp§ғÁƒmùi¬ZzA°ÊbF+«<0:¾›{âάAËڱ" E=Îʫ8AîÐ
×`'cFÍsŽ;sëe²œ¿Îg©Þi†Á¢˜‰-\“­ú5Î=٠bC޶ŸÑìLÆ	þeˆ[£`
‚±PÀqÍ¿{+‰	öµ+cƒ.hJI”âÂc¼Ýò¯Gªu
£ ¥Ï¢šK۾‰<Ò~ý§
:{ }vg_ÄÀvƒ¹iT§þÝ?Ë¸®M£Åà|àÈ2N}i	ÄcÊ9½ÞÚá:w©ŠqèΎ¸ŽŒÎnšr¤þ†qg;°&w¢ÁŒp
@¨`“êæWbs­¡"<^£’oš2ÆΫ¦^¡jçºkôЉk."QmŽÅ__ÊÑùö§^3dH8˜QE×씝êç¦Ã`©*†1w6Š0¿ë»ÍñnîÒ¢Q9÷\ƒr›$BùŒÑљ}€ƒDjZõ}®PDK¬äJ¤á³FÇß^þöޥ܈²Bƒ¹Äj	-ã5êry‹(‹Ɲ]±3ª}ïSð¢e½ìD£±ûsÆuø{ªSG/]IEND®B`‚‰PNG


IHDRJ~õscsClÁ0`M^IDATx^•ӽKBQ‡ñ›EXQD&H[CK´¸õ²4µE†€¶D‹ÔÐØ´õ2Dc9ÅCÑP$Dm‘´HP’ö¢aAŠz‚Ãá@ÞS(Ïö½÷3ü†c‰&³ÐÑK;N	ЇeLƒ¶xEPd7RÄþ䨑$A	Á)NƸ&üè'KŽq9,!œ3Lœ3ˆ#ª!‚2H†°\ ˜VGß+Pe„ŽŒ@þôÉÛdxY¡B›	œ l•	±I™(]v5€~Ž%}&BÇoà¢`y¼¬iþÄN
°˜£Z
øhá‹4
eX¤S,fy«#¹·²Jž[…²ø%ud;
鑱I½¢€nˆš&èW< xÑ@çb†	*xÑS|“ÀÖB–ÄQÿÍæYV$dÆxǍíÅÓÇï6
F¹” fæÔ?û¤)ڀh²òdsˆÃ(>IEND®B`‚‰PNG


IHDRJ~õscsClÁ0`M_IDATx^•ӻK‚Q‡ñ7‹°¢ˆL†Z¢ŭËÒÔ!AþbØ-jPCcSÐÖeˆÆjŠ(Š„¨-’	JÒ.¤¨'8ä{
åپœÏðŽ%ÌBG7­8ñ2M–1
úØàAUÜxHûŒ’¥J‚CŠNq2Ì5á¿@/²ŒÈaàœâ$ñ˜AAP
„l/iÂfp`B}¯@…A¶80ùè“=6É 4ð±D™8AØ*bQ:ì jEIúL„¶ßÀEÞrøXÑü‰9œ`1C¥äñÓÄ)>J3O»XLñVC¦åÞÌ29nʐ@ÖIî4x¤K~Æôz¬€®Ÿª&kèW< xÑ@çb’	ÊøÐã|s(­3„,C̲¨HÈŒ)ðŽۏ3¦߮q)AÕ̩;êvIQ°Ñ`?iˆO¢öi#’IEND®B`‚‰PNG


IHDR``â˜w8csClÁ0`M‘IDATxìØS›ûh†ñ»HÞo3©ƞŒֶm۶m۶½û=öl}¾Ÿe¯¬1ž¦ûoúÜ×õœï¯kM)¥”RJ)¥”RJ©K¦™ž·Ù2\\,ð!ðUޗ>Ϧá’ôy§ϟÿ«وƒŠ>ÈçA¯#‰8˜N7äsR±ÀÇÀW½¾ô}N¦S%‡üçãF%‡’u·Ì3Q*ðž}I„÷ošg’,›
9$Õց/ýQ4r(YÖ0œW€Ouàÿ]z.u—óɸ·uØ+î] ï€4@€4@€4@€zf€&h€&h€&høïL‘§f-GWn@‡çyu ÂÞ-ô_â	tpÕ2w|»/૽ð&Î@‡fËÜwá$ƒü­c‡‰=.@ÆÊ<¶kY–(±ö¹Ü.€ŒfJ<?°+Ô2L¤H€"‡ëªiŠ<³ÙÛrм[u8VîË=©̄œÜóa™‡=ÆFöNµlæöún}jkbÖÐ1ÃDÃõ4ÀlÀñ?ˆËï59EÞÜè—î¡-Faí%–VìrKOŒûœ}ù!ëÓ=ˆm™{Ö{[éïûIJÈj†ÓwbOôW¸j·:5–èòiÃ2°öº/övfƒ}¾'f¾Êñ=P-sרÇ+´Oƒô_ë£k¹½†áگ²ñÒï;ês^îüOÇc¬¡Y˶•ÒʿŒb—[.œ¤	›/±Ôk.7æ`6äø緥ÂöØ5ýˆaé/ÝûwŒ™¤µ¶̃¹8ïÈa,ë¬Ჯ[äõ¿ߖWæ©р­isŸìÙ:â¨ÜÔ]®ŸµÔØ@íNÔçrë·U*ð©)r0uô0ÁDÀY¹¨:Ü7P¡Å&ºx’þÈá.à«f…kޞˆK,qÃp].vˆ8ä§ýpØd[GÌmsô5&è@-C3ýs×Õ³!'^2‰GöÁn8;Äڵéu–]kXº¸£†ð§BNï:€Øá–˜45
Ww
@Pâ±>‡&9ªiˆ«÷tÀö‡>±5.9êí]qv©qà0c9íð!<rØCx‰åä-@€4@ÙõK{w, Ìß:Œž
¤¤‹‡tñïòõÃÀÁÀaX˜X˜Ÿwcec#½êz {LIEND®B`‚‹µV]oã6|÷¯ط\4‡ÚúdYIؒ*ÉIýv²DÛD%Ѡ¨˥Eÿ{‡´œ8qZ»äƒwgg†˕º Wn•X­5}pÏéã—Wt#åªà܏ñ\ÔZ‰E£…¬(­rjjN¢¢Z6*ãöÉBT©z¤¥Teݥ¡×$•ý+mPJ™‹¥ÈRƒѥTqÚpU
­yN%¿‰½N5~qà…|Պ2YåÂ$ÕÅä•\Íú²ÿŠZMr¹ã”É‘M­Iq‚«AMò›ÙjE|UR‹Œw!j*€g`žËZy/9¡hV¤¢äÊxD‰ àž#;"Й7 ÷ÿp¡­Ê)—YSòJ§»Cà<$ö•©æJ¤Eýl¼=0¼/c×É-‹)®“{'òë0
îØØÓhNNN<rƒi8K¼¨KÌwûôõ«#ð쌌Ÿ¹ñ~#/Ž)ˆˆMÃ	C>#ÇO˜ÛÄÉlÌü›.f	ùAB6e	’ ž9̤ڦ^äÞâ_gÄ&,™۪×,ñM¹kÔs(t¢„¹³‰”p…Aì‘Ñ3f±;qØÔ÷	$P˜¼;ÏO(¾u&“·õÅ
ü$b D1<ÐuFˆµý9€#ÏMLÆóʅm 9éRz.ÃbëŒYN4ïs{¿Î‡};Sç*?ü»?VU@tüـŒf1³ò™ÚÑ,LXàŸÓmpq¨áÌbol}
|Ëþ‘='øi”X'»tëa+2ÎX½ŽC·›쇡$lHLþ3Sò½›	»ñ|×3ºg±wãYlضø½3§¢P1n-‘­׵C욜ñ3üÛxœeÌڣǣxæ޶¾™t:ƒš↦æ*i%Ñù¸–䮕,ES.ˆSåJŠ|r>ø
)11«‘ 0³´BpñHµ~Ŀ_Ò&ò{+¿˜‹„5/¸¹vµE²ûôgÇ\È57÷|HŸ~Ú|ÿÜù«Ý{|ñ»нÒìíöx•²n†E>øfó¤UïAäz½ÿ"­6|§˜+‘‘‹vu--¡÷;ejѬú™,W—?_]ýا°à)f.«3MÙ:­Vܢá´ÚYo,®›B›ÙdÇùÄØaâ0ôÔ£kHk‘ç¼:IMZñâ˜6¨uÒØr;B·ñFz;„1õ$-x»‘cfîøgRñÁZ—Š^§¹|؎qÛýl³yq¢Ņ¨xï0v	È^-þàCºüÔöÂNœ¨0š«´x-ÏØV¤½,­uÓY£e·bªþÇ>ÓxuX¢æ	^”\³ú0ã}ž5J¡Ý,^ï
«ýVÎûª[ÅK@«žZÿí¬÷10™íYíî½Ð#¨e£ù‰¨û¡GP—MQԙâ¼:û0á©Â?õø^o?£Ÿ|·¹*dšŸŒþ:áh…ÝX;¹Âë„Α¾“+|*ï™IÏsˆß؏ƒ/'Á&Ís4吞FÁÑÙð7¼¿ùé‹¥“ÛjÛ@†ïõCBÀ6^[rÅ6…¦n
ҋ¸½*½XiGҒծ؃%øÝ;:Øi›Z*ÐüšùvNšO`cêÆʢô0Êưˆ“Wð©DؔÖT2Tp|i¬›uRÐ9:°èÐîPÌ"øìL¾”œ	6CȌ@ ³0;´¤
px»}ǜo‚’j
ó%÷q
)¶¤Ü-@jÒ>Ünn>no —
g“y	¹ûR;¼>aR{"sżåÙ=sXT¨=KCž£•º8ù
O„dƒÂD°ÜK£W°Œãʭéײ´iD.`ÇíèEزʌ¥ø(юâYOáð\Ð3¡÷1¥žK-=NÛjTϥúKêòj򂺎öÿ܅•ö%39óM£Ÿkʱp&PñfW—mKþ“~þúò<èoî±É-¯ÐýÔñ6*>ƒ'P˜û$q|¶†=‰íÛQîÅßRº)ݎüA=	3ŸL"˜À6³!M©2hËN}ª´£ÕÆÉ~?,Uâ実@ïr`mÛ/+üŝ§ΨÐ Äáà«ú¡µûb.{#5ޛêùcͅ Lh"õ$‹^45Ϥ§FÒ~tA4Œ¶¿Ê
NßwWϲ‚za¹Áu…öṡ$s^IEˆ;CGv‡EPÜN{
ŽkG¶2?†8ùˆ„¹è)™QÆÒyqwõ…xZæÚìڔ;ÑãE–\˜o¤НPÏYî£ïäßñ›q‹mPÑNã0|ÏWŒÔ"œ¶׊ðr\áéÄ ñê8›Æàؑír¨ÿŽ“"Ž•¥•g4³;»g'X›¶·rS{LÄ3–­p_ֵ5ì\v¾6֥¸T
£ÐR#»¥2<8‚©àkéàLgA˜’àÆlÉj*Qôàø}w•8ß+‚’‚t°ùš{®QÐЩ2.!uà	nÖ׷wר¤¢ôä,ŠbE•O¸µæå4ŠÇ${„·`®½æÈ.¢݁n»ùO˜ÑQÓ@æ˜/Û׋€_déë?üÞeôx˵«Œmr8Á=N’l:ªƒ"~êšé¿LÏ;,•#fÙð†A¦åBú>ײá^cÅXã0ú“¶Sá@¢+¤H
ú+ÉNXzÎNÁR6ÖY¨YøOÃÁ*©¥§Ãñ¾ÏlLò9$)Iñ0z¹jÜQýü¸>›/>¿ž©¯,oè0éàb?ðöu;치°érOgìˆz½¢"ø¢‘‹͒‚0€ï>E&g¥ê,,xØ7A찬µí´Háí
àèe^š¦ùòµi‡bçl…"ݥ¿ûÍ#Œ7cc…¿}ïÆRJYR™-“œsFO¤Mg¯ÿ"Ïs¶T	­ûazơÓéÇͧÀAAîb?]¡¶õÙèݹn®mpw{)¬Nð⾗{‹èë†`tÔaÐxڔޙ©uSGz{‚KëLËvGz×ٞj‡­ø¡2ŠÛ# ûH!ß
±ŸR®Ê>–¨·D*j£…LJ¬¦YRÎ?|Ú<`Á1W¢‹ÔWW“âN’ŸOQ·ÿ™¥»q‚¦{v/¢d@9d0½±+äA©„€ûî—ÐfÇÞÃ=D7e²2i+«ý—Oè/ˆI³SúAŸ™/¨×é<!œe‘‹„Ä~@Gj¶”»…›\çá{Ǻ4ISÿz(j"Íu‚äá¦$aš +qPY¸(LP‘–¹í6+›0±òòÒ<.îP’¥y󛖤æ§N腶Uó¸CVî¢ÌÍã×AYžB$°üsO¥U˜øÈN'¬5—ú\ì’çzÜ}ø7hJ½&;u€²,(L,ÀZsµ6é¡޺*]3O’’Ðvï€",Püj6obõ>b¡vd…±›7Vì}¾³È
èé”îÿºhyåä¤v»	±nNkƒ?RØÏQl7­¨x3|㰚ñ{5n`ð‚Žtel,±Æ!«š²XŽEôaU9Ä(’jœv‡™y@ÿü'ցð?–Yø[×l¸•ªqºŽ
	’*
pjX6NoŠ&+ȓ;D›’‰‚$@f(w‚«™|{)c$qÃÃӂ(ëFêX0äZÜäa¤bÍSÄZÍE55UÑ9TëÃ
:#bAâXHAH[p²t‹â÷õS.Œ"š`MG4p1
´@y
Œ5Ž1êo#Ì0Å;¤«#ÀàbÔÂÚú®6°չ¹	t°X,á	hùùçöi´ÒPZÿZ3¡M]hÔd€­™ª!(òÄ+KPd`SçØÆNŠܠû*Zã'°g­IcÉ;´ä9ØÒjË4úâZôfŒ÷d Ì`Ôçߐ"™›ˆ„“®&PjFKA羀á½&.—xP
D
lW Bï®qƳ¡Æ¥_êÂÕ��µ[ÂíOŸÚଠO㰌‘ãzV(#NhչEòRáJrdöŒŒ:í¢@^åж”&Ñ	äӿZ¥¦ÿդã_ë‚±¹u¾]85ûϐ͟ÿ~“ð/è_ŸšÌ‹,²Nϐ쉋þ#Œ³4'VB¾~úïëÁ+a:$xFýN';~mV·®°ԫWnäÏÏ÷•»مä¾Ñéþ&ñîSíGÛ¥„	”†|”óa1K‹¦
=C%‹ ¬ܯW}r׾lD$ÿúQG/r¯ØëÑý;Z;Ê8¹î¤{ϊÃŽ讟B	üïFʡ…d·tÿt‡´t“’ôáºxݡ×ý;TXIq÷Zè]øm¡ކީQ|rqï&ÎeۊB?¹‰€Üü×քãv”eØ~j×7îv:þž_Sy˜ìžQç²ʒ4~÷HîÃÄiô¹®e–ãÀ%ð:­Ü“w€ixn(6iî¸ù=,ý†ª™•¸ѯÔlˆþ=¦ìï<­~býz£N?·é-.æ VNÀV`G’"7i,úÚ!ÔâÜSn7ÈÔCX„ÈL÷à&
3¨¡‡*·iHš¢"¶ NEV¨ß4y¸hÿ$v0˜7sЂ./¹üó4ù&
΍7¯ނ~ ÷àVFA耛߹½1Ùó¥…ûVIÒU&÷W©Ôè¶…‰{ÿ-íƲw~ž–‰ŠGiþŒþӳêï«kŒº;(óK?‡þl™¹6´uÐA@ó!ÕñÁ\ŒÊ]«ოeM™­t‚†[¢ÝRûc8=l‹›Hé|µašYvHN¨óÐ/¾~z+Ö.ó-êÅêªV=—}m`KÖÎEo¡á¤ÉäVÚjÇÝ_¯„âá†à"¢.õ¯ÌꤹäÃÍÿ^E¾{IŒk&ÜRðÍ1oam
(zä$Í^}Ÿ_€?ó#׻ì½æí Ü2öW¯ðõê‡ý•°_Ÿ뷊ʫ~粻p÷—‚ð«ÊõŽô*êFhe™kAøÙàxHO(M‰}<þM¾„1¨õüʢ™B] Ÿ/e•yôٱˆõÜ촳Äÿº±
wH݅ZѪÎlâ§>²nœéÃH¨§|×ð˲j̋õ
OE­3ÇíŠmcµå,×h(W´°\I0*ê¹ÈU޳jݜékSÃ4y
Kʘ-ö¾k~ëXžjÜØtåœ$vK\D¦<™Géx<î†;-;ø<‘…]e•1`+[ã2+ŽÅãt1ÙÏúÖt³×l%RƧ™µY¦<PfRʗìT°vžyÔñÜwN´ó¤Œú}59ããcÒqKé0H‚–ôïi08Ÿ»½jÎi¿þÎ4OTežÆ-\RX©Ø~2´BK+æ	Ï(F¡øU2í·ƒ¦ԹÞÂÓõ@oÇ·_¹¸8º戦×"wŽ£„š',ÕÕÊÅìËÙڎ&Å2ÅLì/[¸;èG¬$xþœ9wO]?٨Îè@ó3Óm†³S_QO>K|1g&FtŸí-Ycz²/é|Dm}§°ы9A¬:#m=c]»Ļ£i>éŝXí+¿2ùÂñ=†–ZøÑÚèéM€#V#֠$½»…4í-ƒq‹ǓÅã„ó•±N|fwõð8õ)F
º=æ1ëœö´˯f&ûÒrn±ÎdɈ¡aÚé0‘ڥè¶OJ~ãA­Ÿ_ڏ•ڦ´½áS9Z#î1L×ù¨ÅnŒ6}¦ËÐïù£æcØér$úzI«AÕ=­7ŒÑõ¥؟´§ßÁV5nûÝbÆ'¬FÂa4ÝSBÇTôÔÖóù¶ó$‘5_ÍNoT8çé#¸µàöBÊ0ï=õ6³<hû§ýäoì…@h¦¤‹*Vôamx³5vçѳ…~Lº>ëxc·±nm·ÔpÁTiᒩx°Áµ•!Ž™°Ï½Űßoh-*٪ýÉnœ?Žu˜Ï3ß[±EFmLŒ€VÍØmoKyfi­›¹ºÝör[Y†´é_ҒÛòv¡£U{إ
f3âûü¼­ÄÝ̦;¶rã§ÐO}<K1ݢ™-žá%õøâaÏ'Õ9kÑmíÅÏÏ.s WE¾Ä+ŸÚ,ËršªÍõ€©ÂEʳEw‚¾ÏÇ%÷4.™ǀórjº‘Ô<ÚölnÜq÷äÍÃõzcm9=hýxޚqÈhxÜ2’nâ0_œ¨:çJIL|ìŽvÎ2ó)iÅîIö|ªÅó†8¥™¹Ø=žòސ¼6™ûÕz;,NI•?Žð6ÜêiŻb隁ɜô´ôú‹Š視M?È7žá©´5¦Äԙe¶ߜԪ—½„ͺ]jÉ
Wœ¶¤ðÆNgÂ0‡Õä4ط¤™ r¡֪Îí`֓†Óï?ö×ttZƒ~7[p”N«Ãx÷ãْÙOƒc®wդëñÓxJ³¦HÍÈÖ(¾æó¥»*úó*Ús»:ö{w‰íp\õÔÕÈów»¨Æj"dä<bT¼.£--¶»m[“ýóx÷ej¢‘T"òr4Œ³.ÁX7Š60kAøÛÔ=~ùæ¹´3ßmÇr®¤¦©¹¿¡xk0.Ýô‡¦úùûŽõGτ÷oÐÞ÷Ÿ !¯è/L®g;?î1À[×+õuíúæüßÜøõØùŃ÷Û·Fãÿée^{mƒzF¿»̣|ÌqfpTäp[2­÷]ÕõÅsã(qä‡3ŠS—þôܣRm{ÂË~lè­C	¼ª‡3¦óB³çÝ4Üùs*§6«§²o<Yû¤̋}Ëx¤ú֋wx”´-w˜
'´çÃ÷Èa#wˆ¢k)û¸Qæ(ë·ÔÑÎ{
ÁL}u՛¯¦Ób·;Öa'NO&ãåݧ9­6S¨8BÖ
º­-šC™ߑ¥ο0•ñdx£y¸œËÞf%˜8R_fÄoæ‡Vì„[»ëT‰4’:CÞ×ÓÁ,ÚIšÒ;'òn+Gz„_±Mê@ØTFx
>†RÈ,Ô)'edJŸ^èv‹Of;uG‘>
z%yuŠ1e廗j==³ã<æ)GæÝÂû —w©:Íú«senb^›rû¹Üï,ñ>I)¶w«c-¥rÇ^ðj+¯Fd™àñ²;è¥r Öÿÿÿ̚Y³8v†ÿJ_ÇIX*•‰Ìf¹ŒŎÍb–_?|_ÏLOjf:]S•ªÜÊX #WÏy%9ò¶àëtU
Kš¹zWj(.Ìc„7U=†ÏÂ7MEžI½‹ëM|Æ:Ðl!>K-ŸDŽ=äNQ‘Ø÷K¡-mÈÙs4
Îî
õÕnî›˙_éÁÐӠ¬S{Ý"îÖ	¼,¨0ɵˆ«γÑD_š`¼6S˜xە\ô¨Ϗ«Ã/²žNdòœb¡YÒHeŸïlvZwO£ÇW"@ý¸5Cgmöà”ުâìâ»,/FXË"O)ü+0^Sv|8Åúëú¢3«ȼÄó­òy
uØévìg¢|&M¸ҷ¬b?ž+4ËÜrãL½©Éa£‹6ä-РìX:&
å.|Vy÷tOŽ¢+Äð®¦D’j÷ºϭÛõî³;JK·ÿNšw°½èA‹Ïâ÷q%¹w’g<ä{‹}»ø”ߡZú¨{é9yÙ8X ЃÁx•¯U{3W"µg¹M&9WDç×±ïŠNˆðŸý—9^=¼ÁÙi$PâV…€¸ä¾fON@³#¼ª÷Æuü™R¥c‹ï¼_’,%k^‚l5o7oÞk7xIۛ÷®A-=Ù±_D-*M¬
-)Cv32§Uf5I™àX;Ôðd
¢ZòõÉÃRÔ袔UÈïäàn
)ðQ(Àû„ïBZÛ>ԛ<‚ÐÀ0uF½róýX,&MòîÚÌåf@uaªŠÂòmÔ\Úw·êB]ëe¦Úêm%Vƒ֎÷ÕPžci‘Ÿ4•p9_¸y„ÐË
é9äcº¯¦-ή[з&Nڛ`È„ýÇƅýâϵIüdðåööµ8oÜÎ2g#<PÙ%£.Qʽ¯ õ®¦#%%µÑðܝCsGUΔ3²ËzùÇâ딯ŠŠ*ö(äE«¤iBõYß]gBNÁÆæ3M™5–\¼YSmǍ¦ýù1ÑfÛ*(GÍè@nÙ.ŽÀzetûvàá~‡a¿ڕ5v1lÌð±§3^?µ~>ï¨|§ÈïðÛ<šËQ^K_·xÙÚ:õ;LúÙ&¶’ßx‹ÓñüŸáäÝyXU'TüÓù?¬�Lþå~~ƒ–f«ýž­ü¯Ø?ññ›öìÁÿ‰™‡ýÛ/öøÃ|œ||ڝi²üj•ÃÐM¿°ý48þóõõë_^¦=*¦ÿ¥šžþŻüé®eşÿi¯åÃX`åܵØT¦ÏaÅþÖoûi´ýտúՄú¿(Ä_ì™ȿ‡ïIþá9ý1ÿ¯M–ˆ„?sÙ	Iòªüh‘#W
×ÏÈ’Ҟ8&2W%ԲP꓇ÖơKçy{V¬gzù{=fãñÈӍåDœ|ςH[î]ȹҼ”$ñõi†ÝÛÔÞ&bXӀ»¢Sãa“Åm%ÜÚÓåS
øÅhr7Ï
¿êJ¹§¢IZƒÔp7þ”‚ÄQf%^÷ùXâoê7½\	ë8SŠ©+öÂÖg?Ž2;÷¤ÛД«~¡xwk{™ÌՁҎ.²2‡ôºfó+UG3ÄFÇp\8¨gÌÛÉOt+FS Ì)
T_•s99ľ½Y>[qöG"Ó>ÕÃï=;ëûS¸€‰üˆ5ÂòH¥Éz‘Xµ¸÷WÜ.˜æv4‹
мÔB£å£}þ¬…wLޮŸ(âÄ`<„T¤ô7uø¥8±”¨3ôo«ƒ-ß¶§;—‹Ï/€ãÝëÂß-ÅOp†(Õv}?L Ùg\ú‡%Là¢}$Y¾ìãkS¼͈'R¢EªÌ'J_Y,0¼ŸÜD\
ÉùïäG·«S]îÙޑU€ݩÃ-Zڵúܲ½
§'vžSÏ×#êKyÿ€ÜYAxyDÍëÖ͔ԯªBaSL]Ž·(\iÜã
C*¶÷¼Vö'8ÿ£fÞD¶âÈ&<gum8.‰ØL;y‡9'sڞ0x3!Nª”ÚzjÍ<êf`‰[ƒùðó㬎E¨+YÄc·Ìbß.e£rúª4å½W}c€pÑٺ…öâ‰9§´òºÙV€«èこâ’ÌëxÄ:’ª#“ ˜âb§~J
‡2¬>wt7Ö;͉*µ€°y¾›–”œŒÞÃÕèWŸ5íW)t¥½£ÒFúj÷¬*¨§1d5ñ¾á~ªÜϑTÒU>•”OզKooö˜®—^ÊËz·çÇBôî7Ûg‘¡Ò>;MøŽ¥“VÍ„V‘XRÙçÅNË*ÔÓsÕ2ÑÍYA‚¤ˆh¬ÒȜûê'ΏðY	4
¼­XÍwD«ٽ;°T iG¸•ê•bÀmB†hÔâ#ú8¨ŠA‹·›GA
\^;8ú‚ŸÂÛY‡¼+Ä6ÃÓ}ƒŒðXj4ah‘Y¥bÜP¸«> ¯Î
	Ϊ÷ÉÎÍß/W÷©ÚM&L,6ªÐÜnPEkο…^¢²q{¡I+G užvJe¡[+Lð(‘§³ïiKµIxÉàò.´ôß-ïHXÖÑúð}y˜ѸÖ%dq”C,CñmNñˆy¯Š¼Ҫ¼ŸŽö G Y¹oB–â0[U-ÎâŒgžœ´Ýyt¾$Iþðt%xµ–üQa·È#›œ+N±¤ºÀtHº€»Äï;Py|®]{½7âeb«‡îoeŠz<J×ÍQ@ð°É[#þ8Bu…AžÃPª´Ð
I8W?w©ïÂù©õþ‘艙»–/˜råG¾D6u¡•4yµòìZßÉg»¦<—ÈP¸ĺOgÅuQk¿¤4éNAt›wzÔÏ*DyàO·òJ §·\ꌷ”MͦèÆäQF0Rèè˳6‘¶é‘Ø.YEYGËþóÚà¿2†+¸lÆm3¡O
§Q_
í<0a·WÞËù1nòÖÎ$ót¾Ä3~½ÇWÝX™$VÈcé<7
ÏÒ$!_šàà>–«xÿ06ãѶÉYÞ\ÒXAž"ˠîñ]£Y2!oÅæšlÈñbëMôíúfÔ.Ŭ'‘Z„I	
¼˜ÏuŠ¡FÑØùÑY}+XAÔÉ`®/7íœù²}ÞL¥&˜R cŸ{ û1	§À-)è›wçú7μ62–‰Jßm>‘1Õ{]\WØw¤
;“­ýEño]E9šѫOׯ]ˆ9Ëù&úŸ
Íþ¸·g¹}eT%~XÀ+]Qq$cînÏjQXFïq‰øÎwôîzUI4ŸÀçse3ês½ú¨	˜Ãõպ†î¬Gk‰@Çoç:–_v?=zˆۇ¶+@,ý³ÂÔã̬ΘÚôðh*h”PÍÖ7ºü…Õkì=Üå\†ӗяw—Œó
à˰¶ijÎcSrPà¿¶ÚÛ:êÇv1+^™dtîu¼Oés8טµ¡ëænFçkÇHÎx ²£1õuÜ	†ýH3fQXlü	Äô&6;,*‘‘	wÐEÅ`¾Ÿϸ?¶ÀQ÷41»ãàXáY9$y³úãòݲ+œ2x†P*³“¾±ÛWu«ˆ
dp¥’O6Ÿï|â».P*N¬Àx$459š’=åYciÅ|f^.½'ôpR¡EPÂ1ÄsȦKtïø#báCF@Ö½œ9ÁìÜ׽rïâêÈj�@0ܯºÄ)‘ã€ílÆ+Ͼڝ f
¢61®êbXuÕ|]YLYóɿ‰?¤Ç}Éès8†÷Ç)0C|êã°@t¬¦*ÉþcÝJf>•ù«·àè:뽡-o½`¯ï@²®2êzÒÎT=ó OV‹g,—x@ÚIÅ5„ºyÙ®b'<—þÌéeÙñç”;3ÒôS„ÚßvV‘¿Ìäۨªܼ9ù(-]œC[©×P±ðŽM0®~7x]ò¾gN)ØXˆV¢\¡ËõAàV¤'2Ûð÷ýÖ}ÂB6'D2>ÀV+·뭽â+¤IXjHBcýEü]ڹNÚéܱ®sòˆÑ]0,JS…t¹=»ÃåòÃzãzb¬r¸"åҕœßéÉ|‰üÅ›¨@}ÕrD\i’kÃmh6%«ëØfù^´š8àF}ý©ÍeõqÿÜ4Vr·ÁÐU¡’Nmü"XÊöÕD3ïéƒÍMJàcÈ9n|WÕ̕·)ìڹ… ·]Z~"Aà¬ôÜ(^øX®^7	°`ҥ²˜FͨÐa;GPuéýk[;w./ð:»jO\aºÁs9bÃÙëmî{ïÇUz  a½Ô1˜—´Ž„ʍô|gÝ[‚_-¿?ÑBM—G† 0F$mé>εlÞXÀæå
ÀàUX>H«Ä~G\k|öên$’DÙï¿DÙ{øtŸ  »µ¶Ru÷}òxUÎòƒv­IÆ‚`ÐO=Y{~WR
P$úBg¸?ÌþÊ2Ý zâ�ëÁ®†¿Êxã��Tõ©¼ÓCÒM„·
•Š<´7š³t]±ùgm£¡ÁÔø`ÄëM9EeõkR<¯îG�ü‰
NîžÞÕ|tx>(§g¨ØÀÛèjM7· :NMÏÊ'—öͪªÁ|îõ‚öžB‡zœa“BÄçj{ô慾ç0~	1ˆ¤ñP¶y|}pÇÑx±D¼҅­ôüàžsöîšòËç*
çVQä$‰¬	vîôw¾âã؂Ô3/;q¶ž9?ԾñE<w žië÷Ýc@§V[×mD2ˆƒKwPî<ŸOŸÀ@z,°G
µ9·‰¦a	à8¯|cªʃºÒÊòKtU«Õ"N:„JڝûísöMɳe҃¾~¼ÌXìãœ>Mö(婽‹@J°B^õ¨÷9»±º•_KàOÏ`÷xq¾צ¿H¸2Ÿ1ø»m&dÝCã0rçT¦ï°\aKñË5_ª¨÷WN.èˆ÷ÔFÀVlN:Rüg%‡ٵ97¤oý]ÛýA\qù
Ýhgd†é%›s Z§IÞÝ¿>«Kß".0´›_™‚³r?Hßè>+ߙ˛ÛUvo͆¾&Ý}ý"ŒŽU÷à?.Sٵ=;ìL=®÷B˜[¼ÃLh½
ãõþbx¦Җóæ‚*ñõ¦CBÛ>ÎÐyA¡]Ÿæ]I½õ´áÑ/\p$ŠÞud†Q©>;¢äÖI¥Þcåñ€‹ëL¿åÙb¼bþ̔±°Ø’_Þâ±pt²€,HUþ¤#;~êÅwʡë¹Ðtaè‡è,×néÄ_L®æê繊ÔÜp‰`¹¢oÂúãI륻GZ
“êŠÄþáÓ§²Õ蠋ÜAv/üR2…“~̇Ò;j\Žk¸¦›uV²¶ǙÚÃKfž}9Hú­ÑxCõ,(bcŽçxU	k±œª2?ŒŠâæËMñ®!¨¸p(^-±£'B'ÁáMÎÕ7FùÚCÓÛy x³N5{ý%îν¿§‘Sެëu¶íwñ^ª=G¤Һhºìhq†=^Œbé9õ8ê«%âòÃØëÝ)ñk×ïY+©tý°Q~½Wlw¿(+¾ÄW|­Êø&š‡ùõó|jn@‹c£!„þûw4»vöz ùGnXýõÕ?¼'ùÏ+ÞL{§cÑÏÿõûW;kùÛ;šÿÿ̛Y“¢H€ÿ
/¡a·ŠØÌ ((*¾!"âÊ)FÌß*P[íé{&vv#Ú֪Ò,¬¬ÌĬ/¿猱6h
JÇõ©ü
“Q@göΏÑ‰#3±Іó™‘}e‘ó$ß%÷=»È(úÃ(?]ýq¾¿š=ã‡ËÃÐÎBüahGh…æ6ªb@5œÍÌO”fM\;EÅ׾ž˜Zퟩ�ÝfyÎ
ÂÉý•i`ÖÅ^rf‘ Î#8ݸUѥ\ä!¬
ÕS¬0û¸ì0,àÈo—ñ\v+ö
e„ǗàÞHRØÎç+c5¬„äåò„˜Û¼^«DWax•xKÒòÓ{ôŒP¾ƒÄ?À+«DˆÙfhÍóêÇÑ]š÷³=ö˜}&woŸfX˜ëT-v|ÚÒ
3¾'~հÉjhy’ífBuØH‹•±ù6J$Rãy)Kv?µ~–F¯®õéñ›¯ò¯æÂÙ/PϹ𥤂(?šöU¥.2A,
þ‚dÌEžë°íhÛÂE¦Ώ”¸ÆôΈc|·Ep¬1Á7¾îNؠ‹;"¥fõm7ǜ4éoýYSTëÎÊ0CE
ÍñL¢uYÓ^MVxâVHAº3UŸْ7Ë쌰šËV¬ó£V+ȩ%™â”tYÅZõ-qâŽíD¦Åʁj©÷÷~`†“ï'æd~O£N݆z<x´hj+ã¼zÃØò8=n
Ò*iu{0¨amÈZ¡ùæP–#bÈëxEI\n±b·'°­lí©qb$Jj­MÇc¹©;°V­ÈÜ
lʙx°!¢£gœm)´離PéO‡M°Îb¼½¶<%{Әá¡9™ò’ákW“N€3A|”GËÞFäèÔBŸu(ÑÞvЛ\Eç‘ðŒ&ÃßR®ÇÁúd´ü¥t´Ӟß«šӱ)f`g­¦Ú<1“½±Á7ÅnºJf§ö䤋ÊÎpÖKÃßD}Uš0••¸4ʴçÓNgbî·	sÜÉÀù“ ÞõÀj¬C'Q¡³:3eïðÜx¥f­ä19cz9Uü9ú*ՉZAZ!4¶ï}XÓ얹WS¿N±ÚïÝøqquR_¦›>8•‹ËjTÉ$½ç«.í0Uáó@ÂՀa}º|ã2oƈ|äY瓟î`Ôú÷v=T)ðÄýÕuv™ÞÃÒW|^“›¥I¾\U”?ñðù奁¹¿•s[q«Ñ'–ÿ& җ9î*Š£WÅvâ­¼`구èåR•¤­kíÑgZ»Û5Oè#ò‘B~W8µ~sáÆðöªqyçgŠÁð{½¼4ü¦^ò™@ýà#ás½Ú,ÿ1
áõ}„5üw}õ%}8çÎ-é§çÜ*r¨ýÈÙÃøzhMXQ Œ-+ítjZ8%8âèL9Ço³ìÒ°k_u)žëvùõ"©ߋ2?²fºJwyÉ5ŒÝÉØÍõL«´×MO¬…L‘±5—Aszƒ7ž±x£fòiØ#ã¥שZo.k|ŽF‹qþ!F’ùs}*ÃR¾èi_ß8§8e¸÷7ÿÿ|š·ҫ:„ˆ‚h¥ȶ	Â&™Î&ƒMÎOôw·º…i4£ÝýV£B5
Òá¨;ÆþqGƒK²F$‘ÉøÙ12z¶ƒíáú!™¯--\¦#¦9QÝmÿbŒlW;—©’X±‰Ì/Èz¬:¦·rÐ}E Y³ȿÌîmÛD6џŒ™œ½¿ŸšÜûu‹'%m
u-x$¾Uv6$OBó•Û/ëVþ>aüHøf¦„$'ÔMaÚMÞÈ
k3I¶`TAI(Üj†#/d	/E<Î߁¦†çW?ÀàÿKy†ã÷¸¼[?ßn߃8֛[q)A®;'ä†I‰̅ýL¤˜ç¬(ûôڗ”*Ö]ÐJ2i°qBÕo3`ƒ
)Äpö3ûéiq1µŠw”‚CH’eˆ)Üzâºï¼øž·´CW½vF#åè7&Òë˜I½ܠ[o<yFû¹äO›^¶pe®Ìà6J\à}>¸G²DF\D«‚Á#1ngÍ6*»ÌÈh^Ȑ¡¬Ñʃ˜,¹yìׯãÀ̀x$.Ô<"%-,޼³LAøõ¬ÝÊզë
¶¼é_ëÐL±7ɸƒÁ#ôŸȐ\±Ú_€XÂ16ê&óÎ8èåßçÅ~ýèç„ÍkO ¾4i^/ä§[ŽcR)îyWFðñí¨×Ž$‚.—&Wánðã&AÈÑn5ÍT@ÄykM¿ëô“(ÅB3z2â
Ð-Öm]+Ì+|³®àŒˆÚz»äk4Йžµ=hÁsß*¢õò|eâ(®CïõðÞ	O	'=àü„ÕÛC"RYNTïÛÅê5ІR÷¾—ø¾¹v—à~%n!—:íó°=Ÿ6²¹.fÌÌH?WòŠ‚xŠÕFQèÂÔèLz‰óyçMmÐlªvþ1@U„έޅS$È„g“eãí(TïUá.(‡ô÷D⼶—îä–2E„]¬ýà¡e(ã··ÓÒËUÕôÖI_÷Õp) &P³ñ°bT»¬©ë_ÿ¥¥à–+)

ÜLÇPvç·2 Ñ΋À۟ta>ѫTÃ3Y•¸qW.NúØ.uåƒù|©­êšÏq`&JYú0߾‡ץ¤Œ¥	#1ÃF¢µ-9‘juv8˜òØ?\딝àýì?‰_†Z»Oä)R¼-©w`+Ž¿ô>™xûý‡›üps˜	áâfq;ÛP^0
·løæ"w\‹››HßMÃw LCHk)¼º®ÓTj‚ãÖުh±|Î.¡[©ÂçJµm™¼sÓ	ñÁc'¸4¹ãM‚/I’àƋ٪pŒU+ûüßó÷=1ã?ÿÿì\W«ÆþALˆ>yDïôˆ&D à×gusm續8ř‰Vše¶ò}˞õÆ\ŸЏ­GŸ#º¶³VÖᤘ¤õð1³¯QÕu)°ú04	œ
uÏ,®pËþûÌ(’be^3:Ò¢8$fS=¶ֲ[%OWŽøG/	í)Çü®ǾdYôâiHè#䶯MÂñ—éxFu¶©À4‚ùÓM°OH_4ŒªëòL2hižŒËÞÝʌjºMÛÝÉOoÔßd†8ólIn£ò±—XèulÄåÏJ^5N^
*ZP~ö
s¢|LwWìqÑd¬ÄǬ*|Êqüéíˆ<k
tf–«Yo»xôú;„°ȯͱ^‚{_5èݧVÂ=šØw	È`ög *Ú
%±Çþbn7¢cè0Ñ÷ÃÏXr¶‡Œý$$§úcWÙۥìC+›ÅXKÓò»tÁ_䁲юÚúp0ÊÊBÀ4AÂÀð„T¸)j •Û]ÆîHI‡GZ¾>–RÆGv¨a6£à–wûâô$} Ž÷m€ýQ,ýÔ		ŸÖ~Ä÷¡ÄÝî JÿáÌ?¨cMKýèo9ş~´1öµöÛͳ߽£ýÛ~þò+ùÚÿŒþó÷Hú•±xb÷eóÃ6Û2aá=e†~À"RÓċ€‰ó®¬Q•-®Y{WLÓÖ+r	G/ÖÓ^4q2¤jq:ÀS=AÐ]eºÇòÖ.ë¢ÀxG—.˧]ʙ¶½„æ³àR|yÞÿ¨`¿˜Cõãâ_ÔG¾ß?×f4{¾^Ú'•c•›Üì7¸?ovÅã!JF˜ì·‡pÒèbCÝmA¡A¨‚;óñ"#Nöúá%¬ÔÁï»ì"¾ºÉ/A²o3§ £sݧKܜ
¾•;´×¾úlmSâ¤wXwS»7êÉҳâP¿s޾™M‚dêÕu”§Ù"µPáÑk7ÖäOà·ÂZ¦Ì‘VÁY‰g9¼â-–@Ý\¾؎º$.X¨dÃ}–ëԟì.fë¯Í%cnÛB®<€°Â)zç2·_J«çžéϨÉ

¢«†À劁å/¦€SÃ̗¬rXAS–Ïi,f“lùÑl®ñO¨œ7¨È̎¡= ÿåÌ/™‰mÙe Ï\îyÄsÎÅ3ACiަÌÍÈîÍ/1,6Øê¯ÕÛjˆºXVï8SØB‘¹Ùû¥Zã¹å+íV…—ŽÕØ"*{!$q_¹Ç1zҷÚÿþb¼¿"]tߊ3ð‚E`UŸã]åŒ"Sb„yÀ¥FóüÛ w"Ûy"ÅB¨Û
Øü<S
—0ÚéÝàž¥ô’'</­-I~ˆ_: ‘,Ât‰ü"ò)ÚH~œ#BmÇ~{­ÎÉ:G4ÐW “ôàdÚ{
ˆݤ"Š+60®õjRãªD^‹QꍬŽpZаú”w¼Îqþ™¸‡ӅÌ!8š-e¸ƒD¥‹Ôò´~ÈnÇ!ð‹\=iQ’¨!MO…Eï7¨y‰I«NüV+6j$HH{‹´³|Ã`X~¿b½Ù缿]îZm&£Ó:m_ß8cõ“XÇsã÷7SôN»Ph3¶Ä''Pw޵‚mz¢ÿ®*c¸ã^:s•_±€æDKP'‹ÖÚF×è©m%÷VǩàæfÞ,°‹¸Æ¨
Ü1mŸ>ÝT¹$”¡¢v\ÔU°#ºÛu°Sžë÷qÔJ­#\VûÛË咅Û…îg0y{áW“	œA	æw(M…­†ÿy#­e½zÐàKØ,çV+Â%— ¼£8‰AdJ¡,y	ì?—qÑÃSqC嵞IW‰ýt‰^³
0UZ¼`7ÊaD´-jÇ#2\ôÂ}-|βќ^u@CËkoíøªO­qº¦¯¾돱K⺲Ï&¢lLWÎHˆK*({oO×ÞvÕ¨Xã©ފáÝ\1Τ©n¨mžìáxŽ¥Êüºè¶ѰŠW®««j†
—û~÷‘¯èJ0Æ3€îQw‚)ָxQy¡¹¸dÔ!Ú#NÅXi>ôýe8ˆõ)GÄùEªž€’»狲†T¬Jè±µv úhÀÆt L—ÝëƒÚƒ… o7G–X޹Êg
ŸætÑù¬5⌮‰£\9G0p²DîÊÒÕ=ÀϨLò?=©‡}¶|̕ÂÝÍ׃Ùó±~­aQéµd5aW9œéI{xš­'åсr„5ÇXàáÙ`AçÐûM¹Å‘¬œ’!“KB<³÷yÈ7xaÂd~þKqkÈˆ¸rªëOlz»ÖުJüA_ô u9$ñWQ¹‰|¶¬6œUμ¬/Šyuæ|!Öj-L÷i¥5°žT-—êL¥È^lžfJ™Wq<k,¦Y_‘Ø-38 ~WŠÕA¼ŠÛ÷j§jòœ†ąÌtzÈ3$Íó\àBNÌ91µ¸›‚„øSq	§›?œb׊’ÍSᏅ±xۑljrD§񞪷Ôhgº³ÝH±ƒñ.ïðš74Æ
˜w­/¾E RÜÇþzs_Rè2ÖÜZ©ŠQÞá]9žžf†ëè1xõA­eóÒ,±NðýÒv,·Ž€E|°ìx¡oñ·,ÁáíJB	óØÖM—½ÓûYÎ׽™Í%
ÖnaLj–ñ.„>“HÄ>)kbÝ
<•흗#&wºßҎ´YG}NƒÐå­yRÌMÅ`'8Df0}ôåvj{îMÄV'ü®ÖÂÒä<ÖÝrú²Jìû;QWÊÓTÕd}ߚGøæU±L|nÔ/fñÿ|;6ù²Î_^¬÷ó»Kj~å®ò§~õ&®?zªտ)^ØãR;±ôy ¡ߣt„L0˜Â^EÄgo­ïb|'Õüv
÷íü|j¤Í7t9q]ö´ˆi™`ý„—µ•‹Çýd¿¶_X&÷aÕ6ª²_tÇûZ	;#¥_+W›Ÿÿh|u؁—AÉUÖ/¤oþÿn‰ß·ÄߙԟÇt}¿v·ÄO|±ÄÿQ³j™‚úc)ÿÿ¼\ٮ£8ü 4"ìAód @H€„°ÞØC!¬¾~ÈíÝéåöµFóV²TÆ>²}ê»²ä½ø•ÑF;™êqQB½;W‡}	jåmC×ƚßmœË!°¦Vß-aïT—:¿v‘š.¤7Q<u¸ï(¦¬ےx'S£ÞòžŋO~´âñZm<cmð•N>ãM9ºêu”°Û/ýmOåȺ6ÙHýh.@ò0÷™´0
6ģtѪúλŽp¢çŸÑ%ÏLnI¢zL¢¥?5•I’'>Ç2¦ž$MÉI¸IÌQ.{Wç[À¬¾ö9–©îpVº-»gý¨_Q4öa³í4å3î
P*[ႇkñ²KúLñKNžO¤.¥¯þ½€œð/ýSI‹Z¼½ÍNâʮ„˜5c_Q–›²²‰|<Ædó3þˆÐ µÅ!Þè¾FŒ„
Õ¾¸)AóvìëJ"ÂÚXòÂˎé`.¥Î5r5†×²˜_žƒH¤W;µ•%ÀWBîä»ˆæ§ݏØÙ`#ö|na~<!´ªVݳj ӆ2- ž1uɗ<¦`à±ÜÉ:ß.dd¢V…`»›C
Ӕ©ÒÆ1¥ܰ܊þÂÓÅݷXûÀUdkà`l>)”֬Fãã×쿝¤ÿÏMüÚmÂÓ`Ë/³{âÅ]u´;+ËY¢ïUkM½¹é/nñÕöE[z’㏱ó§Q^¢fƒ¦RìV0š&×±¸ã˜"—ßWKA¢,iÎ@YÛOrýy-æ†N,Ý1”Âl&Eåytg8Õà9#I
ϮT	]
šߤP‘Gz<åtNm¼ŸW(5ܬ5'w痖ªÓ~
\$&çdd4żªbšc¡|ƒ#gÝÏÂeëa«²·Թa°.Rä8ԏ=Ä‚J†mũ§
a \TV©ê«!Žވ`µc$ƒ¡Iû1fÁC…܋ÙrM”I›ÉŸ-Æ͠E†!±TI²íïÇT…5Ñs4‡“\2)vVÛ5Ê	}âw ­Ax½äR#(oxŒp°4ÑI´ŒlEÏŸ!­$çà€ä\£ßÁ0ˆiÙ̵n}Ò8°þñÍëoá*›¹s¨K|òHš¸³iòµíF¾Š¾aIîÅgꏭv":Áº+â
%ýqËã¹ÁíxZžaØ73§g3ã”C²æõ9ÉsѺ¾
ƒ#—DƠ.a̬±Yl[Øt'Ð-Ò|¯©qrÍé*!ö¥
h܍©bH2ZW«˜œNlÙâÛMM5ƣ*yE„Š=¾%¶”÷¯x_Té›×é«%\Aû™Šþ‘ñ1ý÷ýˆøó¿óÃýä¶ôw.ŸØÒþ­­ޯäÿ`ün»ùއöõ×à-l|ïg!þçó ÿ„ôÿÿ"ÊËèmQ,‘‚eZiQ1¨©=zæ,j˶&´æI¡¨4¯r~+líyjJz*èÜ~‘– «º‘C¹iªlš‚P\ԒŸ@³) ŰChÁÍf ›±ˀ×`gc@·`¬ÎB;÷,9JCiJjr>ä¨_¤³\g8Ðz6 oAڈLØu4ÿÿÜ]ËNÃ0ü•UލŠ@?àˆâà6†X8u;éï3ë$N¶´¥= ÔCÕ4^?f¼±cïxD…®,	ÒÊ9ÿƒt5߯ë|œŒif%Ód“Lþs
òŸHÅ>ùPßýÛ×;g²p¯[4¶#Ä¥¨%q¨ƋRù#6,Jë#G8—Uù|Bô‚Ia³ZKÖx9êu¸­Fš’R#-ëS£Áàé1c”CêWوr¯{Ýò4/ï·9‚ÑN4»ã«þëàáµÇÂÕM1è#§M²k
ÂøÙ×|ÄÑÍgō-šM’´–d^¨²	¢Ef¬\rO̅[ddt:æäsd&jeª2è6ñY8@JZ`êZº®,1V`ÈyÅÂܷáuG ]iLmD«L¡˜ªdl6üÆôC/F=ûIJcNÇÌc(ÙÙѾD°Ŧ¼ö•çi“çßæéôŸtó$?9ôN¦ô\"Çæðµ,*÷VXY¥æ!Ùã€Rï?L4m—{ÔÅ×è0ãõËa JIã¾Q·ú
\_P‡Ɔý¨؏Á~ïÝgNœԐ¾6]íÖÆÛçhÂoÿÿÂe6êÎIÂ'ú#t«ޔDę©ì}Y·£8–î_éµúé.n`æ~ó<cof4f4üúÆ'#22*#*£²ªî­\݇ãu8B’%$íými_”v~B¿Ö÷ù2@Ÿ¢|IøÈO|”o:gû'¾äûñõͻ	?%ù‘áŸÿ¦ÿØü½¿f}Ìþ•­ÿù>͖Ïcýƒ ˆ/֋_}ø%:úÃSèÏ=ú¿UùúbñMäø¿®ÿ'È7zø¦áDüç&Cÿã\èS¦ŸÛúÓÏèà÷òµý{ž6ò›Fë'½¾,­ü‹`kĉwAÆ óç½ϔøØyMLªikÔZk݇ÉÑO€¯ÙUà;pٰ¶ªäΞ"\ÐC½¿ˆÙ=¼ó•‡z+
¬
©ÂCñªŸ3Փµ`O|ª‘.¥(„…ÛöÕ
¤¯X ø“tRìG˗εÚ[/Pդá'Ôa_ÈʢÌ`<³ÓíÚ_¢B¡p61ÜÍ^Ռ³8aæ͈
r6ž
lÎ <IúšÇn)¯·ß3C(Ö|açæ	ô.’¢b‘\I
õéL¶³†6Æe¾Ûâ²>Sfúǰú÷sÀá‹Ýô;G¿Ä“(txWã\gÕ-°«§.—ç®N_ç¢!`ï¦î¶s“½Ü,(Fm«h5J!b
}}=ݓ+pbt½«IziÂ{ÊƏš4Ç_RpÔì利³µÎs˜„‡p¡/¼
»"¹Ѯ¾Ûø¾-¤]٦ƒ׫BèµM…գØ̦¨Ø׽V®}3ÕgF}Æç“[҈úÑîå|öKLA㞗FŸÆ!6÷I¢‰p£„ުc™s)Ü?Þ÷˜»6Ä`J—ØJiÊ> ö0Õh^VL€F7«û‘¹šÏ\#ʒ½ã?£ŽÐÚM€νDmœÝ^î—¾3ž(oCC8š³Øñì?ùÄ÷;ۈ¿0ªÓקºäoL!¿£=üÁÀNxÿ7T£W’|ûaÓ!˺T™øMÿa€ꬮGùÃÈßP¿œðꊠeƒÌ1L9–e ñµÿT1úrÄïèN¬JPÐå:kÜ?tcÖŠ>«ËrÀwäH_yнp0°ְ°niÀȋ¯žÉ_”2J½xÅðzQÃu
ûD˜uûwðÍ2ßþ1ÀʧÏޔ[ÎÑìO TñíHqVU‹ß,ſ|Iù=­‹¿UöÏܣÞQ½~(+ýJ³é4ê{º©l´ÇE2Š–TÝpâä¶9o–³7„Aï&ÔáßÖDR8¾сzIßYd¿:ƒ縘߄ß.ÀOo”炱‘ïiB}Ç1=«ô{vyóóï;¦ÿÞþǯìH¾ð€Èüo`»ý/›K—0Üzý(Få¬|Vü³½ðÛýÀ8C©ºzÚՑA*­Oª?Ï%½¥¯»E˜J`ľç*K&ÓÙêñ'’àù ©7¥m0%ŽÍM’Âu IV)’Ùés–ÁĄ°ÕTpÌ4ՅØFÿP zÚ6ÖÞæ1J
y:á\Ÿ†\1Š:ìJns)ÕEd.£M;2+Be:PYJ"¨t[:ÛÑ8W:Ï|ƣ²˲i¨vqw֓Ûè~q&/¸R0ù>® F,Ä:ÙEåĮ5V†OConò>©þÏk¥÷œÿÐ(ýüWRªÂD‚S©šÔ¡*¤Íe;ë*x‹“K¡=ÌîMt»l|¬kµ„Z¹’Àź>9(]¿=È#	M¬›Cà7ֺÓç¦jÑë­<®OsuU@î[—
І´!œÒ	h,u{ò°GéèޕäÆ8ža‚@ª‹çMªt„z°×z\Êx°y»ŽõÎh®\n•ékçÆtšE·´To-©Õ<ŽÞÁ^ÕÎ/àÉ
¥ӝ^Êk¬ָQ[ˆE'–ŠÈfddì€gÔèj(ѕ‹–ôšX³çàøb ÀÑiˆä¢3
ߎޱæñÿ²&7Qìð!Âä2¶Áíí§gHrBÚÀvcI>.X~Ro¿®…ÇÔ8ŸÂ!]oT*Áò4¸ÅrÒv¨2¢׃SÁœÕ~º-bVÜR‡6ƒNó Q&‡̺©Yû™ƒ¥>_iœº¥…§,cøcÒÎ*tîà$^‡GU°ؐê^˜¶†J³°½D ӂ!׵”Àô.^´l<½u1-pw3߷Í9Ǎ(¥VûtF×ÊëŒݛ4˜Ükq¬÷ܺ|R¯
~¼2qusd›OÖã‰ö¦€ê«S£–Oè*͜R‡SõIù
éXM¼kC€ÜôĖ"˜Gú¥8-º‘ÑOýæ—´µ7q§]öfWoŒ^®a-ÏHհ»^º¢}Š×sÊãkæb¡íh:’߈Ð拈"ë×U[˜Mÿ0C(Š8cF̚yÇõDª‘xºŸPíÎæŠ ’ÐÝw[ÄFÈæ¸Ó|Bt‚aN–4§Ž¢§fËÛüZìÐyçóàb%xœ¡c.Ÿ֫q~bçòþ`Ä$_³:3±.¦.MŠzw¡x­hÄeÑ@6ÎAó"]öϳ%õAüäòP‹P¾Ðjµ…êM¬/ǪŸžÜ"êuÚW—ˆ”åñHî(v«ábÑä.¿Œ”~Gãë@úʙí.š\9–EûFŠo¥
,%jLŒThA¾ÞÝÜ+}ï¤f$¾ÂlŸŸ‹3å ݝf¼=֜¼Wðv7X½«ö×-•¢(ןò¼ã+i'RŊœÀ‡]	:Ϛu6¿””ÁØÅøÂN%™ éæÁÆEނg¥£ùa}å29~ŠÖõ¿Ñé~ߺös|ÞÿùËãW¸÷Çòÿ¹±î£ÈÀMÅ>¬pկðÉùD…º©ë¥^L‰uSsÎ(=¸ªQ"0îñkJ"'<Ù:÷'ž$bážå뾺¤°ž:>:ïøªÊ$ñY"½.n7á ‘ÈÎùUN¡ewx>9JQöq(<bRÅþHxZ	3pXw•ªf².·d‘d·­rÊ=qà²Ô‘ùXk°ì"·ՈìåC͞}¾ýsÇ!ۭ©aXT§m°pe4t6iîqàì­jޛ©gɰÚ>¼°ŽhŠbWNX–¯Ïc´¾÷	ĢT¼%…OëæpϷ̃>0+á â: é¤Åj){[åH´Œp×¾Yõþd]²°΢Å2ø”=JMà'eqµ=Ҭb®`ðÓաÁۋpÁÂàE³êɠB V“¸Ðš¡ŠÂÜ#WI.”™ýsF£jQ­j`ÒÎbEdiDbI‡F
wæKÿ¶î8«±$æ´d'ºîY
7ñ‚/4êŒ)^ '
‘Ãr†T؝dX+uµâñuŠB˜Ûw Ÿ´š§(+ºùéÑNíȫèV9㺺ÚB4´`Žf¥m@VwÒvnX­,Ƽ̒7Z½ …bƒÑ@M.^VIçF\åË$tç€ó3Üd{@ÜD!¨9¿Mdz~=ߨ`ïLê}œŒ½Ü'!‰€Oœq$õ¯H¼²´q“Ž+)ŽÖTŽU7><*Аe½ÝÓÚlПh³R:Àáq•·ô޹ä:#¬̬yeq¡Q¡¹…ô÷#{ËM•Ëàû±ÌÑ\Ä[@­äÛ\´Jï(Gµ ýõƫ½§Ø[·*¾oÊrAÝYƒè~öWxðÇíËpa��ÂR[HyíZE½¡©=WÞw(ã
zˆµï!SŠ=k¸ùƒ¡œŠbʛŒ—ع“h¿­â
œóگA—NӋ-;Îqw0„+ïL>ü]½‹py¦`ðdfì5’¨µíR/°îj~V6¹ß
g:æ—"$
náj9Ø?‹¦Òeµ^úÒ<€ʕ*ÙqÖ!#«xô°N°)0Á'F0÷1p§ÍÈ8£Nž?¸х¬;?‘D(mã"rx&9ý:Ž´õxl	ðšy¼ÅçGWÜ1±+O܃ź°{»Ü\ý6ƒ®I˜&¸A¼E·Ùt
1‘)^\¯kŸ؋^›ê„Úý±J´‡YŒ]"³oýB0^2%°¡½>Æå²Â÷™]_³ù1†Ûæ)ApÎ5µb/àKx¦³æ7µ2»‰4ÛN3p2®µ<Ѝ£bN_ëÇÃ:ææpœeÖsY8]§[ի¦Ê.)&üA•ïݐ‹›D¼@)¯œ¸ANZÇWpcí{GKq‹«rå4.n76<FÝÓÍËÖ¶Êä~tjÛ|Æ_£™êÈk·»ZÏ1<Æ
²EßFc	°3Rüœ¤#ã'‘ôQ‰Y¨M?Š>ž2ØÝq£0>a/J×t?ŠŸnbZö>ù0‘iœÎõ»1oo:ÊM`†Ÿü§OS
hú´`ÅÂÏðDžDÉò¾Op~v%ÛåWƒ¶l½)›RþîÕ)\¾šÈÝ9áyî•ïïãÿ¾>ܣ(šì§w´¼ì€IÿFVã×[o¾©óʶxAN¨í½÷ÆÀþú²-nLÏҖÚ>áæHK¦Ճãݣ¹¬¡א£rêÌgÑG1|ïtPê͹ν†C)ÆQK¸AiœˆX ,baسšèˆC<ñ½˭ݍï_eá¦{æåsZóËdW°ƒræ‹®¡<
I¶@<Æ"]Á
E–Õ €¬—yvü¼p	²{xB¬y½öбՕi;>H¦r‡ÖÜ6„lå¦)U…§ÄM›ò°¯OˆEo…‚³õ`9žäRF\ c¥pn*{#‡	,–ªœ‹RͬÌüS¯Õ¥ªX]AQø‚Ž+ºqdEEi7@÷b)̿Êûà7î¯Çܶ÷n+G¼yºÈjvd„t+»}ÁyZ‡f¹û
ÈH4ÀÀÙÏaÛä‡>M¦F¡}Ó3O/+«USÀ}�'g^‹¹°õ
Qª#I]
CH:–ţí•}ðY$ÔRUŠ.	½°" Œ›¼Ö¹ èrï¸íÃÊ'lbx•?¯#QµypqàIÜÚ4—BG®YØW==—@×7N! Ö֕ÌØt÷û‰A^ð䊕Ñ1a‹ÌÑF‡“ÀÄ'ïÎÏ=Öç‚]L·²(D˜;Ž÷Œƒ@¦Ÿ#
#A)
«ç²ÖGݚŠîm8Ë"ÊÁ7ÛŸ–™‡s$îXåìEðÐÃtÕ	¯ªYbj /`ö%¨z†¬™O¦²r§ñ	ÔT^V­KЕB»’¹fŸ:ÚNãd½f
K> ]yX;HfZÑQXöXB…ސ}æ”×qÞ7†àþ2¾ۧvû˜2ÇÍÊòõ1қĿ¼Üx¤\۾ä|T9¤ôªPKÑÇc*rደíG¤±r”Ʀ\u95\©
eÁ,Ï=ð}
?Ñ)xqɞã39ü(G©ã±UžË7$(ŠRQ²²…4iñ‹áwò¥‰Ju¥W£JmƒW0~/6§„gÔÆ߹ÎÝ=/Œ2.'S Pü}'¹ÿ+yÿ#’÷?Àýþ²”cym²?·x]܏•p}{ōû…©âS8	Ñ’îHk*T°àXìd8F;HtÑ2Àí?2šM(
°%
EyNE §;×u½îÄ8‡.b§ôÚ<í¦"ëo·žt•­[Ëåë'£½mÜ:o>A·¢‘<œÃGؓ5h]§ܴn*ßö7¸ä՗ª„{é«ýÚÈ[_ Ê3HêÙx¼zO.³Íf¨nÂQ-¶ç l®ûÊޙgeCqjˆ¡}(¸ˆ·žèyGŒ•~}TõûçÊÚÃ|ð¹wÃÛ,Vëå`“Òfj׿„éû=«e,UŸÓ2îšG·Àv畺Ð|OAº›닜‰Pf‰C4§Ö,#©'֡°wl
Fú¼ªŠ+mßDùJs
çQý¢‘‡kAYT…ÙJ ?èہL ®ª^þÌ~·ÝaQmìÄÎyI\‹#8ںÀõ©‰:c°ŒìhónS_\
I9tá*"ržv:V·ôu•™٤ˆ&s襑($‹çÙõðÊèEû12ÎÊ
ªOÿö{½¼\ÀÓS:d°9“”›Q'¹AãXY4uôS'q±R³:+ôlg‚ÒûûuZÂså¡(ù:fQÛ?jÉóâ‹Eq­çÄ&ÖҾª‘^‡᫖´óÑ%ŸFA•åýծò)ÝY-¾19¹}a¾Ä ÷ºÂSýÇ-‰?[ˤõOM9N¿ùù,ÿHïæOe~o¯ð·e>¨/?/_Ùí{ó?óä}ýƾà]ÔwÚ/
§Ä’üEý’úKk^_ë#ü’¾ýZv½—Söaiôq²úv#þßß(þWã³ÓrôKúë+#äí!ñ?>´ o{‡·{ñ·WñŸÿ‚âÿçÿ~"Ê_~ÿÀÞe>
~«Ìé›eÞñWޱ´ÿã'ì…ð?4C>?ÿZr»6´þŠ¡ý'~z_¿õµ>NÉð‰õ¯þ¢ …üþÌIQò«`à_tI²¦)û±ÿp/þëþ®ìLù¯Šÿý³ÿWſ¯c›!ïëwî§½Ù_-߄jqé!7Øôtx觮þ |Íê‰Íþ®=þço)ë”å5û¨ä†x*²à¸BØ <õìM
Ê\ö,W	?áëkjd%…¯·8Î3°Ï8åá®Ц*è��}£n¸Ñ^8±.اïŠÏÉÉ¡aµÜ^\æ
Íã²EØyºJ|:0+]ÊvK›íÌ?…^Mçœb|ÊN¬tî±9c ‘ê¶à‡Nº,þ(­3+¡Œ±Á˦†¥Hî]h´M·§…£—Jy“Ÿ.”‘w¢OÒãf–ñ…„+9|AHúíÚ[BSg
´¥¡¯ºTYy™xQUtå¯ö“hßáÏsÆQY mà<¯ÓÊ%ï5²˜÷§yƞVEl£:+/¦5æS3&‘	][¢¼V–3{f%Ž€œ4†I²=¿_çýŽgRž¸ÐÕIáˆHmî›`ÂӺ•Z~ˆÞk/óó:ô˜ÍVÔU–	Öâð\hŸoer‚µSÛè¶®ÓM:	¼
?²9`·P‡ÅsÊ霡¿Âidhµæ4úyB;âۅ€ë=
dõf-­9E§ꊜÊnåRq…€_ÌÝ
Ò¡AuÀL­.!?Õ>ù»µ[e»“ZcÐÕ÷s-€ÃÚ>piHÈÙwc7ý³DV‰9åZq´šµú‹[´ր(,#°8ª!dm×Qg– 3là/ݒÒW¬aòü´‡ô™oKßÖã`ƊX
BöTçÆjR7øµ
’e§aÛföƒé+ä^r ¢VÏP³™*µÃ(Ú%YM³(7FññZè¥EudRvl$&á˜?´q<¿X9°ÐS†)«d¯%c0t3n;l]Æþ!¸°¶Ì%@H·äMrÅù¾¦»ƒãVMéGÎã	ÔÕ£6k¯™yš÷“
³j(7ÑS&(«¾ÑÐ
%s…$aí3uÙÕún‘^Ǫ̆Ý hÆãÔ8½??§ijžÓuˆŠ‹eÞ!UԹ.ËÌ÷\ªú°ßsºË9«äžÎKh!.—æi9+G
õ€úexY¦`RU<=Qh¶…Ú-r“É
:¦wéñ]Ê.3_£ׁºº^›ð˜äzKÌWÁ{x•·”zè›\{=çH<·<°ƽú¢ą̀ÎcO‚%ƒãé—WTš¶*îÒO(Sص¸m€çTOïñ-‡eâ:ËNr]j>‚—é{Áê¹XÝl𜁧yt S%^úLŒ*JVQç“=KÓLƃvVêÈ:©p®ÅѰ¹ò/pÄÛÃ7»–ŽL¹`,V0;¡C©YqŒ(Z}EGFá€.®R‹ðˆšì¦yk¯°F¹xە€'ÎÎRˆ¬P,äƒíòMˆ)SX7¡_!èîÒñ>0=b+Á߼Õ]V'´ÀiJ0LÖ۩»IëÒÿï'û’sÙ|žû5*ü*ãp?ld?ƒ™öÈØüuܥ؅|.ò’½ñ€’ßÜOøYþbúÿ•޳´Î>›þºgŸöþÐÔe÷ßäÇ븆Hª.Õ,[V§úNÝVï¶ôôѝw23¹ÈbV¸`“Èóýä!Ïï+°Àn
ZºÔrå;à'X丕ßVÑË/ M7w·&Tì§Oõâ—÷‹~†ÕøþÑ8¾n½1,/ûÙBˆä”{JÂ)Äê&é¯-4E´+¦‹dٺÕ7™U$çÝa±@ˆ®Î̟b6UU"Aм”›`saQæ@wsCNþiâ
Ê{i#sƃ89j{73Ëâ1»ÁH±ûsz[‹,£²
Æ.ÄÖ¦{<#Ry𧴱ç"yÍ‘±µq²9•iFÉÒ3à*QŽÂ::ͨ½'°Š€U™¬–È8Þpm
I”X»̧µµ(ìàûÙw¨&	Â%ŸMhž‡™[Ñ6CRoùL3¾~Ð&³¡3®&öþÙB¬v8Sîà“i>ñ!
1;äû'~“§­ùɞZNb}¦4½n¿E„Núñ@€Á[z®¤Ñá±ût™¸­šIz½ªZúù+»œ‡92(áÁs;ƒn'Ôyu€4©”7œð‡[ðㇲøëô)ÛÞÄåQެë±Úå¼UUš·“îù¥L·9‹}¦IÞëà¼ЀÅ0w‚"¬Øýø²·¹I–³@Ç#ï}°|KöãÕæV	ãj²ïb«•õâS æËáÓÜACÒO#‚Ø+1ü›e‚Z±ñã'Œwôî9-ê.ÅÓʚY©ƒ¸à“hÒö%êÿÀ’[7#}eڈž»Ëì<Å7‡—¥þàFnÀoD•"#6µٰžÌs?¢Cßʑw6£µkð ޝ`遆Àþé[ª]tùQÏEoré}yò?ŒéoNJK셬¥KŠîÔ*Åž«?‚ñh¼¼
R·æxN1´1֮*}êN
É^,…ru1cH[IX^ñúŽ”
õß_¶¼sh[ôh&ƙY\…Ž[S÷"w
•ô﵈˜~ô{ãcòiŸÒxŽÖ\ýo4ùûĞ$_Å]>·ötwzÝdÏuç>®V2äÉVô3á
„‹ÑtQCʮ±­{‘6ë\ÿs’WGMú#@RKNŸ´Šø{.j+ÙKaO–ÿê™û«ÔrെÍÍ\z,ߋ‚µÏêyg̋øûä”וë÷ÃSÜq_
5½3vV‰üÃmvºÂ)šÂ[¸£…µDñ©{Š^%{бåµÖ^jďC=•iÙq¤i/m!¸)þ}b(́Aޡª6F¶ñrnÇ1`õ–ƒ$;ª­úAÖf«y:–‹eŸ…óA•ÏÒÝ&ùüõS+Ò#§*Œ٠ ]9ÆRÑ4õfž§szÜmVÿ²Ť"T‘	Ã1ÇÞ)€ç«3íŒH+žƒÌJ!•ÓêO%m9Šc¡¡Ö߂oç®íxž-öYh¶ÑgÜƪ9`¼òº’P¢‹«=Ô
ÄJ½ÿ;¨üÜçús¨YâßPà?³E/ÿ-,[º¾׶ø{Á. *mývÑEç‡ /óº?Ê/Ã,ŒÎl"t–ȋ²êýt٨ZÚ9ûEvь“ôû‹×ÉUÿa¾b7¯hh«—ø¶™/7zÀJ÷üîÅÝøs"Ðmq"—s¡@87³X„޴£þ‚ÖIú˜'^Æe	øºT±qøy»Ú3ÀÆR¬Üç6ˆ¿á
Ñq˜“«ì0à:õȀtIýñ9­
)ñ€
ïâ	ç¥ÂîMó‘ó*ô\¢L­؃eñ×°áqç׺õÂk蓮bÔú"2}8EÜËۙ<_CreÞÖÂû§å7Œ%RÿâÉËS‹õ—rýŽf+¦ ÌMÀäO“5'Ò!¤ž¬g3Q‰£®º]`QÎ1&œ’Rߵo^Öÿ¡¦ZpIãupâ­_Fò鴕içêÍ1·Þ*%‹Ƽ&õ7€Žùý]ߛ譛Úÿ2æOöx†œc˜.†¤hyiQÎ+¾€b™_–ñÐÑê¬G}·d–<Ãßþ<H.ž‘‰
òøû äϛøCl¡è÷åCsVQžݺL\¿ïz9““àUD—ó{РЦeY¥…„Nvå9ÏÖm֛:¶Þ"v[˜ë¼8„b†õsmèÔäl'âip‹àÁݰqD&ñäëÝe{@”‡•IÏc\ Ñä…Šõ‡axD¤¹©ïj²ÄõMuc3WÊnŽÞstŠ˜Ÿ£ÿÜýj‘šWr™„œƻo }'¿)DU69j-«?¬̶Ϫ³)ÞÛ×p§ö©K©T€¼AJ¿{Dïaˆ‡‹‘‡w-56þ–º‘˜Ĥ+±€ùíàˆʧrO«[+ic‘Î\9ÏôìÓ/Tù«ª•x¬ôÂ5† 4ã
Ÿ›¿§aøÿÿì]Y£Hþ+£y±#îë13Á89lÆƖ��¹ÌmÿúÁխîêêjÍÌjw4+
%$IDfòŗ_&·ߓÄÿÁ
ã4¶õgB[âd×WÞÏlõ•ÀöBߎ´jÜ›ýQ
¬u8™ե`´
G¿E­j4VýÃKª„ö"%/áÔçs“³|fù*8PÕå,|ó`ÂãZ%Ø
IýxÊM9k€›ûMÓEæ91s9x‰c¯#œ[Äâ‡Ùú”uC{ú„áùyoxÈÒéíã®çlQ‹ìhKËunÜä]žCïlßžspcé—7Qâ-:t¤`e ëX\u2K’myÕÑúÞ+ÔÇ&ª”BЁñ ¥GDȗ¨ij,¤Áìù¹9ð6¶µ±O–hB™TQۚ۝›º`Ì0¼[wÑ
Ů¾×p€âå¡p7õ3
‰‹‹ÉkS±Ó†ãp°	ç,Ílé#š½ÙéÙҧ†۾:x±\1°¥©éǀቪ¢d=s1yݫĢ#ÏÛ/#ÙÇX&E¡áóN"+iƒê;S%rÏَsQEÝz ‘oÞôDau‡6*©–²A¡š¢›:ÀÜÑM‘g_zbD¨éÊFӪ)*(̹à1°pܝrAMvʕQ{è™Ç
ébSk»B5#[$Eȿ§{ǰÔc½•á€EÆ8ÜàrÞب`›¶ª½È0¹۫Œ×}{Wéù~GJ㸂v^$ݲ¤'e¬M“)?îã͈ÿI§ùËA=?r‹Q=UEýýa?ú®ÂÿQœúDEƒuÏîéA+T/+Õ2<Ùø`"·EhC1ުPµ2ŒwÛslGGõ¶v¬ΠòƒxB‘GBÇɶåÂà‚ä¤Ú1QøZ6…È_Ê·Gÿ¹Ž\¶'8B}®˜ìeÿÅ2GB—“4ÅW’DAìdfx´ýmùxŸŽ$it;¶NI\I\	d"¬W–â“(Gђ9r>$7Ë{`Ö^©Û(òϙµ<{)*·µZ+[ó:•Øû¨¡äÁju٫èƒ$dÐ@Äotd!Տ#ôÊ9¯W¨)¨­¬ėn*m\`F?J¬æ´Çú2š„y6€r­g*¤ú8E6WŽJu^tÛ:\"ܰG§À
Sy–nk¡¿ø_œ¸|ºmX"ÐÛÒm&v3¡°ö*°MTÍ4’‘Ør¼)†½ÑÇ‘æ®ñ	X=ÀIYs‘RǤëzlz3ÒÕä2ûdj"›4›ð‰™H“Sr”óñ’+Êp`	Ñ7xVۇGÒ>Þmåe3q^?îG&9¬«ؤ%ÂF¡sGdC¸Å,˜3‚[ЁËr0ÁuÊB3’#°ÅΰˆûUÌ">1C˜«~åf¤O;ÿÎÚQºÆk‘?…xB9R­n§J@tfX/*Z:àØÎ)Òh…—èLê®pò;SKtDv¬
\ÊÏ2fp«ù>åÒYy]2ß@•]àÆëFa‰n׳M'F‹h-eý(Õ/Ëô>|M‚:T؃Â0THêÏPdI­ĆÎÖ¶ÕÅXM5v2&#/Ӄ,Lj´¥ÏY·Ël²&²ow„˜Ä÷‹Ìö27šÈêÉ®da–Bª¡&@ê)§ȞWé*@ƒ.Ċ
ãMæNÎU¯2*ܧ8ìWç»@›ÇUNÑf¯Rqå¢/,àCŽ[×r1¦¾•ØÉ`OÿÃoSn´«žë·*ì/àëß(Öýó#iޣ‘¾*øORÕÆ&ýÇô;€¥Oúd¾0M}@é½h§x	ââ+Ÿݟ|ןÿýÓ[`Ï7–ü•a>¶¥ðî—â7Èâ7S{ïøˆpõM[übó·Íñ›Â@çE=‘lÝKõä€móä{¨Ø[ƒ}6Ç+†mÙü맯;ú—¿š/ü{bðOÚzµå¯ñ¸TèޞùŽ÷ßÿÿ­]Ë‚0üãIá šÿŃԪ`Múóîö.hÐ	Ô�m!gtn©âÛ”=^"¼ó¹b¬âM‹3¢юܯÑ&Ùo5mìsC%…âQ¿b¶©ƒ’âXÆIr=Úá°<r¹ƒ­õ(•x β¨L}ڶ¼{ֿžFägÒY$ÔÎîÇD˜6lR‚j¦ÓbÃtÌPÀòüÝyÃ=T\0ØM2Ê~zÞץ¼ŒI’zí¶J÷ÐÛµ<hCÃwÉ/B¦½(½鴮¿®3М—è`ø¹¤@&ë}…NHS›™EÌA¡Óm™º6šÃ{³˜MeÖ,ºIåZzuhåʔ ý‰ KòžÁXà]0Ý4†S&Þ"
Y)ÆGA§vmãÍl`–çç Îý/yzh!¡?‰‡gUËÒŽ@õh7Öl~äë°¢šû´ûdt½?î¾M¦]0ÜÇ‹ÄV[sâ8}ϯPÕÖÔäæ`$„<Ù`<B¸“°e[`[I¶­ùï+™K&“°[û}˶[­VëôÑiÎAÄ+Š=ŸƒSûhjñ}ê>%!NB 'Ü'”]=@îÈEÑ9W'€C€¸€û˜Fj#`ñé‘Ñ9`¶ƒ†Âø*@ À6ŠÄ4îCl’‘\’D°#ðp_7&pq€®Î''…óópº0BpšØ<¡bžƒ‰ƒI­¦dh¶À\	‘ƒ¡b“ˆS°˓;è·ÃàO±v†î×ÄÚ>¢˜ß	‹ä^ߘbÂ0Ç$ª	ÈqФÕÁÙsÀéÆÂâ®jÀ
ÐRäSyåg“ 	£|D$¡¸0āpÿÚ'3ÂÉ×Kðõqód0bŠÀ»ÒYL#´þPUU~ÎƱ»Ê7‚"¾YNA‘#a€½HÁ…L¬'†ݯÇðÕ@±‹ä~~žˆg„	¤?ñÅ1Tl„“°òL9ZrGNžen‰¡ãàÈÛ~…z8Ú~ÌÈRf˜ÎuU„éîä=`?„@¾‹m޽”·¨ª_ò-¼ÉZ±ÌNö‹G$BGK¢~Zß9À8FÂÈ%˜‰ºE0x;í},~O²Qڭ›š	ªbún‹¬óª-·•‘¸¸ÉjÀǎ(æݫ:ē<¯GÊîr5^¾)ĵí°4eÛãÂà€Â9hÃ9þ¹Pd8$úÊwGRf©8ȅI>	؅—"³%WA{áQ)/
¡‡jRn„EjţÐÁ—S¥XUä]æƒPoOµJå¼ü©g@ýò‘ÕvsJÚÇ>·gà¶úåì
‰Þ/5Sf‰8:dÓ1ÞÿˆV‡,¢$ûEN^Ó瀆'yážtÚø1)j*«H€ý}=¥Ê˹`“´l)fx&JQ$<ؕu‡ùl˜(h ã0Ÿd@¾ïvž·¢œï³=OãS¾¿¯ðoÔã˜C‘ë]YmÓ2=)/
¦´=ïIPeï§nŒ/Ò)2Š—òq½ùrÏ2Cѣi¶qÏy¶?ã?÷º-ç#weGôiE’aúSÝ|íúqÔ0áèȨïºþ2ÑÔìϣºI0›"™ñ;ŽJæ0úQΟEÞñûèè¿LøN</@Šì´È©Åòü±£WsH:Gïç`ÂßÉ7ÝdÓɴòö¾P$Båʲ}=QšÍåìÕm+;]ø@'v¦··©íÑßú¨o/‘8ËÃàյrÑýù¿9§›káa#ÞcŸ
Aæ§yçLhpê@k¹½GÞÝ2t]¾Äc£ÓÏԖå]ü#ßyâ͐ú¤®÷äGËMÇkixfoÜ/ëOmÝ[Ù|aµõRÁ–³iCÏ?t£¡W×Ðhq½Úó^Æ+Ò{VÚ{Ã83ºٞ^ès¢›n8º[–åfë¡ÕõI¥ºî¨=kõÍHŸăAÇñ¦Ö`ٰ[zÃy¶ŠŒÇ2ÝšÃÅ é…õú(.ώ@ûŸé×ÿí‰x4<g]*K«±Aû£Ò(Q©Ù3†Vuz»=O¨ÑcézW]b‘{+4/¼X?\·֚‘¤7&ãÍþ­qó°ò`=[y}][~7úaAõÚß•Ju§ÕrÛ,h¥ØO­ۊõ²S^[»ý̟/ÚújÞ4¦S±ÛXXz÷Qû–è¶\{Ôi°°}7XFÅu֤,ê薳²ø¤}©ãéÐí¦i8@zyZ^–f÷ZV¤ßKOz_7Z‹zëG¥þ\Öé ֦E£Iy}AÕ)bÏ3>ÁzHÆãTç(c¦·Î0sp¯…FÕûÙC–VWcœ¶»k½%·Ëˁ;|žNŠpҠ÷hÒKצ:áõ¤c¦ZÜ2/*3“öæt’Ϳi|0軘Ï*•ï£ƵV½0ø¿&+ùîü
Nm&üWÌzP_˜•ŽH£×XeÛ!Íæ#oº·úƒUbý~cðc¢Þ?ë¤7d}s’š=¿ws3TuÓ쵲§ÙS'cÖÞ,ÛڠŸ.=«»x£uJíN¡ëmÍï´K‹çiÅK;֭ߘ'å¬i•«Ú_ÒK‚ еðS‰-ÑB$ə2v¤¢Ĥ†ŸòöõÎð‡Y$€"C¸!6>ÐqT{=×|9̌1…
HœÚd[ºþ ú%šŒGJÎôˆb ÚáTò©Õ6I‹õÍœW»”Ñi-é
¿Ž㷎íî^âcLÇlrA8³Gåß[N»ÐυuÉw.ò½›Wï*P5 ½N]Píu"үµÑO®ޒ ©6pŒݕ1Â&/š´Hþÿÿ
/qMM3sµ4ËwÎÌtŠÊ7
3Ôw
ööŒÿÿÔZY³¸•ýAT0«ò ö}ßß0;˜Ŭ†_?|_w¦35ÓI'™©©ËÈÒսçœk{@T‡jΰ­SÄ:’´è£vӧ'áðìfÂwȇ ø<@•oO·Ð"D]º½kÔþûù;”<ý¸޴õ›’ú¿w­.Ü_\‹)ÿ%"ÃuÌž‘?Ø#͇|“×7‡Êámgƒُ/Ù,›Ç=ËÄ!ڍ~2³ŠV2éžÈMTÀ*¡ñJv‘ªŽÓÅQ–¯òdy°{*“uX£{‚c5‰ë'…2$gqbUr›ÏÛ·™ú‘)©
ãdµ‘Éa|n2zÊЇ¤>³blƔófº„	?îé?GÍ#/õá~?ó™=—;ÙyÄo}” Ôûwߟ˜´`‹_Γ§,]_1‹÷QÈÙ6¯™��._q½ˆâ(¤"À\'
5fVskڛY…Ã}"råŸl‘9ÏtLe’¬ëÓÍ�b›
Î&kÑØ|֊%^‰GOaaåÂÙ߾º]jÌãr/ؘH¤tá>ÅB>ÿ°ž®«r3ðÞ^17–ʷ8´Q
\¯’
˜ÅÉQ.upŠ{"ÔlŽzO.1¼|Ùéãª-ã±[
WIb›TËeš;‘6>+)L§÷¾½ŽöΈ¸øsöh—jwÝÝßïéLÏ&=Ç*(gµA€Ï2rÆ‹.)­Ü|@˜ÇMùì\:¹LjŒ÷ÁÅñ	~ªþüç?
ÐCüÿÁþ¿„–ü›ЊÉ¨ª¾ÀsB.ÓN:¤á×6<&Ѣ¥÷¹{Í?Keÿmáú­å6Ú_Ýûÿe?…ÿk¡*ÒÑ8`θGëñø±ç^’ü‘mÀÿņèéž×߷áÿJ2øWÿŸ[Iþqʂ_eÀ-»%ígTõŠæ 6€Tíiáý¼2bä0ÒïÚòã\ãôÓñðÌQ<ߗp ›7~ù9Ÿ´û3Yø‰ó…1¯C°É^ÀÇ_<¯“‰›ÅѲ¡»¥¡Ü{·ð’“ï:¯õôø­M}=ñ\GÞ‰.—{Çùïî”û7&'‰qŠbtÌ$É(E>/:(
ø	=#؅:ªŒf8y¾	jˆ°“þéïÁA㬞KçžîSî W#ì×G7ýFqüLGCÞ¥8¨žnM£Ù@QK(Ï´fÈBi5Ð3¤‹MJypO²ȗ$ºbUµ}<œ·æùkp¼#ú«çá2¢'|⢫Uµvâ˜K«{4t³ø· |ÚÌíœüö.Ême þ£QUìýHá³wxšÂúî®&ä^©£1äÐJ@yxr‰¦v"j–àIºîaë q¼Jp!—$T¡{“2ϝŒYÓ{íÑWÞð.ۂw:šÂ#5Âtͨsö&ìƎ€ ï]ÿp±±±5÷E²K’l0A mèÚ÷”Z
¡Fæխ¼Œ‹N÷R¢¥»žª«‡=$úÕ&¥¾>6AÂM5Óz“E:¥L’г±/OõÛ¸’Liô 5ґ(®w&bҩ© ’ë3ãÂêzè²ÏC`q¤ª'Ýw¢Z5q|×Q`k4D²q@Ãù½:ƸÏ÷#…ܕŠa›‹(¥áÒûù:ŸӒOP#óųÉ%ÕKJOíÃ1‘¢ë•õ(Ҵ·Â"ÂN¥X™ùõ\íõ‚Z=þެ^ P¦5߅¢Ê3›û¼gæ@*¯6;ݻc¬O	ö.xÑ8•g•+ïcø¸ªüÆ|‘ÓàEáM&¢¦fh²ÙRQqãϯ$šץ®S˜¾„P-–'
™¡q«f;5Êë<í ybÖbGt'¬~gþ꼪;ÞgŠwºæC}OxüÂá”ȹ=ÌñƒÎÖS@ÝˮæE-Wô7Vî¢uˆ§´ùò•8"æ{ºm­ó“=˜fGxãn«Çî+'éýüÑrdztîL&ƒ^ïKɟVީ—¹bEÅj
‡ªÿ¯ ãð£p°ȲU
HÝDdqUL‘Ý÷–È=Œ÷4”­UR<ÌÜ8ÇgåA*±ð¨¨Z³•q ˆÈyꜻð拭Ãyö±=x>¦¸e¶¬eFÏYÜQ]Ppq¥š)ÞøtûòãxéÁšz|
iy]a`CB…ïuk¾úhÌñL¾íóbMò‚Í'?ù°e¤Æ(W©ÒCÝHÇ×6»OŒ§yL}×áá"‘1 ƴF±@hçФÉKúêÍ?dٷ|žµ4‡“ÔڦI{z†ŸOJáJPŸ	Ңùý±̫ծA|_³ˆy\	Sì&kH~Ùï%’¬[ø¬uFÚë› õPe§GYœþ"­ôD*¼Rؓhè!^ã£+Öjðö†ҟVµ|±GC¦hvº°þG<зŠû–¹üÂÊÀõÓQ	6–å?ÿS,ú§HÿôoͥUrûÑî*ÿ…Kƒ+-r2ÇÍÜƿ”óSåT'+(Í)qÊ?ûiˆˏcq,sýÁÓT¨œ@z]‡Cò'˜¨»hœí)
{‡ï§A&M8sþöïX`¶òæÕGdZ^Îz‰R”B¥0:S&¶ïüƒ)
ðŠçÛ÷j†ÎEd‘äpRÆ~pà0T€ˆ¶ƜM«*M™AUbW3*‹11lM‚$b†#Ó̓j´vv”]cÒwø¶ÏäíÛæ܍ú4è€,œâ3¶`>ªê’XQŸ{·~¯ø)bRŠ‚[6þZÌÜf?÷~Ý~򌈃–€ª‘&£fL~H±`êѥêÜûЦ‡#0ÁdžøZŒÊs«¼ۀ:?@~B©ú`ö²æƒ3kÅÀàK3ó¡J E
 æ;åq~¨T]õU…MxB^¢TɳxAA£JÕŠoâÅ`UlªHb逯2p—ÎhU"
å	íŃî&Äs.„øN£ö’qÁá)•‰–"0gÂÌ\O^‚Õ
P/3Y¾8‚ÙëÒCí8Š2ãÜË6ˆ¶}èB¾ÕpÈH€kÊa¹ñ¦y°4#ž3r8«z±óa	æŽ0Cæ´RÜy»5Ød?D]p…k&҃
‚3ÑÇ~—OäïwcɝëÝ7A=ßÙ3ì¤6%(˜°^ù4àH潐ä`h%fW
—3ܳim>ns.ºP‘ýÈkÄ0OLÚhå°xҖ=“íÅyl#=²µnÇ{:Ð"ÓìNz×}yϮ­óį;ŒÅ؅¼ò¡^´õs«zy²å{XÐ,ޑsÊäʖMàfÞ&õ)ï!BhöáÇuàðì-=:5ÑÎÜ)ù#3ÔÙÒDN}µñ¤«ÊÄ6õœîR£Ðyvá0%[›Jܛ½²[êÙäÞ`A%¤ñ•B‚ÝxM‡?dëú%@Ïl:„³l
æèà¼êYÎ7)¯jçÃOfWY|b‘:ú!“ð
ëà¡ã6þ`Ò:¯ìež÷¾TQ¹t·ûMUš‰áa~µæÅm­#¶’	’¢ף§¤àñÀÀ)×êþ6%ÀG»/Ȥ oÖ)Gvq ³ææ[¬ëiŒÒ.P „7’Õ^ËBñ„'&…˙LŒCUcÂÐ<(x»2&“‡¹£åó¼>Ñ#²Ê9ęt_¬ŸR‰â„ãµ3փ	µÎ©jMw”Êè3³ÇÆÔ{•~óGN4DpîKxÀõÆ·Þì˜òÞÃóô€˜"8ëjuUp8î9˜Û-Öޝ<ë_4ӯ°¶7wÜ×ô{`V;ºq4oß܎3Ï#hZgǚqw¨ŠäBÊݨ\¹?&:iÌñ”ü½‰”ÇurU‹$yœ±ê“_ùłõÔÜz[ð߸§9ÃUæÎôòêú^üèûrÿ‹‘ÍÊ©y­Tw?Ɠ÷^A–àYè¬ï> 
4[ž^ÛÏ>n0µèѧè»÷‰նGI°D“ ¾²ë¾ý‘Yë[×êÁD¡²;]úvþÀÑ'ñŽ}L·ʇ÷ñhê
ÞSV1Båø¾ ê3OÖ×
—#Zwè¤G.ŸrówAfËÃ@jûÂ`›dûŸÿ^çoþÎùSüO1ú~;ý÷¹¢–«ü踾ÿ)*0}ýøŸU–ØO)»•@ܵ›m·Ž·¦ƒ¾s‰J™½º--Bô
êº$Dµ_ۤ"ü\Åòø´•Žßè"á	“؟O]ߊŽˆ[{n˜÷—þûGS9Ùʹœd-±½`°Ï@r$»95¾4ÿj	y¬@,Z<1.Uv€†Q!€á¶ÙO<ØÙ¹\| ÆdŽv8m%w”c
{§Oà(-/Мªܦlôx@ìzʣõú@¨&3â˜éfÓfñè!5â	kl€³k3鸳`2Tk‡r»1Wq­SFÈrÛp8¼,slGúµbK2ªF¿+wž^W{µc^ýëµ#w²urØ,{gÅóÎäKü€uåù¾ÒL¬®çhžß{í
  ҁW–ÁÍS–ÞüD¡SÓw'´Œڮþsž:÷?¬ñª¶ÊÒZDnï&åÐu>Tc?Ø
3rEÌwbÛX­2c O'ý³! ా•ñóeL
jþÜb“{·bA±8Úð*œ}VŠ‘-u	¬—–•ͦÆNo»âóšçòêúÁ$ ¬8òøvت°ÕÅfEpáÃـõJ—ñؑ·ªudp³ˆ#äY3à¶3|‰þ,(Œø¾
Ö>j?ûÑÝc«
zõ±oƒÈ7ö3$|L£Œ¶X¸°־*ԢlŽ”oÛM|v@ÛÁæ‰Pû‰£\
ù`VåR(™´ꐢ…•)±ïkh+KÒãUÈ9Bš<š13‹ÆzVæ¡Êwd÷šYù{W
€Î;ÿ¹¿ç¯æüé2wå`¸îÞéSä¾Hٜœ2¶ï¿HJ.nmRZ[)ã^Mɒ‰ºTyly1iČg‰!µC	"—ÛJÞ1Óun©ÞÁtõ¿lÈ Å{zÏ›E8쐶Æ|ŽøUÕÈrÑô*î^u‹õA
ßq£��¥s2Æ]թãÿ‰ûäwŽ`¨ËJo
?|<…òàoù¿¼ú˿Øþ}¸¾wíuþèx;¿°/|ø!±FzCQޒ­c‰]àm#q¨€½VnyÚh±¢(ÀvŸ¯dù³V¾–]ìäwÝq˸€="ÒÛ9ètÕ\AŽÿžk
Óõ¦ÃuŸ§2O–žîö€òê-º8‹/°+©Ðq¬¥aæ
×O9ÜpÊW‘£«ñ”Q{½¥3NBˆru’ú¼]N©Óp³˜Õ,˜×ÛÝrm„)5O¾#´&Ö71÷£ŒËO!Ÿˆ‰³…˜àPñ6´}››¿ÍÍüøâÔìýòKÓ-Ø_:~4Õ÷‹:#Wº9Þ‰Òí7¤CH_(C_b¬]u0F-f˜'۩¤%Ü1îe-‚ƒ
i®3]Æñ%7"’âΩ£(^œˆc®¬;ü…E¶J¹/á\îd¨TqÕB•m¶MÕVF/‚鎜E¡¡m¿ÞÆüª=™•!ìàØH¼ª»áYÚÌ+àxÔ-€ì¥ó™§äÌèûǜ¦ê��Ew¶%" •ٰ£ÿÿÿí\Y“¢Jþ+}_¦ƒ®E{bpWÀ}â>Ȏ‚ ‹¢óß'Qp·ÕZº#&Æêèn³Èíä—gãœLU%–k¥ùBSà'	[m$®sH-XJRgæÇ¥’TwŒù€in¦鿿¦ë K…Н¡­¨HŠ™¯`*Ó6EÂ}–a°l+­iŸ£‚޺O
ϔÃå°?•r¹bQäxî¬*IãA›dI·Ø~]ñ¦3Ìk ¨\×	¨Qõ@,.š3!IM÷äÎT•
4¤Ã+àd6«
ÊZ8"Ê+4œ=ýòûvۓoŠË\¼3Lj§µï梪]î™NÙQF×o0’Ï0-,߫Ø媣höXÔAyQ›A³úäˆQ{(-ŠfÁ$Zž2%}ÞF4͹™ãÙ$1u–œ?ärX€¡á'!9ü$ ð‰m"ÅLGTa1§(T–u¹SÊG?\´h¯4X¯(ڈrþÒd†ró"ªk•&;DMY’ÍRûúò’.äk=‡u86›píÉ.je—m7f+B½«z9–éÑóÊz҅¨ç#ªhÒufÃ-ži2塦B‚›
4	«,ãϛ.ЦÁÊ$0¥M¨Nô šu9Œ­U1Žë€]ÍÄ]ތT¡`>§:头]E2š…¨ˌL@·òó^“ªʐ÷:œ.FÛÙ÷©(Wc¤#,¾ÁgEÜSmÄ[-Q•ôDÃòø"7˜æU´Ññ†H©l­TÖÕPIêáƢnTVR¾¡y1WU"1bè#},³ãÁÔb٨ï۰Nàծ2@…ÁZ`'­U¡gh›õ ¯Ǘ¹FŽBF*	ªÓ
Ýæpë
•nƒLá☭L¥¡–TÐæĨ!ë]æp†Ð
m•‡†ºt"3üª3\ã‚jԸIŒ¨IYL¹tÊ ŘvI™Ñê
'X:L…[Y8ʺuz¢Ó`é9k3M.êàè\£”´á´I·«Ã!ÖŽXéz¼ssJ·zrè‚öl,äôºÏ t¶…KÊC×1ÖQX¥hžfñ>›Ïc
Ê÷{u¶D•礇±C»W±
˛¯A_êK¢”‹JÅUYmçÆfЁ¦ª¯BŽäw6:®õ9”[OKxXB4¯Jâ¼+•R1¦̃"å[êõæÐÜ`"¾¨±­µLi%B;a"Sº§„•ñZ7´¹…å=£ìٲdä„R(Ôܒ½4†M]Ð#aõ…w“4&f¼Å/æJ8©p_Ùü‡á éº„“EÚ,c}dXê$™r	ϸ暌\”ê<‹±eôÚ>gél¯Kùb¹2
±æIVŽ_ôzn(ÍsÞL^ã`PŠ«~Y‘-A¾/Ó~>uûûd”õýd¯CÈô­l·CX5ERcW’:nåNÜÈzڟúϗn%ð&>œõËöše{¼²´+©%”Ö܋Â{©=NÑo/Ößw zÖcÿìqÂ#Q<
2'ö©$[$™Q$i~›òõ¡ïÿ?¿m×b÷oä”mh‹Ɣ¼®7Q¬pý¢D²¥¼ÊÚÆÒü`o…/Ø–üUüñ’ûþRÄ0'؂ñÍ3!_=_ƒ'7Q×/
ǻØûB߂pjÛNðš>¶¶³5ýx× _°Á?ôê!¼lDë”Yæ1T¡½jk/ªmhÁÐA&ªË(××o³þ4·«k9Z’öHZW˜>{7(}î]y‹;͈yµ56f	rY«¿{6k>M?¾ÅÚÿóè>·ëϦ
].êlþL8ìÚï{›nL\7G¦ã>ïlø;˜4ÃIµú
ɢÌޝ]š
äc:oZ‘¶Þò߯‰ ‹ѳ¦¶•Ìš‘#,ìb#ù}¯[˜5Ñ!°CÚæ_º®o©²WENeqöýŒÄ1hw0x-'Z'S`Ç
â´0Ãg’éòeՇжU²×Qw ߟúD\;
¯åånIýó’\jpŸ»XÎf'3B«»I¥„/|¢‡i²íurœìúkwx&Ã.€O®]axP_¹´}¹’—Ìå.ƒ_&´ô&ܓf'ÿ†éºæ'*Ím€¼÷ÀΠ¿ûG†ÔNÄb§7ðr¯)/:¬óË6¿Ÿ[¶]ev®µ¼°»_?ª¹$iJkžˆ×tàGô˜Ë^;½ö¨0@B·#F¾#ãc5Y”ÈOt’ÝL®êzŸ߼ÿÔ" ñ¢þͮüͫ¨‘=ñ¤ßϫà\”°9)Œ“ÖƱµ0Lê;$óí£·ԿÄU¶Ÿcœ´SñÒÔæÑ)PniG۱w¨´­ ¼zÑáaï„|ôà$—}Î؃nŚºCaœeŒ;qš´ìï=]$Ÿ粶ý$ñ±‹dߺ>”¼X™d۪	gXùïƉ³ªýkR9xz¥­*•r³íÏ[{„Å?x.õ‘’·ú=;_âÄz~¶]¯ç!ôàt7:ž²ÛÌOwÃ÷˺,ŸÍ
N‘Êü+<á¼ÆJVxåÌ|$RìØY³"ëIj}û{'ó¶T;áú¯¥>•®Å!ö§™,㽸Íz¿QN~§û{îÎ{÷}è{î ɤ‹†%?ÿãLäÄǰC'‘^Š+zÕï¥Ãùd7Ÿºð@ä[>‘ðWýË÷¼ԟï–ãÒÜóÄ-ÇR1&+Û(ì֛´0ÔG«Ú(¦hnf]}ܥF›i>Ü//.¨
±^sÌMü®P[@ÀVU¡Ûݾ%º•¿ò 纆ˆ¶uÍ7’ÏÊôê̍AzÙrDæ¬pú§õ±>g?SSf¿£Fw\H`°q‰aҰܾL
S
gš4S)t)±2²Ýî„w€i¶فÍÍ%…ˆ­‘!ѓYÝìFF±ÕgsÎp0m<´ƒ
¢Ëڴk7ÖÚçƒeÏé9¨j‰×C€ j]q<ó0©
mß)l(ëÛk…jýùläUû¯¡ø”NÂòr
”ÙÚZÓæÚڰ=.Ç|^ª¶jUÌʲ¦{ô„.tŠӭF×YÑúHSXÅ]õ¼TPBÔ5"7‰9e‘ØòÈFÄNˆ¯éiU#Œñ®ÿ$Œã…IÏô[l'4Úg>{¯önõ#ûÕ]kësÊAžö>V®‰#ïݕÒ{§ªp®‚W
¿2կ:»¨T¹¯âvg	ûRy§eèޫø= DÎß#?Kùk–ï…5¾/Ów¢˜0ÇßcZŸ£<3œRÇîMê¹w©>1ww(ö\í¯'
W½'¶âàÎÆ3ë-+ìkIÜË֧´ãoQ eÕ@àš/p}Þí¿ñ*ðÇÕéUky_œWì¼=ÔÓβ7%¥_/q—ž5ŸkþŽ‚÷”2{×éˆ]\w3^u{Oj_¯ػ‰ވ‡8ÄåÊnú³G-œ$2ÿô~Á÷D½T+ž›ã	 Üîi0|p¨/xÿ}pÃRRüH–áÓ+½[tµ~Ž‡q>²ëëðú/»[ºöI]‹íX[oâH~ï_QÒj4Ét“.ߤ5҂MmB xó¥06¾ _bìÖü÷=e›	¤gV«ծÔvÝÎ9õթªïTÕ×ߐnóȱ×	º2¯‹™[4]$®£ÐwRuÒdFñ
êx*c‘˜D/ĺù„zŠ	
W(Y;1ŠÃ42	2C‹ (Úá‰b!#G:êN¤FœäAžc’Ԓµž SA¨¥U˜r¨'H‘Ş6顕㑛߾~úôx뉫H÷	úÛ0v'înġ—&äԮ	Ey‡„ævG˙c%ëC1	·P?мGVÉkÁ×#Û	e{ƒ«¥ëÊJ°vªZ:®•fwhíX	¾}ú󰄦ޝWØÌ0Ht‡"ÂDOb„fˏÁÑ#ïÊ	œSè® ÕЫâQ7–mÊ~ÝÜØu\Ã½0ºC†U'Òwú*©a÷EHè÷Wô뫋¬pä£}i¨öÙ+àº|ÆoP̈±q’ª؈IrE§¥‘weé‰~W֍_ìÏ;ßûfè1iò_¤6o<g¶åÏr“õ^;ê„Ïd§ë¾ö²ì{é²5ô•©í<üb/Q&ÝÁòYðLÿœܔ{÷ƒzrϋl°õÕoç²ÔWNÕIf?1ˁܛñ&Ô[bwrò䥲ÈWm÷KÏ´­ÁòMYZ¤ªԱÇÁlkôǶ*nlYÄɃ¶LnȃWٶìö>lëÏ㶼٭Éó,Ÿ=G¬£/“ah
³‘Óz±8‹S³Püv¾Ì[9ô‘)œÆ.sÙ&}&6µIú»­áÇmÙ_ckÐi*y´ÌÔ*ÔÔƁRô„ÑtóRËA?6`èfDSðߠËËv8ŒÛåÜ
޶w`&™¶:sà_ð‘/Aü¸^ø;Oy®l˜~›1üqÓðgœ,êjœ£@ËϚcËLV,çCv9‘?‹;éb2ïÒv¼œ¯±Âj…™C»½IMnœv	~͚2^ö7ð¹I[t³“{Œþµ“-握Ü×âÅ\£>,,©ãÈ}êc¼SEžQ¤®¬¼âj¬:U3ŲªÃó–û”j¾½S‹§tԳ»õ<ùbFë™E6‘z ;ƒ5v\5֊GW³\Ëù2•wŠ»‰5i“À©W(ӱP×'uýâ3ô7•9ÅíÅ*Ìÿh‚ñh’á2©•]XCP·ï£);­ÏÕ—¬£߯³»~³—Ûˆöòéö6È*ŒÈßÝßlEeÕö®Qµ›ë’&IèНxîP¶®Ë#‹2›n9i|ÌTžžלsBbg8ŽšjÄ[ݶÂ,ҷߎ	´ÝßÑ8à5ҠL*=•²Ҩæ[ãX?>mMß	ìÆ*
Ìڏ©á˜
ƒ‰®ð
ÿáLìÄ\Ÿ*¾Ê6PlJÝx ì£ihøz¼i0_ÞT°ÌËϰu¹¢ášY?9ußeW5_oBÆ1šzš/È0ÃL¿ÍQÛ;ZºÙ=¡3[gÎ^XåÀñ¥ùe8ŽûoÍï±X¹ô|8ÚÀb£L¬øÞ;šü3:þßFÇÑtQnÃþÝè¸×û‰ŽDÆ"=gßð†ԡ‘,¤ßhº¦)K£Ú̥_7.#œÔUiÄS{T§K££0¢6æ¼Èq®‰<Èt ú=AÄëb¬AÄÓÆápQtbujÃ×I5'+ԜgIfªHÚIGý,uË)’
‘™FêÅ©)D]QsZ¾w•)µ
yš:˜Ê& S”år<]Iƒþ5Y‹1Mqe§&í›æ…Q'Ž:&3+1´ŠÎY=¦ÐQʽÒ.,ß¿ÿþ—¢q¹ÅÏŬš(?œãâóLÑسàO¶øÉÿY¶€ù¾w€)’…ïꬕÜ,]JÛt97Á÷{Äájõ—¸aº0Ƕ½`wk“SÛr a|°”°3ö°»s"…‰Ôe){‹°0ŠLï
Äéj4¥T1Äv(œ¹'ô쮲Šû”¨®
»XDä1e)µ¯&5#Ð4/™aBY@-™B´=·nËö=[¸•ž!b8§›	e qÑ+à>€	Ò	e¤–¦X–qQãcz~ÏK»Ó1³ÿ,c°‘kÚe“ÒœZ2a™Fƒ“IʓÙE*aTòÏ
ɡøýûÂ÷ò…¾£$҃Î*p†¯š®¸&¶ˆ}þ|cãý麴°7Â/g
1œPBˆtVнůRÜí%[<>؂#é[°ռˆ«y{°u{W‹9Øj]ÄÕæ¶l1¸uާGì_:_ð¤p{2ú³ӆ|låö‡ Œ üEãÇ0ŽìÐxg¦I¸Z•—¢:˲Ü!Ëÿ¥»Äëµó‚é·ÇíúšƒOê�aì/¹§€ûÚêðH=¨jQ¦}òbXݱñõwc~¤²s¬sa\§ˆ÷W÷ÖmþH»Ö8øåÍûæAy¥o½TúHY=4ÖðJ­ó3uÖõû'‚;‚Žõî堾
bĀ«s[9ñõ*\ú%§B¨‰PNG


IHDR22´6@:jIDATx^í—_h›eÅOÚüëŸ4©]׮Ý跑µ]ëæWél§•¶*¬xUôÊ!0±âUŠ"(ŽåƉ…Qo'nµNJÙ?l/4R”*N¢Ž^¸±tkeh¿.™íXº=>yyßôÅäM®„}‡@î~œç9çI>¦ÿx\šPXTP&]x)]E;qé*ÝÉýY*C9ÜðH¹QŽ2–«Tˆpò7ýƭ£9­Œœm„r•‘¼¨X¹»@ü$(N)"Öú's{ä˜â!҃ïÊãÙ_ˆ&h˜ ¢9to5ñüS,D ü_uÞ[uh@4P‚13KL‘ÊáCà·ì<ÀÒp»ɜF>”ÃU¤T%_$ŠH0܆C1‰'¢Ó]¨‚eE@„?‚«gœ<‚èÆO§¿?úÛ4I?CþúAø¥cˆU¨û{..!)Z[F?úÐ×ól63%Ñt÷æhXz1…ˆaU£áÖw››Iôb?«7q’Ȑ"Z>¦¼˜C¼¨AãÏո"Dtr6ì^þýR®11Š2*NÙElѼ˜C¾~U->D9—¯ŸÛH?qVBƀ(E>ÑãqЀðíë)IމdM­u%" ·çQ‡J¸M!®\€Qßֳ+XJ¢¹çطeæ®@-v c#ÏgI¹²l饜ÆC¨^ ù­`÷üq•%[xg	k¥<э€ðbxVܨDZ†MHzœ1ÙLrfòȱד3ú ³¨•A6¾]A4¡íÚy¢P¾÷çÆð1øýÇÄP½”¨A6»Âjù£C›+O±“Kïžysi–ÄØl½”!éÅ"îBhF»sّ^l1² Âî´A²ÔËR@Ôq©ǮOŠ/¡BÙ,%{1€H/µ9/‹d÷•ԘôA.ÊR@T«±»°/}5·èa
À>XjQ­”f²ÜK[<æȆ(­-ÿ09y„(*»¯—Ò¢eÌÂÞõ¥²)"ÊwίáIVÿÚrJ+%»A6€¨½ˆ¾´ÎŸÊg鋣âץ=ÓïˆRÊúíó¨Ï¢¼lÉu?›±d)חЅ½,{á"‘‡|v¢-f½û­×Ώ糔C:þür³+S´‘ƱCˆîÅzíà¿K™ÁVçó)†ÔãDßK›ôRèw…}¼õ4šŸvR cC2¿FïC، :õÂh'ߢ{نð3}+?Æ)B–t0̻ ÂØh©4ï‰—º­xäÄ+ù𓾺4»4ûó‡ƒý者­òo«9Dy'¦Ž1at¢Ýx=üُG±mhA‚ê¸9Dr5»نìF;:…öð÷hF=jP!N½«hˆz_A‚ì§MØ.ԄF„ïWˆâ!êÍË?ƒŒ
¡–?AÔ0دz!*
¢ƒ¼ðÁ/䃗ÁÀBéýuU—K %ëyùB
ÐLöc‚IEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`MýIDATx^í™kpUÕý†ß@’sr;¹‡„B\$$@¡*X­…ÑÚiíX¬X‹Š"¥8t°ढ़*„QükۿŽ¢ã࠶Öb¬ ƒB©w¢E”p“[ˆ„ÜHÈ9'çifÍɚ=ŒÄÙ'ú¥óÌ0¾¬g޽æ]¿u–ø/ó?s}ÎOL?ÃÃ
æoó¿r‰;»ôpÅ)^yûI0ÿz¯8źÐp/`—öÌó™۵6°½ïa >Üuæ©ã?½/CřD¬ÄPœ¡›ÅÿYÜQno#ÜֹöµÑòD’²€ÅÄ«ø»2Úÿî€vêyˆEÌç6îe#'$Z›oW‚É!f¨ÎåãäÝQü L=sˆCNˆa›ÀÐõì…>Å…¡
Øåö\nØE-:/WҌQX¯$«0»ü3Â3
J!û8ºHIŠ3{aˆ±òÞ72t`ún(§èk»¯P	f;F/`v¾G)­ëþŒœpki`/°ž9È}œø£|ò˜Ï­€‰?±n\ø"Y¦³œ°™+Ìi Ô<3O‰æ3D'`ŠÇ#ßá‘åçtnøìå¦7më‘eMwÚ¢ˆU¢2ºނéV Š6<Q0[iºfTý°ý„cüô½_¤d)Q±Q
˜¬œP3|Œ,¯ð×û5U“U©‰š¤šWV¬C–gøè:“íE·ù”G¼†,­@G“jU¡ñ*Ò«<³¦ç8t:ršÊ0D)àUšüo"Ë pzTµŠåW޲•§B•ïZ°Y6P?K)Šװhҕß{!ËC¼
”-ŸR”¡<×LuÂ1GE_@ÛËJ7}µÀÉz€J+0’^ 竄QÊP²’”ªuo]Úú	ÀîgeÑh6룕J6ÕH•ëçn°õ¼{ƒ²•öñ%íÿ:çrU, åq¥Ék
ɵ@¼|ÊÍ+ë9]dX
<ØôrˆÝ ËJ„0¥Üqcaä\pÝqJR¶Š>¬ûÖ
f—y…”cÇr3[Áòõ½Jµ¸,¢e¨`zM¨Žo¾†÷YLúV&ñ΀âÉrm.š Wã¾|à&dÙ
-hbX
†ƒ˕jKم€ùÊRá‚Yá |†,óØK”µ`ö²L®†˫TTɑMWZ8Žp2c
·°œE|XdƧ‘l)»†E6â˜Õ?؂,¿`b*Ñ–#\‹,—<ªLSÊîL¦Uzê=€*+FÁ_ ‹i(6ΐϔ²+{&ª襅Ï!Ë#؅ƒGßýÛ—ÌÕŵsßþÀ	¼VàzZ7(#RÊnL	JW~|yç>ï@ƒ@¨ûµ3çhšjT­MՌž€Žýò5îý}™-e¦•¢*~k%@²làñŪQ¥ÊUªrUÞzu_/Àd¹“Ê[ʮl!Vm6ÇôWÀ7ï©R%2³AÝÜîý`pŒª©t}­W²…äBÀQH»X‚,ÛhÝþáÝۮÿ|ië¦pà
¶!Ë,³…äF 2fjôœé}ÝpÐq=Ç1pB‡NS¬Àh‚@ïþ9&·‘£9Oã›6üY²yÄJìãQJâG<,øt¾-$ҰR^|y8GICNÁh|ÎäK H¨ û_vJt#à,å½Ïl!
Êí¬F–·xóvJt!àÈ`ô¤Î&€ŒDÀÃýt8r™@û&[HnlywͬPÀi–Œ΅DnÅ8–:Žç/BÏLQ²É€½)*S*߼´³L£\Š˜Éíl¤mMá vœŽ7Ðò¤Ò#…äBÀޕ5BEIUÝGÂ4ÂyéØÿUÞÙ{ëæY/'p÷ⱑBr%`ú r6–ì\ë˜É:šÀI¸óО—[¤iýL_r=ÀGç^Ý9xÏ@!¹°[qRu°½‹t„ðQËrà›ƻL¸\ÓT­*UôS©êæwf["º¶G¦wö3˜Jú÷S8'e!¼ðZUk¢JU¤Â~ƪü酯"KÐצ™“ѥ€³’n¸40W1b™H¿ö¿¨TdîŒYÊÖH©âÌAèA–”gѽ€³’¿w0Bxh¦¯g^üÊTŠ’”¢L_hÓȲÓÌò›£ٽ€sN|ðøYVûV®R• •ž|ÀSÈr8{XùJRÀ9'¶4ÀeV “nB§~S®4%*AÉïÎîÞ	ÐLžãºpâUåG€sN|áxYV_-zaÂ]þ¿W·=ð5åI¶ß)¿™¢°s¢Ê:¿;àwtƒåëÈ@–‰ôgå•)×ÌÈQ	8çı[—A=rÉ|êx‚¸šäÀÇç4¬T‘²e“(ìœ8*yB[#܆¾“vpr{|¹ق	.šp°–Î	´…X€e{èüêҋT¤œ™ J›Aºü*©»îl<wދz6kÐúÉU—j¼üöw£¡˜’•¥•Ýteó.èæ/\F<²¤rÏrÂ{6ä֪T£”©$3E>åh´Ê4ùÅe­Aö°×ÙÁú BëîoT•JÍok)v4^À>äxBJ4Qտ¾¶aݡ-m_vŸœî>~ªq_ýæÕ?ûñGÿ¿v¦¨B㔯,¥ȫX÷3áyg£%¿ŠTª
MRj5Õp¡¹/NV¥&¨D…ÊS†’í£ÖÐl
%)MÙò«PÅ*Q™.è§\e*ÕxkŒ
4RÙJ<äØå‡*à|MLP²Ҕ©åɯ|ƒ_#•k~ÎÍ0‹{#¯i..§nrˆ—W‰J–O©JSºҔ*_?ÉJR¹OšÑþ¤;ð¨kðDžtͣ®]ü¼ÿ+è=D¦,âIEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`MÄIDATx^íÙQ‹‚@Fá“eIȀPŠèMEA ±ÐÿÿO-x±6}ÂÔ.Lïeˆύãy|xà´@ÏoĈ€€qgAû½“{Œ˜1cþ»!“á ·‰/-BŽ"b1qY`ÚÛuÖB·€ˆ%+°bIä0fFB¦2fŒÝærc˜¿P(€bÀ<À<À<ÀNM}SbRJP’3e¬OòUvjê‹1¬©@ÍC¬\kå«ÔÔÔgôéù*IMçÉWX©éfv¾
@RÓù$_`¥¦›Ùù*IMç“|}o¯¿ñÈÐ}
Üì§@Î*öœ¹ÒèãÆ7÷×î|s£ÑǕ3{*9:'!*¶ìùRwàąF4\8qЯgϖŠœ„w†9…º’šGpdGMI¡.'c…‘wAçmȂ%	F)kJv
`Gɚ£„%y~´>\Dÿ:J=À<À<Àr=5Ýô|uÿ½%_ŸSÓ!ÀÎW;5ú‡’¯ϩ	½
°óÕNM‡€á_NuÀÓMÏLÈyIEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`MIDATx^íØ=K#QÅñ£Nތ/‰F#ɺA
[‰,ø)¶Y_š-+a]A?ÓÊZY[Ùm/"kgc¹½{ðž…Á3NFb3ó´üȝ¹pï<ïH) ¤€@ gÀFl‰}‘7€Èr†þ~Á
!â¶Íý¤€fd6] !’ ã:›È" c  óYî·\Ç9#$€yn
;ç:÷[(AB@ç‹wÛÌóÁ	™H@†Ð1HøóE#€Êßìú<eŒ"	Èq«ìœ'ÜìAtþÔªGž,ñ0•çVÕñ9
@çá5L 	(p«öŽ$@绀9”^(aÎ4Á:o€ú«uÐè¼æ_
˜7€ @ä4Á:o€*!pHL–4 y,`%
bFPâÖB"ìÁ"o€øƒ‚D>1@ôoŸ|¢	"ß7‚?¿nw,ßÂív÷l
¿۶|ÿ<¬ó¬SQ¼Þ#ô
pò¸ÞC‘ud1Š©«ý§Gú–z¼ÚÇËYxš‡žПüÅ!š]@E”QGëüèeBȟ¡ÅbÙÿ‡Á,Ÿá­–?;Æ2kþý*è¾FN`Ñ6B€
|Æ:Öô`[,½œo³4âÅíž(¡öÁø„U´±,¦Un­±¥ò5Öì¿P€´°€æÅ4¸ÑŠãÎÿüÎsœ& Åø4*(‰©p£–TÞNCAHö> ó„doD:oEHôN¨óЄÞ2hB/™4¡—‘$_±?͘ÿõ]ç
 	Kþ¤ŒõqêO¼%7€&4±xyà:±>Ï;—XDSç
 	U̢þû[œ
n×1‹ªÎ@Æ1‰
Êq®hˆ­`ã:oeM(1ʉqIî3^ðùÈNô5ӹ8×tà>ãA¬¼¾¨äĸ¨ôÛÆMHøÞx;½-O) àŸôm‹
¸tÍIEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`MôIDATx^͘mˆUÇgæޛö!$-X-´¢’`/ë–”R¹õ¡Óò¥¨ úPFŸLÒÕòmWWñK`-ÅÊE`A,T¢D¡Q°‚©»¾ìû:sçt8ïäNw{.ØüØOsï>¿}þóœsv<ÍõŃëÊÿH@a¸êª5”Á3øÿŠgP^ªŠW[‰‡uVq–¾!o(d’7ø…jŠÀêx…ƒWž!‡‡qœxy]×U]ÑåL*æ3u¯©¼ñǿ©w¤Ë:NLÁ3ä¡eòx†T|r€?uߙ•TP†…֞
äš;€í@ÿ¶=NLÁ}»e
øx¤BÀ&ðg‚J"¤e|¼tܯx7¥@
i}MÒàAJÿ¬٫GZH€‚ädÈtš‰ír•&C@¢ @¬ @® @® @® @® @® @® @® ®…P@„P ­Ð%P8…OÒ
h—}&蔀XAӀ–i£€XAF@ÍVsÔýj¾Z4.óÍý9jv" €XbêԨP" 8.%*Ԩ[T!‡GLH™c†+ãaï–(S'r+œî²14¨Sn¡ej„Įr…YŸ^‰DԩRɤšÐÈè€@¡a%²
Iyð }
fuôÝ@f´éº ^	å
¡Bz›ÁK*ùNÙþ–¢Çå°
gžÂGYÚ#Ðޝø²°ïFžtñÊ^ç0 AÓ
\lLéRËÔµ8ÙdªªSݧîUw«™ªcÚg¨6E°‘€
à8Àenö·?NH•’Á-±v•‹h Û6†ëÙZ³‚éÐ<¼̮üÅÔVPv{\à%¶¢t_ßð¥kÀÑM̭SߚMÝö hÚh*®Z(ð";Pº÷sG¿„Õ á4x¬~MHjz«!$9pV±Å7;Ÿø”`C1º¥i¶ÓçΚĄ©Í&)/Šàyv£ø~ے>JQñÄϰƒüFÞ;²ŽŠ˜X7®"¶H"x–½øíXØK¡øþ¾yt¦†qÖ
&S°í<–?Í|~ÜõÀnƒ²?ΜkÆƸqÊÁÅäÉáµK@ÂçøÞy;)JöÇ0pD³‚HØ,}Èã)¯Èq²gn·-_qOxùÍ//†ւã#4ÓîéšNޅ Ðħzælu]'ĞóJI!x¡iQ꽍I”T@0Üs×fʮ|d©S£úa_™Ž¦a<ܾ|Úd|<„ڍ왱	W>9¿E„˜(ú>kóGègŸ´‘PÀ)4ïx;I½†]N´¹ÐDԨP8Ñɣ¼ʯe9èáSÛ×?v¬=chÿҠš,§!¦¼»Q¥´yp$„¶p'åú·Ç:×Îذîb À-ªMå±wìƒxvôäwøktǡ©kê¦H‰*F<Cd±ÍOÇC…àЁ¡¯W½ѱîåϫç9Ï—(R%$wÀ'h­ÓŠè=þà¦ޟ¸€)ÏF¹L@Eځ´‚F+N€*E.sÁpΕ/R±Ãê¾ãhó+š8	aŒKŒ2’/Ùò
ƒ4‚l\5ÊM/¢֊ËH–¤:Õäð鎒ëoÒ¹¸ÎZ>WIEND®B`‚‰PNG


IHDR@@ªiqÞcsClÁ0`M	4IDATx^í[}lVWçýì[úñBûÒõ»S*Z¶“¡Ø1†ÃA‰‚K±¢Ý©Ä"$$‚’…„¿œؒj•Ď™!I#! F‚eP *ý²¾Jéñù%¿ӜÜÜ֛޼7Ñ'ùårï9ç9<¿óô<Ï}îy'(¥þ§álø?–ìã]Æ$ ä†ј´Œ¼=Á	§ÑALd2ø<Æ~aÏÿ_gƒsÒGÕâj²ì3Nã0níڵɛ7o¾vï޽]?þxxxx@‰àŠ{<G;ú‘Œ¨I„gǤmh``à{Z)ÉùE€cÅã˖-Ëéééùá“'Oº”A?é߀qoz„7h<Ýj"õ‰ҕrŸi(
3Nò§Nš)«û‘¢œû×Gê§m›Õ+ïÎW•¿)WٿãŠ{<G»҂q§OŸž=¦7x% ã¹¹C7nÜX-mYn$؈éyœ;qþüùâÞ}˜øjÿõÝ÷kUôí	*2Ў~èÁxè!	1M‚°úp¡”¢CW¯^}Íq®|[[ÛâÊ=˜°µ³U6N‚žþÇ?‰^èszÂXDØ9)(T”m۶I‚54~á…ùƒƒƒç1ÑŸR?w7Ò×vŒÃxˆèûz5	^ÈL”p4øCWŸz²oݺõ&¸ÜwI¥~Eƒ¼`ã?éíPè…~ÎC/›€<A™A€_$èÕÏ\¼xq‘¸l7”¿þçe0Šz CCCÝÐOۢ^	(7ð‹½ú9/^|JÿÑõ!°'€€>ôcí^¨0ð®>ÿäúúúöB!BÚx}þþþ÷0éŸŽ{Lb7åáÇ¡q}<	˜ßR­ ¢ÿŸ˜‡óÅì°'Átÿ\A¡„¬;P„äF`#ZGqS¾‚@?æÁ|z3´#s$͈c†>qõÌÃù2,	°'$rKe§¾X1?<ú1çKØ`O‚I@Ùýû÷;0øå–}Ù<xЁy¬	°'ÁݺººÞÇù±/Qú}ð{1cÇ~„Avµ+Ð9~üøöQ ªªêY)nôú‘	B/ôû,Hpä‚Ϟ={ö€Þö] oGæȻ€èýôÛä~63AAYii錻wï^ϷAèƒ^è·É}!ˆ3GJ0uë֭¯‰Ëþþré€öÏ@Œ£ë@ôB¿ͻÀx’ð¦&A×õœŒÓ_hllü>þóÐÙ•Oƣúkã¡ú —ú'êÕ÷—ï$d€^³¹T¦o޼ùõ;wît8k‚ˆëEy0WÜ;k‚JÆ]Âx衾)f=H8o.]õiŸŸÿ¥#GŽüLÊó=ʃ úcšúr]+BöؓI$$IBÝwfyyù¼}ûömíììü@V÷²¸÷=(À÷xŽvôCŽ« ž¤Y´!Àzݶ”Øt6[€՝«ÁûÙlŸÎþ¥ŸëZ¶'ÀOà}W±Œq|š JðŒ隣½Œýó8Þ}åí	🃈Æï)ÌäJ¸Âe¼–ðùöËḸ»ñöøO£§AYté$
ÕHòy–«á4>
ØGùT_‡J:	°O–h”Ýù{ÒN‚WãÒ@@ðI>öå5‹3B€„à°hÑ"e)æù„L3ÄŠ€ÚÚZ׶P(¤.\¸ l…'Uðz›6mRêêj×öuëÖ)HooïP2™ü¶´Õ¾*xIð¢jÁW_f~?ƒin93½ÆýH`ذaƒҲwï^×>ÙÙÙø8© ïŠHÛBúEÁ,jâ9æùŸgŽ_"HŽ€õë×ã,ä£
£Š‹‹]ûîرCVèáÊÏ|NðÌe‚+^¦ó|ŸˊN,Ô×׏ßÒÒòÇk׮õáfûöí®ý+++ñP[¶l©Ã[,äsN't®ŸCã3±	®Y³fÄøýû÷¿#mßinnþܾ}[ÅãqW<¨ ÖÚY´(¤|‘q…Î÷cNãÓB@]]6^Iù©YÚ^,F£+¤:ó
+W®t%@Ž©èƒKO¦N:‹‡ÝáÌùÓF*U«ð•UANœ8ÑĊL5wô¥òìïh;sæÌh!GUäܹs`å&W×꼐–LpŊ#ÆË)ÌfîàÏY–,YòY]™;w®+	


"ç{û¹	¦èæáÀ°|ùòãÛÛÛßaèšƪkÿý‚ æʕ+]è·gϞQC¢œ?Vݻw£RÄ"H4h”goõ7¶ßkãuá‘(á®þ’l†¿•耵***r%¡©©Iqü@'ë/xrîv—´=¯gèÊÑÅK2;++ë’²þ·($ÒBW3NÄüÁ €‡¥££ÆÏ0׵;€$²,½@ÎçžÀ89Ã?jH<|ø°Öýó¤þj›n‚I‚"qýúõ]Œٕ¦ñfèâ˜<ÖäçÊyýzÙäԨ!‘…!ñA*•±y$3œFxjƒ&º»»g¤¦Å.Ƈˆ(ãy	SÜW%Ü݄'Ož1:#P@F¨´:tè
ÌG›€83³I²cðCkît{ï=RŒó$÷o֛gMMڸq#ÜÝüuǰxWÇΝ;8¦ (Di$ëðsq‡ñ„yês½åy‰ߔŸAeãÿ££GþmΜ9õÒo	?mU‚¼ rÔàŽ\|¬ßEHR÷Œy­­­m‰ú-PBäîD"Ø_+ø:úðµ·ä¥}0kï4(JD<üjLoÌZ½zuüöç¯r݄&wK¯°èñ=&E‹¥› d ìñwxæŸA6½ ’éò|@¾&x™†?ÇöF,soI'¶ˆQä)VsªŒ*OŸEŽLÇg-PÌßи”ñE·HPÀϱ0<Ð8#ÉD†Î\\Ǫê‹{˜›¨‰ˆÓðtðkl,M^LݶIEND®B`‚‰PNG


IHDR@@ªiqÞcsClÁ0`M¬IDATx횆Ã@…WaÐ[`
TE!Т Q@€À.%ìBÀ9Ãaï”ý‡ž²VH&Iû¤Óùç™Lffò"I’$I’$ ¦iÞ[ž2ÿ d€2àñµ4#3
6àt:}ãz‚r£…±6ތŠa6›Íÿ†òkü¶ZÝ%þiäÆÑرeY~ázŽrlÄjŽw=¥$®ÆHG4-u]Wt=Bù+ՑΥ7¼4úfœ˜’û×"Æÿo¨ï‚ú'«%ÿaì)™®0{Ô¦ÛRJ~k¸>[2!耇n;ߧ`OÃjR]ŸFû³á†0œéí0™GaM£}<°1âTˆ;¾èî7¤à@½`t-i’2 B¼
ñGU‚†ä†aÈ71FU††pDÜ,øî-ãWq~!ãçò>‰.ÜÐÏÇõñі?é%ÿpD3Ïk€T`0Úwˆ[è- y€f‚Zh5¨ýíiOP»Â:ÐɐÎu:¬ïô…Ȭ$d€2H’$I’^¿’òÀڸŸ¼
IEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`M¬IDATx^ÅÖkŒ]U‡ñßÞ{n½*†ÖRK¸¶É(ŠB‚Z41‚EDÃ-š)Xl´ÔÄÐhhE¹©$Rä¢I¥ÃU ´8,:#ˆM[¦Îíœ9ÊÎJV89ΜÂó~›ù°žõß��¼·•zyïHÆSo‘†zc­TTîžD*•ÉԅJ¥IyŸ'¾’$É×ät7ù«G­q¡÷çI’¼K3ä'ÊÌö¤Û-t‚c}ÑÕÚ|L®™ÐçL^I¢oðÍ_Öj›/ZRJ¦»ÃԼY¨4ɒ¼-µ
ÄN×;ØW,v²÷©Ïkžžìnóì¯Ña®KÎã`ghÔàp,բY½LP¨E „íPwÛâN7ø“nK4ht<-‘³áS´J‡[üÄ*mtj.‘HjÇ?b~s²܍–ØoŠ•–j2é"̂ƒüÚés’nu•“¤G¹ә²Ê
¤UܿÞ
^â~ä|×yÆþ\f–)ʘÇ9~žç|Ç9.ñ ¿iLüØdY­	dšœxˆ•Àá–ÑèT™J4q•'8‹išeÒZHe¦k˜+™ÍR•
#Â0C&­5>¥ÿŠp„ŒٕطÌlÕIkA=m
"Ma–LEÊGc+l—„ªa%ºúuŠp$¦©ÈTèפy%a'T)PBIID˜R‘ýD ›^ýêòª—ɂJùñFtð¬GAմ `+¯™æ{÷²
~fN˜‡¤zv#’jZðª“Ýç‚ú¹Ok˜ë›Ö;[]XLÒ*Žѫ§Ýp¹€j聙É~`›n;ýÒä?w´Lú΂@Qç€v‘}ÌD5	tƒÅ.·/&Yìœ+ü>T“@Q1ŒaUì[ž‰œG©«2A{…1¬:&Í"{ X@T(ê4²¡ffõ"OÀfáû±Úvùw»A‘9Õ¡Oˆ°ž©vˆS0dS
	ôàZ)zVXr•’PPŠï€
"8@eö٦٦ƒ.½y®H+|ÿ¥a]†—2ØT>†sªxݘêH‘V%žɏ/)‘Vøøœ­Å>oŠ:™  K1&ßpJ¼-`’k_Þ)QžRÒ»TƒÜæ«\ï]¾eª:)Júü«ÀH‹{}X„&m–JG€u[¯¨ˆ߾GxÔ‡¦W¸ٹg¸ÆF'
:ڌF£ÃD »l^ÑÅ&»Cb™©֘u©N߷ȯ¼d¡t¶Õîq´L¢“õÆÆIî5_d-ü]1(A
!þ3¶ÀJ
€™nñ¬OóYkÝìp/Ðfl|Î)¦”<'€44 SçD¾-GkµڜÔ|��ÆÈµôj+O@˜þ©œÄiÚÝæÐÔG˜n<¬÷OT#Hœ©¼ª©›ýÞ\4þ+ÄûÇ$ROs£ʐùªv§÷1b]8>¶¥¼îòÆծ´wSÔNvÚl	R”PR´ÓE¥í˝§`âáxØpܐ‚EÃڜ£çf_²ûÝX§· Ø#

Øâë6=hž×M,ƒZyÅKqŁ!ýöxÝùÖmtœ.ÉZ}<V~R ä
;]êÎnŸÔjâ¸'4 L€( ~ý†úìr•ëw”N´ÆÄ0â~vy2”'Š!…=¹Äo,:ËM&‚G¼Î:‚å”â(æ}ta±÷|?4~~‰ǗD…8}öxÊbÛ.·Ìø°†ùŽ’@xŽoSèÓe‘׮u™ñp—^Ò–*D‰¢áð"öØb±­+ýVí\«
+„U@hİPB·e†–ԼšZ=ÇÏ+(Ž> ¾‰\!ž·j‡‹ÔÆÕp«áÞY >ˠàÿ\ícçq÷ÓéaCq«7Cފ]¾kp‘vccÈp­¡8Õ
ˆÈ:­Øíþc,,×ÎCž4h(¨V |9õû£Û^ñ/«–_ø)[­0(4€1	ÄG®q×Ǻ݀Ñ)h·Ѕ¼éboÄû5ð¶½p¥ë·
Í$ɨU¯٭ôX¤݀ÁøÆ,‡1,¦UÎrŸç½8jmö˜•ÎÐaO.î_‹@P“Ý6»Â-ÎÞk-°ÀR·ۡO¿Ãñ#¤0	QaWÕ՗ß?ÎÍQa (ôêõæ(Õk—ÝùýÃñ㈿á{Áîü€JþÂŽǏO@ü^0h ¯þJþ7X¾ý*ó?ÄP°R)ªŽÔIEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`M@IDATx^íÙáTWÇñϹ3˲%ÄPjڠ­ZM)ñE«DŨ¤Mc‚ÚVcKB¢B"ÆB@Û465Òؔhզ‘j©¡"”Ä,‘•‚e»ؚ¡A
ڄ¢‰$twggî_ô$—L®Ûvˆ/ä{þ€ç{~Ï3çœÜ	Ñÿ–Ìÿ»À%KU‚7%€ˆ 
€€ˆ”„àüE¡51Fã#´ۂT>S5Ϸm3h—
–š¢GU÷[î?òcûºëTeBH ¤|EÕýî*T}Þ7Ýá ,S@ôCkäò Ʈ¤ò·[5ÇZ1Ӱ#~ê'sâ+,›k¥w™b²3þfm8¶Ân»ÐQA4ŽPµøo£ß|0Õ
n0պ™îf/)¸Ú”ÉDQS±|6ÈÞ43¸V·À{Ép=¼Ódð¨ýN:唃÷!i6:H	x•c­ÖLÒÂ[ ÏMv[Òû¾¹ÓçN»bÚä÷ø‚gÜ*)t>™ÌëäÚ$sï¤êF‹U@n§ÏVF¾£¹<±ý™N˜áÊOúœ
 â&72Ë;ôêѣª"“	ã%¤¥}¦ñ6Зû´…úüÅ{54EQlh)š%ßéSÂz׀Zâwîô9ˆYkÇUT]ë>Ûüڃ®W´Or®ù¸jÜÈGms™ŠYë̛å	Üm‘…–ù­{Tµ0Û|嘤»Ê$Ÿð¬[˜o‰™P¤C×ûÜ6'{Ô+NÙäªÌR7káJ´Ã­ôˆ;ÌÖ
SÌT=7«ªB•¢¼ë¯ôÝëzÁíú˜ýJXd‘a0Ï<˕ñVWÃU
¹fÈTL÷D¥o³o)*^n“ªr¸L»×T„¬è¾e޾ÆgÀu–›8Ó¼‡dÅ¥þûŠV¸Ï4á‹vø•‚à%€*¤¦2³4¾&­@!@îøÆÊTü™§•±Ln1ìOsNS2@Àfq•3Zá
ïÖ-ž“s@žcYñ ô’M¯”NA·€!¹¦fjA*Ÿkxȑ-s1ÙIÝ>¹¼H€(×P÷ºÕÎ}Í‹WᠳRdһMؚã֎XìÌÅÛ?¿—§Àù-3jÄvOðU‡íð¬†4ÎP7fԨuN<iP÷9g¯yY£5¤jFµŽïê>F٣QŒ`!Ó ŽU3èø€“ºM?<“öß2JFmÍmÔ]ê¶sڋI H UAݘ~#ë5u“½Î0¨&	Ð*@ÊùÍ	Ow¿»‹òåÅïa£øîõ3ì9ñ€fjÃQ/٭[üÁIžw.(ˆElà~ÝbìTא‹å-éXn3ä𠽺AÓVFìIñ/êƬïVûœdÈYI€rPØíðƒ&ÎÏa‡zûéfð=VŠ&ƨ§8[Ö2ÆÍàyCû=iblsš]†%Æ€”šu«6~ýêmÄóŸ(Gmü»U.œã8n¿$ËÊ3PSóˆ¿n°مò}M~a,ímÄâbª9ku<·ԀÎáeñO¿,oU(W1ePqÔ]êυòÿ6¦.c»Hs “ÙçN_6KÐ)u{lUSOû׶@Œá92²RL¦}R†F$Ú­£˜^Œ´J›Zˆbh?D䈢†šªLèH ]îÅþu$Ò4Td~7ŒI!ה‹bçD4“Bgå!&‰˜Êw.€(
.Œ¢R.ýw|Ià?ñÛyÈlNªIEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`M/IDATx^í×}¨–gÇñÏußÏ9í8§ÕY´E؆•Ô2FÖ‡ 7Xåp•4
Lƒة
涃­|	k‹¶^d:ÉQQsj­li#–8¦é*Šƒ
ÜÆÈô¨Íóò¼ÜW0.¸á¹9p{Eõ½ÿ8ÿë{ý~×Û¢/™ÿuÔ €ˆˆz"¢¡Q2AQúb
‰Ðk!r
óÝéQû=á»>ª_.Yz NAɽËcæ­´ßr£:âÌ/ 7àá|î—ý٘ӆ½—Ak5dB3*æÿ6W-s·…Ì5èqWð1/×0ó	dšJÐo³ÍÑÌxAf”UhÉf>T‚*äò™O€0å éd˜é
 ügÞábÄÿòëøÿH'D "ãÅÈ5ô™-ˆFE…Ò+áâ¼Óç]k³Ï]žÑ!ˆñâlÑwµyfiÆf\ï:owRGˆuo›¾õցÛm˜ç6i+D¢ĺA@ĩo¸RÉ
6ðVïp‹%æih:f§uþ©PÔJ 
–	.·HÇgeSP(™K|ÜÀ|¯ÃÙþã'ô>-DQ¬
¨¾þ\ã’cÂf÷«뻆Í>
xÉGì[â:Oië¤2J
d•=Ýg•–.̿à³æ_bȰµô[`¶÷Ã[,s·5ë“ËdB%}ŸÏÙ0Û}V
ØhµÍo´Ër“j2 (Éàk.÷ÚiÈ?t@„Œrþ[;×o­%²†+lóÓç²ØáA‹Yê	säBw駇›å¸V	ë|’«¬×Š~õ¸ÜNKÝì€å¼ÙJ}2j}²L	y‹tq¯·ºTÉ"²Å*Ý,ð
а>¨!„ª@î$Ïé¦ß6¯VåJݠ$x“6êæU^	2™ê.s›¨›×zÐô)ž‚crUø‰gvZ§Êr7š¯÷E«<		Õ
¢¨Ðt›3wڣÊ×]âü¹É7¼À8ˆÝm-Ϻ«SÜdD7op«ވ2êo
Q2Êùkkš´×ý'|ØÝ\¯79Á!E)PM`҄	[ìø‹µ]X~ûuJ2(´^VóU‡öZãÂòsÖÑQ¨&2hš0á¬Û=ÿM[]8F=ɈçËá«	D…–IãƼ`±!G\(~¡Ã~mmE5 *¤Œ;jݘ
†Gaö”	”E¤Æí°ﰟêÆý’ž–ª	¤í˜RøßÖ;ìvŽ=šÒ`jRaÒG‡ýQïl‡_k§§™Š
?恨GZvqÆﵧH ZCڒM?ó÷­á¤ÞØg”aIUՕ ­éœG^r_Ô?‚Ýݰ*PUh™ôCg¿FMŸ¦휶_;)Ԑ΄–S¶¶>ö²N±۸V*@½bRhÚêìý^4]]eõJh:åûcáK¦ǨÇxÎÓZI¡¶@,ׁ8¾5œæü'x\3
º婨tÎúè3EÓù³‰Âö4ÿ(Ö¨¾“v;'¿q˜½Ži¥[°¶@õ~\ïøºðQ}Z5µªýC£¦@®á¤[⦡yCΓß9(-@ÎW©„Læ¯>eµ«u‰F¬5©YYµb© xÖé7>j¤—ž¹šÚ
‘úÕGŠô·O.ԩ/ݩ-qºi.I )—êP¤s¤•æoÚ©†BG&j&ŠôïI€Hú7!}uˆé›bpøu=cP¶®„,IEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`M¯IDATx^íÙkŒ”WÇñïÜﳷ™aöÊˊ°[V¶ ´KƒTӆvA[nj(	ZkS_5!ƘTIÖl”¨$
	¶oššµ-
ÛµA75¥7ʂ\Êì2?ÉÉÉ83q	'ÏDßx~¯çùæ9×çyÐÿ8Èæÿ|”R¡tÏď¹byûOû“
A˜9ʮBa"D"DÃÐm~‚„4yé+„	Àç
°×黸ëÏNü¹ðúø®Ó÷DZˆ)¦|„¸¤És#\"Üyñ!¢=\xSUmbäø‚†0% Dœ´$iòÔF‚ @x¤¯p@’.j·6k…úµRßÕIIÅk#÷µ„)Rd,yòýÍXÂü„ˆ]’Æõ¤b¢,aí–4ùÁc9C˜ JyIz¶Šp‡€0ɟöêU	訤SO‘$Œ*@ŒZ%	G‚í€iòc/JCB1­Ós҃–ð5I—_¦ž¨éØ)´€;Át!u´­VñŠ~ 1Éf™,–ôñ12$ÝÐaÎÛiòÌ>H¦¼µoòcÙ{°TÒø;L#EÿԀéàNð"A–Î6JÿxcÇ«/¾'ýÍÈm’Æ^¢™´	à3øžfºön`Ñ××^;#×!”Ш¤7¾íp'Ø{ÐH³»Ÿ”þ¨;
_”tíݖ9]àN°3!E–Žc;¤J
¡z½*iòÊsщ„'‚Ÿf2_="=jøYýURáüÎ/3‡;
nŸ]Κ'ÎJͰGÒÕ÷¶¬aÓɘßûÁàBPi5ÐMÉooKúþFæ3“i¤1ÿßà@°3Ìzú®É
ݬe¶¹ý1‚ø®»£4ЮŠ¶óKöö‡LyN„ÒUê;cÒ+ڦï骤׿I+vø
`qšö?$*PZ/ü¼]€p¸AâdÞÞ.í³à^I׏“'åPM؂%T~·N:lk%]>èá8|Ðt÷œÉKҰ´^§$<ëàB(kÚ<U¼!Û.éžKŽ$!G€;A`ÏEtý葏ö_9wøðg, ƒ&â„ð9Ü	²;"M´ÓÍ|ú襇äíè
p'ØÝ E†V:™ÅL:ÈSoþ¿p¸üø	%IYrdi"MÜò^	b$H’$N”-ïðF°§6ö™Ðàa,Øøñ™®ï„êæàààa›ªˆÀ;¡ö€Ïëö;_°ǯË>ÜáÜc„kxZÒ@a›¤ó“u²Š{XÎÝ&,e1ý, ›²¤ˆ¨	àIIÒóe€¤.Hڳ‡ûXÊBúX`3ŸyÌa&­djø†ŠR±¨	µ”vJ:sŽåô2›L·頝VòdÌúª`«)ÿ«_~ðOiG K7oå™MôÐNŽ&Ki Žq"5„_5å_Úźá_Kg.#ì—ôþQ撧ޱ²D‰²åñؤ¢¤W‡YɚàúËÒãe€û%nÎê³çÝ@Eü&>O€
š”thˆ%pk–ŽTLÆ’Žý‚6Òñ‰ê+ázSþ­aòÉ[égÅO$-)#l—4~Ùdˆâ¯)àSþè.ú覓étó)Vü»´¯b2^’´wÍ$	Ö
Ð!I’Þù¹)ßF–,­ô°|ø'EÝPsaHÒÙ:i Œ¿†é/»¹˔o"E’F:éO|á\¡z2U,#N €Ú$it7lù$"$Éó	V¼vH:]1+iôک#„Ï>d“>ÜÍ\ºly3HÒÈ,–<¸u\•“qƒ¤ÂõL7Dð{ø‰&;ö3³¤¶”Êûð$E+½¬<qZú“øu¿~£›’¤—7“%FÀ+ L‚údŽidi ‰ÙLJݓ¡›e;‡'$­ҷ4jJß,~8úãít“« H„iÒv-·å>BÔÓÁ]Í_<Smã7\´•ø4]d¼|&j×òÊoFâä˜˲߿V4;áðÞèYÍ2æÑF½÷1à+=P	T53#¤éômÜôæ+ŸfkYý,fö”'@å׾êH’£‹…|†ûøŸe1ó颕F¶ünûä?™ô˜³O3i!Cš˜}üªn5ø#M†<­4“£‘ÔÔÅk(}Y$Išdå™ç¿ 4HKÀà_̃J°%‹zÙIEND®B`‚‰PNG


IHDR@@ªiqÞcsClÁ0`MíIDATxÚì›=‹Q†ÏHP4i„р4’"EºÄ&VjÔ&6ùh–­Û©©F›4¦Q'ÕV¦Ú"h±° M6 ]e$drÎdFfÖÙud'7j΁×{ç~1ç™;…¯¤ë:Ü4‹źE¾£¨#ÔÇP(ôõòMÓ`ñ•E¥PòuƒA	|I{üBuP‡â¿õ·¨*àu‘­€	­ôQ[2™„T*årJ¥„Ãaê:G½G½DݙÏçÐét ÝnÃ`0€ÑhD»\vН€ÜTxR:‰–[§D"¡«ªª[sHtLí^æ[sü8oãâ‹`©^¯s¨ÜdÞVpÓd21®p6›]I¦X,®´Ñ8Oó®[wgإ(ŠŽ÷®땥vê÷ºֶ¸òƒ}2ê5êœN¼Ñh¸h6›Vr4îWigØ@<A]P’ù|ޑ<›É_˜ã`üA¯Ãc,êT¯V«Ž¾J¥bU©ÿ†_ß®ß.» †ŷÙlÑhtَ<ˆD"T£Î<~ù  ’6B2’3“]†íøGþó`€0À`€0À`€0À`€0À`€0Àð%4M»M%ýUÖ¶cyßwÀcú!O=†áU}´·ðê“Ééꪪ:úÈ,eÆJJ@„_ûï¢òŒÇc=‹9ü²,í¦g@1Çñõ
҉
è÷û+}™Lz½ž§¿ÝSøe›rL§ScۧÓiGò¹\nY§vê§q—’»pll›«ÕjÆ*a_lsàÑ8Ùív0Üúûkœ”$IÇã†1ªÕjéx;XIü@½1K£úi§y"üó4Å'Ô+›yúêÙ&ì’{ü'üñ¢>£>`â_\Þ±xzŠº‡"ƒխ¿
à·ÏK*"SXIEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`MUIDATx^½Ù_OiðV†°X” ¬„?Ò&¥½©-AaC‚÷
ßGoֽÞMŒÊzµ›¸üù<«1¡ÔbVw³êPµØÚÙ3=ÉäP§OÂ;¡s2!¡'y~í̼s&ó֧ðò»–~ìÞ/õTð·¯׀>	€×ø¥ñ+<£¯w÷0ôå¡/ۗ‡‚GŽ?ˆáÊ#߯Kù~å†1¨€KüŃÇAüºT@8xŒ‹Jp¸ÇCŠâx<%¸xüOÇxKxbÇx­µ®„øÏ	ñ<žñ”àpˆ§‰w"¸l¼l?û‹å…ï›Ï ƒÀ<>ºfC,ßm;Ü0àñÍZ¥X)îuP:(5;ÍãàÿÚô6k>ÿ,€û{ø\ƲԒÔ2V°zô¡pô«X	{–?—}ÿ>9,€Æßõs
¸‰䑓}·¾¾ï|}[XÔé¼rz:’¡6 úJ¢3HaNö򑀼éÈU_‚°øÁ,~8ì³ÈÖÞujï5€€Å+਄”D_B—q©H@J>¹,—„:*)€,ÀÆn„ñ0‡q‰ÿ^öq$#IÓ1g„ oúýè/`;€@ãÐjÔß6ޜüTãMýmë¤Ð:éèh(€@ãà¸*ÀÖ]%üè±7+}*².„€]:<pBø”ƒa®¥„ʆá)¡ª˜¯g„!I;=Üi>>EžÚÇ“ÿü®„Þ|ÿÿ$¤Êy.ÿ©„ó?	÷7‘z0$rÅm%œïe¸·ƒ’’¨‡@OBŒbJT…ÝC0€æqõ?[QÑéŽæ±˜øÝ–´Q=	ÃËc˜FBˆXŠ+¯ÛãƏX–}·#’ۦcµòÚlü‚¤ÌHZx†®`Æ,àÓ~{Ü( /û
,EÎK¸¡ÁÈòi_‘ñWìBÿ[¶%èD$ÑY7í6Øˆx¼™A’ö¸qã²_ë:\ÓéÌê@Âã
€bގ×H¼Bœ„Æ[%ÜsÉîküvt¼P‚>˜T_Ö^ԟ7þª?¯½¨¾l5:­Æé}0aßÞ¡¸çѬ¸Eâ
€ò{›àYNjö6‘'ñÀó¸^Ú
΅µ³ó$ÞaiBàñiL“x`„1!Ì#_ܦ;ûê±Ïc^ðc®ç]Æ.<ˆOàñ“Àã''¬Ÿ!þGwðÚx||8aÆÇp‰w8h||'ôN¹»…‰	à÷ˆ\ùYùr§×ü½¶Ã¦DZ*‰)„k~_\b˜”šÀh¬—p~u‹F¤äÕmüâ/¯1(åaÀ=þ¡Öъ7qØIEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`M¦IDATx^íٻoUÆáßîìeÆãY|Yvm᯽+ãKDbPšHHD‚††(¨nґŽ*eþ7(E¢@J4q$
‰IlCjß3Gc>Ér2sr¤¡Ùy¥mßGs9óÍYÔÿœ> èú€“N#8
QŠQƒ£¢€5  «ËTq£x™âR¥L)FX¤~£sô@ìeÜõ¹ÇƀAª”ì|µåýM¥î(_‘!âS¦h4€æõK»[BÈ¥F{e<êŒ1uíòζRMê¸8öOC•€aÚÌ\½òô/!¤ڄx¶9CŒò
½Õ!¤&,)„¿…@uF™bî³÷„@4h2ýñÛÿü©ÔOª‘#@nƑϗŸþ!õù*7æwïK}ޗ;9»wOês¿	oužU_°P8ŽN¯?øýôúwÕÊa€6¿ÿ&ãú]%¥) 7Žlt(ãÄ…yýNL\¥ŽÞ폦õ?ßúð£'…`бøðÑúž²Öÿò
¹øÉ²:šªFMø~þ˜^ÿŽ®ÿõkγÄ"ç>}?&¬+ßààRc$¬Ç×r3!88Iý½çÕÿöKt™æ,^[]I†€ã1ÀO· J%Sý&i2N‹3ô‚Á<ààÒÒâÿß-ܜÍP?M‹a2&ó‚) ­J_ž¿1¿w?SýKx¸PGÏW¯ìh-c€ö·v7²Õ'÷##3×.ïm+Å8
Ül€	Ą;`^/_251ÁÔõKû[ŒP3d¾ †£¹¶L¨yE€Lë
Â(å`^/„*~—J4XÖ#ßÒT¨ÈËÍ`Sr7!yÁc5‰NZ½ ’€=àÇxiz²ºB—I†	RëŎ5@–¦í/ޢIEÈ «ãæÚ2C¸8ráàѷKÈȒ#@·djÊ ™šò˜ìæ{@[™z‚–õÀàR§©”9án79V€"UjzߣÇ9.ðæ3óF”¼Î"]ÎÐ$ħ‚=€2>!/3Å=æRÒc–³L2–[@úӄQš´™xnÚQZŒ3BH€›º$¥d„ð©Q'̔5ñ¨àØ4RŒ0،×ÛñRo°ÿCú€>à_#:„¤¡E€{IEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`MçIDATx^í×OKbQ‡ñ§n×?WM¼é YŠŽX)%ô6š†þ¬Zͬ„i‚æ5ML+׽Þ@Ä³i´¬œë„ýˆ{8Œýnjõ|…¿CoÄ{3ý>´‰`“ƒ©Ÿ‘§B` âS¸ûû¸L)ÄLàà»ÿÜ{ê=ÝÃÅv:ÁûsäûŸ§߇xD‚]€Î'îŽûùÁú„»#Á*@çoOT^ù„Ûc` ç‚]€œ	–r^&XÈy™` äß'ØÈy™p¢	ƃ¼@0ä%‚@ÊLBޔ`0ËËÿ!rޜ Î
âêWøðjòG}YÇ'K8@D=c€ž:Y"aQRä(Q§É:›l±M›vÙ{À»ìж͛¬ӤN‰)¢8&€,Eª,²Ä
Í`-Öؠ-Úl°F‹¦Ú
K,R¥HÖàâ1M–<Eæ)QV¡FƒU°JƒÊj%æ)’'Ë4®ÿ£x¤H“ÁŒ*4@ƒ
røzҤðˆ†ÿ#T\¢Ĉë%ñ)P5
ø$‰£GŒ¨>ÛCÝŠ æ G„$9* BŽ$œWÓO7¡CŸ²(ãǑŽÒÑƀ1`ƀ1`ô_Ç#>HBŸd¶Îò‡OŠþ(µó0ù{ˆ‡kx–ߜö	=v¡ò7§ú,7{˜\}yVƒüËóõӇÉ$Ì0G½ÛQƒ|·C9fHè§Y¸Ç)iòTY¾:“	rþêŒeªäIëÇiøç9>Eh]ž1yN‹Šø&Ïs™`œ7¸‚QÞäKÐùŸ߇óf™*æ™"o
Eóæ€9o ÞÉ[È9o ļ}À0¡ÙÿŽxyþ��·&Ìò‘F·ÓíÐà#³BÞ:@Ȑ§D5X‰<!o
§	i²|–%'çÕDÀ?ã@ÜeÈլIEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`M¯IDATx^íÙMoUÅáŸ=ö¼db'ÅÉ;Â-qjË4IEP6HH ñ"6l€+D°ƒ+–|‚nUbÔê¦^ƒT$+¢M[Ú5͛“áf®¬¿°p|ÇS
çìsžѵæ'Dÿs&€	`˜=9•¼Š• y•œ
‰€Q€¸¼@Ï(®ŠC1fäÒt½*ÿßÙn
!
 €ÃtRÀÑN·ƒK1= OŸà€Aü¨«‡w¯nàcc¥8”©*€qýÁýÏ^ ԀôG`á2K¨†õ{}ò2
˜ţHz50¬ÿè5V©3G	G - ®õ»®\¦ÍST™‘çÏ`RŸ0²þƒ7èР*§™‚èGøûÏw_b…
SRŸ@»|¼ɼ|ø2aÿ÷ÏÏSÂÎ ©Ąƒ߾<‡—É䆮53øúэè•!„ÞhB®Ÿ1råìAyóði=Z¤¾·7!.·(n7o÷'KB€ÝT˜Gß~ç§kI	ýys«u|;Šp±±¤~÷Á{o±ÅÖÏߤÞëvŽvâ*i 1@êß“¬³ÁÅ_¾6%ôë¿?tG¯&¦q̺^_9ÏÐä,+´Øøõ+#‚…¥ë{êé»0OËtH}›3,±HÈ2M֌6S××zwOêõÄd‘J@<7ô…Ë3T˜c‰•Ó?Äõv,Qún½_,à™–tý‡¯ë¹Á,S¸x”x„p îˆ/.êz?¢¨™\*,žLMµõVen`éÁþo«Cûۇ÷¤>) Ìüá=µtÔeíèWŠ9¡_/ê&€|\¨²ÀÜÀØÊ¤>1 Ÿu R¡$õˆ õ‰ºÀÆÅWñp¤>)qúòÀƖËL	隐—oü1+!=™Â:•ÐdCÝBH’„á„s,Ӻr¹÷(Šnd
€<<*„Ÿ¾¸w_¿t³È1¸Ì\Ý<”—nF™Sßnôv¤>#€¬ëkRŸ!@֎Ôg¬¿)õê³X8ݎžšIB-%@žÿVKêÍCÈ,.騸„œ¡Å:Ïr‰çTžšK\ Mƒ*eòi–°À2g9G›Έ´Y¥Sø
Ã"G€K‰€yY¢¦R?55Bªúk	ré6Ӕ©e–2¾ž7i2Y\ó?èÇå½®RÒÿCc ûLÀ?YrtÉÄ>ĊIEND®B`‚‰PNG


IHDR@@ªiqÞcsClÁ0`M
IDATx^í[}LTÙßÁ)3ÀÈÇ2"ˆbT]Ñ-®µKYݏV³‹ÛݦJMëvuÝøUi¬¦MMì¶ÑhHmq7Q0.d5²Y?𢬶Dc4l¢È"à–ongrîd¼yÌ#½™¼IړüÂË}çžÇù½wι_óœâjÃÿ	b±1BLÀzã¿،0“ºR>|œž؁o)ÀÁ÷ì¬2®ÿWQP™ž000'
ú3ª%f޳ӵµµ3Ÿ>}úûÁÁÁó###mp¤tt´ghh¨	mŸѽ˗/ϖdø!”€É6چ?~ü\‡ú°k êÿà¸xñâ¬þþþ“ô¿s&]êÃDØL	ð>—F»»»W¡-5"ASTçå[»wïÞr¼å'220 ¾*ýX4ä­Ÿ/*_„>'ªg${ÚZËJ=:$èó”ú’
¶%_œ9Ü!ˆôe¶µµu
Ú"ŒHÐcçÃAúNòm•âlò4=¿ ¶ŠrÁ2B6ȖB‚)`"àV?¯æææuF$hìø’ßÒҲÎó"‡‡ōß¨ŽŠs³RÅç¹oŽ~¾ì-ºVï{úP_²A¶$	2ü0³j/XöìÙã—@Wd腕——§Ñ', ¾ÎWÿÞðžø¦¹Y¨Bmt¯B!A†Ceeå²-s‚¤$
\’÷ ټB@ZO–©oVÜýðˆ½¯ÚÚھ@ÒûZ¶=8W-N…{õɆԭ ۀC†‚ÏÓ|$	2ïD?~<lS2«Jˆå7oLÂððpÿþýûGVqqñúúúR{çùϼ}ªâcdb>zôè<_s’ôH0ûQíí퐖’b¯ÃÿzïWânÑߞ%áH‘—„C‡mGß×òòòV€„nj§pº÷Š	²MÏðý
̘®H×ÎI*Ÿê?äòOßñ:Ðóå—Ô4&	õ>|x3ú/<qâÄ鶴÷î]¯Þåw"HÈ6=ƒŸe× @“ãÏßÄaT×! ŸNLxj<‹)	EEE8ÎW1z�s3SHÇc‹„lÓ3—-ôI`8ù	È؞€­´yµÙY‚¤§§§b~<_Âýû÷멡vÉbN%ÀÕ`ž!“¡>ú$Hœ@4(	øÄù,„]ٷoßÎñÐÛÛÛ懀D~–S}Tb€©˜Ô<êÔéτ%7|ދ8°Ì	5È6=ˆÑ @‡s=zT;V¤Gٞ²¾	=Íͣj$ۚè“`·nÝú³Z©¤‘`Àӹjժw ÷
HØê‡Ã2H¶uB  $¨Ip÷îÝo VGԁ7’„.kw"<xpÛ$<;ê��m$Ô2¤"‹* 4½•ÑðöAÍ9!…J]GGG=ªC‹a‰d
²I¶uÊ`@HPBDú֭[³ãßȍ‚ÿýd}IÈÙ$Û:¡€ …¹NϨ®®þ­œ7~°‰bpu¨[šMð\«÷7½ï“-²I¶u†#ÀÛÝ@†õ½?É‘Öò“ã^‘3@êK6ÈÛt«“!
´HÈWHñ“d`nYYٯ=¼$FՁʚ\#Ð5µÑ=ґŸ}oiié²v&›L‡uÐ'agò£9Rȁüüü\¬êԌB„‰P!]êÃΧ°­h“MôI°û®1LB20xiíڵo_¹råpgggF†]pvˆ@×ÔF÷6lØð.érŸd¶£.‰YD€9	IB4‡C'±9À<`ð2Aàë|oë&qßh“EQ
OBÇm,‡Ät®å3ù
§1fs[*ë$pŸH“eqü×ÁíQìT;˜Le$r[é°n„º1(¢M@àIðÝã°p‘1Œhns±Ž²5ÆÎ[C€~‰ÔÙXô	°’›þö¸>֓ !V`=	Ö`=	ÁO€þʒÆ!¬'!ø	X²d‰Ð>Ÿ LhlAEöæÛm6›¸yó¦Ð>©òK
… #   @dffêlڴI<|øp8**jÚr€7€EÀ+>È~Èœù>“›IÀDeNo=۶mR°a¨ãr¹h]^CÐöcvô% U0HãIN2÷ÝAG-[¯SŒBhRL™2ÅP{ùr…¶›ßü÷€ïß!²$ÓØñxv>R™ÚZKÀƍ½Î;vì(Ne}Mº{÷î5ÔOMM¥½;víڵm/°“r÷¼bxv7QNt‚"	®_¿Þëü©S§þжŸ~L
X¡¡¡†$œ9sF ¬]CÛ, ÞgúfƒÉNˆ¥eKSÒyqá…B´e¹v»}å“'O†¨[X†dggˍʑ”””t&`¢¬ï~ Lx,"`õêմâ*Hêêêò’T&gô\´}AúW¯^³$޾}[\¿~ýC^Ј”ãu‘àʕ+½Î744rŸØ¼¾téÒ÷ñvIFF†!	›7o$ØÇÄIÐ-7+ƒ–€å˗{¿víÅ|:×ço“_ȹsçNogYqþX”””äór–°I‚…ÊIccãé<¾“‰œÕ!þ9‚60EBB‚!	ØÙœ0o2‰1r„|0nܸñ/=Kçc9¹HŸ™ñ†¬ƒf%$F1„ÎäRLøĆ`ijj"ç_Tœw†‹3úlàuW¯ã³yc–ijgÏJÛe<ˆâRg³š§ܞl5}Ä5;Õ×y¥t99lR€Œe˖mD’þJ"*Š,‰}n·{÷w!V žؘÔÕÕUä34b།açpHä!nÊ]»€Ô××{		ñŒNŸ>íJ©ªªZǹ$ŒìZM@(̢‘±ãx‹i‡…Ëw2b:n“…ûÊ䙓“#¶oßN¡$Xˆ:Êބó>›¹O\P ìÈD”±¸Ñ/Fl¿ÑüµÌCxŸA¡BcàҥKÿ\°`ÁFè-~Àá嶚õW¡êƃÉo†&0Iqœ3ÖÔÔ\¤l/g(‘%8àDµ?x“t€4Î-ÑPl»1f?ESO|ÅpÞH_³fÍZl[ŸÇßš0?r/ްšÀ`'f|¿´©'¾x¸ü*/€,^cÇçòýDÎþJxYF€Œº¼ Wyø:™+Š[ÝÂf²Í$˜	à’È{ûìd¼²…ý<0QÃñ &7’¨[Ú.“U "@jŒ·®­$à?
“!<…R/IEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`MIDATx^͘]h\E†Ÿ™³®Ò4ÊV1±^ÑÛ*‚ЪP(±6±*j+¶õ"*("*5â•B(
‰š´MŒJJj„–ñÂ"B£ բV±Á"Es‘ìž=û¿ã0v؅p‡3Îs±WËûð~ó±ÃJ…_$xå$ ÐXÄp	bi–YêEb\’@"Ó,>D
‰LFA6Å\FpåÄ|úÓ($Ü@@
®>x¡×*$' 	H\¿ÿ|"
­—P’€ sÔ*$y	€×Z‰Ä
$« ¡E
SÐJ²
ü*Hð« o‚¿
ü*Hð« o‚¿
ü*Hð« á?+ôY…$¬»ç¼%øUàWA‚_	~$øUàWA‚_	~$øUàWA‚s…^«à@ÀÁ{uÀÔ%ÙFჃ>ì9ÉY–8úÿ…ù-Hg#xžC¬…Å0ðÏq¸[Ü%ÖǬkE·¸MÜ*n"sÍ4ÂÑžå-àì™dŽU‰È’ӄä‰(R¢J
ål
û¥ê=,‡˜	àñÍDäȲh!KHD‰25êv±¡>š;•b7öS熍.3„¦ÛB¡тjSàIFêäЦéO>…¤!æ7Ž!/߳…
%Š,fe*¦…jCà	FœÚp˜Â³ÙsM»0tn[)©Q¥BÙB¥ßÎcÁ7ûîœ$Òf§ {Nð©åGî:NÕ,ªnhgÛ8@Àé‘;&ˆÈk¢þ™êBÝ-˸bGü4wû*ÞÊ$ߍ®#oˆ(ü”ýýHó2Ž“eY÷Ìj# \	(€	øþ@×ÛD†E4ÃSªÖCÆ.#ï붓"@8}§øq|õp#¼¤)SšûûË4OcÏ>Wõ¼r­é	€¢pn|ÕÞÆFW¨*”¿8;š–ñ⊧±´' 45øs|å›Dq|™ªY)£ðð×ᯙ¦e<d¶ߔvрÒè ùý7ØøxŸëÓY)Ø›oä3‚^ƏÖ#4¨QYñ2E
qù:^郊*»¦«ÝÜËsüÌq6AåâÌÇ=]_¹ÙêxŠñìu<@£ƒò¹¹£pŒAn¦pqöžû3/ný¥ÁÍtÍoÛÑz”FÞW5Ôü驗®{àö±£Å÷¤n$Œ@ÇLùÐ: Jƒ̾þê掝}Çs‹ä‰âa)
(ê1ª5^c†@aÍäg	ɚøxU©·'Ъ P€ˆß@¡&o/«ýŽÅå³Üޑ"òDM¿üX#P3-”æªÚð$b\Ó(C[ç_¤[ ™w/–HIEND®B`‚‰PNG


IHDR@@ªiqÞcsClÁ0`MoIDATxÚì™?‹AÆGA°°PØþR)z] ­mÔoO`—tjwǥ´°(j¡¥äl,mB°B°É}É&øçTDɼ›™Éx¹;RfwŸGgg^…緻ï¼;àœ3?·øÀñx|Ž@@uÂá°kM>çԤiPŒyÀcƒÌç
~·P(äIƒ"Ù%è{½^ÿ1žøAD"¡w»êZ`ð†>f³™0¼þ$ߨ—ÉdtÀd2QÝ+s)táÙ)=°F£¡Ç
¯wtCëd³٤µÒQ:æ›͆ӸÐX(+u‘ñ¸Ð[¡{òÐn·µ7y•ÞÞS!”ƒ_¶Û-K&“l±X8’ËåX·Û=»5ÜØ:«T*ºð±,‹Íçs:çóҙº%"ý~ÿŒT<çõzO§S¾Z­µÿ^¶móÑhÄ…™y”q·	à…Ж&ªÕê_?òŠț4O^/L¤kE°T*yÎ|¹\6¯’kå[™¿P	£V«yö
 ÛY¸x|¤‰Á`ðdX.—®É”¯þ!gçq8%&¾>\²Ù,ëõz^_2Ö©TŠ‹ÒѬ^»´p{«Õzª¸¡àOtÏçuÀp8T„ƉÛ*ÁWB;òR,µ?ò*ý}¦ ›ĥ¡ŒûÝÒÙҽåð;ò2µ?ò*ýÙzK,‰°Óéä¹-1ù4ø}¿߳X,¦Ÿ‡ö±!x3ä{x=à³öK€¶Ę––_>žIEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`M¶IDATx^íÙkp\uÇñ'÷ͽͥMLڦ÷@[Zjah‹€ãTñ‚0ÅQGp†‹8¨3T±
Î`gÐñE•¡‚µÙ={kÒdJQK	¥”n’†Ü6ÙK6»¹oö|=ýÏéxv§MO¢‚/Øß$³çÕó9ÿ˳ç"|Èù|ø b¥œã“e$[%çlÔQ–‘ù|ìÌÒ9’'ùR Ž{¼V׶êϵâ0R y’«(Yÿ€Y:WòëÛâOûSý`f2ùÎÄÑ;4ˆC1ì!ìÌ3ϓ‚_/ùqªT˜ LQ0Ã̔³{‡J¾
„}€*nœùgˢê1€nžf
d™Ê".å.ö1	ÀôëooU#‘£àÿ)À<wGۥÉcÛÈFΙ
î'ŒýâÚrÉ7WÄ<Öò…]7ë£pŠë¤„Ý$ɖ=uR`NÅ|fù¢¾ÛHÂó” ¶r5=Àôñ½ËÅa%ؤ•ïØÉìBì‡:ځ©<Tkæ°¾û2=#sL5§€±}R*j9ΐ+ŽË+§ކ½HF
¹‰çéBÆ9Â#lÊ$°ŠÐû=)–|sìÔùçKéÀ.8Eq ‡Û€Ìð*gnRÃϬ–"ɓì¹Ôì?А!cåWâ 9šèŠ
¶ŽÐg`Š;2ûÈsRfNƒm@–äH”õÿ´Œ™}HMÇN[[†šU†šƒ‡B¯OܟXŽ>þø)6ÇÀ6 WŠJ«¦߇miƒï’cá#¡æðp?ì{U|Æ÷ƒC-ñºΗÒ¯=»¤Ü{5ÿeþÐE–p:ûð‘ÈhoØu‡Ü
FÈñD|¨y´BTZ7“ǤRŠ$×&@M@¡,ì
ž²”/&Œ¼9ó&´¸+êr)CÆ÷˜6â��qxÌ(`ôGÖI©Ú6yR,ՉVØa|HÆϔÕƜ‰¦HSŸ	ès…㸖pGý±cП6n߷ÉqHŽ=€ڀR“Â2àE`¬#êKåǚ¢MýÎNMèÔúѦ„3nŒBğš„Ë-€§€îݖI°(òO.‡‰´39
¿1썻M±f­ݣ´{:´ AŠ;‡ÝßÄÜk|úƒT«`ЅßßCˆ%)t¢þ¨;êLjöŽvè<iì¯Éb)µ	PK°âgW@·
èzØrÍÔ½‰÷tžµ¾DR#ejÚܼbˆ%㤈
i³zÝAOütŠG2oè/R«ú¡m@¥£AŸÖ)²þNŠᣃî>­C{ËsØçly¹Mx¹ÍÙrØwÌp÷¸û½ã¡·Zïÿf®€
Y:~Š´߸'I1ÚsÐí:î>âsµìkUöµºZŽøÞötiÆø§f¦YdìÞܥ¶§Àa–÷ÝÀt’Épó«Ïթµ»[ý®fÀÕÜêowwj½ZÐ=˜GX~÷e©1[‘Í]°@êŽ<¯ –¸I1Ö5ÚN¿3 ½éiõ+­þ7=­×èŒі©dŠ/X@r¤j­,’û۰@ʤöŽ­úÌ$À&0'ƞ6Üÿîw°)⌻§â)ö§¡ú^•åR%ŪÙlÅ%†xeäPæÏë×ÐÑõ©“	§ê„ÚqO»÷¸§SësEœ£þä°N‹-€BBÀ¿!K¤B
%Ç. WФR–½ômf\ÿ€ =vöj]ZÀm,=-ä{wf¬Iß$NÈZ˰CªV4ƎÁn$-Ÿ#ŒN’‰ёÞPGðdøôHx2•Dg?iØzbwÉ
sØd›“°bϭz*ÉU„
%È4“Œ3Æ8“LqÏg@sp~Ù 
Reù%°yET(¥^Oüz¨G2’ËV¾Ë<ϸ•%ç¼=сèÑ!çå‹͋²,û¥ùR"ղ|ÁÆÈðÕȜs—"$^ڰÐr—dë²<W­ƒÉêk®Nà$+lr¸Æ$|Š›¸`ìÅM,÷Š6ÙêºÈèˆÒxãö‘w Æ-¶õ¸йÇÚJ&ÁޝQŽ9
Kå¢ÍW÷zö³aV@!÷©b s­
Â,“P ¥a™4ÊfÏÓqÐy/â8 ‘Ÿ0@w[ð(ìDf%Ød«•P¦Fa­l¼áúš™˜ÀËnîf'7ñMb/ {÷¹ʶ.܉ÌJ˜N(•*©“•²N6_á_FOè:df:ÞyàWw˕r…\yl/Ĺ꜄„…0ÀJ(bY(5²LÖÈzÙ,—úúßß߶çä+§µ_—«ýÏÏûVé'd‹l’
²^.)»ìý$äH¶ÍgDj9I™TI­X%e6-r™ÊµQÖÉZY!
s…4–Ü!ëÂë8”K¥,–:Udµ¬1J6«e¥,—%o‘TY|fÍ„¿Ÿ0úBU©ä+‚
ÀÙqÈ3ER*Fµ©‘Z•U¸BʤÄ@«±Zb¶œžeúï=۞mҟ•ŠÃ`23¥ªp¡ÁËSqH©"4žðU`ú””«Û5»a2T¡|#ê¿ùœ؈š.³,=!›ðÀ*Qc``…˜3æ±ùQÄÂÀÃëԕ²
€íØ%l’ƒ…õêÁÅÜó'ÜBÙl§xïi©›`þ„¿Œ Ҷôbu¿8Àü	jSÊ&ïccÝCGŸ]t‰4HõÜáü	õ²úLÿÌö¯“ͲNVJ­چ¹sنó'”H…Q°Á@4ÊE¥Á8Z(EçnDöcŸ¯Úx•ÔH‘©6ŽŠfiÅÿåd©6îPMºÜH™Á9ûNE>€X߶©X^m}0³‰gôNÉ|Èù\"·ÏÚçc‚IEND®B`‚‰PNG


IHDR@@`¹UcsClÁ0`MŠIDATx^í˜{pTÕÀç޻Ù]!<"
µ"iÇ vÂCªíŠSe:V
íT°
Å)´#µvZ§¶±P_VßÀ(
°J ¢ƒ”È#˜˜çnvï=_»×3sf§!܌Íø¿oÎÎ=»™|¿ùÎs®¾X¾`¾øRÀ#DØ^>(Óì ¶u±`S+T.nIŒ+,MnÒÁ]#’€2ᔻëGöŸåuN!DÚýý]©
ÛVO:B€Q¡Ë(éhlÑ]œ彯¹¹èûÎBҴ’¢Aæõ#^K€t.`ŠîLJ<1§÷|UyŽשæ##ڃaŒäR&²o}0ïœwŒÈçP(\Ü7Ï:ÿ/޹°–{X¦#úpó~ãýS—¬M ¹ø&½Wsåà?«Â}ÌáU:§ˆEÌţ}ÓÊko>Ne(¤Ã}&Õ~oÈãªð¯|ã¤顅ÛË!âßøê£ñ̊‰„Óqúý߸ïn®£…hlä"v;{Ú3w”…®
Øâ¯ýú©Ëp±˜®PËXöQðͅÍZçúî=ƬTE±„|’\ÍԠÚx‹ÅTO“h¤Çw݄g"GüðܲŸV,.7°„2ò—XÀ,0'џ>pÁOjÉ »2	Ãò/(í+ÌÉK_Êk,§¿µå@ýŽ£ێ¾Y·­aOêˆWðO~ˆžbNïëo³S1jñvʂµLÀҏCg›kÒÇ­ƒvœXѐD˜ϽXÎa¤–VÜQKÆÔ zzô½îÁâòÃðÛvdÆü\ij¹È=9éæš÷#K¹
Ën^F%§_¥VÀT॑±AX‡e6•èlã»*åŸ	¸AØÂ'/hÿ¸õ€b¥XVý¦˜‰H4³ù­„ç²h٧RŸ¥ô¦¤ùÍ}™‡e5)â×áâD¯€ƒƒ×óBX‡e
}ñ›ý:7Léh/puÌ47×rߴÖÀ
6íluùEÑÌ釛8va¹h¯S:""M†&×Ï}ëAƒn?…ó±ìJ‡íB¢p.IzÒÄr>B¦^Á­Ì~aPˆ µB2
‰²Q¼…ä ›>¢Ày½ ÁRŽà·!¥8!Ÿ¬	ڄAXê§¢	¨\HB
‹ƒƒ_èX2€S€2!ςí-PŒEӆV*ÐY%"Â'XzAчÔ-’íëAöPSHú_odðÉ*­°î¸Zy…ð>–¯©º®ž†’ÖéC±üˆ—ŠrpÅ!÷iÃôEá8nIÀkXÎê Q+ €4}<c$;0ð$·/‹ ݕ˜…'ŽòH–»îFŽaT¿‹ M@>¸uÀäKyo³žK¼¢ÓÚöHy(î߉Ä`ÅﰜÉéøMsw£‘0"V@£W¼qÞݓÜ>Ôc`.ÛHTMكŽP‚A”£µ£ÜøÏ[ÃX®Žm8ž1+ Ñ:ò˭}FßdWª™ɣ$‡Å¿ÆՎ`(IÄF¸=kù–$³€MÏâ£ÑHÔI(hüuÀ<а<Îmˆ*š¸À)QÿÅ!J9ž7$1Êëý!ã8ŠåGô¥eﴭø¡BÄ!ŒÀԍŸîpî"nÇòöò¥%ÎEÒ*
’&«ª§ÓV1z,å,ÖüÞ\È4D_>Y2U÷Îzt®ó"›°¼ÂPneý
U!a3¿æE,ಂbŽl¸z£)?]!È	ÜüÎûxTQŽêYÈ@.æîã,a:ƒcÒ[F1ˆ»ïðüS]Ì&õVìàQ@’¢޽ö?Üç¼jÆQGW™Í&c˳£fT§0ó ʝPÐá ´Úvռ–ýÃÙÄiDÅå[ü‘±\Ãš(š²õ¡ŠDçw‚|Ðá ¤Io¨›>«齡lçZ¢PÎjÖñcÖó43™&zLݼ¼"iN" ‚ ɒ!MÛóWΪ]WL¯0œÎHrï2ÅýŒÇÀæˆ
D”²(@m¯+ÿéë׌™=¹ç$^a«I“œÉṳ?ppK<9 ¢?ä)¬¢×Ô͌ž±#h@:°ËÑ(2®jâºßÞøµ+/_Nš-¼ÍG4¥œÉh3GßÿÛʙÿ¨YÅЩÂIDh|̲Ä_shÍÒËVÜ5ùì	½‡UªJòÉ6ڼæåÙÛTS-üŠj6u °‘1¡ 1tþ†ÄÁ
e<Œ
ð*Knqک¥eñ"×ó³-õÇþ½õ½¥{›3øN¯øîŃ&639OFçhy&Tðt´wD*§JÄÂÃÃ%<ødÑ.Ņտˆ  ‘“½¨eR„»#^..*Aç"Ѐ‹ß(ÃﬖA“V1¹ÁØ™q\òç‚lj0&qM8v9Yóï\¤‘á‹vªÁO 0m×ցː<“Ö\Áa³¿	\ Q¸k')Ìà)úÎa%A”
äK€6¥Ç4ÄFT…j¤c…gh¤øŒý–&@¢TÀJ€tø¶<ÿS0t¨`Vw,Ž‹ˆ,ÐAŽÐ8ø)Œ£ÿØ}¨ˆ¬0“§*y¨©J	yxЭ
ÁàoW±‡" ~Ëø‡îÈW¤Q†ÜùÆÎ¯ïõUH×í}ú²eÇÚÌ˅|n«‚ ÇVñ섒B÷ù㴓¦ŒYV ÛÄ\pb¯µ¡ðɆ
ÙV@ý¿Ì5ÂÒgÈ⣻³VAa®ú¸˜ç0Ìu½»@Ðf̺7}éÎU€Mg¿!%|±üiÞå2ÞàIEND®B`‚‰PNG


IHDR22´6@:šIDATx^í—Q‹‚@çÊÒH$£0D_¹(
‰ƒþÿêÄ?ï@\„ãÜy“…ÝutyÀ—L¨… |”ÌJæ5³’ê?Ò[R	¸x¬J<\8•h€D¥àÝ•H4$.¾H|\[’֘J@M50¬Y0³%q	EàڒÌñذɞ
s[’†H$†•]ÉQ$Ç$“DU±ÄgK,’˜->ËjŽ6­["jð1ìHE’²Ãà׳¤im”BmZ—DÕG¢Më–H£ú¡Më’H£ú Më–H£ú¡Më’H£z¡Mû]2xãU¢Ë5X¢˥OB΍EÓ/^’•_<)ÜÈIЍ×#́„9Ÿ5g®Ü)DRpçʹ™—s"á€a}1„ì‰8ÖĤd\Dr!#%næEì	1è˨YaMÀӰeGL&’Œ˜[Lƀµde„@ސú?ÿeœ$‘6ʦD›fý7UšÖn”
‰4­ըþiZ»Q6$­¦I£†Kì_L›Wì˜$½ø¿¤Œ1'XbúIEND®B`‚‰PNG


IHDR22´6@:çIDATx^í×ÍNQÆñ¿2JÚf S§Öb´°|„Tl ,Ýo‚—À
°4¬X»æØhÂçZݱ	&š@pìÉ“)/‡15qazžM“'é/§yçÑ?HùÃô‘>³®&ɍ€DD¾$Eê¬@Ê@ª“Fº8¤÷ýŸ‡¤qt»ûy¸ïÿîzA‘ÆÝ»9Ž"<pº‡¼(º9ÞÃ%-L2¢	oçñõIÔYäC
$¤AÎt×';ñ„ID4±]¾2„Aòâv!.ƒ䥽:Ý.+Ǝhⓠ£<ÂÃ	5ÝgÅ$ š)1¢J¦£Oб!AÊÈv!Y
”M‡•ш…„§øäpIKpÉáóT£!ÈúÂF}kümù]Iò¶¼5¾Q__ÄÂh¤›ø(„ 	ÁÊÄ+!9O÷1qD=E3qÄìÃÝ-i¢wf·„köG¼ÍàÇû(:‹žýò,:ë ?Þox8ÝHš,ù×—Šéøvøz‚<YÒh„°Õüz|›IXЏ8n5	ÑÃԚ­ó“8“Œtç'Í5†õÏ%SµH™©ÙW_NãŒY¬±B›åXڬ°fº8ñåtöS<¡(S;ŽÈ^2áS¡>ӎ1‚,³È³ÌH˜eŽE–M'fÚԩà3DÆì}3Êø¦B#ÆҤA*	Uj4h
#T䱠oÆûAT	ð)Hð	¨Ò0ÐR1Ï忤F@Y	9
ÔLg#,£^3æJëõŽ$>êÍuaA4Ól]„ð·Vhº‹£/5aG43¹4o¦€ýñ{y°4Ϥ&ìˆfBª«Óß?Øß?¬NS%ԄÑL‘1‚7Uۑ¨ÓŒQԄÑÌ Ì0b;ܙŽa5¡	šÁÅãa'™;©Óáá
Z
±¸`@¸­]2¢IÌçä.±c=4’ÿ᝱ô‘_m¥J¯ÇCIEND®B`‚‰PNG


IHDR22´6@:èIDATx^­–[hU‡¿3{Ñ
E¬XRSµ55Å ©Š¥Zú …¶V0‚`…ú`Ÿ¤Bƒ(^ÐW/4ÄËK¢ҒX£>¡ÕŸ*"˜ZŠ•ں;÷ãáðgÃÀìݏ}úÏì7¿=g{<¦â¥\ñ -”É=C£;S¼â÷çEÃÐ2´KhÌ…òV
ίE‰
D¡cê@û%f[H$øußü8€קÆ3´ ‚^ž¦ÚxÇâÂ:šÕ;oҖP¥Ц™'±Ë×ox롾4öŽ6TЦ±2‰ÜҼíñcÓ×Wj”<tŒ¢˜øÉhvїF$¹5‡2‰ķ’­FӺµZ#"ʲ¯ðŠÏõw-MEÁ+X5šœªZqÐ8$qÐ8&)×(åž'{w*P!qӸÿiUo
 ˑ+Dâ¨Ñdô ‚Ú'HԐQ£jLÝS`LšÉP.©¥ÉM˜ˆ€.þ)СK@DŒÑxPKs‹hX‰O—ˆK.ºøĤ’ÄIš”ÈjʓøD$d’ÄA³ŽšŒ„ˆ „P¾¬^!‰“&%!.!1X…HÜ5È.+%3h¸kúmhÜ5e- KèKò$ºÀy6‚i§æ
ÐøOI’Á,ÊÆr€ZX+I\$8ÊÍÄLgÕýj‹ºזÆ]j“ºݔÊ`ëîíËV¡$˜Dñœ> cÃ}ۮ$'ƒo‰IÉ\«^Zë8Ë1¼ö›ۥ§LmH;Å$dèÚQd‡ßXþåvÈà=`ø±թ-ĮÔFHDJm©!Åg¯íZüî</ƒãüÆëç6Kó†ö“ЫŸDG_yâ8~¯’Kw2
@Æû&ÝdôHóâHE¢û•hÀ*æ&§‹¿tñÌ<ì‘ñ4«·¼ÐdºgÉæµ$:ûòåñ9ºj†lk¸À,xOÔ?PˆDŠÎ(¾}éA£IðöÒò÷«x,ï×éÒSû8‚o	ÑÉØ#Ÿøgi¬ùhÜJ¨+ÑV’ž޻ùs+¿C´óëè¯!¶1À~£ØܰËæPJՓ`sÄ#³’ !5$$è×Oaš?x•õ¿Ÿ~ý…g]wÚn̈ÙýBBô֌NiöΝøpïՏŒLO]D;HdEd÷Ëޗ_Ä'çþ<üóIñÁŸ9‘øDÈÜiá
©%³
Y'b›&‡ßùx‰Žô•£Ö5“ˆ&ÿø•+E˜z:Ҿ6‰"§ï$+AԲRRŠ]QH%þ_§z-Y"BdKT(œ$²ü$ý֡*á_
¾ǔ˜t
IEND®B`‚‰PNG


IHDR22?ˆ±àIDATx^ݙ[LTW†…¹ãáR@¡c©5і҇ZMjÒ'Mišx+é[_L4Á¬%mcb¬ØÛ4áAMƤIû`ƒ¡ÓJQ¬ET*¡ˆƒ Ãeõ_ÉÚÉqÇáÀñ8¦]É2Ì9›ýÍÚkïu†Dô̘GÄ	ñёk¢DLEtQÃäÀ	\ $*äµKÞw()}¬؋ˆ€àP“omm-}ðàAÝäääoÓÓÓýàŸx}nttt/¿or¨1ž—ˆž÷Ž;Ò>|XÁ;nϞ=é|Ÿ–˜Š%œ áäɓÈ„˜ž™¦SWšéýSïÑÒ#Ŕþ¹Ÿòkþ=¿O|=ß'Ùq*™ç!â`‰
6¤G"‘„è
ߠ5«yòQá÷ù:¾ïG¬E”„x‡‡‡¿V%G–<&`£_§dø~G-³XŠÄK¡zNœ8ñòÌÌÌ$/—µo‰€¹àëÕ2›äqx<ʉˆqI䁁ƒ„hîlbS¾ƒÇáñ@B,EœÀÒÆÆƸ6hÓïZáû80Îï<ðÄJD-+/LMM
bé—EÚÄM±ÐÑâÀ9æñ€7v"²¬@ê#"“²$’u0@*x<K‘Dà98þ±##Èì0üQl]$ˆ–ã;jã´óxvˆÄͥs5:vwwµc×Â8_Í+#3ë\]À
¢| äîܹs-êdêiξ÷îݫÍjd®í·K–ÌGà¸ÀO`¨çÀ_ ü*AY9Nˆážyì|=Çõë׏C Èt×2„™ÄǀƒAÊÌÌdÓÇp»݌z=>ÌÎή¸wï^§È̩×R÷ï߿\PPð
òÔ9bUDÒ>ПœœL׮]#,@>ŸîܹÃˀwjnnV2œ¡6H÷uttDôîwÙÑRÞbywâ×\ª-¡‘‘‘®7ò’*‹ÕÉnEDec¡¬ù΄1xÒ,â÷û	¡/þ$ËTRReddСC‡¸£¥ق{³®®®ïËÊÊ^‡@	‚4³^k¶gj—o*ȧ¤¤,bü=gE	:N:{ö,ݺu‹®^½J§OŸ¦üü|ª««½téROЏ~úѣGwmmm
•••ë!°\$rA†ÖýšŠ軓lŸ0d&b”a‘@ ÀK„éöíۼR||¼^[ð)x¬e`	Š„oNÏ#za¿
ºõbž¯H^^óFCCCÔßßÏ
…OT[[K^¯WɼB dIq{çü„¨KH"üÉm۶šššhÿþý¼=Qäüùó´yófң¡¡ª««¹Žhbb‚ð®j‡xs ¾¾>ª©©Q™ùHaûGfÌDœ"‘Â<é3gΐ1êëë5$3ªf¸È9;,’,‡yP"µR‹išDœ€ÐE¢ïN[íڵ‹ôàÉTTT•`ÞÍXÅL,E(rκÙ2õš˜ëtzëý }ûöÑB˒5!%¥À6ËS`ÈêRóq:Ö`<55•z{{Ÿ8;[®ÚÅ.K}dHm8ŸF$e»¥òòríð²|© êãC’$sBXI‘b{´·}ÏTdë֭Jd‹zސ¹8¢ÌݴFÜRdé4៚ ¶··Ûo ›L–!զË\⭈¨í7I=IVjm߾ý™ˆ´´´¨lü
U›®
ݪˆž•B)ü»Üðñ~owTUU)‘jo8?œVEôCÑr¤iûÐáÇm)..f‰	°ä¨úPËʪˆ~0.’íp
ˆäæær›a›ÄŋU6ZA±á tÛ!§ï`’•;vÌ6tJdo”óâHô¬¼փ™ÂÂBn+ñԧ;žIԲzäèۮe=+Z­”ÊÎB°s·ú,‹Ëʽ‰ô²²Œy<ºyó¦]‡`•ù²².-+%àÀðŒÕ�§‡ŸßY¢,ӗ•]"ÑZûÙç_RKÌê´CP[VöˆèYI–u\–ƒzéV»,p|B (j’ZVv‹èYñÈÌE²$V€Uà5Pn†\·R>ˆRÉð"c6x.vˆèè­ËB‘Y,“(–	…ϐÔYÈÉt¢I6lÑÿC둃2]Nâl)֠r]¶ܗfpx{EÌe\ Q²ã)¿dÊ¿\š KÄBd¶-$΃¹ϥÅc—ˆ¥öXEaAä?ÊÿSä_nÓä/`¬IEND®B`‚‰PNG


IHDR22?ˆ±IDATxí—!Ã0Eçm½˜¨񜬯­¯§6ê¡5Õsõžyæ½÷>»ƒ_ÈŒ¤ÛðÄB®ä³&½œþB!„ïýÕ<|“A^`©ÕN÷ mÛÞ1V«ÅS©ƒºzSDÁ؀¹ErV',tQ{µكÌó|Ã؂9jŠ¢
B\TQôæ¶m+~æ LYÿÌ„pðMˆ0¨-‚:x$!ˆ f-å谘^u	A̵]¾Þ	ڱj'’mf[ll$Öj¬֞aϊýzŽDô)þ@˜ïyóÁiP;r³óøÍðAd‹’³idϋïìùaxP!„BÈ‘$9
š_IEND®B`‚‰PNG


IHDR22´6@:¨IDATx^íØmˆ\W€ñ߹sw£1ټTš´¢…ֶAH
Š´Fˆ‚Ö´DQԨ¥Xƒ´”X•¶V),é
bã‡*HTT|‰¥*¥Ii%ÑÖVcJÚYJ´[ll^šnc­ÝÎ۽G¸\¸p`‡™~ŸÃý¸<óÌÿ¿g˜	ÑŸÌü_’ÑpB@õˆ ƨAÇ+	!d2¹ܔ‹] ג…,„‘JFzí™Ì3®ÔBۍîWˆ!ŠÔϸ’A†P+^g¿©
.òl<´¾ü•͎*•bý@MÒ(Z2ï·ÍåzÙ鳦nw#„½®™t‹SÞåϸ׌ŠÅzò!Š–nã<=óµÙY®lµM÷*V:ß܅ÏÙâmŽˆã¬p¦åµnYã!'œöUÎõδ¼W;©mÞXãz¹– Œ*	2¹+L^ë­hùº•R˜®TKMÃF2ãHZºLz£.L$	¹LF“´ÌqÀz)¹%€Àó&+Q«ê	#”Tç”ùFr©”ež†óýÐ~߳©é.‰"hϛ\&e
Àßá2›mô	÷ٖ®@f1¢R›ºÅ%R–7\iV×]Î	f\ %¥¤TzŒ?ÖY¡^ÕHp§KMú ϳĦJ2¼eu޲øT–5+¬ ”"‰J…ÓNөJl”ÂãòôÎdˆ
íÖüÕÅCK¢ã>Xðsž[l…ƒ %·Ö¼Ç*-³ÍTRÉJÀI]oüA?C*iþÇ_iÚßìs·'M[-x¼ù›·۫áZӀ§ñfÀýð°RÈ…	{lYk«ŽŸ,ßîcv9ÔH–û”†o5±Ökû)=¨l45ïµåMھé;žr³e«ÜjÞ…a\åà„#<á9E­iJ„J2áÝì´,w›í¾a��h+ù£B!"-‘›âÕÎó]ù¤ur£ñ[ø]¥Xäíʴ٣.ñ1…œu¸*‰i	À>§w¹>€ÕFã!ÿä÷:éDÈ@¬Î>ã™;|ØKÆy³u	©Di`à˜O›½Ë;œ2>w3p¨zZ"Š
='\çà#®0k<Ž™刳J%‹•tu,8k‡Ÿ?e“‡Ã/a¿z·R	D…¾Ž—-xÑNw<_¾Ó=FçG”î10H/r©Zš%Økþ¥¯]ïó¾7k–=kv@N¢‰õùµ÷f>ž?êõ†߆_èW‹JM-Ávýë†mîgÎ>NºO?]ßT"F1DÍáÇ6¸|Ɨ
ç‹ìÖÑO/”TR‹B	ÕùŠŸ޴ê"[†Žü7<égzê±KÈH5J…¾nµkÇÝTô?âNQ
”v»ŽŽ›-è©KZÒÔè‚ÌA7·o_z«åR8ãEzvxTW?íH%©¦ª©$Á¶Ú~fÙ%RXpÔ��«Wu.I5ƒz.Ѿd"ùözº::ºuÇð’x” Tè¥ÄúžèUŠjŒQ‚ˆ¢¹×ä²T¢¾½õ+E!Š£IRM²º#•D…2ùÀKBDYK‚@"©kÄú_QP’( 62Cøßù½ë?‘.Ø?içIEND®B`‚‰PNG


IHDR22´6@::IDATx^íØM¨eðß;sîѲ$uå*D!"	ڴpQB¹h¡‹6EYdT‹ÚDTØD„‹4%+‰°MÖ
?ˆL­0Ê@3ͬ0K”oçcæ^.ÌÂ{ffÓ&î3Ë9‡Ïûÿ/^&Dÿ}2Sf™F¦‘idé¨"¸$aÔQMb…ԽAdBŀX=ñ(Ô!T„\îA÷Y pÐ:KÜbžÂ/6Wˆ¡D$ִ
Q•"*“^ÌÍ7ð; ‹>Ñí>Q¦'*«V[
>Ȍyd¶œtÊ\é7==;^ö‘ï±ÇJcrYÈBh»]ÑÑ5k¶…àn促e°ØÒY¯Xàf›<ªkšáßdòDÌpþ< G\†ŽC.8ï<æ
«]#—֤	Iû$7ÓrOyÀL#2ÏõàZW»ßÓºWGž˜šíš·›l°Hmf(Ý`½Þ˜ñ×û£šTÄ
ã٢•Þ÷’®*_Z`£;T¹Ç«<O×r¹¬¾I&7ÇÆîظe`®gÜh+€‡Ta.˜
… ˆuM–¹êñDÀîӔU–€¯àû晤­âr¹4eBá¨L ~&™oôÖ9àVírÆaŽš€æþÃëgÝiÚe’J¥˜ž¤TÚâó/¬Ö>°öJH]“˜ˆ¡¾çüùšCڧ°“*$¦ê9mma­ö9à4{ýX‡P*ôõ|ìÌ{Îi›àS…aóqE¥„¸èÃ	[µÍú>KDÃq«.¶¬Ñ×&ßú‘¯3T(©kR1}}¿ÚuÒmò.ìLDšI3†©ÍÛâ«zšm§o·4‘fDudŽÚuÌMÙçû­z4"q²KšËZ¯øY}6ÃxêÑ
©º¤ó“õÝëVù¸휲ËäaiwïŠ1D…žŽ­ï¿mކ¼c¢šH+¤Ú1¹g³ԘQ)ì·Mß@ѾIÕe¨'Þô–Ž).;&›ГC$T¢¡±$­ˆž4‘ uDˆJƒ©.: J]T(Ñ©æ’C™l$R*P$²=R1	)„)	ˆ$Ž ¢D	¿2Šàÿó½ëj
‚sqûIEND®B`‚‰PNG


IHDR22´6@:®IDATx^íØ]ˆTeàç;çŒK™‹V^H)Dôƒ E ý\ÔEX›X`åE!Q‘AaáÕ–†?•áE$JþaŠ.†B©i¨%Ê*J‚æìÌì™ÌA†Ã,l7Ñ;{·ï÷~ç찡ðï'Ñ{þGd@ @Ï#ÝqB$(®}Š(*6©&R5/Úç¬S¾qŸT"„`\ɪ	©׼“š¡åܣxÈڊ‰>HÔ,í÷›ӆ­§ÏËjãï’T™šÉýnÏÀ-jR‰mrù2 ENa"‘Tè‚SÉD7I"p˜8$€¡'‰$Az¿a2ãKÉÔ(BùôO82Ó&Sµö™mrEh£ 
Ë*ÖH"›ÜèÞIhζÀ¾×î|
íP(ġèíI¤2™TڽÙg54l!x×V¿8l—ÅjÒr­h“‘¸ÛKf8îäf€0—ɂ+³ÜoŠÕr¹¶H£¬‹H]o•g<h±åñ¿×!sÈ8b¯˜ëœ/ÓÖF?® He-º=lsÞZ7ôyßÍâqS‡`¶„™žóºƒÅ^;IW»<=ǐGL÷¼ïL
2ñèÐv§}>ÕßgÐ,©„8B"3Ÿe¦æ[xÀjO`À<K,g’Ç:H´I(›¸ÀaÀ=6xÁ¸ôC&ë !Þ$Hìqá#»ð¡éªÃóÀOp¤j(üíͼ½ÐӼ­:|ê¶!wT"C
Úr{¬ö¤zËE¿rT−ÐÒ4èÇ–zË.m†´ÇÈ82ª¥¡î-'×Ym|Ù	{Kbˆ²‰†½ª¾Ì1½'·+ÊK†x“B[KӈºãG¬Ð{†œg¯‘RÄ(ƺ¨Ûäâ×.é5ßÂr£ÕÇU¶)wi¸jkݽfM»;Dü¸ˆÌ߰Qk¥¦^ò³ß9ä’Q¹6T#cÌ;N[¯—|Û;D=®“kiiú\±BCu(l¦i§V¹Hy,ÚqÂJÕaŸ?Øï¯xâ]ŒjjX¥þž?Ug
lëô¨Dâó7òñU‹ª«|Òf†íè ‚ˆï¢!³ÁÜýOSëԻ‰ ñ]š2©7œð€šxÈí·QSK^Ѥb—† øÄZYô[յÆuñ#:HPU«@Ê+҈/¢ANùÚû¢_Ïhكj$¾K‰ŒJ$q¤\¯䊊&•LùKB”€¢„ʟŒ¡()AU
ˆðßù×?<Ш³w+†#IEND®B`‚‰PNG


IHDR22´6@:’IDATx^Ö{lUÆñï̶…ò¢@y¹Z”DP „’j¹Db¹)	QD…T‚*‰Ѣ&(`‘Tl!€XR( µ ñ‚"‰wAŒÐjMKÛݝ'¿œd,óÇîìy’þ³Óùô9¿í™Ñ,M%©åøƒà÷’Zš/ û>OÍҼøa<àzo4t¡’,(×ë„ܤIBèȤº‡!÷:ñ]_ôdMÓ }e×úüžh~®¥èú´òž¥¹ËßD'M6²¶¦i‰i+ÀÙ{"ï•\øi­ÝÖݺ©wåü†ÈÛ½!}<D)Œž3©fOrŒK-z²s!ÿû‰÷ÙȾÄÉ켨ðóJu››„ÈHúÈѲþ	é1¾¼Ó숾‘AŒdÏRÄ8†ó¡Ae¤«.þ&pÆeæIÀh‚¤5îzVP‡·~e*Mtšôí}^ݫ/“\&}HBFºTÇsxÌJ˜Gø“2 {ª7[…¨.rIòÌû÷Ýð25œc«ØÅBd7€Œò-ëØD 1NÑ^«u`E/Ÿv,Èä'–.„’d7¶›ø'-
lã‡Ý/,ëÞ_§€| ù‚šˆ¯I0&ŽI¬xû’Y¯~P¼¦kö÷Là`,³n¬Á’¨֑±±01v]-½øֲÌÞ'™H#0š*2¨ߵ²NúzHpFšXH—Y}Ƈ™Í
`2Ÿҗ¦Sã7ÇÂÆQHʌL…xáôZ®¹TӕK5¹K/·#.W($5Æl\ªKh`™\<vç꺘‚€#HPÊÖ`¥n
€¦:3BCšXÞv¥Î O
rxÒÍÝ@º%€"<$uF-ZÙÀêî}01½
	ÄõTúæÂ*VPÌÃ@ÿ°±Ô7Ëñ ÌàŒtÉè	gøu—ۃãø›¤ÎD®A¹@ì*¾¥”p~:kÙÃ6Õ8’Ğ|âü»iöž¦'×jflÆNñ3¥.ؘwm|aæÉõ§6íx¼߲ۈcùT™GÞ쇆EŒhɹüм²E_ÁÀÄñ!©0ƒz£&QÚiuÓF˜¨ 6hPy87å:ÀŒ!K«6ÿ‹(aÚi£]5±4yH!ûùüA#}èS‡vfabqE½IÏä%r1vuµÚdm¢6NË×ò´±Ú(m¸6H¿­Sþ‚¿°ä 1%–""B£ñ´K±8aJg"„eçè¿Z=WÔQâµHŒá8ð™4p=㵩²ó­´pCM ¦& ’Ĉ"ì½ë›~ëÁÅnrfÝ'B;2dicÇò€dET¾2·öË*X¢cÔÓ)»ú^b2b³Ž/
ñ×Î>FdùÇfËhÆ`ó0j¾ì~œ˜&qïPOª‰ BTÏ<L;áÍu‡a±âË0¸e⻷¶cIl7î‚@ˆc´zzµì{˜ðŽ}ØsÈàoöƒ>í1ÿ[$‹8ظÄ'Ï!HdŦo2Y’­@ϼ.„Ð	ŽaaZ~aIčñõ>X¬îxšBY;§BPÄ$þË3÷P@T½s…Ǎkƒ˜B_^¤¹ÒC6,‚ôˆØOD"¯fÈAÑfœÿÊøƒud¹øKÉÒE¨Qo¶QԷ_ÅÄx}ŸcÞFšu峲¢n3F”íhÆ	Šx1eƒ¼CNýG”7^Ú{vû£Ӳ—/üÂc >Omð6q‰-„š1¢wÛTQG꼒kpœ€MãÝoRDå¬òž|1¤‰†—$›tŠV“"B»Du$Þ.£ºD%fB"8¢ï©ga%à_¬ã>™w€)ëIEND®B`‚‰PNG


IHDR22?ˆ±IDATxÚìš1nƒ@EÙQ„†K¤ÉâÂuî‘#¸¶d»2e*:j[Šð	’¤Î
Œ„RÅ
x2ƒ€ ´¸Y°°óGúÚõÌ`æywAڵ""ëìκ@2Ûôò<×=-~X_¬7Öké{a=³X÷í&“‰2©C™>µ:@šö]¶޹$Sަ–m۵<ϳ|߷öû=•^Ç$>‰5sû²ÞF¤«¨ù|η |½^k²,ëeD,1Bm%IBAã8YHúâ;¤»ƴŽA@*-—Ëd³ÙйÜ1€è4•âäׯ@#1bfô±F´_Šn®j-ðgÕ‚"@€ @€ @?˲ìIÚ4Mk_ÕïÚ2iô!0ë¤(Šªî»nۼŠ+HlˆÝøKôœ¸Q«ÕJuLâÍAOsj¹®K³ٌv»ݩŠo·ÛÂ'±fîèFäŒ]×ahˎ¬OւõXjQúŽCÜPáO5Èÿù`×mcsÃÖÈIEND®B`‚‰PNG


IHDR22´6@:´IDATx^½ÔáJbQð{EoD+"—Ìe¥XZвlSÛêû~ÙÇé	z_ w±,ë
zòCZpwîzàÜú39,;ƒpa~pçœAü°GW̥’Ckψà“dÐ/ö‹’3Adϗß.Þ.Η‘E†„‰°½^Ư—½!1gåÉ Žïã;a&ƒ³21㫄¨H&ÌøÊ2¾×S’Ìx"LÜBa<•ÐD'tff„ÇM„ƒq#:áÇ0â&8W‰q DPÀ$Çøš¡qϊÜ£"|£’@‡ø‰ãŽ¥zˆn‚T†gÃÏÂ4ÛGK~mBÚÓ¦83Œ0a›�š„4¥ZǎêM³ˆJ¤Ž-|Gƒ†T·P·83Q	Ì:x×NS/Dßi Â/uÆ Ù^4$Ä*þÌäª!k&ƒáéÊK?Žâ¯ÿ‘.‚¼ôOW"˜"̣ðëÛó€ây𻆂tΤ”;ÑÐ2¾ƒ¯þ%Fãm”ÓH€yDXoþx¼5Œb‰ÇÛÖÖ!o?—(¢‚Z£c˜‚IžD­[b·ƒ*(bÁ~䰈¾`³޵ŒÝQ´»¨n‰f›ҩ„ÏÈ%y÷¥¸”fªé•Þ]\gbIˆwQgìŽÒv—©ë„]Ä4
3ãàU‚W=3³"*ñaf¯ýtCÏSyzO7{m&afƒÀ
¢2UBG¹iL˜q넎¨7­J„6n7âf܄q3UáB܌“p#nF%„™ݎ0f™3á‡0SkŒ†£aë5"¼fJ¨`­Ó8ÚƚœJiÂafED(KFrZ´„¡P™GA2/§œ!Aˆ“É"ļdˆ,^3	 #$:ò¡h·Í.ÝMIEND®B`‚‰PNG


IHDR22´6@:ïIDATx^í×AkA‡áw»»Ùd7MÚM"I7¡ml¡U[­ ^¼ø��‡z1zñÐ""Þü ñ؃'R­‚ `z«JA
…´cücX’ŒèAòÿÝBàaf˜³¨ÿ	 ¤ÃIÌΑ@/ˆjB`aã$Õ!Il,4!¶.¨†ê:5ÄÄÆý|¹;CKq&¿¾ô“YVÄF›!}¤@ø¼¾·+L'$ ƒ£‡‘À#G‰‰ÕÛÂtBŠŒÄÔC,Rd	§öôŽ0ñHˆOJƔµø”˜dvõjN=)ë"“¦@åä·×Jm¨Ê!F”ˆ‘-sñÏîÿþ2"ô)̝s­šˆÎ¯^Ù^û(«Zˆˆjl'…‰Ñú•äJiçE;ñQɽéÂÁUJ56/’"!+â^1†,÷ظddíO—ðd=v'bó퓇roúD¤@š„0WHãâÅoԗ7sg8ñè®0} &I²?…a>\ïW∯ëó§9Âa/7™>.£IŠQвô_̻[ÛkqÄâ)f8À~jÌJ4‡±^Ÿ1AZŒŠ#ŽŸdŠ*!cT˜¤&¦(2Ú+
Òbâ‰TÈáS Ä8ÏëªA@–doH9BPõNÄ>²x¸¤ñ	(®/‘gXª¾_„ND†$6¶Tg–òdp±µ‘踙jXȆ)<†›qq°´‘ºÔÆê}f¨Ê΁44	œ轢‰ ÷fo÷ÙMBrxØB 1¢7™ÀúHë޼ºŽ+H4F[ÐF"æýUÒRm£$ DŒtÂè#¡ê2ÒÐ)äu$#Ò]]™Í$´©úUjbÅ(ã(óÌ1Í!¹ۦb#OªүÓíá SL2N‘|„´§;b`á mD‘r{¤u‹­ÑDd-Fðc3J6*„þ?x4aŒ^>݄èù[ ä‘òü	¬%OAIEND®B`‚‰PNG


IHDR22´6@:ïIDATx^íÖÁNAð®."
ˆb-B¢(µÓ¨6ú¾/ WO>ƒñ	<“ZðÜ=«¨‰‡²ý`6Ùœ쬉‡¦ó]&3òËî3çòÏ"Àë,"^ ›ø½6Bàc\Í\ÍÀö#oG$1†Øi¾ßî·OóˆaL2úˆ$Ì㹗ŽÃöÒ>žƒ)}DöµãüfÇî,&,"‰"#}DI€‘Œ>¢&Œ¢"Œ&¢&<族ÑA”„šÑ@Ԅš	Šxÿz7Îg'=
Üx#œ½L0Ä@ìhžO!ÜÈ	2GóˆÁŠð93öY¿Ûïöz/ƒØO~Ä~rg5ƒZûì0>KP$
)°„*êøŠ¾c׏`—£-ÎÖYµÄê,Dƒ!‘’ÇGT°‚š	Äj¬¨°2?B"_âH ,
(beTÑHƒ£eÎY•euqñº”…‰	$‘"5Cꪩr´ÀÙ4«’¬6¯ÜÂdCœ”E,M¦"
‰4g-VÅYM"ø&B1&†²(	¤ÄÑg
ƭŽ0!/-2XÈ"G-oº´þ#ºo^xÃ[xÝ-l2‰̫[8CÆë4·0ã$Õ;w|͇ˆôÎORZ§0âû9ûB±/ösòXQãH핞/—Vف"åá¥õ|¹WB
㤋 °S{º’Œ$ìÔP!_—‰)äQÚÜè¶}Œ º?77PbõL½S8†	L£ˆåzë®ã1’¸ëÔ[XF‘Õîõ«õ!$rXÄêúöíµËHâöz}«¬Ê!©õ!¡fԄÎ)¬`ԄÎ٥b”„¢d\bmK®…>"™ê—-î´áŽZû†ªŸ‡Hf¥Ѽo߷M¬""™,Pi6š
TØËúˆPˆd&1Y™Yö&=""ã2ñá—XšI²"áï"3a1¦wA½
‘Œ1.@"<¢‚¼°é ï?ëÂ=´‹<”íIEND®B`‚‰PNG


IHDR22´6@:ïIDATx^í×ÏkÓpÇñw›¦I›®ݲU
ÝҲÂƶê`þØüêŋ€†(êa^,ˆô0Aoþ!¼ì8^vÆ…y/Sˆ Tcú,ãKI41+¤ÏçÖˋäI>ý÷äÿBúH‘IyI{Ñþ´$å%l¢2è˜äƒ‰N¦›q‘D#Bx€=ííEa!
ÑÄNjäÑÑ rv 4ËBl,1ÂFRĠHE!Aâ珵ë8”“#&ƒT$Vo1Á(ÃXdI'CrØ8‚„+wh2N…92{AjA¤%û^}È“ŒbËuÈFzˆÔÝMù²~j:e
Šè¢˜¯/ÏMa“—[¥&¥’¹îֺ˜o/Zu,tµÝú~
i؈Z÷¦[ïb¾?¿;Љ¬]ÙíE·í—M|Ä'$Aæ~U¹²ä¶.¸m×%Ñaâ"ê¡}´õúwŒÔdëÃ%ퟚ�MlÄ'ßãäsŸ^…ß4,òÞ_‹_6é¸/£O–Yà0GæÏ|ÞcZuì·W:Ä]Aä%5Ñâ c;ÄÊmæh2Å4³ÇOyÒÞÜÜ!„*Cäâ CTýŽj2I1̜8dd„ð‘1ì8ˆI‰ŠÛ^k1Á8£”±¦Bé0F…81©úF6–p¥‚M<%ö…3­ Z<D'O‘ÊS’Խ˜Ã!òx±ÈI
¦åWŸaF=IuV1ȒA#µû+²-Ì>}àzÓJŽ£ÎV)…£c1ŒóìÆÏ²îĈ0*mÙë×ü÷bO
V‘¦ÍRxwU½DaIG	ÑsÄ_{Nš6bpö‚dåÿ"r¨2ˆ™ѤÊ8Lp€ƒÌs”cWaC4iP¡(UŸ¡Ê8“̰Ÿݑ®nøG%=	F¿l¨P•V®u‡ªßtRIU6%†°C3Ht"ä¯?Œˆ‰™8Ÿx‡»ž§ô‘_€½ü<0Þ5IEND®B`‚‰PNG


IHDR22?ˆ±dIDATx^ݙmH•gǧçxRóøî1Ï|›sÔtî…lsîÃƂƒ  ö­·ɾíKi
[ؚŒ1ˆ@–µ1èC'¶„¨­1êÃh†Sږ³Ü5Ò4³2ͷô¨çÚõ‡떛çôðxd»àÏáÑû¹½ÏõúŸ!¢%“a‹­‹E•¬	¶Dz‚h‡w°œ¬Ö
V¬’\ÇÈï
j¹AL8Ôᛚš֌×ÎÌÌü6777@DÓøäë+cccð{
ʡöX.Ó®ݻw§NLLÔ‘Ÿ7?Öí۷/
÷éމ4ˆá„NŸ>Ïø¹9êñùèʦMt.#ƒ¾gn|â?ÇïaXûÄ;N³ @lٲ%Íï÷_Äxw7]Z»‡*üë`¸÷Œ#Ò 
ÂÅJ9¦ Îy< óò¨ëرÀDOÍMOâ?ÖÍÃà~ì£Â,’ ђ¨ñ>Ÿïå@ 0ƒp¹TZ:‹‹iêþ}2mft”~ݸ0X¯Âlû`?ì=¤X‰ƒƒƒ_[ϩS ùù€0aˆ«ؽ;wî´(¬îƒaì‡}#	┧—:99‰ܘÊÝǏpø…`úûû¯2L3.fÁ}0Þçì‡}#"a%1홝ȹôt€ÐDoo×Á`¸ìÞÃ'r 糲Æ}fûaßȁHX±²8?üQ¹Ć-a@\.R†ý°o$AbYɬg¹Ü7<¢žü`0ñH@÷{vûaߠ6š	’Í#ǟFެ···…sâ÷`0È%=GxŸVìgHT8“«žèéììüʬZ¨J0T)T«…`̪…}žÆ#¸5¹ÆHcZDq,7+•³gϞõœ'³zw£›	£÷ܿÿþõ¡r$Üñ;FBæcÖUÖCÖ ëk«†u…õ«u‰UÁ*b¯à±ÒXW—Þ٩»¾9ƒÄÆg€¯zgÇzXww÷)x>dÕÒ,Ä',r8”M™™™ ÕE.—R×ÖG^¯·üѣGí֬¥ ?~|#??ÿUÈU}Ä*ˆêÒnÖ@bb"uɁNž<	r»Ýt÷î]„*544(x¨™¡ûÚÚÚüæôûƒ׋‹ê„käÄüô;::ڱuëÖw µJuv+ Ê+%æGá	Ýph€$''Lšž¤î)Š‹‹£t.ÁGŽÁDK‹f³ŽŽŽïJJJÞd€ÕR­RCÍZj“‚@򦰼¬þ¤¤$2
 úÏáèt:éòåË(·tóæM:{ö,åqÔÖ֎]¿~}˜«Ö4¯Ÿ{òäÉC¶¶æææúŠŠŠÍðŠ@ä°ÒÚ~53«“›õësV5k(ˆǃ¡ ܢŒRtt´™[~Ög¬·XëX%¬à	p‡õ>"f&ö{¬N3™Ÿ$77—¦¦¦ÐÐhhhˆ@EEEÄoTSSC			
æ}V«€•%á”ö¢	!^ðãÉíܹ“Μ9C‡B5Z¤¥¥…¶mÛF¦Õsy­ªªB˜Ñ4JìÄÄ|¯ª««•g>eåKb'³âÍwöp¾kr
Dk‡¾xñ"éVWW' á<£rIFP 5’‹©D”‚¢W§í,ڻw/™†Ô——“ª€8™©½½PÄI¯+DB¦™á~ûgŽÞ²èàC´€é^²¤ ”¸Ìb–UÌòÈÑ Âqhëk¬©””º}ûö‚±Ӹäª*vCò#]ÂÊiDúE¶”[*++3š—ýòù|*¬¾ÖƐ89ÌH’$ۋ¬Fñ·}K
²cDz]½oà,VA#.I2Lšo³`@lmmµ@Š& ÆXEjL—³D9{Xå7N½‰WªY´k׮%illTÞø‰U Æt•èVAL¯Hâ?Äzo·UVV**VžÖ?œVA潢q C۷,:zô¨í ………€˜f•Êߓü°²b6Æ)‡ï²ü9993lƒ¸víšòF«Pk„.;@¢Ì
&^9Ϣ'NØ‚ÉA@éA‚{å9ÖfV   c…`½»ãDÂêu„•Yv-ƒ˜^1reT:|ø°ÕêyïX¥‡• æ™ yek2>>žzzzìj‚•¡ÃÊ:H0¯ W¾`aX-ǷnÝÂû; XÅfXÙl´O—:ÿ’
1T«7A=¬ì1½’(q\ _
ÔɴÚaA³¾‘‘$[Õ8Vvƒ˜^‰—?˜%sX±týu¬7Xe¡$ëJåA¬gèÞÀYì1eŽ.+f•¢PT°P’u«åAä°<âéXÍKbþ‡6^eštb¯$kv(É:¯ܗª ÄãÑÑ`ä[ñŽ[ ’á©0”,ëݪ+LˆH€,ö¯…Øp%ë]àÐ!ì±ôÏËÒ÷Yù¯êÿ	ò/-nJ"~
Ü{IEND®B`‚‰PNG


IHDR22´6@:1IDATx^½ØÍKTaðǹÎÜùþrœg•QSS̔BKˆ„ZþA!´)‚"Bˆ¡…µiµ*pQQ‹ÒÂ((7͌苐,¢…˜9s:óö t3sñ<ÜÍ,ÎofÎÞ{´	Ù<DW…ŠUmpýрc1GQö#À@e~v:…J
²aÂ	7Qîåd&CÌ؍8
üÄõ{îNܚ±qG(ŠÏûn'®Y¾V_{‘0RÄ·`ì@<ˆ"C\°`ìBêbÁ؋X0v!õ
±dlF䌑3rDÎÈS"g䈜‘#rFŽlÌÌ™29#G䌑3rD̔„È9Rc/"8o„ÈA²*ueÂ(҈‹¾nÀLfÔdJCF)O͚¹ÀÀÛGÀôc7z±ÛюF¤N5~1ÂD¡.i¤r”ûµo›wc:с64£ÉRMäóDßɣ™	&§/£[åæuÈ …8¢ð«ÑKMän-Í
kd‘•…@2H †('Œ |L8åƒ×ÄÝóØ{ÿ"э8è3O‡™Ã/<ps\Š®°&îbzVíÐÌ#?Ÿ õpa¨è‡&Ù͝"œCo÷ü-¢qÄh…(w½‡åÜ3ñðºЊ&Nëé!Ê-ST37‰hñ*"pÃ(íЊ ]  ÍȠ)ÔcëÒÑ)ô1²ö­/
_aiåˆ!$imê¤ZÑ4ªf6‰ƉDo¨B!½gæõ1aÊL›9Š:Ô"‰(|ððE­¿}åÑ~JÒYZ B-?GXaBÄ	/‚ˆ¡U1k©àšf¯}¢տ™±#m¥"•0™	p|ð0a¨׼…u8ԟg!¿öùÙøqgšPƒP)H…bœ09.¹zÍD	d?ޘ»vøzЉ-È a‰å3ë~^ÓêKŒ …,ZÐʯAuP‰Ï̺@#L5þҜâLú™pŠþLЈEô¬|"Ì	o楏[»â¬ÜàÀ.D3ÿ˜dÈ?âª;GIrIEND®B`‚‰PNG


IHDR€ jû§&øIDATx^íqh\Ùyö‚@@ ƒAT²Ê*ë­So¼Qc‚…íî÷mët§NÝ8qªT­6JÕ(Q£T tò)Ÿ©6Ûhëv[ïnš֩o•¨U£֩[5NܪÕVE ˜>òïÍÙså¹3÷¾gÁ珇¦²´¿yßóž3÷}ï{ÎÉýÌ/.7«ç¡]¨mBÐ<tjƒrJꄦ [МðódxÒ@
öu@çäYwÌ?CKò¬ ÏÜgù£Ђä·¡:tmCSçí’[ÌAëòªò¶Ä'sÐ錸mä‹ý7„Y7ù•iþ%þ7„WÝŸÌÉï2ŠÿqÚ(üGì/Aãñ)ڶ(¶î
»*ìWdnŒfƒ§Åþo
³"öoÓ~áA
ãoÇ}²qüÙþí‘oü¯¼þP÷Ä'ùנËÂ߲æ¶œ4þ›uư€ãt(¦[!Øpð+²ÉPR?t7bÿ<ÔC†'õAí‰AAAAAAAAA}’t]‡.xx¹×#IOÙzÆ]P´¿døU¡
öW,®K—<ó¦SäwK.u€(Ép!¥ñ_‚Ê	øe‰ÏÞøEá&委ÿuI\ÝKÀ߅¦RÊÿz˽$㟢ÿiÿ|Âñ?5£/~¯Yú:Åüûédó_êâÿµž0þ{²*]$豏ÿUýÿQÿà—öëgçþµþþ¹©ÿÜÔzý=ýÓúÏ<óeóAf2¬ˆÑÁõŸý¿+õSW¾SÿïܩÿÜoüÍðÙùU򕾴¯›x÷¯üí7ü+ʅ˜NS7ö+ퟌ�‚‚‚‚‚Ò긘”äãŒ'þ¬éòˆhF‘?å>û•ú{~õώžuýÕ?¯ё1î§ù¥ú£¯×OzãèYô÷þóè™{øŸ<§c	¹Å+È1¾{”oœýÜëüýÿ©~ñ¿ð¿ÿ~¹¼#m~å>ÿ™?`nÁvÿËÑgø…/ý÷Ñg8û»;ôÉѿ
äZ%…gî<t%šø2§ Ÿö?ñِI¶ɿ(;ÿÚl!÷i‹ó?m¤­ä‘O=9—>¡ýG¿ó³ÿçÿ‘_k!ÿÈ[þgü3þh#ù`þ(Âÿёý§§ÿŽ¿cøUhšü⏢mˆÿïÑVæ¾d3ŽØg^Øæܠýd·ʧÿ/X…Æ֑ýOÌÞþIü-¾Iûÿ´Ÿ|®
ôU4ÿlKÁ~{üíø£O›Ñø«A³-äÿS6Ÿ¶Ùþ§FvÉwø¿å¢ðàƒÖê_øwú„ö3þLý¡’bý£h֠SŸ¼I>ý?ÿßü[;þéÃö´@#|x`·dQæ‡y×s_­K—NwFmYe:Þæsbp1:¿jø}dd¨¡ó/֟üüýœ¨°ÿÿ“¿eª
Z6;ôËȀÑæµKðmB×Tãý)((((((¨Ã#»ڶ
/ç•ù[Ñç(&]g>óõÇ.߸+E†,UŒt¶ó’I’½½è3n
ÉFG†]?ÛQû™Xßàáwèk™ñÅ~“ì§ùSŸøë´ø	ø¶*_ùN[k]?QþW™K±àÖ(Ÿù“a&‚'[?Ž?kÿ†Äße2ü®_ºJÖZ˜ÿÌáȧM‰ù’ÿ݆z›å³ÁqÅ$¿a>‹,ÔJþ·ßmE⏶°ȑhüÅÿ†ß×äúGû¹þ%Æ*×ÆNbûEç„OÌú“Èÿ¿åÿס®ºê#—¾‘dþ›ú‡ñÿf
ùwª ȕ$þÅþøñoú=vù[Ï´×ÈyüS·XÛc€Œ4O‚S⾜ÈgEr7ã"Ä\|Tì¾ÍBÌ=Ó*›±npÂJuÞØOþžñ¿’f¬8òO’áA…c}Ô­G¾³G”ùƒ䚎‹G?ö“v™ÜV⟌ðñìô†éò0º穬ϐÜ7|°ßÖ:?rèŠÈÔ~vtߥ}è2”{ï¯3-þ	h7Öþx]‡
èŒIÝÿ’ø%Ñ,þ&ÿ5ëÿ{ÒqÀÜÁ$¾͈y@O‚e¿ñ?þÎòr!FMþ1˜0þhBÿ»ó?$ÿ9‘týûÓâŸL'ÿYpniü%ÿäX’?Ø`®tWìOiüßàXî'Ìn@,¢µêïZÉ?ûyþëµ&ùŒ]úв¿9¡˜yŒZbû»´%µÐ#~9U€¡qh
:t8‚íQ¬dï¦Ý	Çæ0A:À8­“Ãg52Ó"Ú¯€UµÙÒ"Êjàž¹@çQyŒãツ6t>iü>«ñû¦©¨§"m¤;ïÐN¤      ahÔ»'z¸¦l#ØñÀç³
·5D“‰õ÷~ü/5:oߴØGµ
 Ë;Kþ¾ézpt¶W UhÊePê%_º>Œÿm]“gýPÎ;4øeÉ1¦ sP/Ôµ™ρbaþ'ŸþãOHÎÓmòùÙ%è,”c¨‰N±n‰?æJÇñDŽÙaå_%+ÿšrïþÐKIãŸñǿ*¶~›ð'¡—â^ÆÿüÌ?´8ÿ
z:õ@}âó‹Çð¹]‡sz»þþ1ütMì?)1×±-&A§-äӶÞãϵþT…oƿêmÀ~òÓûd4/ÙëŸ=þãÂÏC&þÄ7åcìßKÐ	sÛ]mþ!´b­?†ÿÔ1þG÷æ?±“i¯™üÝ?ä݄ýí«1|æ4¿¥úºù¸®ô
ی>²þ\}ÀøïÙù7MgåЖFDÕ	-@UG[ÏÇÙHûL¼%¢c¿ÍC5ŸÛFVgám‰á¯Úl³O­²–ýéoA®¸ø+ú;k¾è*+Ÿ6_F²/Y­ó§±–¾¯ƒaù_MdZ­ˆAAAAAAíҪ^mBÊüm²¹•­ææ;/ûòJü-òñƕ\»ðqI\–ü6y6à3Šͧ–%ÙæóU–þç3š½ݧÍA]䋸¼™	_ì·ùP/¹Qásæp&EZüMˆÏiÌ\öw’'tà3Ij–Ÿ·üŸˆo]Íؿ.þ··U%§)4À.Hq¤ßüÛ@’øŸó?©ÿíüoÎʿ^‡r˜×ÍÆ_Uø…ä|;ÿøZþA||Î8~wü.hA˜®üç¸ü릋/ZJ`ÿ|Œý´mëù×(s%¹íñŸM0þK>çý«ÑüK,¨ރv éíªÆø+iþ‡ùÀb;¨Z&?ÆþMò[ØyÅÏÒLüKýãō(ß4_™âäÆáC9TzsØÿFGŒ@{ŽÁêvêé±–oˆðàb1íÆ¦RdÛA›Cە±ÿÀ„X/“‘‘èòG¡CG’¯qaªž»>+‘™Úoœ5òk¯±ÏÇñŸ6Åϱ¹6ñi2´ä,€å¡3·)OCu
Ýæ ËÚ|$‹vòwߙ>ù{ÒaÀg»,ùSÒù`ó aò)ø&‡AüË·‹»Ð٦³äçûïs85mþ¬t>ØüÓÕb„nî£g}$3|Ú?ô–ý{G9:ËsèàÜjÅn›Öùñþ¶øxéüêQ΃\æ~þßñ"‚ÛÆtþØñﲟãO&óžhþ…³RLþu¤Û§­øµÿ}¿õ÷´Õðé{±ÿ5Äæ–yß!:Ò%Äy“pþ»ígüsËáðGþø¨¸…|‚>grå;òÏÛè„xß5þ†Ïä›ñOûMg:KŒý“ BûŽü“1þtLº房ý¨ÿ™[’/ãO6ç@£öÓ6Žñ¥ã
áȗnFø;Žñg¬Éø—Œýü}Ãß!(&ÿ¥ý
å_8ðš̨Žbû}ӛÑõç>Ÿ;êÿA螃OûgÎMòPøÿç[¦ýf›'c›1ÁØ4ü!ò]ãO~‹ÇސmƟc`ÖŽ
Çßð÷\öc¾Ì[ tÅÁDÖ>°c;VŽËl+þ:¢È	ìàW±heÊg È ”µí—B”©Fî:ÚÁjàg}(4ƒñ„küQ*ÿg¬6'ocBØþد¢W̞ZV÷1?ª`_]'îŸJÔ	݁ê¢WW‘ȲU=ú=9…K“oo{ؗg>dfÉï¾½í`ê•“œLùHdím/ûÑä[ë™lgµõ­ãÿ“’x²ã‡ɎæøÓÿEáó™žÉG–ãϘ·ù}™Û/|ĸmÿTTàwËø³óÎÿ^Iü™Ó4üGعäeMüoÛߟÔ~úˆ¾Šv*`]k6þzÄ~òi[>}÷M±e:³–õØ|ÛÿÂgoáüWb÷ÍĜµ"Cüúó鍆íg¬ˆý»Žã@ŽͿðò»ӲͲ]Ɵ]mŽ??+ùý>oäZÛÐQ ,¨¢.Ǘ8K)ÉøsÌzbì¯f˜ÿ± Éï
ò‹>çX¦|±ßö¿ÿ3)Ùç¡â4âj‡BezŒŒùk|c3ìj‡Â„ùìù/³Eö´Ë~´Ífm?'2+¦ƒ1þ_ʘω@ÿÅؿœ5_ŠqÎñÇb²@†’6YÙ7m˜˜<U~ÉC’±#	Nš ãáSPP’wb¦ɽ,‡Žò°á£-`)óùd·ÝàP
þbâ›Oüªðùi¶d¥99pԶD¶9ñY2K~	â3‘Í–®#>KfHðlÿ‰ý,¾ùàû³ÿyÏ÷ÿZÖñϜȶD)þK2ÿRµŸÅkvê°3	SëO+ösÌì#Jb¶‘ž³ù¢³-tý1ÿâÜá£bÏ+<ÿÛ6ÐGýÈ
nûÔ×Êú#ö;ó/VbóOŽ×|ñ‹/Íð9f´?.ÿÊ:ÿ#Ÿţ˜ü÷
->ý_sð—4ø¬¿¸ø(ٟS(0·ƒUÐnסPàžuœŽ]?¯1°uÖaÿ!ù
þwڏ…¦‚V²¬ùlÓãø»ì/+Œ?3.ú.û˰_ø™kêÌÛvüEü¯¢— ºì±g²S~t]’¢t]’‘6åëÎ+¼9íÝ÷×g´™ŸSÜzVÁ÷´}ÛÉ<ĭ.çä•üY“|à߲ö?¿|&_ø·¬í?tðçÅ~&YÛÏgaû¶Ÿ%ÃGA2kûqþç3´Ïñ׈¿²ƒ?'ÅûÑYÂñwşFüW`#s‚û_ô±þ̙ñÇÜhi»Ì³·s´qÛ{(Úñ—†ÿa—iXƒ^N·5[ÔȥRXh?}èʿ®Áæãò&nÁâ6ËV^1vâòo®9™ç_°‘üŸs>ï±þÀ5¯5_ü?çÈ9çȼ¦ÚN8ýéïMêð׺˜ð;ª`£
|N¤ܓý,BÑÿå·ó7ƕø.>Úä&üŽÿwGµÞnãËÇåÍ.œ-&¨æ›\of$þÔÔ+…¨mhþ¡?‹$((è,T§X„á”`h®Kdñ»Ⱦí¤ ]YkÂo@ÝHȲ.>Pç >‹Øöw’¯àƒÉ>Ÿ™4ø£¯;·ýÏg>»êØ?ýwŸþ'M7þõý?îŠákÙÏ\ fü×|Å?s&ýøӷÿ´Øïä+­Á,tŒÉ-Oû¦ø¥ÒùÆÿ†¹¤ˆ’y›°³K‰ll•J£øIç’}ÍsðyÎcþÅ9¯•ÿÒþCOù'ù\Ë]ùߤRý%Öÿ¨ÉvÉqGþ²-WWUÐEþŠÍÇö¬’_ûß\Rä—þ_ò<þ‹Z|´—ûô?u‡—Ùö/+òóÑ+†EWÈ𦠠 vhڔVüNe~	bKºé€`22#[4´ÌëέsâJ“
þ"º1mþª\i­Á_@э¾·íçw¦/ÿ¯(òi?ŸÅ,ûÕü¿ä°MÎüPáÃ~¯þ÷<þŒ?;þWå–5ýñ׏¿’cü¯*Úß~Íòÿ¢"ßtŠ˜Ë{D鯻ix@1vð“©)ÚÂó`®CëÐys˜»çüsZkÅsþ窱(ñ9—\ü’
\&·¾d©uEþ$Ü‹øoÚü
MÿÃ~o||ɍï{üVÿS“Ö›Ԧ"ÀÜòÁBZ]ف·E†²Ơ%h4$ÿAAˋVQöº2oHíui7ªhñ×rù\«ù­ÄÕæóYŽjð7Pèrð÷ø¥ÁßôíœÕáà¿Iû}Åߤ"Ã{ü_¼|ßþ÷ºþ菿¾ýR™Œ\–ó:TÐä‹x³oyâ¶+…⣪8—xM´ÀÅó™4óÿSŽü笢ýc¨?øÌÿ\ùï–çüs]õ*l«͐ÚWä÷áV*Ÿü~œ+à•ï°OÓÿžǿûfÿ÷{¶ÿßtc?ª:߾ê7¢i2<+(h:òÀÞåí'ÜÃ`؊ģ Èßw|/ô㍝ßÚ~BñYEŸÛü“¸ETîl›ßû}úŸÏJZü»°ßóøoØüèðɧÿ}Æù^ãóϧÿûãþ֠nä
ªÝ7آ’·ÊQéoO
âö²3ŸùÇnš˽÷ã©ÎGL]-veè¤É/bMñš9òßÏù÷æ•þª&•nŸüN¿¦Éwø¿¢Èï@…Ý'¿ðPûßüpž…OÿSûPqȇ.¼ù-“¡¬h@AAÏYEÉKÊüš]€ÀCb§&ßљةØTµ®^¦ø¬â“ߥh
×Âúô?>ý_yŽA5þç¼Ú_sØï{þw=DëÏ)Œÿ}ø´د&òØõ$WÆ+ti+hø#ÌñJ“߆ü³ìqDQÿÖ<×_jª œ:íµƒµ¼òQ}˜ù‡ÿË^ãϿÿ+¿70x]WýV=$ûd֡[P¯0ü+¨êòÀ݁ê,Žâ­\Iå[°jVWUP|¯¢åÞæwa­òÉçw…O~·Üü¤¡šƒÏï
Ÿü‚æø?ùù»Æߧýü®ôðÿÃÏñW¶øU¨
¹ŠW~ÿ æÓÐiˆÝ8fû©ªÐ!®ºíK_A]¾Á-vGÅ>œû§ÜµúTäJô
tF‘Ÿ÷ÿaMñZêCU×ëß|,n¾ù^[àpÍßQä1þ³ÿO8ìßUæ{ÝՑløjÁì‚*PWþ2ác•¯
j‡®AuQI™¿½øјäÈýš|ëú_Šk•OþIM¾uý/ÅgŸ|ÚÿЌ?™–Šªþ_|ó6þ'<ói¿ïøóêE~Éâ¯@ì€QíÌ`RN®ÒáÓú

zæË,<õ ÆÏA]&¿‡Ûù—ïú‡¦Æ`]‘?éHÀ7”ù>í÷lÿ˜Âø+ðüÿðÄÿæôþ@u&û&áÃ5Ÿ·”oa+Ij†(lÁb‡"cŒ³Šü­'çdßÎ0®xֆ#›TL@Ö	×
5û|®>ù“xïsüéŸüqßñ§Èßôìÿ-WüãeOûÇí_wGÇ?¤t
Ì[ДÇx0YU?$xäÒ7o¨ÒWPÐȯ½Æ7:y5¿v‡ۢµÎL+ò'ùז¦JޤeEþUG–oþÒCÄ_öëòW}òW<ûű«¤È_ߧÿKžÇ0“{_üY¨Ñ”†ouH7Tچ†Ùs<W¢r<Ì5äªë‚c×
-þ’ƒ¿ªÈ_vñ·@•üÒCdÿÂ;0þ®b­öéÿ5ÿãÿ5¯ëgû—ùs¿ujùŸâÏ`ÞWv`ñÐqÜ|©¾Ýϙí(>=Çõ
:iò/;òϒ¼:t]÷¨˜`º®;T´¿ìàOhòá¯|‚åuü=òä{ô?ùñß•½ñý¯?]¾ýO>oaãM,BñàÝG>üò Jº݂֠cÞ*NíAZYÖ,ªŒ«ÉÕøŽC«ZüQÇ!°œ«]ZöãT¯|—ýðÁ#ŸkE·<†¯eÿDŒÿ;=ÆíWããl¿ËóúSðhÿ6¯äVâ0þ¯÷š€rønT=ûgæÐÌÿËÿ_«¬   ÞnçëìáG?öª½ΞQÝþ`]CV:4ß~[×`û旡¼Îe¿"†|\·ióJüi¿¬>þӛÿûãkۏ«U-ÿ«ÿ¼sýño§&ÿñO½åóðIÛÿSÐt3å-b—ɏh×ê>ºÉóÁè´Ã×Ï~îßê<ÿõ%­â ®@·o‡àZ1£Äï<¬Ø|ülV‰ŸǍx6Ÿc¡Å]ü9­ñǺ`ó¹VhÙ_ˆ±^küq
÷á;,þø¬¢éÿ²ÍÇ5ìjëçøÏǬ?Sçÿ~F†Š°þ3k‡dkÈ^8Œ8(((‹. ^8氾©_Åê“7Ÿbqڇ.B9ÕóOF¿ø_ÑE~Ò`Ÿ„jH0l~I‰?Ua?“›(N‰?
ՅïÃþ!¨æà/+ñ ªŒ¿7>öXÛü%%þi÷·yÿy%þ0Tõ¸þûmÿ/<€ߕÚúcóÝ��4h ­ø‡ê¸‚ç1¹ª£Å~(Â^ÄSQßÔGv鳡øÝÒu´• Ç´Â5b¬ZüÌDþŠÅg¬Vµøïùè+‹ží_Žá{ò?ù\3µø¥·ó߬á S*ü‹×|گ4þ¯.9üÏøôoz?áx²ŸëÏυQâ_°^̜ÆKÕóoxõ8¸<™ñ¨ÀUSPPPº×Þv
¿<Eþvôö#¨Ké¦EÇÛï*TTà÷@»1ü^$7·~æö÷¿eÿ­(¿¦äÿÞûü+߱»/züß籿OÁþ!¨ì1þÉßóÿ½Ð>ù,0Øã¯`±‰ù?nþڄNfÄ/Zü«æš|JüÄgÿ™[Äø·=i¬xûåóêñ®H«{¼ª„ 3€cw"
~DK¶
H´86ŸkíïO¡wìv§¹8øo߫°¡üšƒϹ[̞ÿ•¢Ã~~gí*ð9þÅû÷ÉWH@ÝöO­Óÿ'ƿˆ„ßwüùâ‹ÿ÷â֟“žâñ¿F»‚ÿ]ëÏmnG"CaþçÀïsê†rØèãí¼"O_AAAál×Yè~ìò·rZ`¾eêÀÂþ,tꂸNƒ½€ëÖM3_˒Û&	·3ԭ›¦ ¶žfÉ?c’_¼á%3ª9ûÉûmÿOClƒ˺øpâ•۶ÿ/+ðG¡'_â	n–üãÜì`ógì‡*Ǎ?•â*ßnÿ¿þ §¡Yèd“ü]§ýÂÇÖ×M]‡PÝtíI
·d¿ÍwÛ-©vc÷^“@öü³ã~‰®}Fßц¡Vøè¤`×Ï=â֞Ç
7‹™þ~“üaè6ù¢KÇـ-ó6Ÿ>þ…½éÓÇø8c>×"×øsîîj
Î-Oÿ“OûG‚uÆ®h&ÿ”Âø;í—ñ̞¿1wÀcüIP=þ„ÿò
ö_´^œË2T„îИævžŒo£




Ò<è•§Þ_äÑ⯵϶ˆä¢Ý_µñªŌošè‡ê8q¼Ž·ÝämAíä¿뗮fÅ>E6ëÖ-·¡|†ü4c¶}ðäqÚoûÉEVþï„æ ù°ÑæoCíì~ÀØdÁï†æ#WK;ù´ÿ–U×Ñ*ْüÛ[¯¶dü3õ”¹þ¶ñO' 1¨³Aþ¼‰?0ìøßh`üÐ]¨.ªɘ“Æ|ìˆÿØù_$‡U›¿á™,`sLä¡•cø·ÉwŒ;ÎÝض“þ-üD_NA
Îÿiñ?ÿÖÉgüG×ø‰>¹mñ9vÜ.VŸv&ZÜü5Gá•cXÜpØÏ5ŒüE¨ÐàøÏBµÈ`ªvÌøq-pÚO>c˜ö7èÿnñÿMèõF‹7`pLìñçÜeїËPYˆãïÿUkü3áçaÿ†+þÄþòµí§ÿ%þç¡þ,í+&þjӅ¬ø`䏉úÿJÜן—n’‘5ß(Âjt¦ðYöùT„ø¼e¨||÷å°V*1ƒ‚‚‚BH­Õó½—þ‚‡iÌÛÝ^é<š4‡½¡½?û›wžùrպá`ê!?ÓöZé|¾ð'vò»3ì>:íGŸXþãéÛV¶±”£ü|áߣüñ?ÄJ³à5(Ý"×[:¯\ö÷¥äö@Ÿ”"AUø|{èâ÷Bà¿Ñóœ$—ÂìˆØ?A¾ñ¿2ØEbÇ_‚ño³|z­AãÂ,Dìƒ^‚­â“ÍïnÀÿäñܤ‘KßàVS„¡6 ÂÌGøŽø³‹{Pñ~
å;ÖYECv"]_”xï‰t»Œ¿v¼ýn¾¼…퓉ò9‡ØÅcü_‚&ÅæNJì
*EýϿáßÚó?&þ¸&]|Ú@[¤£ìj$þòþ˜ÄJÅæÛñóf›>éÙþ7ü²ÄØX$þÛÈÿ—¢ãÏ1CuŸê=rü÷ԺÓ~򹖋oW §mÿËÏ^ŠŽ¿¨Üà6>ÎÉXÿÓ‰­Ոÿۭø'3A±ÒúÏQˆúÿªÅϓ/jåPwÆdÇßmÿËÎõ§iž;þŠ1|v‘Oѿ—R;#̶ÿøùW–B\>^¢ù/ëÏeÃPäsþU®¥§ÿû­ø/iÞHÅ-àQ,ñªäfAAAAA¡ä_üòfdz¿Åî‹À3{»ï@'ÉÇV„¬÷WñÀH¦|ʛ¬®šÜ5‰3’){ÛÇíÏÈÿ+äF·Î ™`µ«øÀ=iø¿
Z2	¯‘Ùr‚dÎåÿø=Ð-r\’®#Þ"ââ›økfü_:Žéð¿‹ߟpüÏ
ƒ] u\
˱m„OÿÛñw/òÿcøÉÏÿ8ڎÏ1e7@c|‰?·ýÂw¯Uv,â˜6Äçï`KÍߧý2ÿ]|þŒ±9èâӗ<Eüòé;èÿØõ'žÿÓ>m¡O{ý±ãÛÁ\¾gLrlX ½ë⣓”¶54þHælÿ߁
ùH"™Ä~Šö7ä®?ô?ÏqÂá¦,ÞL8™îñgüí»ÆÛD¸¶шî$,OÿsŽì69þ‡Ð麔Ɉ‹¼H"ßŜ‡Ú\Œí—õçÅhW⥔»´ùÝ;ÿÓÿ×2ì_>ùíÝTXÉçß
̥¬¸öøÀ;
A¹ÈVY‘Å[jdÒQPPPPP(eØbÌÎ#Þ8 vضÕö˜ďBG€Ùz’¥V¬Ηm¨Wn9Èê˽â›JÓubó‹ñßê¸ùS^koy¢6-ÕiùÿÙhÂÉv‹œyáûäÙڊø¿խ_7¢\Ø¤ðˆØf‘€ɊËÿ}Âofë_¿aâ­ “K°^%“lc?~¼ÿ%þ“Ø?ޤü§|Êî$ðì."“lc?Dàoñw\üná7ÒbÞ[nç’4Þh%ö—È7öÇÅß&T”­¯ÇÆ?ìeŒr¬î¸Ø[úokïÓíBŸÏdÍbÿq|Ž
c„¿{Ûŧoy>c63!¦h?˜ã¿ÿ7µþÐ7ÂßpðÙQF#ñW"ߌ?c…¿cóïß@üÑ~úˆ±²íæï1ÆȺÿ3òéÚÏ߉]ÿäm~#öoÇøŸÅ=®5¶ÿù3ƿ=þŒǓ֚×ÓÁglñ–ÿ‘´FãŸ|n[4Åʡ&¶pŽñ?Æßæ—È7ãq‡ŒfE?qüÝñç^ žOéeùE_Dÿ²›LŠQ©MûíùoûŸ…¸|ÞÞ2/yüoZ»Yñ¹þ®H!ô¨ë®ÒËÊÿ҉“Í9AAAAAAÁ	
‡Û񼋟î氕DƒËý엥…øy(/ÉgÖo“nZ[^ªÐÔ.É_ö@LŠȳU3|+ùKC‹HüxSˆðºíÿ#Qo•»ˤŸ×i»™nû…߬ÿû &w£!þl„ÏÜ$Ü9î‘ѤÊд‰E¶	~»ø®Ö4_üŸÐ~Æ}eøÕùóP>ÁüãA~ªö'X8F䷁q¥Eû«Æþ$ñÏ)º¿hÿ%¨ܢýsä›õ‰s£öóofSðÿóP’«Œ•¼Œ]¥YßÃÞnØÛL̵º™øãZ\iñY{þU`²;çjZ]­b?ãڊ»ÇBй˜vü=hýÙG¡µ-Ë.‰ÿ¹ÿ„_Œ,ì—"Œè‰Ïþ@óZrn¿ÊìY-(((((HĎ;ñS¸U"úÃÖ~&6YŸñÔ-oÎ6¡¨/ÂϪó¨
Iåº#ñ_¾Ùö—6çY‘åÒ=貹íN¶]¥åÿ%<Œº¹ñöÓÿ­¿¿W$b‰ƒþVý®
úp9a"~-AÝ~¢Ã%™Ìñ¡_ΌZLÈ7þï1|tE$²Ÿc…šü"ùMÚ_l6þø»ܪ%1´œ°pOŠ7]ͮ?äs̄_Jh*Eì§/ñ+ǚ!áWšÿÞ&×?ÚO¾åÿÄö›ùŸ¸ðK>cVlX‚Ú®…í+ôUÔþÅö¯b¬òÜã/ñ×Ýàúóücÿ«T;Q„ßÍÇð NlM‡ëžÿEhÉð%ÆP|ʪ“ڎÿ4µË:ªv 1Ÿ¡X4?óÂvË]ÃAAAAAA¡¤²ŸœíÒl!æƒ)Z¶U¸Ü+/I‡9L‡[fù°Èmy9ä{š€:…Ïø¼:÷Y9Xú´&‰ʹŒíoG'9��6¥Û`êHÛ~$Ͳ¬-Jw„/öÛü7ÈoúàxvîH0J†°¶¬-NëòÙÎBmÂçÙ_<ܶ©ø§Ïè;Ú 6Š7\öÿ\Zþ>cˆü‚øv^X;þ]hCøã6Ý	iÙ?!Éð+boUøûâÿ%ñQ.
ûY„ùNû-ÿÓ·Èû‘ùגýè°`þ„06ÈtŒI|Tˆڏ-3Mñù7œ;âÿ<4&ükÿ×ȖŸ-¹Æ_
MòoñZfÃÿ¯CwcâʋﭢkKñ×)¾]qÄÿ–ð§ÉÆçMí;T쏮?óÖúsºµakZ«L;þ¹vEã,ס(›ÃzÝëÏ í”nÂÌÏQdüqî/̺b‚‚‚‚‚‚‚þ~ó¿pßú¿†IEND®B`‚‰PNG


IHDR22?ˆ±qIDATxÚ왱nƒ0†qL°ç=	‹=#¼3¼C»·sߤMH\Ÿ…+‚HªdùO:$b|÷òÙ:ãœ[°'c#€ @€Lšym mÛÑþ޲,¦S`Ó4£:LÓdYZb¤/mS:°Ùï	äH×uåM]×jóí5nôç~nÇqÔÐϐOºxž'o²,S¿¿ÒI¢ÃE®7J˜¦©Ñiá}mF_QÆ\:P°<ÏÏô˜mÛ<I^U×B¹('å&
¤¥{ê½²þEÃ0<Q %4t¤i7Ô{«´Xçôàš>~ýéšUZEQ\”VY–k(­ÜÒz§IAÈ qkzERƒïû
äcÈ7MǯÒ[	ÇïžrRnÒ@Z:
ǡ^v­üUӨÚ1yѦq¨ãq›ƻé-í*„NéØ̊0üÑ€ @€ ÿ³_£ÒI[¹)øIEND®B`‚‰PNG


IHDR22´6@:®IDATx^í˜[hUÆÿsÏ&ِ65ِ4iLҤ¦¨­õú`4ˆ´E(XÁE-‰M)��>‰ ø$hLšGÁeݤ¦U,±¡酴ݐæºIpgIö23Ÿ'v]—8C O9ߘùsöÇÿûŸ۬àè@¶!ې¬ÍCådÈCmÞ6‡¤ÃÔÏ?$¹’'R¨UÀ^.ßµeˆðçGZŒ³‰_¬ûˆÙÑä­ÄÏÆٱ6…R ­@ˆ`[cƒ0‘ÙÌØàÅV‚rS÷ʡ(t̎qà5ìF>¼håÓß¶:&E*[H
Qîƒ£	’¡&\›î“bqÑF1}¶‰SìbÄìé
CÓ\AT-ІÚmø¢UŒnœ¤ºQœÂ(ӆ÷Ñ4ÖÆDYU eýøNrж–Á^ŽŽ0.HGÐ2ÇeUÉ×ûaÆQ«ÂlXˆ‘ÙÈìºaÁ&ޣb~Äó«N)Q–9ƒè<ÊgÏý:ÞK„i.ޘ¾Ä¦/-Mš¦Ó:zÀì9)׹8„䲐•F8ª¢EˆÀÂâä½ѩQö15zotqÒB”¡Ž0RÉQ¹!Ê,¯T%çz}‘ˆ5ãîÈTðf}ÜNE,F„ªœ—*Ž¢aN!,ºTÛq @EO"‰•û#ø&ɈPùì„T«â;†ŠOü„ TCgBø&‘‰‹Ÿ£
Ý@*¤6±4«èˆa%r=8¸`WãëUHÝ*Þ ¹ µRá²:’*|ܙH‡ܙˆ`Eþ8€Õ_ÝCh×䧩)܃(ÂÉ[Wäjàöµp2Š>0ñ±¶Ë]áÏ<c[©Åø-þÆB‘Û3·gB‘%ö¾ы±ËþþÓR£VJŽ«),Msß:ƒw1‡e,P˘c/Gã°vïðw½¥þ½çÌ5 7mƒìÂÛx]idâeüñr³¶Ëãb[‘jiþá4l“?+Yå!Bð<>´Íl.¿U—Úòn²Cê¤}ìXÀP–C«…F%Хz
³>vªF
õqìt«—]Ò(=fˆ£G°y(Á¼Ža²A}ј€øogªSG‡–øhÙéx³{ú'ÛFF³“Ñ „ÆM0ŽŽ_© ¦QÚäÀ/]þbñÊú’´ëKócÁϏ¾²·+|-¦·JoúN/â£iuÒ,û¤S“ƒrˆ:(󙽎g—ÿú/fõ3V4_˜‹ã+kSÉ|ê¥IZ˜S;Õ&­J�ó©•ñṭÌ9ñ)Ë<..wR"åUå—ZÊ/5”_ênï|2ãÝؑwlÆ.¯©4Θ|RAù¤œòü°4H›Æà|øÒ¢¿ÓâR¡a[¼p«çb¢ªhäÞ‡‰ÑÍN¿ê²ù§•GPÙ¦õ‰ýñ°•Xýóüqf·S¼ÎìÚ\ºb
³SͿé¤öÉ#⧥ÅÿSx-ç˜RÚÏê4Q
âgϻ±R¶ù÷üó´‹ÚÉ,¼zÍËÖ ™Ó"_
	*¥¼4ªÀvâ£óÉ#*?ý3ÏÄ-(ÛëöŸÔ6äY‘¸ªȟIEND®B`‚‰PNG


IHDR22´6@:¯IDATx^íØ]H[wð'™£Fªv1¢Õfjý€*ÛêM÷ŒN£]ÙÖÁØÅ`;-…Þ
¶Áv±‹Á`W£æ´^öaSevc­CAº¢֏dÚøqRc¾γ—?2'ç ôÊóܜ“‹ü8Ï{Îÿœ|y$Èr€ìºÙ$öœØ${o{#٘úúǐ‡|8PhÄ!Gyò©PûF@¾~¢Q»’M/qG&g?kW&›¥ } Šȃ#д3Äs·ÔÎP I ¼c±©spΟշÈ8ù°€n6ÉÞ ã$umþ,œê|lV‘áZëgš¡ŸȉŸ×H2½Ö—ÁXCTQB,œ§žbñ?écŠÔÎ+FJ³„¨Y8‡[tü€0âb7{$ÝteUÚH+œj6æU•%šôñØÙË(i$*Gvƒ"©]C	ª2³ˆªªè›ãLÅY­›`”$µ‡Ë—)<m
ñ1N¦¾nG‘ªÌbœGéò‡ä€!_$e8ë3¡›á‰ðDèæƴŒŠ—•«$—?D©q.&‘<¸pH#Ï(ÂÉ-êŒL‡‚+Áðxx|%
F¦uFéTÈi’ÚE<“ˆ*ˍÊdˆ¬UHӌiKÁÅñ¥ˁåÀÒ
ÙƶÒìRH-Éd•p«ÂL"2txõ8éPH“ÜXÊ)X>I²G!$õ¼jø¦‘Bxà„Å’`$‘OÙH>xPh)Cu"L6(äeîpcëÞØÝÀìõ™љÑÙëw÷Æ6¶vح:’É0ªQfYŸÈ~QޟÊFîOE1Žäú¸uDêšù,s	÷r››ÉÅ;s£KæF—no&·ÙO¨“üë«u©Á_~^OgnÆAa4F6WV"›š ß7cÓ2öϡJÝ)vK—0ü+ߓƒ†mg0ÆmILözh7øInϝ찆7#jß1µM^ÌZ »xA°®¬²qR¢ýþjƒQ—Ͳ/~¸D=Å÷ˆ]c|‰sžäö­wj2K¾Éå¨AËä§L“û<´¥¨O)®^1±ɾ*c³K=£mƒ½©(çOóóYģ|“#bSò‘ÅĹìÍ0¦Zð£h{»{á']gΦ'£‹ä<ë÷`L=~Q&L=šÑñÖ+·¾üç×تžL'b«¡Éàg^;vjmj7æÝJcÑ7û"”Vƒ´¢Oá:%'ð´ìËQÛîü—YÿE(€Tfú•%8/jáG#šÑ"iF“JŽ·?¹Í<I2µªÌfáåE(¨R(ª%>TI|¨¸¥ý™ȟƭVd”C=Œ-¾¦Â7JàA™ăR‰GàÇQ‡fƒa'=üŠdô7©¸RØ>_¸վK¨JÔâXÇIaŒMOŒ¼nQ¢r“/P‰bšü3ñµtbý«çP‡
¸ÍֵwÔÄS¡®¿6´KZñ|(ƒËÜàÍ3Å(‡uðKê„(‡[Ý){ V’¹þ<–T nãžÇþÜˢ…KÜpÁabY±ÊµåUý3ÏbÚíë_’ä_ºlœøoêí>IEND®B`‚‰PNG


IHDR  Ùs²õIDATx^íԱjÂP‡Ñó¢讆¸8ƈS •F@‡,Üñý[ÈrÉi‡򛿳Ü?×÷/÷×À¥”‘¥JD³§Ç‘zx:ǀ/ÚÍ]䉻›Z£Ö.ŽNêŽ浓£‹õ8ÀBî ]®t[˜ÊúD?—™†D+‘hûy‰F3ȣ@HTªAB¢Pô򗀹½\ngoþ*°rUØé¦pµzH´*…\&“+TZ	q{OL‚»ˆÒþÙ§•Ɓ01`æ!a3|„yHøØvùŒpf±%°ìå!±Ŀû•ßÀ®·¢H³tIEND®B`‚‰PNG


IHDR  Ùs²áIDATxÚ핱jA@‡ãýÕ_PƒD;=ÄAP°H‘VT-ÕÂÆN°N@IaDð­Dñô76s·˜9ïnƒ.ÄaaÙñ=֝ÙØ/ã/	ø‡X‡KŸÛä.žýAÀBL3"Ë|6Wy6$p<¾¨ö¯
+^íÇV}% §”œ¥K½‹óB„g˜VïJ8+\´"L{ø„-|ÀR:5:\Ax£#`‰Ùm|޹¨ãZMy%x…	)Lø3%yØj:ïÀÍT¦͞=	HÂL¯Šo|Š«IOböŒ«*s;¢OW¬s^Ŭ0ã^e3pŸ Œü¬I!FG>Îë#(#)6¤ØË{n"cRŒ1|C¸P`W¤à	#Åq^ֻó‚?1P0bþԼp—€ðvÓ5‚<
¢1ȻFí&)Ä꺌qóŠ7æÅ]àl,nºS\Fª»þÛwêN5΂úB\FŽ×z–¶¡Š ¢Ö#…c+׻<Ë2·ÝYïR+Û.S¥øä¶m,݉׬Ò^çÇ7Ž«"ñ.¼ÎL+–u|eÂI±2ŲàAÁYXO
Ò®ڞ4UWÒ”‘+®8åHA¸¨‘‚,ŠÃíø¬»yövõÿ¿‘Á•‘¡mªóA»IEND®B`‚‰PNG


IHDR  Ùs²ËIDATx^íÔ1„ „ѽh#D.€¨¥çØû_eÖLCáÏd-
ú½>¸9®Á8TÌÝ`F…S
ßsT3¯|·aèŽùÑ#?Hx¨Ì',Á&«
$†¹Fž	%h6B<m€$
ŠÊ	hBæ4¡sšˆˆ"' ˆ€éÁÎ5PE‘@€˜B@ÐS¸¿ˆ÷·QçUü‡ÏÿÊÉÈm8é㜻Ç9ëãì°ÿu¡ìð½5Iè+mǨvÁcå푰Â?~­¿À">ÙA˜]IEND®B`‚‰PNG


IHDR  Ùs²üIDATx^íԱjÂP†áçƔ€h Á[rv(•‚w¦"(jÆ`TÑe…€’ íÐA¾ù}–ós|ÿr
¼0’R±ÔµÀØÕYB8‰³«qðé¢ppyìä pñU
¤2k[»€ˆìl­eÒj€®™…MIPæ6fºÔD¦OD™›Š¨ž‰½Xlÿ˜7´K¢P<ä
@Häò{®M3+«2ˆLÌï3½
ôd–%°”é½Ďr+sSSs+¹£¸¼{K+¸‹ y>m%!©Â<¼Τè‡yHèWaFÕÃ[Þ!œ΍R0¨ȡc€÷+¿8>
4y%·IEND®B`‚‰PNG


IHDR'€ՆLIDATx^Ó1 @Ÿîϵép	0ö@Oê¦U“½4é䁤65+jFڌ´™i3S0P2C3Óý0^Ùþ.¤ÍH›™®îú+|û懝B:…0IEND®B`‚‰PNG


IHDRØqIDATx^íÔA
À@@ߜèÏmO¸(RèmÉ-0 "Z~Ì\ƒ¿±ö=t$ò ì{HÒÊÑC¡•M£
­l„J•ÍP)Ù’’í¡ú’‘.!YȆG¨L7<CeJ¨ì¤=ŒÂH7·z2ö€H¥ç§Ör?mIEND®B`‚‰PNG


IHDRØGIDATx^•ձŽ‚@à
!<–µá] ½(VD^acI#X,o€>hHVŽ5rÃýǐ;þnÂÅ
¢¬̓e\…:è‚.Ôq%¯™§,¼ï'²yhWÝïÚD*›—ETÀ%ª/‹	˜~l5ÌVgÀó& 0“ ;Ž`¾Ü<°Y?óå*‡¾MõA€õ¨VÎ&’˜¹ˆrõäÔCeQ
ãˆ{¥5GY"õ
a(0JêYCŠŒ"KW„"£Äwj"H‰aB-°ñHf¨¾¡â`¨†_5®8V@sàǑW†as°©Ï3ž¦>2žš‘³͐Ÿè`L½x¬
`Sõ¨QÎpÝõ²;^»?¯Ž­Ž7¥§òO3 yᨙcQ“»3yßN¡=¿	gž¼Ã_Àñ!o™7 Êv´6^IEND®B`‚‰PNG


IHDRØMIDATx^•ձŠÂ@à%HÈ&…‡i$Ú.˜‡H8¶»!²U°Ú4Álj>‘¤֜+zãý—	wù»!IœÙQŒ!ÆӉªâ:´At¡kuЉñð¾Ÿh”•Ë˸ûå%+͈»©là"›ݴê÷™E€™YÜ~tÛϘÏ߮ØL®ùüOßfnA€uÙÿ³’˜»ˆrõlƒƣÎ%vOñÒã	:ÂP`
UCŠŒ¢*ׄ"£Ä'Z"H‰aB+°ñHfh¾¡á`h†_5®9V@sàÇQ†as°:åOuJ#‡Œ§näFnÈ÷t0¦~x¬
`}uÙÿy£Érô²:6뿮Ž͚VǃÒSù§9н°l‡˜lóh`!/.}hÁ/dÂ:QÇÕùù°:«£NžˆòòºutUÔޣIEND®B`‚‰PNG


IHDR  Ùs²4IDATx^ݒ۪Â0EWN¤ñV±⩈¢­ˆwëÿÿÛÙT‚ir|uåq2+3dóÍü0"§`L1>²åÎÃ9;2þE—-–³'%BÊåÕ
=GêFqÏa¹7­¿t$L84’Iûð¯×-.`˜©Vcñáì~¥Ç;C-sÂðF_þ°bªjÞöþ
Ë%¨Ø=kç·Øèß ThRRFjéBDaT›ãkTlž•%¸‚åSPú;ˆ+$¨Br„¸‚ê)Xã0Vƒ¸‚“þˡãä<¤°ü9`"ŠR2ƒ™Ì3)¤*ð°WqRH“à!Uœk¦^ŵdïJDßÙÒjwß΄º‘\ذdI©S;† V×}çJF9gOsA¤ÌYQR±¦`€á[ù»•:¢ö”gÂIEND®B`‚‰PNG


IHDR  Ùs²_IDATx^ݓ?kÂ@@ŸŠ¨`·‚Z2èEAPì"­ÁÁEpQ±uQAmüƒ½p‡G’Kºún}¿w¹äÂ3“¦B—>rü‹ÎÜ֍%±xaÂ=d­°ˆ ÀþaàĊ®*q¦j?«ÑOòHÈRg­"ð‡߫|B’7¸P$íìGÞðS–‡ْÂǻÚݔhJ«¶ÿ‰Gcb)¼:¤åëû^	[æ-4*r$‰avÑhË‘‰±p‡h¸ò¦#1î¾P¿PÐ4>„¸‰¹pGh8B»’‘Ø	·‡FN^ :D$J2h_5ɈÄTxžßs¤ÔC“–K?ò_(›bý’!K^ç+ͧ5B¨*e‰M%¦j¼‡%3`À\|85N#E¶ÜC–G¤h±vÉ,º™±`D›$ÏÊ•ã’Íþõ¡_IEND®B`‚‰PNG


IHDR  Ùs²IDATx^ݒ±KrQ†šEÁÉþƒš«Á6ÁUÃE7'q°٥àÚàæîâ\Ї}`cîââ`“Xt«Í®Áápðpï=ÜVŸ³½ï¹Ï=?ø±Ë쑣F“uòÄù'ôX²Ù:k†Ä>wl|Έ$f8b¾õÁ'#™°Rɒs¤øVŸ^’@BŒcÙ8”ý?W§\m˜:kÑþÆmö7q“•ÃL‰àâTýݤ¨ȶŠ‹žœ=ūQ1݋{m–¢¸ŒŠŒì’hädœ³‚Ñ4Ш‰ð‰Qq#ò×rÓ h‹´FK„O`Pè‚"œ@Å‘tÑȋpE,€b&¸\ ˜Ká™÷‚Œ	›üÛ}¯ Íu0(l!hâs¨ÖdM
qމâAR®󊊧–‡">œãÈKC2„Pp̽ê,”ùQ]pK›6ÌTæ`ÂHš)ŸcS$ª¼¸4‰’4èÐg@‹3Âì*¿#ÀUÕl·IEND®B`‚‰PNG


IHDR  Ùs²FIDATx^íÌÑ	 ÄÐÎé4Ý\EE/ùñV­§ˆÍ Ah@¡ T„ð“û0`ÀÀüíÀý×4	×sYIEND®B`‚‰PNG


IHDR@@`¹UpIDATx^íÎÁ
€ À@æt6×	Œ!÷@’¶Üx«êºŸ@,Cç€0‰à€1à$8	@‚à$8	@‚€à€ïÀN @€ @€üßT=Í"ºÉxH!IEND®B`‚‰PNG


IHDR€€¾P‰X	PLTEZZZZZZR¤\¯tRNS€›+N‡IDATx^íÎ1Ã0ÄÐt)ˆ¢1ž 1/.ÊNzϋzršÿ ë¬}F3•ÀV@#™À €“Žf+ýÜLø0aà̈́.&0¡€	L(`B
˜P&0¡€	L(`B
˜Pz6 







ˆ	Úkã	ÆmãIEND®B`‚‰PNG


IHDR66ŒEjÝ&IDATx^íԱjÂPÅñØÆvtÌfgߡkVw'w7ǂ £Kž@G³:¶ƒ>@ÁÉÅÑQ\ԂÅë>á4dð’›x„9¹ðG®?DDDO¦ù5ô¡LE$ßùy
a掄y‹êÀ?˜$²éä%ªg°„ÔD–*î
ףث¨”oìÞa¢v{\¨¨9¼&lßàWíû.‡-TØgŠ}]í.‡í$ê/)ö¶s9Ì\Ùx‡aK¾#c؀yœYÉ2,cIœeØÑbØÑÅ;eÿÌâ‡1Œaæ
ßpgµ(a?`”YQÂ`”1×ï˜ÄýÉóƒÿŠ…cöcÉ:˰®Űn–a%èÁöA[9³”>€ˆˆˆˆˆ¼š8בÃSIEND®B`‚‰PNG


IHDR66ŒEjÝ$IDATx^íÔ/‹QÅáuwt£ѦÙï`µڍb]lvA³à'£S»A?Éb4ŠÅ? ‚Ìõ„Wxƒ#x™;ãxã…rýàCDDôf~†¾
ÁTŒä3/­QuXy`õ´Euà&Šl:i‰jB¨–ЂªhÃRŅÐt=ª{åCþÎî&j·‡’Ëa5‡¯ˆmþվïrØB…Õbìj¿p9l'QgøŒ±/ª°ËaæÆÆwưè;2†
˜ÙșÅ$Ã0–I†,†\¼SöÏÌ~ÃÆ0lÊðy—³öF™e%ìF9ósýŽIÜQÞþ+f2ŒacØŒ%ë$úúI†å ÛmåÌÜDDDDD|®*:}ŽˆYúIEND®B`‚‰PNG


IHDR66ŒEjÝ%IDATx^íԭŠQÆq¿F›fïÁjµ˜Œb^›Ŵ°{^F§5è,˜,F£XüÄwŸð.¼awpÁÜŸòxàS|ˆˆˆ^Lëmƒ&aª†úY.®Q
؀üa¸EõàF7½¸DµánÖЁšêêg¢îÐö=ªG5‚ü/»"LÌîeŸÃ>MÔ²!Û|™ý‡Ïa+V`ß4û•ÏaºBæ}Ʉ|%.¾Ã0†…ߑ1ì@žd§g–¢@	¢»8»øx§ܟ™ü0†1ŒaØT`'}W’61I	;Wþb¾ß1;ë»ÊÅD†1Œaۂ8²2¬ï0¬eXÞaÿĠ½ž™þGŸo\…øF֗Ì6IEND®B`‚‰PNG


IHDR66ŒEjÝ$IDATx^íԱNAÄaAВ’k ¥§4ötô&ú<–ÒZjö$T6–”„0!$xãSP\&lvïœK¾lr÷¿M~¹ìù233ûg~>ª5êҐ^d¨{µ¢Fu苐GÏ:E‹êӎpˆfúE‰êQFOº¡k¹Õ=HF½ԣš´"È#Õsæ.é™ +j¦ö@w:?0{A‚ܧ6%Hûˆù.A¦)‡-µ¥êó
‚,Sƒ ä;sXþy¢9áDæڳ3lDd3l0l“ڙ
¿gùÃæ0‡i®E¯´ÖÚ*KØaϸ,akž­¿XêgLqßZ¯üW,e˜Ãæ°!Y̰A0A̰
ÝÑâ„AíYùC€™™™™™¯_Ÿì´<6wáÂIEND®B`‚‰PNG


IHDR66ŒEjÝ&IDATx^íԱNAFaQԒ’+Á ¥§4ötô&ú<–ÒRB¡…¥	•%%¡L‘ìõ·  ‚ÉNvfý7ù2ÉîÝIN6³GºDDDþ™ï·Ë*Zèaàz~¯šjTŸ°]üY3µ¨6°=6è¤ÕFs¸U»õ{æ2´cªcs8Ý1wŽg˜[ sØ̽âä—Ù3¼ÃÜ}Ìac˜»>`¾sã˜Ãæ0¬q|À|
ææ1‡™³ï(La{ÎȦ°œL}ÏZ‘a}X ý"ÃVÃV1ž©ð{–?La
S3
±ôµQ–°lËKY–°-k}±ÎØ_¾^è¯XÊ0…)LaX “"úúE†Up‡YŽA3߳ò‡]?jòãê{l’ÁIEND®B`‚‰PNG


IHDR66ŒEjÝ%IDATx^íԽjA…aÿ--mDë\B.ÀÖÞRìí¶è
xZjk©…¹€€•喋ԀÁÉ)>á+T¶p˜™ÍäìŒ9~ˆˆˆþ™ïe£ÃBŒå»R¨Qm؁y`íТðæÙB‰êÂUl¡o¢[w…®ïQu8ª¨	”ïìª0S»#Ô}©¨O(>ÙVàKí‡>‡mTØ{Š}Gí7>‡$ê…ûš
;øfnl¼Ã0†=¿#SH<H"gÖ\†ÍÁX2wv¶vöñN¹?3ü0†1ŒaØ4a	'y6³¶£¬³v£\ø‹pÇVð#Ïÿ3Æ0†1,cIì2,²¹ËÃì_´—3ó鈈ˆˆˆ(÷›ó»?RÓåIEND®B`‚‰PNG


IHDR66&L¢VIDATx^½Øoh•UÇñó<wmÞæ 3z¡Ž4X j&HٕE¯F*kZæÀj«"é´„‚1’ÞôG·m仈/ޠÈÒA ‚¦k•l«ý½!÷—ÆeÜ{îsîî½|_>÷Ã9ç¹çÞçâ•`#]¬ÂØ~#Ë?Œ2Äg¼ÌzLœŠ3Ûèc!Ú#lå4AX,I'çí"ýlɹr°•éåHl¦›déØJn"~çmÖ`Šö5bŒV‚R§ñvƝ$¶s!NÑ胵ñÆ?vs1Ë3ñ°Yš0%ÕÀ Bì*Ž%ø‘áÌ"zžo©-†–ša¦¹±÷-õ°¨¡…£|s»£´P㸋=…°Mˆ)ÕÌy”ÓyšTÈ/dÙYhd{iwP]ÜBºE—síčù0w­d-p–çX{»vÎZ.K«ƒD|ï‹-gÆR}Ü1Ï×ñ•åfXîø"\F´æbI†Ùçܻ߳ԏ$09Õò«åÞuŒmâ2ÉyŒ—#NlÄb›1j±؈8èŽ0B. ¶cM#2yvÉz‹Mcµð	k#ŒÇ:1ÙÜWÜEØqD¦X‚IÄCÇî$4lDüUpëéçŠÑ5ú©/H}A†u†upS ȣÎÏé4¸»á…Ý(ˆ½†è5^kUú)ÄÏÕÂV#Æ‡衮âX=âºA¨
#²XFføŽ´aq¶‚“Ìr’¾s`G4zaidûÁB4{a³–ñÇz¯V|dó:º{®Yš9Ҭô"íê^š+ü4üX_¤	ûËR¬ч±wÓAX1,ä"aœC쨶q0ÂèFœ!ȃ#ÆóbÏò/¹R¯ Úò`¼°˜¼-eI„Ùö!®Ґç¡=ÈD,h‚ƒñÞφ_bÊܖ|˜¡‘9ÄSe¥ö#>̓م YF*E†,»r±Jµ‰)ÄaŒ[Æ#‹¦eÑGàƒóûEíæ&b€DñC—#1ÈҒ±'Èr˜0ÞqÒÓ\G\¥À	¨‰€&Ÿƒ²ûù	!N³,&ò$#¼QÚ`À^þœùM8¡5ô0%„.ÌÕVGÀ[\â8le
j#èM."Û(ԹG¯4ZÐGö!b’c¤còÄl ›^N1ƬŎÍOá˜8ýª;VæîþÝIEND®B`‚‰PNG


IHDR66&L¢V´IDATx^½Ø}h•UÀñsž»6osý¡Ž4X j6²+‹þ©`¬i™­­6”¤h	b$ýӋnm´ÿ"¾P´ È'HÁ4›´hm¥ÛDoÈýõpxî¸õô¼ºg|¹pßàÃy¿ûrñʱ‘NV¡l?SâOFâ#^`=§hF³•^¦„63HES8åéà,b»ÀI6W¼r÷±…çèá¨4ÒE>=¶’¿ðkP‘}Ž0F:¦8¸‰mœANQŸkåuTŠ4»˜@˜å©x˜Ã;%P©ª£AØåø¡ȳ¨ô±Ÿ/©Ž´¥f؊LšbÏÙۖzˆU™fsÌ|áv̽WÝÁî lB‘*k2çŒTtÎ4…`?RbGÐÊöІ
Ä:ÍMKTvÓt†¬l?Âê£æ̏µ˜’FÌ3f­[›±\ɴ„ìY?Â7I±åfÆR½æ¶y¾Æ|f¹³<«ãW„–J,a/:{ËRߙœQU›Ÿ,÷f ¦؍¸`~ãy„áPlØb¾h¶Øp¦9ÐUÆÎ#lݳ«.U4Ž«µØÕÐ9kæ֖±G.á„bbSþ,&ñ‡úB7j1°ÓdŽݎ£؈ð;NVkNšI#1štßYˆ}B‘uŠuôq8pÎŒ$h @èˆê뉰ë؋=Q˜ØTŒ,ˆ~X,l5˜â0ÝÔdŽÕ"\S’ýÊÐb±¬WfûŠAÅÂ]‰°æk3ëÞV$ÀlŠq„úDؠ÷ì·ɱ!„¦Dج‡“c=3_٣¼ÄýŠN„÷“í™Ë͹äJ?õqu7
8ϙæ„õ‹ó	ҀýfY¬¡eî¤'3Ìá"B¡ŒE؞¶á<NëB8ƒƏIÐøÿbOóí•?R'Zñc‡a‡öl)K<̶á7ê|˜6o˜©XДûNïÿ™fáS–"*ÛìÃlõÌ!<ZÀö!|èüì#¿€T"%vú°ÚÄ„#¨plÝ2õ03½èp,áoöݵ‹}ä¢]Ž"ý,M=F‰#8񎓞䚝»Vt"DSå
IÊîå{á4ËbB3ÌËéŽ5{¸<ÿç7
­¡›Qa'f[Âjx•‹œ ƒ-¬¢¢ڃ^áb¥šè•E7ˆü§÷<ì]„iŽSð­)5–c]ôpŠ1f-v|þn ‡ŠÓ?IAe±–šyIEND®B`‚‰PNG


IHDR66&L¢VIDATx^½Øoh•UÀñsž»6o×AfôB8Ò`¨™ eW½©`ܦe¬6Û(+h	

¢$Wþì_ÑF¾‹Þ.(rB¶A ‚ÿÖS²Ít›è¹¿äp—î½ç>çñÞË÷åy¸Î9<Ï}ž£WŒu´SgGþ Ã5ÆâÞb
¦âŒf3½Ì -F²š&(§³ˆé"}lÌyŒ'ØěôpÌè [Îm„|ÈJTѾE˜ …ŽºŒo³-ì"±…Qá4õ>X3¡"¤ÙÁe„9^	‡GÈЀŠT-ÂöâXŒ/ҼŠ¯ó=ÕÅ0m¨Y6£J‘;l¨§@Mœà»{ ‰*7ÀCì,„­GH“tPœC²:G£ƒ
øÛ
Íl-ª»ÈÿºK»sï„ëÔçÃܥÈà¯±ê^-œ1\†”ƒ@øÑ[ʬ¡zy`¯áÃͲÔq#L!¤²±8ÃìF;°C†ú™*«j~7ÜAÇÜv"L_À؋0æÄÆ¶!g¤É`cL3‚Ða1Î#lA9º&ÈÁ»rÔÄg¬²Ï!üIàÄÄäqg±n„NT%°3O•{@±á˜ «Hˆ®ÒG¢ õiV+VÓÏTN"tþN›ÂÝ-/ìVAì]„åµWѯL"üZ)l„âԔK Ü4U`fAV™)~`P1ðˆ¶ŒSÌqŠe¾k ˜D¨÷ÂÓOþØB£6g±´?փðNÙgö<ûyRюð©çž
2Ï Ë=0û¸z”‚2ßgšÖTæ	Ҁùg©։Ћ2ÓJP6,àBÒbœEØZ6l+Ây‹с0Š΃M"MæÅ^å_Z³_R/#4çÁöyaûPy[Ì"‹™v#\¡6Ó`:4Ít¸ï3ÍÂר·13Õ3ðRI©=Ÿç`v#û‰—J’&Ãöl¬\­ç:ÂQ”[Â3÷M=Ë,B/ڍÅæ{î‹ÚÁm„~bÅ]Ž!,ŽŒ½@†£᎓^æ&šÑ^ˆ¦Ê
>eó‚0’PŒñ^´#@Í.þZøø9¡•t2nÏo̶ˆø€KtÓÆ&ê¨E£¨¶Ðû\DLã´Rify_r²ûÄb#ÌÐEÒ1'O,ÆZ:èá4öU®ka	×C…é?ªÑǀ=‡­IEND®B`‚‰PNG


IHDR66ŒEjÝ$IDATx^íԿjAÅaÿ§´´ÓÚGðl··éíì}Ÿ±µ4E’>`e³¥¥بÌ^Oq‹[èbÀaf7gácAŽ?d,ð!""úg~¿Jˆ`s5ÑÏ*YêBrCݬEõá’F7ý¬Dõ 1+x†¶zÑÏD%Ð=ª{5…ê•ݼ™Ý!‡MÔ'”S¶5ø6ûQÈaKֹc™ý2䰝F tǾnÂv!‡‰ßaÃÒïÈ+l@d£gÖ}†Í@™ù;:;†x§ܟ™ÿ0†1ŒaØ4a}7óöb|ä%ìbœø‹…~Ç4îGß-þ+æ2ŒacØđµϰðϰ"aû ­žYüCŸŸì´<T_p-IEND®B`‚‰PNG


IHDR66ŒEjÝ'IDATx^íԿjÂPÆaÿwtt‹C§^B/ÀÕÝQÜÝÜz^uuԡ:œ²dt—Ăˆ%§ïð	ß !ƒ‡s’¾ÂC@Þø’
DDDÿÌõë¹}˜ÃZÌå¿FQ£zQ´zE‹Ã/˜,²%j©
a/b¡ŠKaà{Tµ€æÝ,Õ.ŽÏa3õ	õŒm¾Õ~êsØN…½æØ÷Õ~çsX,Q¨åطUXìs˜¹±qÖý޼Ã̃ä̶˰KV.ÃÎÃÎ>¾SöÏ,ÃÆ0lØÀI®AY¶`”²„À(ÏÃøÄ‰û‘k—_ÅR†1Œaۃ±dï2lb1lâ2¬
op|`ÐQάæ """"¢ÊjòãêËCº¾IEND®B`‚‰PNG


IHDR66ŒEjÝ&IDATx^íÔ1jAÅq5kRZÚS{„ÀÖ~K±·³ôž )ÝÖÒzÁÊÆÒR„ D;¾â¾B…fv}?ä9ðGÆ""¢'ó;y 	C‹¡|d5ª+07¬ ‘µ¨üƒI"›NV¢BˆUÀZPmXª¸Bߣª°WQ_P¾²{ƒ‘Úí¡êsØ@EÍà%aû
sµïû¶PaŸwì›j¿ð9l'Q'(ݱ¯¨°ÏaæÂÆwưä;ò
0)Ùș—aK"—aG‹aGï”ý3óÆ0†1›Là ïZ^Â~À(Ӽ„À('þb¾ß1‰û“÷ÿsÆ0†1l
ƒµ˰®Ű®˰"ô`›bÐVÎ,>@DDDDÄç›ó»?e„IEND®B`‚‰PNG


IHDR	~6ze›½IDATxÚì]xǕ~°WR]¢z—¬ޛ-É=.9—\Šã؎§\œ‹Kì¸wÇI.N.Ŏ»lj“sÜb[V¥z³du‰*¤º(ŠbAÜ{¨Ápv±ì.vÖÞïÛ$øñ¿÷¿ÞfSÀÂCUUÞts+½ÍÆ3Ï<ú°V<ïØCÿvæç¤?¬ÆÛEËg+-àÂq‘÷ÞÏB<;ᙇg&žixú\A<ð¬Ãó,ž§ɭ¢(ªËqP¾r(_,®žMxð¬sšâªt9®.ËW:ž¾ÈÃHR¾ê	<ÏP\­.Ååãâ0‡æX*ÇW3ÅUCÏr	øŠÄ W«Ã‰ÃZš_„¯3Äa7<ó)_äLðUOqUS¾ܬ¬γ|uÐyzÖ0|UJ ‡¾D:ᫎr&“ÎÒۈγù©_¯³B"ÝÐÒy ˜X¯ |µJ y4¿xÝhat¾V¢ºñ†¬߈¥•è¼Qݨ—ÈFüF×|)_Õ��.êðS½„þ°€ÑùlŠ˧áçeò‡]ÏÐñóu”¯J—óÅơžŸobt¾J¿ѕñóZ㯀ÀÏËâóè™EùJaøj¡1XGù’ÁÏóºKç«$uet#߀nœ•ÄFⰓƸ²E£pV‚º̏+3qÐFt>W£ÏÆúÃ*	ü¼ñòFüa
£’ômò@»ßÛÄùy·놨?ŸMù
(Ӹ²€j¼øyt¾óó"ÈòåjŸ·RM“C36\£:3~>ÀŸ?ãf\\PÝëZ`DCÝ>^¾Ðð‡µ2Œ¿WF}æ!¦y5Í0!Ð
}gw<I-SRhl¾nô+ݬó„/ĵ1ÍÃÛшoH°º6µB^H
çøhI÷Au¦NΆ¥ëçÂïÜ>þš¸LMÅ÷=ñ,¬mó0ûַ@ï2ÑDð+LóA=â:å‡ý¹)°+Û‹rR`¹[ça#|!¦وmbԈ|!gZնüBÁlÍðÃYÄU¸Ê×ĵ¢0–~8C	º•/|ßsۅˆmò՟ò•ÁðÕDò,;Ž#®Räiw^
|Œ_ºù|¥٭¸ðæBÄ3qÇÛ"Ԍ‚FÔ
•Ö/ŒÓÉ/<+ÓAä과TX|~äf\ÈÇ5-p!Ñyäj bëŽ|e!i_äëòuãpžKº¦Ár·Æá%kÔôÓA˜q8‡ÑùnÈWg•úy䫹ªÉ@¾Û~ŒÁíx»y[ìfÝ@~æ#__TçPçs#:|5£֡nœ@¾c,~šã‡eˆ{…›ãè<ÆßÄ61öC¾z"®W;_ÈÓŒÃÅnÖy¾8|1<p$SPëó[).|€Ju¾<ÓGòSa3òVìfטwȢÞ0Eù¼‰šô·éÆ)ÄsùڅØ[­óŠE`zâÙÏ^tPó¸|\þÁIøzä÷TLºî鰦 
Þ’~kŠrIÝñ€g:è7}\·7«p±ý}+Ù"ÂñÕ3^\´IuÏCxžJ¶	¦¸Oýá‹â:Žçrë\¾z3H³GÅU†çÉd7;\¾RŒÃÃ.áËGñQ=L„¯c”¯S.á‹à雠n4Q¾J]¤	ë<Ãc4OºL7zY_¥.ÃUDoÁuœòuÂEõ«(Aw+_}i&ªnâ«;­_½,ˆÃ2êF¢þð$õ‡']”_,ðn󇽘üJõ_VùC7ñ壺a…Îw™²RçË\¦‰Ž+Y?ÿ…?t†¯/ü¡8¿Nº¯"ƕ÷’?tsÀ
¿Qê²üúÂ~¾ü¼«ƕ×nPýŸ^pXdѸÒþàÚ__;ÝÿY„Y}2aρ…ðÙužL*׶Àu'á[åM0³¹5¼@´ý¸©~ûâxX-›?$“Ê!¾ZÑ_9„¹<.öHõACÓpSXæ–ü:X×S¾¦#®l£ÿ;³+¼»j6¼áFHÙ\‹\}Ïyz|édöGáögFÃ.ҍëP7nDݘA5ċ«{:¬ê–”
¯%{~™,²Až®EL_ÃXœGyÅó<d1âZ‰¸^ï‘Oö¢¢‡5-ðS¨óM0ÃL~ñšÒ-
Ö¦ÃkRá/É^¤BøBž®CÎn@Îf·Ðyqð@žV¤[~ÞHözÂWu3܀ùE°ÍF¾²âÍ/Âb{y`6ü-ÙùEuƒèáͧMê¼H7
Ó௃sà/.Y—Bün¿?…ë_=?N€¯µÝ3àEÔø—pÞaÌR¸mG
Ì5ˆ«žè¡ùŠُ"¿tp¯ÕÈ׫y)ðf¢z¨$ˆ4žá9À|R_·l­†¢¿eù¡¼o&¼†çc‹g)Õ姸†Ä'‚‘ãpÒ,‚#«Ñ×é~Yð§éðWå0.òâ94¾ôŽ?Nïƒ~ˆëIÄU'+_‚ƒ|›o?9Ñ·8Œ+•É/«q‘oåìÅó@p¥PLƒmÀÕ@ù*I®Hfڀk_ùŠ[ç
â"ùò˜n\“È×P›ò+¢!éF2u>R—íˆC¢ó{’ėŸre‡n$“/;u#’_=¨ó%´.‡’„ˮº\Bó«Ùa\vûÃ}IÔÃ/tþ݈ðUâAè¾ìò‡ÉÒy?Á!6áJæøËnÝð¢?,ñ0_ÉҍÁô´Ã&³o3˜êáþи?LVÿÐNOšnÌ[©v*Â¥
ðíÇÃS_é^T"½Î/X¥æm„ûŽ4À
õ¡ð‚¶ðAvª½nÁ[5A¾ö'ÃoÌ,VsÏ4ÁOËແPxáqQ7xã£ð®,:OâðTîE\ßl`øÒ;rR ¹ü›uqåœÂ=‡1¿Wa<Ïqc?øÝË`¥›üaD7¯o×äKï ;Ĕ]·ôÎh¿zQRtƒð…qxâº)^¾´Žl?”΁ßm=žHR~ݸqXùܙ~83 þÔ-žvz~™àÂüºóëpUeÁë=Òá‘dà:Ñ?=€[Qç;[ùÜYm¸^î•O/™¥œI®Ÿ	„ùêf_Ï's=@—àßg›Ãþ×RÝè›/$yýFû¸rk5äNXϫ	nàDâ°_òøŠ9®\¸®^|®‡¯>™ðrßLx2	ëˆ"|
7:®Ô[øÅå×Y̯?$‡J€Èÿoٌ0µJ™òmµퟫ�Ã}G0ZïÒ}pvP6üÙv¯ø¥¸Q£Mâ"ïË/ú,oߟ=w
pÕɁ§GäÂÓv¯HL€¯¶˜ß,¸nú´
.¤|ýfT<ê."ì£âÀeö [Nï 1ա8$|™]UNòËgâñäÛS۩±w÷‘ñµÚ&Œœâk,˜û¶²‡)_NÅa¼ºáv¾âэåÊg×6<K]¬­[ªI\Nêa<ºÑL¹ò»תé&ãLârZçPef"E¥~#Õå|Åã{}qè<эCê†YßÁf6¿œÔùÁ—ٺlv\äe¸Ãa¾¼èãÑy•ž>ëF<zh6“‘_NúÃí.ç+ªoãbwÊn— ¿Ô8pítÐÆë7Z%È/³:ßJuÃÍþЫu9Oýrºoo~™õ¾ŽùC²ƒC¦®xubøó7[¿üqġ#~ƒàÚ]w遲»É%æÈ}S;ÃëæÂë¸juký";5†àîýõðßÁVñ„ùŸÆÃ]·…wLâërŠÉ8P¾9Á×Îø⺃\**Öã'w†6̅WâìÛ8¦ód痊&¸»¤î —Î3ú䒁y)p¼ò2¸Ǎ:OøÚU÷"_?֊CÑAvØ —ˊlÚ@ŽçÆÁݷöï\–t§¸~‚¸î1ù´&VKHcǢÁٰ¡d!ü*Yþæ×ýêá¿Ìðe:ÞàËf…¯´Ý)Ý@¾î)©‡;#:oäP¨ŸWMèFšj‡dÃ3#óà	»ça‰Î7„àþƒõðC3qϑÙðÛîmÀZˆCÃ:Ïæj†)¿A.Ň|ý¢°máM‹Ý|!Ow™Õù8ù"ëž•9´ }œ2o\·¢¾ëÿȥõZÚ.ϩ˜Á5$ž)H/¼qb]Š渲û‡ðhy0ü%ˆqˆƒ”f3;	R\¿‘O¹iýÆw·´çJávZ—Èå#—²t)_ñ¬¥¼™ØIêüÏQçŸ4˗b)XS íú›z¦Žl	MV°’Õhä[‘ÂJ?˜ŒY+aÚ٦ðu¨'
ÂL½"ß%
ö`0~cõe“Md‘ëmNށ‹˜ºSxVàIV’ë˜7±[¯ãó‰N²j‘<_áäåpç¦*mñé”
%Ã׺¹Êz›p¾¦h#…ÁEø:Kù
0|ùh“âGž¬æ&[؇'u·Õ@΄eð;6`‘¯ÝCsà[6âêDùê£)ÁÆ!YÉŒ|sÆ!Á@VÏv¢ÏÕ4&«ÉêÚKÖÂw°ÝfsN£ïG/¿ʙ8¬£ùÕÊðE¸ȡ|‘oKtýIxÂû|Ž*qM‰ÁWD7*9Ý`qeÐüêLŸ«{Œ¢Ap­Çç¨N"®åë4ՌHFpù¾òi~uK2®<‡càbu£Óyž¯®ûR9ä¹6ÚÌW,0:Oøª¥|©ÌódQ\òEbz>Gmùjàt£ßO€yŽˆÎçP\ä3ê	ú“g¨nÔ؈ˈß8Áù
ž/Vç£ê—_ëmÆ5դnÔâûiäf:­˹TçàÚ`³nÄâ+ÈÔå³ZþòՅÆtOùµ>ÉqdøªftCÓÒ3+É|Åҍ @ç8gý†‘ü²[çøC—ØÕ®³TçíŒÃé1üa€×yÎÏû?ŸÏʕ_mö‡±ê²h\äüa„¯Î®t—ûêåT3긺á+˯dâ2R¿X?/Òy‘Ÿu©7»ý†Uþ0“ñó…úÃ*ªñß`ýa¸Üàç5úzþ°[Œºl·ÎçR¾båë7ê4øÊuQ]6â£"—^ãu£•ó‡¬nô€äúÃ|ª‡F|TD7"ýÐ@7ri&ÛšÁÅúÀ •í"Ý0â\?ß$ð‡Ù\ßF/¿ˆþ¬µÙšéÛT1|©‚~T'ƒ>ÊV8m…:u_¼RÓ>ž?¾ 0üz±ê2ßgSh.™õ‡¶é<u§^«jï6×~	ãÃ��AEüái¾M:ãç#~#i}›™Åê¤ݵðçʦðîƒLÆ}¥ÜÿÊXDã§A£À÷“†kêruZI=¼¢‡+Ó•ÈÛú¼X•Û{¦Æw¦A9ç72˜ºl¤?oký"|�¿ðqÈá:‹¸Ö ®
ˆkC¦öŸR¸:Š/^ç{ÐyÛøš¾B²·^F¾FêÄaMa:¬F\ëã&ü}G~*œl¿dÞ۪2«+hp¿Oƒ²ÂؒêQ7&쭅7Î6ëæWòµ©S*¬ÎòÃ<w!_û#|‘ Ù~èÑ‚ñ­0¹Ÿy¦	¦ýgø³ΥIm­ËTç	_#´ƒÚXW˜kóR1ý°1ûC*Y;·M	.ä±o°†ַ4š˜„¸f°»5‘ÅçÁÆåC­|ÝØS¯W7‡¦hñU|m$|!¦ϐ¯x[4S!þ7|©AÄÓù‹XÆT·À,Ä5	ÖôÒdö…ñ0ï˽”r»pa~‘ú5Dæ×:̯M¨둿}©
”-ŸÝÖËÆÍô+a¾†!¾IÈ×äÓA˜®·(©s*ìš7®Ÿ§¬³)gb]~YÙ]äW~
¬Ɵ·!gۑ‹“›ÏWH#i3šU(B݁÷CîgV4ÁD½u¨;†çÀ×íÂEüáGáªol†Z5ÎP'z¸	ãožûëCP¹$八ÕlÄÔï…±8	=ٔӨz‹ã0	_7¯›«¬¶	W‡>Jȟ½~Y¸Kq­E¾Öe¶å׌ÇòˆΓ…ÏÈנ`†#®ÉÈýT̯)AEš˜«ûFåÁ×l^ ;þúÒ:˜·µú#®5¤~aî]uEtžÄ!rӽE…ñu-á8œ|MÕ[|Š|íB¾n²y]ŠÑy½ʷŽAàBÆÜÑH’…™'Ãù5ùš‚º1ucšÖYp
˜õì¼ñsºBÄ:±ŒÅ8œMâ0†Îïœ
ßÚ0OYkô½*&@‘Ul@¼ò˜†ÉJøR2ð2½zÁNêó1 ¿w4—ŠV½ùh™혯<a1Yd5åD\äZòÀu	âúֱ|It]`,zMŒ ®Ç-ÆEVSŽ×ÀÕJù"gy<«ÝñùI ¸p
üè“røº€¯–Q¹pÿöùÊSãHùòiðE¾At(.¾ÎáêOÏöo{ŒY
ßÝQó_Ãràñ]”G,Æ5˜򥅫”òe).î5>Åç>hCNÐÀÕBù"ߐ9Çs+TdILéÄú|þý6ġ–¶Ð,KWåªHG›¶ڀ‹Äá8×$qx(A\ä³ë«Ã×fâPO7Zhn%‚«åªH'‡íʯñ:q˜(®®”¯~:1Aø:ä°ΗY hŽiá"ºqÀAÝh÷Qøº§ã|þ®W‘ŽÎ;ÍWÄoÄU—
òÕJóËi¾SM<g]. \9]—cùD}[—Säˈß zX‘@~ÅòQvÔe҄:OGç#þðLqØ?_›“à#:_™@ýàAXHùêçpýÒóíþ4lâÔùÆoøŒC#“lô‡Fü¼Óþ0D¹*£‡ƒtâðµÉ¿¡ÇW¤~HWª®ó‡	öÜèÇÛgK²Ÿ•_‰ú.ó‡?F2h¤P?düF,?ÿ>‰•¸žثξghx!“ž?LDçhös’¯ÑKÔ{wÕÂÑ	¼¹°r×|ø…þÅå˜?D\÷ìF\¢Ȅï
„o?;>L øCËucÔbõ¾Ýuð€hb™ìÕ'>è‘Ïõ˂%fw)àø*rÒ"®»öÔÁcZ|õF\ÝÓáù
ó”ã̯ÂdøCÂâº?¤vü™ë@¾Þ+Lƒdâxv¡:?(ÆøËr¾Æ.QïÜY‡4â°g|‚qøÄõqœ¸Œø¨-vè!êÆZs¤}2à£néðâz;\ûëÔnƒ²Úáh`Ìõ§Èףìkl¾ð|.Ûš޵åmU™ÚžÂwŽà²i]àãU³á
'ú6#«쭃û4âä׿1¿^A¾Þ7ÍâšÜ.:„o!®+ùùå)áßëçÂËvèÁEtCƒ/¢ób>×?>‰åë¶c¸X´k™_‘ï\ <æd]Fq½¸ñ,|Y\cô ‹UJàÒò ÜHâP+‡‡·Í/?lƒŸÏë-\
_^|®ãqaýzaÃYX/®Spë±FX¨³~ãÁó•'òó“–Ã7*š 	uþëç)‹Ì>7YV×W!_ß<Úixš&äëQ«ãÐ<^)íš��Cõpæ׭'aAHc]ʨ\¸oÛ|åÇ_‘þa\~>‡'á–ãp‰–æŽh[GdGêõ{ãW†cy™JÖ݂zx™Æ:¢æ&òK1H¡8Dƒ(rmë=¨Ɋpv±Zˆùæ7E±üϯ%ºeÅ5‘šR-\{WÐ
\("=0ɖ˜7‰
YQ¼5 ¾j.=¾È5»÷Y…‹òõ0&Ü7›[;~qýâºÞ"\“h³H”X%Vò…¯GDƒ|fø£{aì»áùҊCòÜ{6«ò‹ÁE¾-%Œ‡~Å:˜Ù+þ«ý/񿎏
¡®½”¯fq
£§hÀr€àV›ãpÍ/«p¥Ó\®QTЁ˜j.Â×`q
£ØRlƥ•_͌Î[…+ƒæ×P
¾JhCÀ
\z:¿ÛbÝp’/½8Œø
«øJct#™|YZ—)®¡1ôp³¸Èç·Ûâú¥§óVòå˜?¤|Et>Yùbê²Õ|
ñåÂöS¾­Ë>Z—èèü>‹q¾FhðµŸú
'êr‰ƒ|‘ÉÞMñ5^—u9Áe·?tÒϧ3:o·?ÔÒy;ü|:ÕÂ!¸¬̯ϣ?Üc±¦1|%ËÏGú{,Æ5Tgüå_‘úÕèÎ;å7"|-ƕlh‡ŸwÂÆêÛìó°?´ÚoèñeIý"“S‡àpñ»ÓދºAÇW¤Ðl±ÚêÉNˆëõ²¸†ÿÛS£޻‡Àû6ùÃavú
Ê×ßW‡+¤(Ð80^ꕏ.Ÿ­œ´¸o3ÔNHp•6ñ¼^€+8 ^é÷!®
ù¡ã-ÑyÊכÈ×p(®G,æk¨Ýý(Ê×ëx~…ÿ™Å8|¥G:<´rŽrÂB®3þ²2¿´ø
ö˂¿ồûWÏQŽ;¤óVò%Ì/2é[”¯÷ɀ‡Šç(Gd򇔯¿#_W;Á¾^ÁÃaÐùÐ'YqHFa~½Ü-µ
™‡=„éür&¹üjÉB¸_#RҺœ.²óخZxC£~	uãAԍÓVñu¬9T7\üß1îÿ92¾fÅ|å#{àú‡öÀ_Tn]¹ìë€,x©{:<l.ä«'òuòu³hE¯ù‹旣Æ_g›!eà"xº®
0ÿ„~ãa«êòÌbµzÑG7À×D¸úeÂ;øš×Ø<on¹ŸŸ¾Bí}:aNS´ Èâu)Žõ{#|a>-dêõ-×#ùEp!_7hðõ7<¿îÀú½”¯ U|•áº>*#^¾ƒå™xöüù-
`Ã1c…Z„¤½ŒäÏÿ
*a9°0²]dœM²%vß$à„æíÇaW1âº(A\3ðì-øóQj@mãq½„¸.àZ¸.N¹ÄM
\Ÿ²Û_[yFýè%ðÜÎZ¸ÿ[ŒÃá‰ǡV~‘¢Ÿو‹˜(²ƒùf4µ‚2b	üÈ$48«Gä‚pùiŠp¦qØh_´Àôü™˜ì5ìå,ŒC'ø§ëÅÕjƒnØÍW&-œZšµ6A\Z:„ê†]¸²hö±‰/­8<Bù
؈k¢Fn“×^g_Çh£!à1¾HŒ“ošÕۘ_tbeM¸lõQTç'hÄ
ÑùÕ6âÚb3_Z:o…ÎÔÉ];uÃn¾’‰k\ÄG9X—˨n$ËG%ÂW²ý¡^Êê³höuX7ìæ+‹òå´?´{\™Mùêc.-ݰ[õü¼Ìþ0“êaß/ü¡4þЮúküµÕF\Q}‹uC¯.Û=^¶»o“¬úe›?$‹£öÖÁ''aù½0îžÒKÚíõÆ)	åu»–œ
†c1êèKeÍV-p0©ó	ãB¾>B¾æ
p}2 ¾»j޵;³p~c¼>ŠòµùšÉÿ­g,ßZ3W)“ÍR¾þ­1µq݂¸Øȗ-þàڃºq’ê‡kŐlø6æW‰ùe‹?$¸Jêàƒc‚9(2§1$nÂüڗݰ"Ûužã«ùú.òµ;	ãå„ùÒÒCĵ’êÆqiù„ë²V~õʀÅý³à»vášS¬8ظ}¬úÉ`(±8sPç?é<֯ÅX—o²«.#®¾êá¥cܼùè<X¾å|x0E	×å„ýá5à‡›"ë“	‹f…ó됸f«K‘¯£¸P¤Y	ÎÃjöžØþNÂj»ê2E|½ˆ¹=O¤Y¬sÐÙ6NA\Cן×þo­ÐÂu˜úy[ú3‹Õaˆë
O°ùºԦu)¶ò…º1¤uCT;-Ê/½¾mëmh>¯Q;—#_—èáRt@)Ty²ˆ¸’•åàÀ1v‰ú£µð4¿‘’6ÏìŠ=Šk†€,[¶¸×õ«žâWíÑ$»ÐB\-—S|݆¸~Å㢢x~œ¸DqHž‡\oü°¸Æ-U¿qøs~W3ZÄæǁK«ÕLóË\ø>ˆ¡Ÿ2k%ܰú\aA~iá"ϳquÉr}ä¨ou`\ž¸b¬7û
‡³4pmt¯":pNš5q^&C¤NÇ!Á5	:~çm¶©2ê½$Í®#t®邁¸£:ï£?åËoajù
ÂW™ƒ¸&:£~Ã&¾Dzè¨?Ä÷A7“|Y­‡-t€rHR\zuy“ƒùö\dRe•Å:¿Ÿ|MÔå¸&‹Üæ-¬Ënñ‡zq_zº±Ñ>Ê=t—VýJD7´úNúϛ?´ÚÏ;í7œò‡Nû"ê7¾ð‡ñ롓>ÊI褏ömâ­ËdçSAxýÕ	°trg¨ñŠ?$;o|Z^5	;±|°i|OV8q™šz4Ëx\d7¬Qypûg(Ï%ÙGŇ{ë`1?QCp
υ»vÌW~›d¿—nP\Kø‰P²ûòu'òå.Ký¡_d·ž‘¹pÏöùÊÿ8È×D®¸üu¯>濠Oø‘÷"®_%ÙoĥZqH/ít/æ×/eô‡:|Ýx`‡ŗâŠÃoÄÍמ:XÆ/4Hi˯»¶ÍW~“亜ˆvÐ
²kԈø©ø&[Õg»vƒšV\Ku90:~´õåONà:o©zëÎø5Ùý«(¶ìžÏdú×M¤o5N™°nÞ^³±~ýë×Âõƒ]µð4?¿Læa't‚ùqÎW&}^̛度_ò»ٴÀ1??f‰úãݵð„`ýF¼ëôúŽ+é%’å×Û$ˆK«àXŸmôõ'»Û.ýÌãZ‰¸.x‘_ËéæXB\z¿Èà€ߖ­³?²]Ù’|s!O²MâZ<߯ç(7
nêru
ñ?BЍ½Ÿl×Vz‘ò“„SÆo£GVQ®À÷Tmٚ”¬ÏÓ`Y‡ç¿ÌھB²µ>„Â׭o?Èvme)טÄEÌË _Å&q%Ìu­ީAޝ¿#_×[ÀWž+ñ=Õ|Ž!”/áë”Ñ÷2c…:ù³jx¿ž‹C²}åዕ«Lâ"Í~Ûùzʗ\d+Ùó(.ÂÑz<ÿÏ®{wª=Ÿ=›WO›Ⱆꆣ¸ðyHnÎÆ3'œä!ðMY·ֶÀ‹pÕQ¾jŒCŠ‹p³¹?‘k#o´—Ù8ÔÒ
³¸ò©IÈáþ´Ÿg³I\¢úUGãÐQÇçéD㐿î|žMðeEýZoVç).‡üÌdkÓO-૞òUåp~u¦q˜eAjñUl—•ù5×F¾h]®rI~ŃKËG­0©‡VäWåË.ݨ§|U;œ_Qu9ÁüÒò‡fë2›_‰ø
Q]>„ϳ!Éþäȩ8qåR\96é¡~~ͯdšV~­H’?´J7DùeV7¬ÔùY‚ü²²~'	—ÈGY¥ófë²Uqh·?4룬Äe·Ÿ/N‚ʧ|eÙėY?o%®ÙݰJçÍúC«â0—ê|¶M:ﶺlWÑÇê[ärRáØ[Sàñ…P§?´ÂGYæû}¤¾{8_bïËöCù¸NpÙê9Æ>#}¯eþ0‡ëäØ|¸rí\cŸ‘…ùe™n ®ò—ÇÊòÃéñàR|¹n\ÙÿcõMþòsט<øòúyÊ*Yû"\™~8s^>\¶n®²ÞᾍeþP”_ˆ«b\>\ƒùµ"	>Ê?|ý
ùºNÀוÈ×j‡óK«Ï_ÿÇ_‘ðEòkÃ<ee|”¨?oš/ÄE.ïx-§ó§FçÁU¨ëÎ/­º_o#®«8=,o¾.[åçXᣈï=ܽ¼âœvä¤	±yp嚹Æ本š×#󰧂ðó³áåÞ´züÕ‚†Ë×ÂÁe³•NâšY¬NÚZðó˘ëÏoŸ¯|Ç$.²èo ýC«æÍßÌ/¿Uv‘rãJ³ã«Ö9Ì@\ÿÂx)äp½¸¾œ„q¥%:?u¹:m[
¼AW›øŠ§`_s‘¯4pëmâ\—bÅ<¬%ù5e¹:}{
¼'àKsý†¢ñ†ˆ`L$×2#[—áÿ“Bó,ž7âé<„ÿ$9®Ð%[¶m®‚¼x Q «ùŸ4øA¢&qw“Áÿòdâú´–ֵD¯ĂJV½?c—_KŒl¡ç$_£ráþ”ÇL$üDîîjZ¼ŒðEŒϯñü–F¬\OQ\!ƒ¸ún­†•5-Ñ[·›ŒC_Õ4
âŠð%ÂE>›§ñ|Ü(.²5ç¶jX‚¸ús¸F\%È×2#׸µ>'Y	{þ±Fè6³nGS>ÞÂ8\adëMqØÀä—Q\d¥ù<Z0؃¬¢>˜@=\j¡nüz¨nЭÛ	®\îOdõþõ0iõ‹n~`¶Áèêpúí¿).ÃEø:_€‹|Ká€ÁçÕåxpY¦ó:¸Ìä—|œ_‰Ⲋ/'â0Q=4ã7ìÂ5'AñUCuÞh]þµ
ù5—PãÕy+êr,¿ɯDë²=t?¤õk®ٕ¦$A¾–Y‡ñø¨tª‰ð%Ê/3qh´~=aÒo̵ÁzÁoȄ+þÐÊ8”É>!)_nóQŸ7èF·¢~¹±.ö‡#«�#¿ç¦)?O‚;®èÿ´ÐšõQ	÷mF/Q¶£¢zWy)P:.æ¹ԒM¾W+Íðõòõ0{_N
™ó\zΦqJ:íÛä%À×=È×_‡‘¯q¹r\)•í‡;ÁÜ$ãJÈoháß	æ¹T Ã}Ã~cÌõ§ÛkàIør¢Ïf˜¯Q‹ÕûȮ<®qàüÕs”½²úyÄu¹Úë¼|˜mäRnõQ:uþuÃl~ePϵXçKGçÁ<#—ԳÉG%\—YxýF˜ÿÖ1¸½T٨<˜µv®r,I>*aH^L°¹h
×ÌbµßöjX™‡˜
›—͂ßôË/”Itœb¦hõ¼ù­Õð	?o>2ܵ@yDÖq%ákk¬ã×9ŒÉï
úT}€¤®K!—D¾–ðëRPËîÛ1_y\Ö>›Î:¢Ÿ!®'ÆeY~Q¾–#_†ÖG)‚7E8q4y#K
‚"»e,Çs¬÷ûx^gF<6UÁvÅÙÊuz˜†|sŒ÷E
ÄBˆÞZ–àYb×2h[Õk).BãvÅÁ5¹3̉õíŠëBŽ/3Ah_D·TÁ&vE,Á5­̌µúÆá…_$,^](_Fp½çµf␟ÍS:Ãù±¾]B¿岀ÃUGó+L\´ˆmdWœ\“;\XßÂЉÃÅ›‡]hޱ1‰ƒ?ԟ»Þ4âjA\³
âZèÆ8ÔXLzû¹—þJh
¾\¡ótFr„ýùßE±V¿SÓz‘@çÌ/Ût^cÐÜJqUǡ‡Š+Ù|eQ¾2ãàK„ËL]6“_ñ຀‹CÂ×Çp‰tÃ+|ñþÐ>ŠâšÑßøM„/³¸ìä‹Çe”¯Dý¡ù•N?óxò˵þP£.\ŸÄú–õ‡|™ñ‡vù¨Dê²þÐ.¾Ò)®x겖n,¶ÁϛͯLª<_Ÿô‰öìÔù,ô‡fë²ÓõkQœ|™Áe·Š·~¹Ýò>*QÝp‹ùÏc풤S—ݪ‰øÃzʗt~ ¿bêü´êԳMðËL—Fç…ñx¢.“«l8«Bê¹K8ѱ&¯žû276û¨¸ýá”åêìMU°¤5—™Åvò·?$»]¬­„5®ò±ù0Áàä²Ý:~q¸ã0-rٱgr'˜ap‘C2ƕ1uCÄÙékR'ü“q\®ëP¾ŠÙK琝£&v
Ï1ís_¢º“/²ëʺ³a¾R¾ʑ¯Yùr¥?$¸ַé<›_g0¿¦»$¿â곑]W6VA1§‡'1ç¸ ¿´üFLHtcêF(Z7ȎXFë²Ý|‰üá"#>jc›ÎGñ…¸f¢n´8¿¬ª˟§Dõm~¸
È|õK&ê²]>*Ѿhþ+éýC²	ǖ*X…^uãҙð×4¨”¯Å	ôíè÷š7ï‹q³‰_Np=@áÆdê]PÌ^á,ÁùeWô£®mëR¢ÖÛ\—’h߯îuD«¸ud‘8L”/Û|”Æ:¢f²°Ã<e-ûX÷¦ÈB°)ÜýäEWE¿2 ˆ`½F`é©8“ƒlßö°Áçbxp€{
¹Îzû›C÷«þL®­¬óa\S9²ȵ/W˜Äu‡ë"×Kñâ"бyp9k_¼tíÕ×dŽ/‚k¥ø"FîW“둳¸vÖÀ_ð5ã‹\›¸؈ÈÓã
׫×®«ãˆÃ+S¾ˆAG¾^4À×AiÒãMW+ŵ€Áõ§xq¾ÈVñ©>h`qí©3œ_¢8šÀ5†áëu×üDp‘÷Ð=î"×#gp¥ _¯ġVÄáB†¯À¾$ý¬¡<©SW7nÙ˓ ¯sz·nÐ϶˜~Öí5Œh}ïft#‚+§οn•ÎÓÏvU„/¦O6€‹׍܉ȾÂ[Òr¸Œò%ªËfüÆ\DçGZ„ký¬Y¾¦ÄÉ×
ñUÌá"ïuªA¾Õ
;ók¥E|µ¸Œ/Q~U¨Îۙ_Aʯ‡ñè¼ٺü¦×B+|_—M꼈/³þÐ.¥U—§' ÁòË*¥‡“ã¬_+Lðeg~Ð
+úç٨‡+¸¦Æé‹]„«XP¿&ÇÉW±‹|ÔÊ8ý¡–Ÿw®xùšlŸ·;­òó+]„Ë*?/ƒÎëê!é}ÈÞ:˜9müü©}0\’º¬‹kâ25uW-¼ÁN¦ú ž^ñ°W·ÓGÅåIOùz]@z«cóá2#‹¾ð½qõm_;kà
W`L>\adr9IõË_˜[¯²‹RHÏxòedñ†[ǕD7v×Âë,_dBptü‡I\v÷Léåë5vÑ™“!½~#‹¾ä+d–¯=ˆ‹]ôEp1Ǘ}6Sõ‹ðEužͯFÄõ%åW±Y¾®’zx‰Óà êáU.ɯ@<~>¢ó\]`~}ÉD]¶›¯¸úÿ˜“;ÃÇô=µÅ!꼑E_:ùe•ҪËSãW¶üv,<k¢.Û:¯Î3ãJŸÅýCKæaIÌühL\5^£‹¾ÜÐïµbÞüæúåìü2Ñîõð‡ƕÉÖ
¢ÉcÛÖ´¿Rk‰†œ‡MtžÈ'¸ˆWå×oìAïÇ:‡D×YÊñ>~nýñ´Ö$:¯g›"•xnQêþzx™çKဉ.űA•yaüÿËðæýÈg‰ç5ø¿ow	޼Cê>žMxÁÇ-üdK͟쨁_Dݧs©=­ÙÌàºo>°ר%êÛjàç.ͭõ4¶ª\ƒ¯yÄM|Y¢þx{
üÊ_¢-×}MüÿËñæ=¸.ƛw).Rø›Á5n©úý­Õð¿ì}#sá¡]”‡5ޗ(¿ÌðÅãúüß	w}\×£±NŽó–ª?ø¬~ËÞ7*ع@yÔD®Æ×<'®ëñÿa®[×sì}#ráÑÝ”LġÝ0‡<.Sqˆÿßï—ûá†GöÀm5-Ћò¥y)K
¾Ñù¯àÿ¾#¿LëE7ӹ»5·^ÖØ2Õ̥Wx×•jàÒܢX#×ããK-æ+Q\ý©AgÍ-Û5ê²\|~‰Ãxò«ˆÙCóg:o_‰æ—(_ôò+ѺìT~‰âP—(Íàr*¿Ìò•¨?t*¿Dz¨§VûC[üþ_¼™aB7¬æË.\fùJ.³qH¶5Ÿi‚¯DǕñè¼UùeVçÍԯdú(³:ïF(òzþP”_vûxâЊº,.³þ0‘~”[üF¢>*™þÐì8ÅhÇ8E“¯‘‹ՇwÕÂL3X½©æ½8A)vY]6å£F-VïßYQ——?Øzò;™ý!ÏW¸§•·}vòG™ý¡èRmcóàGÛæ+¿qÙ8Å_£—¨÷Ç9\w!®g\6®4å£D¸ÆäÁoŸ¯üþP3E¸FåÂÝ;(?wYßFT¿4ý!É[‡·c>ë²ü2U—E—¼5‡®ì‹"_"_%P¿’é5ÇS¢üÂúõC¬_ÿë²ü2Ûïm/?±†?µ¾;07Ë)%Âe¶oãºy=¾Í|Ž}ìêõDãJ;pY6o>:–¿>þ‚ú¶ÌÆy"Gt~ìõ¶m5ðû(-υ‡w-P2‡®ëG!®!®_Gi¹Υ%â«.½KZ#>J´Žˆ_àc^Œ¬tÅ=Ç3Bm׬Œ¿-r7åC€ökW“Õú_3ñ€÷˞áo´%upç‚Uj¾àC$¸ømÕ›Äu“¸Ȁ°GG\?™·RÍà"+øF
ø:â6¾ˆG¾Šy¾W'
¾Fø:lâ%od~~F×GÐv-U If
1âˆk9{߁zø‘_¿ÝiY|ý\´è‹âú8\İöɄEQ|ÕÃóW©]5pðu4N\¿™
‹p=ß;³÷¬‡êÄá˜uÃhò¸¾nɍ_€Y‘E_”¯»4p‰tãX:ÿ;Qñbò+nݠ9Ïçýʍ?j´(t^ׇàâó~åFį‡Ǎš(“|%Š«T€K¯1¾Jã̯Xq·nÐÜà¿á4R—ß\NåÉ
^§Çêð5Zà7»0¿J|ÖÈ/-x؅ùuH€kŒŽn$êÊ/‘ŽֈÃTA–%ȗ-~ƒ~ÖFqiùÞ#.ÄE>ë2A¦ô‡‰ơQ\f}ÔQßiÂoqÀGYÅ×Xú5ZàÍÔ/'}”8FX&¨ˣLèü1ýF"º‘¨?<âb\"¨Å×(A–¹0EþÐ_‡e÷‡d=³žÚZ
¹ú
»t¾L_B'½ÒõðCö¾ž°Äè¢/‡ë²ÈG	ë2òU°¿î`ïë“	4O‚?<lÄ’8D\?fïëK.úr?-ò‡×sq¸Ìè¢/‡Ç)Zq(ҍÒãæp­4ºèËáq¥ÈGՈÜ\~‘¹£‹m\Ðg­¥‡ûêàn×
£‹¾î۔jÔåq8u¹š‡|ýϗÑE_ç——¦b~ÝÅë¡É8t²/zܠß ùõ#^M֯dúñ:|ÝÁñõ‰ÑÅQçW™	?Õ¸w(ì9°®5‰Ë)Ufr¼,żžFßf„NÿpŒDýÃ2ƒ|i+Û‡	ϛʅ׏l¿þ8.jcôEšOItýÆza
bï#µWgý†¨Ïæº~ñ
½¸ysÔò»M̛s)_ϒÚÊñu»‰uDfû‡Žø(2Æ Þ5Š/n=»% Y-šÁüN¶Òû̳X`1û¼Æÿ:†dÃMäú•‘߃­ÐùHî<”¬>Lçpmu+®AÙp»UÁu2(Ä5ˆã«ÙÍ|!®oó|!®»Åá–pýÁ®Ùqàº9Å8_i_Ÿ9„Ë4_ý³à6WS+äoŒGRÑb¾ž³™¯›ÈöÂ_¯4øbu#” nØÊ×À6¾_¹åA!_¢üÚì_¦qÑX
o廹
rÏ__·îÕÐùޝDâðy›q}
Ñ[/gИ‹¥óÒðEt
\ƒ-æËVÝÀc‡+ƒj_,OÔGÙÍ×Vˆފ>æ’ÝøÔåùÅâÊÔàËjèD~…èÆ‹ý¡Ýùe—HÝΫói4—DùÅûC7ëáÖ8uÞíz¸EP—èFÈæ8|.A\Ÿ	ø2¢ó!—ëüA]dÐnu1.£þpˆ„þ0wÒƃk³	he]¶;·
øh°.»}üÅãêP—OáŽ5•pí”ðìÂÕpuYCø2ŸÙ‡ÏY̗Pç6ƒ¤Wù\~epvÔD‚ÛòëSA~uàëdîF\y‘ßÉeJúeÂw\î{cúCŒÃ{HO‡á+@zÅ.WƬË'á§l’K:ˆkvœqÓ’0é-2¸‚C²‹C+øêÆáP_ÍCӍçݠ¨‡w51ºAâqÝ&‘¦‰ò«º%ZçSÚâðÉúø*çtžäWQÜ*™?¤¡l]Ȋšwãø+¦?üN6"6ûè`J_ߖŒ¯Á¾7ªß[˜îêñ—ÈWnq¹nñýÞÏ\Ì×gh´/êÚ~ïŽùðû‡Á6ùe��|õÏ
Ï/·_öÏÄú
W÷Ù×wÙK>’ÚKÆÆಕ/R[ùõGpŸF¦ɢ‡8†º•勌1ۿˆ^øE¯]É'Ý^×OÝém Ö7éjÖÈB…f‘ët"i¯E™÷|‹½–%Å5Œû×=ôծĵz޲
Ñ_Øû7-pís3_äú£È׫ì}Gàf®Á¾ã¢+ºÍà"«Å¸ÏÃ®ƒý8¾Ê:òåðµ×LâsÑéFmˆµ’Û
\³Ãכm?Jà[ä:í1øÚk’/W˜o;q‘ëLc{…ãëìµ})_CÑ
§ãqB¾^bï;Ô߾dšÎñÅã*I@Ã|۩$––UÀÑY+á«ÓVÀÿ.¯€kö×Á÷º1T ‡
	àÚc7.ò¹»‡±×:×Ðù’qÙÍW@ðÙ
à醝|%”_|
àžˆÎ'¯zÁk3ÈW£‹ó‹p]b€/+ý¡S|э!‰øC®~ͯ@ù|vCàÚíf¿Aqí3 ‡CäËi\‚×b@7âÁåF–„úeu]F½®^~•H࣌è†h¼\ïb\8u>Q?ŸŒ84¢‡{$ÀUg\‡ñú
ýa_dì\ÖжX£¹²Ÿ†ë/Y“\‡
±ü<éužû€þYð*éÈ\—Io
qÝÈ>``6¼°f®©Ëë$ÃGéúCÂWiÜÌñõ
éù¸×n½ü"=ҳg@zĤ÷èâqŠˆ¯¸7D/j =}äk·d}›a\7pqø™‹‘ÌvÐ
2ÇÂÅákðſÆp_¼οfF7’Ðgk0¯‡È׋¨ó\̗ÈoˆòëV^çÍԯ$ù¨˜ý¯ôÂ-çÃËfÁ'w†‡æÀïÄåD~•ÄÀåK´gýJ´%ùbômöJЏÚk o3$A¾’Ñ?Ük o3,‘>@âPÔ?l °×Íó_DÓúÓud1ò„N°ègCá°Á>€kûl¤¶òóËdƒ`=À‹qÙÎ׀ìèõGpƒ`~yx"qèô8%¼Þ&;z½
òu[dCD<zâ™Í<&ëq4™|œ?žé™÷³»HՇ Ûþº¨mÑH d1¿·й[qµ¯BlAAz¸†K—ëù*L‡‡|ú|õââ°E`*cÙqàj¶’¯òu°®çâ03A\Y‚÷k+®^ð(+¤ÂW9¾²ԍ,NðB&pùâÁÕ;`WÃ\UÍQqØ]€«ÄíqØ=N‰æ«ëÉF¸.®DtƒðÕb·n<²¬«„‹ZԶojÝ@=¼Ë/öón#¿ÇE?û.ºëÔ/)ø¢¹ÂãêÉJ¦Å~ìnċkO\Vè|2øÚÑßËâL´|9k7ÕV“{Úèԍ	݈ÇfǑ_Vãâùêe_YIЍ}œndrù%Ò
×û(
ï¥ãçö‡VÖåž1|T¢:ïD~•ð¼Ú#¡ÆÒy+øJ–?ì×	âPä7x(c~í‰ᣬ¨ˮó‡?Ûçi‚NúÃ=؎ëT®!½·ÈïdlcìŸKš_�›᫁h\éð $u™×ùv¿ѪÂ
®`ßLxLµWÏִÀWH/‡Ņ|=*_ºþp|•ôr"¿“^~ÏÓq˜¬qŠf]&½zԍBWŸxHҾMޝv¿Hzù½2„»YHåU€ëX'»}u7‡ɪ˚ºQR_çâ0ˆùõ3	úlº|‘9ÑÃ>™¦õÐ-}^7­ËɊCMÅöæt…ª
sᥝó᧲óÖô{³“_% ß?ìiÁ8%Y>*¤ӏ+½Ò?Ltž(Û¸²|I7¯G4{a7øó§çÃ÷7σ—¾Þª¸ü’r–¬H‰^—Bjðµ:|Yяr‚/~½M7âbè|‰ù•®néð· 3K²ۏûŸR|cÍàòcååDïøˆ½ïtü'ó«W“Ûq­ž£ïÉ]SõTcÔ7pÿR&_kç*Çpü±_}eŒC¹^9{ßÉƨo²Ɉkùlå$¨>`ï«hjü*“WEïLN7‚Q‰Š¸‚èáiäëö¾ò`Ô7¾úsÿrD\„/>×õ1â°Ñí¸h®´ëéX#¤߹.Óáë°|ÑË›«Ÿìu™òÅï´X¤ÃW™$¸‚¾ŠbðÕ,iöQ—eዏÃþ²ûCúÙÖэ¾Ç!k€Gø*Õɯ¾’êa³@7ú{¤.ÒÑù"Iq5LjÃ"/øCƒqØ$iêùÃCá:l‚/Yt¾QϾvžèùüqÜ2øöÓ%0¬¹U\A=?ύŒ­IODv\§‚ðMö½3áCÒ;ÝϟnŠúr,ÁõޒYÊ)Iu¾ÝžŠî%’	˜Iï[öºŒ|}5НøH"\š|¡nD]ú°'òef7=—ùù~_ÿé¡8ìÇðu§óÿ&=}Iõ°ÝcœFM^\2é¼&_ÜÑù÷%®Ëí|…TXáuˆí¸>’„/‘?ôB߆ðuÄÄxùD¸ôú½¢q¥¸š{ó¥&ùòBßF4¯'Å<ì¢ðìØ<¨ùCèØï•eö$S±÷ŠöýqØ$_Äó±÷UDMúˇáu)ܼ9Ž%ÃcÿºYOîÌlµ<oæAôusÓñþÛ
ü{ä
éãɇYŒêN£¯ß=þt8_bq6٢ýßÓëåzó„ɂ«G:<4pn@yL'۴-›^EÉóuH\ÝÒáUäër–/²]à¦ya\½øÂl×H¼™‹g'‹p­D\;LÄáó,.äk×´¸¯WÊàˑßO6Â\&¿э‘4ó¹ûEùõ{ÄuˍÁnHÃWa:¼\Úpn—/&¿ZlÐypPŸcãqʹQçÉý?fává:P‡ŸÚ7,¯€©‡`¼O êƫ:/
_´&±עïE½†b‘¦'C7eÐv½ïÈѓÙÆ7‘ºœl\¥®ÞáJj~Ñ÷:@‡ ˆÃ2‰ò«”ÃÅÆaë2_¿œŒÃC\>
¾J%ÃÅæW¾ÌâJš¢93˜Ë/Ÿ…z˜,¾r��nÈT¿_Cê¼ü$èç݆«‡_$ŠÃRݐÝ­ˇ$ŠÃ2‘?<øWWÂìæVÈþ¬æ“ó_'`D¸rÝ0_“–C
b™Ûal-W~uð½׶˜Æõx~_f—[|TX70Ó0£ùJƒ—MâJ¦*é<ͯi\>X¾„:éZH]|fqqø¢D¸êð5#ª7Œ¸Žʥóƒy§º1›}`ÏxÞ\Nöièüž¯8ô0=‰z(ą|Mçz¨WX7—qÍåtã…2yò렎?ü`]%¬ÿÕ˜º¶¦šä+ÙùUÆáêÍô{íè&ÕZÐ?tC]Öê÷&Ú?L¦:âþ¼‰Í¹ÑGY1®t¥?¤šÕ3¾Üַ±ª?ŸT©ھ`ãS %UÎ:ózÒè<â"뮎ü~*3tÖ۔ʒ_ˆëv޼¼	f’õ
>!ÙZt>óØF|âw‚ú>Þü–’nåq'¾‡_y ¹ç»'àt°:Gî›Ô	.Ý8Ö㏙‡6às¾—d\wà{ø¥Q\ʦVÈcp-D\[ðÇÌCøœïÊÂI&4µg‚qmåâÐ
¸îÂ÷ðŒ	¾Î"_¹‘û&w†K6̅.äË.>¿¦t†‹×υͼnàù.>¯j×ðæ7ÉÄo«Jº*W'†¯+¯՜n˜Ut¾®L?œf/
@ùÚÄÅ!Y0õ¯$ã2¬×²]eO6_*ÅõK£ÿù®ZÉáé<)úï$™¯;ÌàÂ÷Ad³[Ú~BßS”âùž4ùÕö>®ě殥ж
±´u™¾+ zKÛÅô=Íw™ŽC:(¹’P,¡|Ië5p‘üò¹ÐGŽC
\¢8”ÊGÑ÷q•pºafü•tEùú’ÝpCý²BçCœn¸—Yçë²(ÝàÍêá_"—ª~iÔe‘ÎKշ1‡n¨Ëfq]i ÝP¿ͯO&/‡©›ªÎ}[ÇÔg¯è	…oM‰})á"u9é+`҆³çvDZgE€\–îj9t^Ë"_³¯wX¾‚­Ð5ɸÌú~~
òµñ,|Èðuöò†ã0ùý(±ntˆCä«&ܳºZ*Åׯ%ˆk"kzèº|vìK»¸x¼Lâð<ŒÃö«u¤!®+{BYôP«o#Ðy7ð•°?äãu£2|¹ث¥òóú6“–ôÍUð¾ä:ßa\‰q8ãð—ÕåDû6D/T~œ’d?oª­å=ҏêàã©úQ:|‘ˊ] y?JÔPù>È4¯šýy7ömö‡‚ñ²Œ}6_ªq÷‡o«ʤNð™]áÀ†ý2Ãï_؏rA~™š_Ft†[Gt_–z^/ó]µ‚_@ÈêÂ=î„APäÿ~i(r<…Ïß×Èɀª0ֱ÷5„Âßà(äzÚ®_؄ëiS¸ÒÂA×~Զ„ÇuJ&¾È@±kl`ï«Áùxӕ{èIàzÒ$_QqXß^éٍ{h¹Kpõ3Š« -¼ȋÃù¾NyWà"Eԍµì]5Í0SėKpõ5ŠókS®¸H”_.Àõ”I\Qß$¯…ó«0¾ìÐyŌΓ£+¯!¸o
øºì¾Láh]¡×)©òK쑺È^—5øê&ò‡IÎ/SqHßëI|v_fq‰ø*9).þ=wù
™ü¡Æ{.ø
·àê—@tCF?)ˆÃBâ2«ó§qØգ:ŸˆŸO:.
MèæÒñr¢~£@P¿Ê%ÄÕA7.\×]º¾ôè^y8žô3£ónɯ~£!3Ÿ’tXcp‘ƒ›pñ~¾+íq°c´M'—Ý죺áØrÇ×Zàz2A\]jšÃßgùÚh"“ߏÒÐùš–¨I( =᫥óQü<âšÃáÚ`p‘›tžÇUP×Ök;—_¨.ˆçõ‡uÝ0W[u¾ÆᅼnȤóZãJ¬˳9¾V{@ç×|ò•hÆ)fü|ÒûØþ°Х}›§Wv÷Îë%Ú?ìâÂq¥Ù~Ô)}›r©æ+Å1&ê÷žôHŸ͍óDOYÐïM¤˜ü~Öڍóà™_Ítї–ÎK7¿Ü==¼éKûQ×Öې~^_oSÝRð¶3÷¸JƒÏ7έZ'ÆG"ƒ²=Yu<:^_Yx䥄H]›ˆ7ïÄÌèáʰ×x£¸òSaͱÆs«CëC0¸-4񨐍¯N©°þx㹆–	_ïLJ#\‡©°å•cÈÝqơݸH6‡«1|նÀØtƒàJs.ԍ¬n`~—@~¹&óS`ÕQ8׀Âü!à댄:O´]ÆÄ!áú_	è¡+tõpõÑ98D\d{ÐN²óu¨ª>)‡¢µ•Ðo_ô
©0cÝ\xSv\ô=³ۚw<¦BB\¤6±)'xÌYÙò‹òÅâꢁ]F¾Ø@~q8ÂeùՏãK‰S7܌+_ã1Rù(cl~uN—›øêÏé¼ê/çøá2Óp‹ÎWr|uè†[úføªàpå% ‡nŠÃ
_^ðQtcw-\†ÿòñ=¸ÔIlݿ^²8<ÍկN5-áÿçÇh2êFTýªmëݰc´•Gå̯(¿ÁãB¾6xÁևÂ|³¸֘ÀåŏSòhï†íÅm8&¿êB{¾瀦Âz	qñõ+ŸönX¾V“O7ø>@gž¯\ãºá&?Ëõm:óù%±Îóq8–ÓÍðQ]æ@æÔ{Ç¡ßé ôÍOµGåǕhÿÐ-ùÅûÎ^KF¾úY4®t[ýâûQJœ|¹ÉGUèG¹¥/j—‘þ¼Œ}¶J®.wô£¼ÐßH¤?ï&?-È/éûQ9méòÈïumóËïʮóaOˆZç02E F'öح/÷(Šrc¢¨TU}Î]ÕðJ¹,ô $ОËáVí\>¸¶°¿׷„¯…ËóU#!_Qƒ†P˜¯lîaUŸ.ÕE¸6Yȗkpeú×áäùʍS7\ƒ+›kR£Ðખ¯í_ý½ óÈ¿³cQºáÏðEó¥¡U²ñuݸ©
žŽüÞ5
È5·ߓ=\ä	*5ââßsn×ä— Ær©–¯jA*²û
ƒ|UIˆK¤ñÆaª‹ã0ǧ²òÕꝯµ/7뼨.˨ó5t¾JB\U꼛qåãXepûóâs©*”zÀoä ®\d½tƒŽ™5ÇԲúùº–öç‰à2ºPÏÕþùêÇÅáø(²ðkˆøâõ0›öÏÝá7¼(ÕÅù¥󔯭Ñù"ޝuê|¥@çp|mó¢Î礸¦.'¢óٿ?öãí_˜û–(òá2Ò¨‘0¿:è¼àÿ+=‡‰ô{Ýì7rWºÙæ&Ðp³ßÈK`¼ìjèâ~”Õ|I·.Œõ{¥ëÛtNƒ•}2aGAœì	'‡焽»ôë7Ò}ў=ï ²ð+ƒ{\Hvdøa/û{øšßÑר'G½l¸Ò|уÆÆÖðö‡™ÜÃjeÕî‡=_=|I‡8Þ)à‹ÇU'a~íŽJ¤è-ˆCéò1J7‚m|eËÎW׼@¾z	t^F¾öqºQ 0õòµ…ӍBA~ɨ{9ÃÑÃ:/ˆ±«•—hA@ȃ|e	øª÷_™‚ÇÔIˆ«AÀx ëðUëü"Jõ¨ÎCœ7Ç!á«ÕzX/È/Ÿô°ր~¡óîͯ«t×óü’âʡc0MÏ/«nع'7öÜ)!.¾6e[£/ɑÉõvdÕ
ä«G_rÆa?ÏóÅ÷eå+Šæãp¿Gt¾õMB\ü<+Í'e~ñq˜A{£,®ϼàQ7¢v5OQ¢ç\<äë= ^íäx¸à÷ÀøKÔP=ÚP<ÈW–€/¯ö¼ڟ¯ñ@~y‚¯U³Ã_fxŒ‹Ké×odw\Ð]´ð«Q6`=3 ,
@(¼õ»’\û7 .„D]O´©5¼ú0{X“l¸R8ÀáÊġt|eøá8û{°¯TîaA	ùŠʯ5\$׍½U"ò•ï¾²S¢ãùÊð_P4_TçS9—n`YоÆ9êa¶t~Õ8$ȯLÙë²@HnµʮÈE£ªF#SzØ(!_±øòH¦	A	q5øÙý¡_ »Î¸šø"[w«²óE´ŽÓy¢ñ>ê|¾<¢ó"¾‚ˆÌÜ÷áq¼ÈôCm–ê÷_¨üͺž>ªèSà„øJAOÏ^¦HåÇh²úCÚãÐËHrðµ)•ö¤ØÈ		qñžѬFaï1JÊWZǗŒº!â«1}ٛ†”xDçsdÏ/‘?¤½¶sÀ[
_žÊí:ŸÎޱúŒ”õ+(Ðù|ޝãˆCR“½зi2АÑÏ7|Nƕ‚>@кû6žì÷JŠ«É_2ÆaÀ_^Õy/ôÓ<¬ó¼ߐWñ8ʍI2S8š˜*°·¦(!ÿ¿Ôfž¤TÛĐ]‘­J„°|¶Ҙò/µ‘.܊ÅՂ|µJˆ«Þ+‡ÂàR¸“޳E3•zÄÕþ{kG¾Z%嫑Ņ|¥	ø’×ڹ8hŒæËÏëâ
ɆëÃJPy[EšڰP¾|²óµù|¥™åKmÕ_2ê<Eõ+¢M(zëçê²|خVT߿Ô̫š_)Ü#lË-4¦>»>3R›:¿¯>٬Bn°²°’ùš¯„Y\2Ö/†“Hìñßj“Ò’÷¬ªçüxÄ’øFXz|…dÔ
ÊWÔ]¢ÇHˆ+ÄÅ!ÏW«Œ~CO«’æ—.)ùb4O+AbÝhexò9å7ÀÅê|Šê²Ào(u-m;‹œmÆ;h–˜/òÞ#‹æ}!f‚qÃ=96¿ütÌÜRÖðM~Wè˜9b>Zի¥õ<_)z à‹öÚÚóKÄWˆÁEâqÕIˆ«ƒŸW9Ï!±n°õËÇêê|“Œù%ò‡*ã¥ðΐ¤|ŪËM¡«¤íoDùÃO‡7µ‚ïx#d!Ɩï´‡/;ûlÈ{z)û½T7Ø8õmdõóQõË#}›X}UÒñr¬~”Wú6|¿$æ+V~y¡(âKVÝhaú5<_R®ßùC/Ô/‘?ä´^Î^ïՊÊÎ/“/;ðÌgyt¨êxîRێxδ›O¿I’WkÇ7Ø#EV\)г+]Â+L%ίÐç/™q)ŸC¾TYq©úZî—WŒɻV»p‘šo'®šèU×ͭY˜ý9ȯ‰qµ$#Àåó¢nÄðìªĸ/úCp¸	ï=T$ƥ~õ¾Ð
ytÃgÃÂ/—ġϋºÁ.ó’ßP©õðs×°£WåÝP=ª~¹uÞïQ=ÔԼŸõ»Š8ˆ+ţãʨã¢nPñ¥PþþPú½ÑWì°ØÜg‹1	yQ7<<®ôjà\ráú¢¿!_-ãòä¼^ŒÚûE~¹W˕ðuõ*øJäôq…ڏ/¬Xª'޼‡çz×(<?Àû¬5q™šÚÌl¥O†l`¦o&ȆÞVvðèïˆdäë’5jzKô7mšy±À×ôˇœ{W|I‡ÓW¨™\6	ø’׼•jÇWˆãK‘ׅ«Õl¶IH¾aÎÈdÔ
‡QZ	ìõK óA.¿,5#Nê<ÖåLO••¯Pô%x÷ËÈåÂÏ
¸TNIq¥r^7äó‡íe+j0&½ÎS.ü:|)2úCªÀGÉȗ:~3Jz(xϼÎ+¿ž[øòI¬z|Éé;zÀÐKeÐçá=0òûŸÁÔÿ܉'ñB]f{‘ž?¦–ˆ¯¨E©§o#ìâ#/_,®Âõ7ˆç÷®V–/²KS{Á*\]–”¯;oú™/’’±ô¼•jŽüa«Âùyĕ"!.?‡¬Î=ä{q²úy6Uyûüø+D{mR×eÊ˙š]—ӯÝ ߸Rà7B:“½oÃ÷eíÛøtú>‰ùò{° ÄêHڏòAìþ¡ú6òKb¾ _²öõøJñˆnt˜_–ئèè|ªÄóDü•`Zd÷Q‚÷ÞB]×ҪãR<³¸ûȵÇ/³Q¶úDðA5»¾ª«qÍê
¢ø N€+S6\õ-ЍÃU¯Mœ.aöŠC?œ%ãdÙó+Uìï8Xnð%®fŠ8¾ª ãêréâ°!½9¾½ ó~úFãóÕ$;_sºÂ`ޝŸ_h¤ÓùêæhÝ@¯ġŒ|Eé|¦@7/éòëÊuÐmÊ
¸ñâ5pÅÍ[`æc{Ãq)½nÞs£tC 	;²$ä‹ç"è¾^½Ñ~^0¶jò‚Ÿ×à«Yöºl¯/t޽:ßòƒmpïC{àß‚¿ynå{²ê|z›Gd=~/ðÕÈN0‹<¤¤|5QïÛ~ԶD©%Ս ŽUØ;êZ¢Ç2²úCړj?ê[` tùªH5ºÇ(©ßhJóEçâò_Mém=ßö£U…žâÊè|”nÌ*V½ÂWTòs.²úÃÂtØS”Ÿ̓¥ó
àŸ;AŽl¸½&ҋ
x`œ"êcŒed¬ËAxÒ}›&ðnÿ°Ùýtnx‘¯ €¯4àõ{½¢óMà+S ‡M¨ËiŸ#—~^Oäɪ½.@³yӘÀáÈõí0šFä³ê¡ÇÉ ôhn
7®<ApºWc†E©ˆNhðÕ ®†ŒR}Tøʑ×`ޝr¼©çEF\c£º~8%àKº8lj…¡_$ë8#’#›"_£¢š4)pLÀW–l¸PGDUiœàʕM瑯‘¾êe¯ËÁVÍéüÊM‡K*¾­êò)nH‡'‚0eãY¸8ò{—4Øsß0ø¡ìq(0׍‚Y®„¸ø](긲˜ûeÅEøRe÷‡‚8l8³%ĕ+x]Ńº!â+GB\y\^à+[ƒ/©ý!1ö¨CÏq2‚.Œ×"c™ƒ’ó quÜѬ†=™캁žþx°é\ޡçƒ7‡$×ù†?œn`ø
¶yã}²Ç!ͯÎL¯`ސ\7ê×i6¿»!x³[vˆºqšå+Ðֳ’]ëQ7N¡n°¸†H˜_9¯dëW ­W ›jé|'†¯Æa®@I].àz ‡$ϯ†ãÃxە¹/í§ֽ^²øªÓèÈîç\9úy­¾û¼Nʈ+Kðº*H>¯'Wjô<¢²÷mr4tƒ×yÙã0Ѿ‘~”Œ}¶<:ï¿é‹fHî7øüjðAÇI¡N¾àûxžàî#“¿X‰êÚސùÇq°ö“™ðööà{À#xw
÷°|Ùpá@kR”ûðÃaÆÔGŽÎâ:/**S DtqØ‚)ìï™>8*àKÆ8ŒZø•ndÔÊÎW}Låò«LÀWžl¸¹üB\¥¾¤ӍúLæâð€@7ò$ԍñ_GuYúú¥¡óÒÅaCKt¢ÎäWž„|áâð€ü]¸ßk¼àï¹Î#|񸪽àï¹ÞþPðžk<ÂWgù•+!.¾6Õz¡.Þs®õùۃ0È:O="ëI&y€¯ôˆû¹1Úè|ƒ±žœt£qÒSˇˆë Ç×X	qå
ⰌS{!¿:èF@Îüê 󴇨9¦–˜¯}\ýçÝèP—¹ގ¬~ž×CÔùiñóµõóõðó<:®Ìôê=€+Ï_^èÖ
t#ß|‰ôк!êoäy@7ê<¢Ft^F¾Œô½Úïõ‚nÔ{$;Ôe²𫒻³«U¯¦(
ùÐà¹O²+Æ2<çãý6f²yw_¸–ځ«ºfD±—[½ÀW57hÌI	ã°Ê!\åváªášïy©°ÙÁ8,·‘¯™¾ÎÆÈAéøÊM-Ð6ÉÌ…²áªjŽæqíð%nÔ4G7©sÚô°Zvðõ™€/épÕp“@Ù~Ø!ÐÃ.²Åa5‡uþSA,”
Æá,ޝÝû
[âðÆOáÂçK¡¨©ÆV;ȗ-¸ïù¬Gü<¯uÕ¾¤ó‡‚÷\é Î;‰«Æ~^ƒ/W7ä—S~ÞN=ìÐøÎVè5f)|·óð‹_ÀK?/< óU¹mÞW³W IòùU…žc;ç!§x ¿Î"_Û9¯5[Â8äqÕ䥄½/Ë×d/è3³|ɘ_|mªÂ1óf½1µ¤u™àÚÃÅát	quЍ|Y¸°2‰|U#®]zcjIëW%Ö/¾.Ïô€ߨfu>Ë•]Ӭ»��D~ÞÉ>À2‡øªñH ƒÎ;8®tÒGô{
Ž+½2¿ìԼC¹ƒºád Üa¾œêÏ;é«:/#_"wr^/™ý^çDqèdÿÐI¾¼è«ɥÏpwöPU_[Q-Gx½GOa­Ü}ÝeÃ5.J›Z¡ätã›V²S`1Þ]!;®3MÑM™<1.¹âðmUA\Qƒül?ãÍiî‘Ý$Ä5‰ãk‘Àpô°òeíÆuíÕÿî‰èˆY~XI
N_âšÌÅá"Îw—	׼•jʚÊhÝÈMò%cNâøZ,Ò
	qEéa^*,ÄaOÙp½2z('%ŒKjݠu9ªùÞ)>é¼Lõ‹ðõæQxôÕÃÐù‡۠¾O&쾬;|ó7cá¤ÔuYlè‰f(²ûCAm"ÞP•¹~i¼ç3\Ý<ÀÑBŸÌu™p ÀU)à«Ð¸„|ɇï%Îl©†Ú50©qÓ$ä‹÷å8#M½»Û³	=?ŽÕàj©tƒׄ39mž¾×é zHùpñ|UÐ1؝LN$Þä­)JHfÏNUQwa:«-Ÿ­´H”_|VâØòc¼½«À&˜"!_üaŽ?š/Ä5UB\tƒö¤þ›э)2醆ÎW`®`õ0\¿äÓÃî‚8$“w0¸fHÈW?ŸÛÖËfùšä8,”
ï͇Âkznÿè;7‚|þ°‡ÀϷz`\ÙMàçÁ}#óz=%ÄÕMзö™Ǖ:}›VðÕÍ_2ꆝ—ª?¯Q—Eý^ûlü{®0ƒ2úÃ
c4q‘8ôŨÝ2ơ¨?ï…y‡ӑ¿š™;Éõ,@’	ëÑ×àl¢„¥?GŽtÉp¼7
–Ÿºîÿô|¸õ›ýàZÕðB"®n²ں\½0:·
`ªê³ü°„Æ!‹+M&¾¦tW 0=Œ‹ðÕ"k~Mî!®ö•°)
Cjxҡ‚×
Œٮ²à*m€…ÁÖs[V’8h_ÐÆò•)®Cõp9‹ùjÄʵB_RáªÁ%M­ç®Uœæƒ:º@Š×ÃÉøºùêÄêåë,—_Y’áºqå±ùEù:#³n	tÔy̱ºQ(®)ËU¢ó]X\™þ°Ο‘ÙGn€ù‡a¾P?²`øöšðeFøüJ·zf·?$šÀÜÕç¾9*³ï%1˜Éá:#§¤ÓÏ@\]¸*qHÓU²8ÌàùÃ. Ïѕæ‹×y©ê2ոtnð:ŸñÖ1è%®:fdûdŽXËڷ×'µ›Ô:Ép±ùEbï,ÖæbR£#w6„ €ŒA%ÓC^7ÈÄùÇt,>ˆ7&cPÉpu¨ËÄӣO0¸:—5$®_$¿ÎOŸÆäz¬ܺ¸L¢üö³¸üB\yêá
‰ãèFea:,eõŒÑÖÃŒùC^7*HOŠå‹èƤNòà¢~ƒ÷‡gÓrW¸~ɥó"•“‹W‹uþÉêr:¯‡Dç9¾
$‹ÃB®w§Áú¿N‚è¢/ 9ØEr¾ΈÆ_2ùyÚcÊäuÞãJ¡΋ú’áêªӷáça»I†«ƒ?Éçõ4pEòKÚy=®ˆnœÄaÉpi醴ózZ}ʈ+M_²ãê&òQ ž×+Œ/®ýCÉú½Z}lQJµŽH0®¬ô)ŠBVÂç?@"Âr¿Ÿ «“é
å“1ëæ£(òø|¨}eümóùJ3ÅuBë±n?Ná»Q£Ì4XK¾ªW4qx*·°¿wO‡âg(Aš_Çdå«<7GU³tXÉġ´ù…¸¾…+
Ö0¸ŽËÊ×é&¸‘ý½G,§¸Zº!M~häøJ‡5^Ð
ŒÃ8ÝX®‡2ẍË/VçOȪ‡7s|­X;W	P\¼Î÷—¨~ÝÊñµšáKÚ8<ì «tpIÃ׏¶Ã%gš •¹ë8õ½Rë¼@Nêøy™pñ±EøjÕIŒë¤GÆ_4øReöóqáëø{'¡ÛüÕðåü÷á×wî„ßÈÞ Zµl^­“Œ¯cW#ñ®›%Â5H‹/ÒˆÂÕߓ]牧DZX_'£Çj’éáÉöüJÞE
=׷%×ù0.ÒÃaÿP„oI„«H¤¤'…¸VGõäÒC¡?$ùՍӍÓMÑ=9Éø
ë["_+9¿ÅºÁÕåò T:?@P¿Â:Ï×eEù×/v>Eæqåß+3.¡?ÔWö—× q8Ð#q(ó¸r€NÀK|ÐéȔ_E&ôP&¾ôú‡Ç=Ä×1þaêƉù:áø9Ñy¶ß{BâüúùÈöl‡¹?öSU5Ííˆð=¦
€±Xqë‹ÿ“.®´¸x¾Š$UZi>åÜÊk$¿È<¤T‡®Ç5o¥Zp,ýíÝÂ4ø»_ýeȯÙÅj!ùz-_©2à:€K¢peÀ_™_Ëø¢ ®™Åj/Äu){_·tøóëAJëD#,äâðU/’לbµïÑÆèoƒ"®?ÇÐù4ø:ÆñÕ#^Öɯ"It£çQN±ž½—õ«êüeœ¾¢£RÄ!©ËG9\X—ÿ£~eÈÀ×ïŸz}¿Ÿ¶¾ñæÑðÎ<e:º!“ŸçGtt^æqʑuÙ|•ʨóô³/ÒáKäeà‹Ԣ~ÜÝí]°
z\±~³ô4\WÓ=ˆv¯,)®2
ïXë.‘W† Ë4¼ _WÚ I~iÆ!òõj_páüUjwIp
Ðê۠·Ãu)Hªó¥Ì“³Àq䋌d¯Ëè_áøºxú
µ·¤qXÆðõ7—$ù¥‡Ý;ê¼,õ+-FþÃõ%‰põÓò‡Ýå­Ë"\Q:Ÿé]à½LÛ7̅µ^ð‡ îc{ÁϗÊØߠ|iúCtÞACçËbômÒ%ÃXóz’òuHg¼,Ë<l¬¾”ýÞXþP#S%áK¯~•I\¿úëèÆIqÅò‡$Ãt“:ß_"¿ÑWGçeö‡ýtø*•TçӵÆË)ô²¢l¯ŸM÷ã9Ïm:Ï[Ëü<_d¹ïu8ós³ÁÇû™ßë!zuÞ)<ÉvÒY®aàÂpûíyž/²€o(žÛ]ŽkئyðúšJx÷Þ]pѶj8op¼µåÜßOÆÁW͸Zb=øx#<آžÛþ0Ëåù©Q¤NpŽwºש`4®L?œí‘Մâq¥P¾v¸×É <Šæ«"/%ª)OâlמÉàêv¾ʃp?âJcquO‡·ØPè|²qÅԍð(‡ëôÀløÛfm7‡I×ãðP«znמlÔ
¼y+F~
u;.ÊWº_"=£~¹A7ââ°ܯÀ _¿†&WL¾Ž5œÎW¢þ-†ßçgnŽÃc\’üB¿ñ—-úþp¨Ûý!úûÃ|á¹þ,\vó˜ò'¢vçùùanÏ/úõ|¯V]Þár\"?œ«˼λÞ
ø
Æ)ÒùCúùqåqqeʢr·ë]Žk(‡«b	éð>ÑÈúPÛ%Fˆv¯Œ?~O‚>€ã«=‰÷ØUϒË.…?(2%Á%â«ñèAžiµ]¢˜ð…5ïAüñ6—Çáp=\ƒ²á¯{jáW,®C
ðþx³„ùÅö£ÞB¾~ÍàJ=ÞÆ×-nïÛèÕeäëͽµðKԍðâ!2¦9ÙæëF	piöóSáÈ×o¨n¾Nãü¶„~£]çI¯q=ÕpNçÓàüñ;úÃv¾€¿áØå7䲁TçÔ/×ûCŸ¯!_OFtƒà:„ûñÇÿ’@5ý!Ñùݵð?&ë²[ýa{æ¦Àߏ]®ií½#~ލz¥:ãÊ.Ç5BàO¸|\™°?”¸0<†ŠgžÈ-~>%.ѼÞ6	t#EG7Ü8¯O~ÅêDæõdëGñ}›ã|É牕_ÒÍëQ¾ôôŸדװõKÊy=úÙÇòfû½²úÃXóz2¬#é†Ô:¯DîÁ7FHÇ<(„ç¿Ei=#]ÉwÏ>`ýQƒg|í³Z +á/ã€}†ÿ³‡{IÂñá"Áu)‡kþÏ>ÉqeP\©&qµP\$à"¢T¤‡kÆ
µhÃYØËNœˁ_ì]¨ÜɽO’´ç™ÄEVÓöN®9Åꀵgagsë¹ëÃ"®§×O¹÷IÕc9\às7ºWß5•PÂò5<~µgòî}òzèj¾0­G¾؅#ráéÝ:ð%‹¯¤å׼•êàUg`GKl\¼n4S¾ݨ‡‡#VWÂg!fá×È\x|×å¾|…(_7âšU¬]W	۸üzóëgtõ:|
A¾v°¿0ŸÁ8¼Ë@]þŸ»ޥõk֯í¤éƒ/©ü¡¨.#®_ ®;]̗‘üˆùµqeH¤†êò¥=àkw‰ú‘ÈÏó¸š)_®¬Ë&Æ)"èZ¥áçE¸x7R—eà+¬—CÁ;àš}u0yZgS<G9äÆüÂ×Ϣ|ùõÆ_Ã>QŸÚ[wG~OQ 8¥3[3W)sé¸R„k+þÏިŽÉbõñ=µpoä÷T¦w†QIâË.Ò<»Ä,_~äk*âB¾¸4Eýù…|=ƒ|ÝÁšÛq]+G.VÛU?cøjžÙÎÃ8Üíâ~Ô%±ú6#«O�ŠC‚‹äW‰DýÃ|!®ÇvGóœÞƮšßåù%ҍgP7î0©ónóÛðvs|ýùº“Õùɝ`„ËqÅô¾‘¯á.Æ%Ò
Q]ŽÒù®ip âRíÖ~”QwYÛ2¿ç8ÅõþP¶y|¹©o¯vÐy
¾>tù¼^<ºá•y½xæS܇"¾âé³%»._j—Tóz&tC¶þ¡¡ñ²Ëê²eãÙæõŒöÙ$ô‡Fq}žüá‡.öQYÔ
ó‹]•Hj,9䃘 õÄø$¯Âs¿ŠÈõO¯ÖE	¨F÷â\G
âÇá
Ò⏃\ã]Œkg)7±øJI_dõ—cẬÌÌIŠÈïé>¨ê™kà
r¸Îs+®ƒ
ðGvÑWšj×S‚‡–øJFž0‚ë@=¼Ä. |õH‡G5øj’…¯2ä‹]ô…|ÕtOòuÀ%|\Wŵ·®_g×cp¥ºYçKêÃ|¥²qØ-~a@7\­ó%¾0¿ž4¨“‡Føú»è‹ð…qø„F]æùçV\‡àvÑÑù®iBÝ ï/ ‹B\/óqØ'Ðn¸:¿¡n°‹¾ˆÎëè†pŠC¬˯üt'<9r	|éièBß{‰ºœšD\_ŽÃÏëù^Þ&C7NÄ5žóóMï¥DP—Ý̗ÑqåÁy«àÊËÖÂÿ쨁yM­M<³[ó‹ƒ?ָ’x|¢•íÝ
ÔÐR¬.WúcñE<‹‹Œm°¦¿äò>K‹¯êÈï¡6¾žwqNäW‰€¯‡ù8ĚþŠ‹qðÕAçI­æøJ%cÙû6dLÆòEpísw~7R—{gÀ3Äc±ùu ÞÕ:ž‘þ!éQ‘1—_/»¸.Äa‰ Ÿ cVçËàO.öQ¢~o‡8ì“­ódp8ÏIÄW“WDçS\Ô
Þøö®<ŽêZŸQ\±%¹ÊÝØÆݒ‹Œ!ò¡™^’@¡ƒ¦>y!ɐ@¡šî瀍e$¹Ërï¶ÜÀݖջVóÎYÝ1£ñÌìÌ씻ʛï›Oöj5³ÿþçüçÜsîܻºÄû—!W©x•ϵW1ðQŸ·šւvŸ¨\¶æó¡VÀc”‘üÔëØ#Cȿêut£-ö��zïؕ‚z}ޫzïÕòÃ
\!Õ×ÓàËhýpXñUo¿x¶Ã&ü+dúzyÔÁ6Ž±üð˜͸ªä‡<çQ«èüy;äïE±þ¸Dqõx“ÃZWǿ¡ktS«͖>†÷kÖ{ޓö­«xy#þ]±Æû{³„R~âû¹„‹f·ˆkþÝA÷‡
_´/ìxŞðﴞ�®Å÷Ç.Úv\i#D\WW­8?˜ówLž1a‡FpuW8q0¸È}º™Æ
ñ¾­åð?ò××Ü]9ÂÏØWEÜWã}Žò„kø
ñ?·”·nŠH„§wçslæËU;š+>°­þ[þڠDxjgްЄn„.ò/´Ãyœê†!œ+>²£^Tðõòõ¢	;äNç×Èë%®9ˆëiº±ïs„'\CrҶWÀïZaM‚'ut^ͿÜÌ7Œâú5âzYá_óпæsšoò/Œ_¿ÀøõjzÈ_ˆ뗈ë
;œvø¬	Ýàο׽ˆë|3•VŸ˜uÜøö(á3º±ïó=Où†”*^.¿;Êù¡…|¾_ßÕBôý[¡dÉ8a‰‹¸l§`¼{ã]«0,~¹uªðÇ/kŽ+CW:þcԿ.ç쪄V±mh<¸mšðÎpeàÑÁð5$	Þ>Mx9øÒô/äkò57Dqiò…y×ã˜w=§Àõ8âz!”ëlh‡³Ñ*p=„¸^á±nŒ¡nüuã÷¡ŒKͿ×ýˆë8‹ËôÔô„`tã×}¿^åüpÐrñɝ•­Rž¿Ø2UøS(燗¯oÝb'tøa"¢Á|ž=ÔËçC¢Îf6ßà .j´Ÿb*.kÔy짘å+”ûzzãʐ¨‹š§hðËc¿R-~éõaC¢Þk6
•:›…zTHôõÌæ‡:ÿï\?äÁÍêù¡Ù|C-.»©Fu^-é١šñ¨‡fùòzQ0ùa+¾•9
ÏŠ›å˜aæʁŸ1ä@ëYz%ì3Š:—£‚ëü›rNp%áéŠÀRÊ>£¨cT„«½™é»(ã—._:¸軨àWŽܡß;
Ñ/Ãû§:¸.Å3Eö2½w9/¸¦¬­,"ùª")‘°z'°h´z¢
|Ï/),…|ùê6„«w<
®eˆ«’\
ÄQˆ«@¾:[r$_Ú	2ðE>َW;“'ŽÝXyòU{ÚGÁîi©0$.eüjb¸¸ÐùÑyâ¤Me°Lî_í"aoN'd’/®pÍ'l(…òU±¯]È×P“|ù..â׸|1q-•Û!êƾáÉ0(o’ÐdB7¸…|A\ù¾ÖþµùÊ|‘•Âr¹®Œ8@çÕtƒ›øE:¿þ¬TÄå}—†²n ÞЗå|íA;l!ßà*.×ù`ÞÒñðA‡(h4‘ÏsâgLdŸQžϟcŸQä_¯†ôGwÀ5>hwI;˜¼6[(Õñ׵…bxîØy®úK¯ÑL£ÚDuÙ¦PÅ5ò[1ò@5ì(k„~2\µ#S`êúɺP­0¾v _™Òk´uۨ˜Ì®ifü‹p}sv#_}åv8".-œ,¬q¾¶#_d|5 _Ӑ¯UóP7–Ÿ†¥­t£ý+‡#\ÉL7‚å«u~êájŽpåXð¯]
=¤­ö²ÖdB5.3ߩЍÚˆËíP/Ä5qmæµ~ˆGËaõø"\}¤×0ÿgÙxøE[Éyiè†Õú<oul»êó<õLç:užúDj¸Œø—_+B¹¯
õ(›u#—s\Vøâª¥—ðÅu?%ˆ¸¬V?ä=~YÕCnê‡VòñC«|…b~ØüËt Dâr;öÛZ~¨Æ×v(ßêØ/
˜óµ<'²=#½EŸa¢Í~+ԛôŎ
*¸²9•­
ú¬ëôp±߭Wà¢kLb{ó€k’ñµÁ®
ì½J\<ðEßm–"(ûf]Ÿk5—e¸Ö)ø¢kdqÂWìÿŽƒ^C’à|³ \€ÆÌD¸C«	«Ð
%_¤Ñ^ã—/vßV_È'}…	ÐÔ?n5ÀW¡Še±=ª==Æç‹i›Ë`‰|җŸ¯¸Å_ÜÚaVØwG|.ŸlC|õK0d‡ÜêòÕ{{|*Ÿä@¬þ‰0Ë_¼į‰b¿­åð…|ÒÙaÿKºÁM¾Av¸¥>–Û!ñ5(	nҚô¥—ÙñÂ×_k\}ãáv‹|MⅯmåð™ܿP7$ÂÍu>›\¨óÿRèÅå[
ꆚFsÂ×
¾Hço·¨ó\ÄeÄÕcÆåe0s@.Ì_z:šÈç×òœ²¼×R>M!L¿+,¬h‚n”‹÷còüOkz+Zcœ²^ÙhŸx¸ƒ|ñ|Õmy{9|E±ž¾Ôƕº¸H+)Æ)pÅbîòùl¨Ö_wÊqQıÁbŽpe™­®‰~¾ZÙ!暜á
7£„‹rþ°Ö|E!_Ÿs„k’¾(ç§IQ2¾¢9Ãe‰/̵nUðzø)ç|Ôyʵ”:cƒ%˜K÷âXçé<Õ@Â:Oq™j&Çå€vˆ¸îRàŠÙÆ_ªõChYA—¯-ºÑÕõ—‡%m%?~ë½Zvh$Ÿçv\©Ów(4Øwà•/IçMå‡:ý/žøRÆå€ñK§OÒ}=¾²Ú@_O­Þ;‰‡úƿ[_¬õay¯Û«óÑàŠfºaƒnpS?Òyî/·uÝ05®佯'‹_Ê|cƒAÿⲯ§‘oø mä‡ÙFp…©€£™†ʧ•é‚S¼Çî=ÏxåxØÈìH6#o£âeùÉàš̾cù±Ù .zÏf¾¦yŒ+†ñ• ÂW¹\e*|%xÄd|)íp‹	;ܢx9žÙa¬Ç|eDžCܦ)ð·kº[¾< æyZ—áRêF"Ó
ϒD*`UUMÐUþzf<mä)
\	Lì=³C*`¼t’¿Þ?ÄU¡a‡S½ԍ	bÏMåðmµ:Ë_§­ÚÐ×ä«H×/ý‹[Ëae­Ï?	àüþ5ßÈê :ëu\f“RòW_³<5ÎpmÔàËS\Ë _ÉéÆê,¡È ®M¼ñE“¾ÔøB\OšЍ¼å‡_¨‡©­ü+ÁWx\Dd“¿¹WK\^oQ7<×yŠ˨ó¹¨ó]ä¯ÓV£q•ñ—iÂòUPÍâò™zèuÕ:xî¹}pÊD>¿UþÚËÅ0,õ_°Ñ˦%Åå/OÂ5ù|™\åûªàP³øCq„¸ß]	+½l2³ÜTmœ²ÙÈ8¥p²°–|Qþq¹Ùr/ù’Mˆ³‚‹4cB«­Ý)×$õrG°uâ‹bü5ŠñáR樛Œ<…L+¡.!\EFìbƄÙ
\8Âe©nC9¿
_<ã*2ª´½»R9Ö
£|­§±šBS·aãå$_™ÎǫèF@¾(çG=\¨à«ÕL(æs—âZE¹¤W×=•°Øãú¡¿æ¬Â×V#vH:I;xøÃKà‰ß
>ŸÿrS?ÔàËP~¨“ÏG{¬S­ê†.ÏǕ²IDq*|§ðÜ'г’êô‰xÁ_›9æËj_¯"Äø2ª•þ5Õc\±|ìë©ù—¿¼îë©é|›èëYͣØ{6«Äå)Çe)?LwõCüp‹A\:vèõ|€,¢~êó¦p ÓÀþù¼ÌK‰Uá˨r××ÓÉ7‘Ïóž^ s!ÚSUY¨©Æs•Û˵±eÙ&ªµ?Ë&“ע=:•…š<óÝ^^-˖­BV1~–&¯¥ÆWž+=¥6¨<€Ÿ¥ÈäµhÜ^*vXà.Z¦r’J𲗚V1\•àÊR&óö€0€ðM¸¼°ä_nƒÿtæ‹2­K‹ƒOÌ®	U;›/ŽØ^K”Ms‹¸h/æ>*|­r{ùJÚökk9,VNfC\Ÿ!®«mÒù•nÇ/ÚVùú\ÉWz|xx†pƒ
:_ËìÐU\£óÄqÛ+`±ròõ	òõS찆١«ËяÉ'"®O”vˆ|}€|Ýh_ùnûmƒH+³Ùė.Oü‹¶OÝÑÂWª
þÅM~HzH«J('ڬó+=ˆ_¤‡_V_¨óVìö²Ïà!.#_ok‰Ë]¸!®ë¬ðµp/X°¥U=ãÃáÄÐd˜éövE´m%­`&€øé˜Ÿ“ê_:šŽCø›Ú*m©¸èH
´âqD\?v{{)|Þô8q}Џ~Ҫzg†#_noƶuP›`WúRñÃÃ5p‚¯ÓC’áj··ocãÊI*¸L¿ÔøŠ
‡’¡Iðno·§3^6]ß@¾>@¾®çW
ã+ÎÿúùºFëì$¸Úíí,®,•º¾ÞG¾nPâB¾®t{ûQ\Vøº@çãH7’àÇᚨ¢¦ùB\Ÿ ®«Uôðr··÷eñ+Û)ÿâ0.›Öùž_‹_~WWҿ#àöùðÌC}ü뽨&‚zóËJýP+Ÿç¦~h%?ÔÀUÍÆ)å¡j‡œõlÓ
žê:ù†]}"Oêl:}"+¸B¡¯g§x ¶å‡:}½Uášd“n¨ñåU_/™Ùá¿E_ƒøY6؀«’Ù!/}ØPï/kå‡VpqSïuÁ½Òy-;´¢ój|yÒ'r)?t½¯gg@'?ô‚/­üP“¯0ëQsá¸â5úÂrðFi.‚Jõ•GᙒF
äß+^£kOw5«¦«E¸¬è»8¦x-áêá2_9|m´pÉ"ö·jvØÓE\=_J‘?f‘¯*þE׾Ôe¾z2¾”bx|^&|dᒛ4p‘^ä".º×ôW‡¾k»Ã_¥×;GÃêŒ8¸Éf;tM7†­QT
«•“ˆ®ë-ò¥¦îã*»p³®1¸®³è_j:?i¯+Çðâϑ¯|%_ˆkUzÜlQç•vËøJwא\ñכÊ`…rQ÷X|Ý`ÑÕøšê&®¡¹âƒh‡˕vإ…¯[läkº›¸-ÝP
¹J¾Ð¿µȗ.ɿzºi‡[øJUê¡Eÿڨkº›¸ÐA¾
”“¾˜ZÕùã^燈ëÔÃo•“¾¯5Öø*R§\ºþHÚëbüºùZ£œôE:¸fYákÎnˆŸ·~+måLצ{à½îu3~–BñUٝ¯-„Ùø’Øw^dözø]ÜB\·ª²alÄkæ¡müÌ-\wm³4òùãVòyÊQÈ7[U7P“ð»+@\¿r9Ÿ¿T%Ÿ·4þB
½‰´TÁW'Š%¤½ŒSŽZ嫿*­ª6-+.-ÇXù˜‹¸ҘÚRߠ˜Gš£ą9
ñõu›ï­Ø!å(Ý/ä«#æ ËçŠ{P߈U©Xáëä«@‰‹ÆB+]®GMSÁe•¯WžBiå¯4Öó€¯xßl×õJ¾HiLî2.=Ý0Ím«¢ó—óg®gºˆ«‡N\6Íנ$¸–pÑ6¸súËõbð¦~؃Åe»ê‡Zunê‡VòCà§ïÐÃÎü082Ãe¾lÓ

¾âܮG1\N÷‰¤:››|¥ƒvŸh³E¾Žqà_„kªF~¸É&¾¼°C­üÐN¾<ˆ_væózèE\Nc|ÙÙ×ӊË^àR/[‰ËjõÃDð¨¯gs\>΁jå‡Ç-ú—V~8݃¾¹v¨•G¹­óZù¡¥:ãK«O”á²nL·QçÕâ—Ô'Jw—mu
;ô‚/½yDš|	.JÃÆ㩶‡?A¡Î!@d#4îMd­Æ{7[¼6ᇧZÀúZ–U¬õ}§ëÂå_kܛM¸´ìøÚì ®XƗ.r®µA⚀g7•_–åßkÄ5Ï4ü+œñÕ;b˜¶Jn¦¬‚Ÿ®᲼IB•Cvè¤nĞ©‡‘½¿E•ML"ÊïŸàÇUç€nïnt
×ø|1íH
¼q¬Î¼Z4Ù&3¦‰K‹¯£Œ¯j§pª·NÔù—ßluPñ_Ì×X<{hø.ñUã®ÞÈ×ëÈ×Tåï¨!‚v8ÃA¾6;…+«@ÌØ_
o#_]æë(‹ˎø׸|1óp
üqe«ðe‡nhÅ/Gó
Ú6ùzS/›ìГüq
@\¯!®Im‰/Úöî@5üUM©1‡q9Ç.ÝxxŒx¹¥_K{ƽk²…#NéFq5¼q¼Î_µ×ä•bæ,ËOÕû9kutoÒâà?ÂEñë»Zxíh-ÌPþ1}°kÜd5?D\	ˆëk5\l"êòÕù¢¸<õف0ÿñ~°G;iœ⳨µ±¨µ_㵳ÔpõއûVe	û<È烧¯×dµ­_<ÜY%ìw3Ÿ·cœÂp-Õૠ/ò…¸v{0®ª@¸öWÁ&¢ގþuÀA\kä:AÕ_ËÔb#åhéqpøF:Q·!\û¯ãê|åõmñ¯Cá¢Bèp'êzñùZŽ|Ýí”Ψ³…‹éüWj95æËzÅùu㐃¸†ëŒ%Ö——"_ã¥ג"àøöið[̡Š®Æ0¾´ƴ–ã2Ùá¤0kÁ¨֨³mq»eSM/ŸwºÃì0Ín70NÙì0.=;tªïpŒáªvW,㫧ݺa×&§ê6òåhýÐÉü0@=ÊÑz¯}"½þ×f‡qÔÑ,§ørº¯§—†z_o¤ùa;t£¯§¥óÁòÅ]_ώü0€†r6PüÚäpu±CvèYŸ(@¾a‡nèÅe'ó(§óC­|ÞËüÐÉ|Ãi;Ôˣò%¸ÀnÐWå×MxR!{ޤÑ&@Qø#Ï~x†«¼e?ûBÅ ï#0ƒ裁‹´\ƒM¸hOâþ:¸°„Û\”ÐôVùu#ãk¯|E3Lý9àkŸ͸ú3»PyËAhÙ×<X\aŒ¯^|íµWÔ©Ë.;c|õÖàk¯ÍvÉøꯅëº
°mÑèàü9€ùdºQo#®~_ÏîƒÌٻ`®¤ÝiqðyF\›7IhrWóã½vâ”Ï輸Ÿ7‰pÁ^ñ´=­”b.­øåcz¸Ϯˤ1õd=Ì?\·K+µ(p}F«M„_“WŠ]Ž×ÁSªá.Ÿ
_éqð­â_’n4ØÅ׉:xùºUÃ?¦Õ\àKÒy[pM(»ªƒù‡ò¥Âׇ´:ˆÃ|ٮóÈWW´Ã琯Yˆ+Òa\z|ٚ¢]ô]-Ì?R7ùÔíðSZmÂ\aŒ¯VyTi#Dôý淏‚e]¢aîÊ,áŒ]|h±ÃÛÔìü«cÌÚ8%8ûòÃÏNë73¨½çŸì‰ ®W<¼Ñ9ž¶êüSZ:ß3Ój_N/_#FffEÒvEòƒ¶.B[ÿ»|M[%vþ¾ž<X
w£Æ8¥‡„kW%¼«Ü^ŠñUŸÿÀïpNîDá”Íqù6äËÿ4[|8”¬ˆG'ùÂÅlœÒ¤G ­¨ÜŒŽpÂo§FÃüµÙÂ1»âò©zxô«qP„ÜøœÊç®÷•۷1\h‡ïu‰'Vg	Ç]ÊçmW.´‰w”ÛíI¸ˆ¯n10¿ KøÞf\”ÓG:Ì×ZþÕ3ÞElOØå_l\)SÂæëŸÊí,%ÿB«;ò…útÒæzT_'Çˌ¯”ۏ:¥ó¬ ÚÏé:ãë]åv±2Óf\Ñ2¾ÔpI˜ã+*ª…i—vòvÖõêlvÙaâz‡t>L€¦?ƒ'ïM‡ÃÖ£dz¨å_›‚ËÔ{éü!V?åó´íH†FýpŸãJ†‹|k€_¶øW¾l¯à˖üÐ@ýÐÖz”‹õÞ@uŠ'»àËÑüÐ`=jŸuÑ(™Î;͗ž:Ñ×ëîô‰ôêQNõõúº›}=WòCûzvòEq¹—‹¸úꌿÚl_/„óCIçÕ򍃌¯f‡íÐ��àt~èf\v¥nc0?Üks¾ї¾¤|ÃNÿÊÔWÚ¿õõìœ é|Pù¡`↽™0†iGÅڳõœÅ/¯#¼öÔ\>f€ÁƃáºXãžM×¼ïYqQ‡lÆՋd˜.šÉ|ï[bmՓÆN-› Ç:`3.
ÌÃðu8\øjf|t€¯ã"®Òu쐞`*v€¯‹uläKrÎYa¼~–ÔôÔÂf¦nڡ„‹8;®4f‹­p+€›7”Œ‰0wÇ4á9uƒp}Ïø
aJw"ŽË忧f[ÿX¸+GXà¢53¾è<mט<qúÉzøٱZ¸¬I¼p"@â”s¶Ož·WãKË¿c|•˜Æõ™(\Òfœ®‡»×j£hÌxzgŽ°ÐŸ,凭âÓr¯ûÖÂåjm¨é|=å2_AÅeÂ5"f–4À]ˆëGjm¨9Šº1ßÝ0’²¢óÔd«öÁå'êàžãu0£YeÂù×@çôP3.£†EXQT_ÃOÌẶP?X
Wžª‡»Ûµ‰lä_È×<§uþ²5pÕÒÓ-[FPÛ=¾ê
F}^añUÕ3Q7î:V—ù4øÊt@çÇæ‹àg~IížÔhF\‹;GÃ_Ka™Y\ä_#SàGgê[ì°I]7×<Ä��çŠO쪄yÍڸþ•oXµÃCÕ0ãL܁:¥†ÎS\~qͳ×Àåâœ=UðâŠP³ýî1ðuj4¼žKMO6k‰_SÑ®—Óê=9p›Ýù!ò5{w%ÌÕðéFÂÕ1Þê_.mòIU—Ñï@ÿ1ñ•“
~3>sz¼<$W||g%,ÐÒàn1þ‰£o$DÀ³|‘~_S
&Byd˜?÷
wk\Iþ…|ÍñiØ>òõÚá[½âa±i¾Zç½iãGêˆëԍgšÕí°q-ëã×ù¥¦õð\é››|Íf|©æ8£ó?àê Pd7_´%7êáBøåˈëõÂÉÂÒ êéÌ]«³!®'×
=$¾–ü× xàÚîpÜl~(Ã%ÕÂܪ۠þíp¾×à$ÈÛ>þÂòùC¬~hµn“Êøêé¶õK€ŒOFÃ7:ã”`ê½r=Ôò¯Íԣ¨h>,P½×Ҹ²åúrÿŠp±~¨7þjbu€CVêØ
O׉_^Ô¿c>fµ՞é†Û|é+%\d‹g‚°ô|mr×H
>b•/¦í¥ú¡Žn8Qï
Ä×üËõüÐ@½WÒy«ñK®®Å/}½`û_򾃛}=²‘Qàm_Ï	ÝÔO9$.)?ì|õõ‚͍äóNÄe#ùF0º!Ënæ‡Fìð×ÿ
”G¹—íȣ¼Êõt>辞¸ì”néëבüp³y”]ù|:g:ïŸD~h\iJ7“7O£YңuГ*'ð¤‚@)ž´ÔYD"ušMNO䧰kua¯i<Öã5*A?S2þƒg;·Ž3ì,dzZ¾L"›	MEÈD†‹ˆêŒgt\ð:åâº$_„žú%ƒ¬¾ãi¦1ã+–ñՎ]+®sŒ¯
‡p‘Ž
Àá:É>Kã¯Vf‡áC‚£à"¾Ê•Âøj×if‡ôýV1¾|2;Œa¸’™v
à_„gÃvȿê˜JºQÍt£YKҍötƒ®UÈ®Ó̿Ê_õ
¾$;$»Ne|Åj]ðXTý´ήËÖ{¨
̿J4ø’t>N¡çq”@ʔUðªԔJ‰„ýƒ’`Öê,¡È!\‰L7Ú䫌é|bPÍt>‰ùW—Ká飵0Dí‚í£`7mײ~²°ÎA=—ëY\.a¸ªä:Ϯã×ùyð³ò&WҗÔúüøTä«x`"ÌZ“-lp×zxJf‡5ò¸<ò[12:º5‰YÝ£+ñ¤­g꛵}ùړ™·:ˆ+™ñe—?.¿°6–AÕù¦óg¢0¾=ôla(r4´¬&1¾ÚëàÚÛq­Í
=ä«nÒJ{®êã#`]lì­öÁQiÅ'ÆWφf華%¾ÎÔÃ8ä+I¯‰p‹ƒº¡Ê×'ǡêðïé߱áp¶C%GÀjü÷¦˜pس*ë‡$œ¶Š b†
/G¾Î4(†¸¯Ûä˯ó«K ÷äUðŠÚÄÄRŠ¸Ö ®õq°ùÚ&À	iûBâ+.ú"¦>ˆmtE#Œ9Û£õørZçÇ狗쪄÷Ð'úh½‡áZ—„¸ðßExîà 4Y…¶=¸Ô1
ªñÁH†kL\ûú%À݅“…•Nà“'NÜ[C\ý´ރ¾S–
…ˆk-bڂç6ÄuZÚޚ&å¡fô®÷AÄuqEŒgº¡©‡ɑp€tÞ);D\c×ۈ«¯®ŠŽQ°>)
ãáq‡·ðU'ùænuÍ0 ŽøúA7tuùºݩ<jl¾8fO%¼£‡+ªW!ÚÎô£møÿ-	prÙ¶…êüЁ8!GC˜ΏRÆåÈ0¨)̆‡'ûÇoŽæ½
ÄQ»+ámÔð:¸*;EÃZ´Ã
¨ó둿½‰pDZt9ìQ×b‡c¯QÈ×xâëùA0÷±¾þ'å\W"_#ö¢n”6úŸ¦ӲCҍÈ×Jäk+q†yìairùéù– @:r²^™÷º] ;ÜWoéñÅtc
é!bڀüíB.ŽËWbdùaœ¬¾щý_ë(eãÊ
uþ]=ÿB,gÑÏ7`üZƒñ«qî[U‡$¾dù|‚Éz”c|ÎÇWÛÈWf øõh_XðË^þ§<+ٸRTð%ÕR
ÔÎ1¾*ҍ~¾.ˆ_hw'˯€_±ñ×I•:€¨RhÇr²®ê6%L+ä‹ü«?M]2~=£œըžf\U)ê‡áC’l\¨ÎVÊôÐËúa¬PÆøªWÔmbUê^â¢ïwó÷@u6©nS­R?”ê½É2\üËëúa½l¼\¦Rd|¥¨ÕmÜÖyƒõÞze€ÕD:[G¯㲉ºÍiYߡRî_òºLçSÄe§ë¢Fq©ÕE•úa{Æ}WþåtßÁH=J^Ÿ¯”¯ަ¨&2®Ù!|Õ)ê‡Õù†f½×#¾éFRç5úzòü°+îë:ˆËL\–÷õ”|ÅÁý#}"GóC}=¥Îëå‡FúznôaGƒù¾ž<’÷+öõÜÈá’çóe ßדòùÎã2’ªõõê|E‰¾'ùaƒ"Ÿ”J}X¯óÃ@qY™*óyùü
^òC#:/á’ú•­æoXÌÝð/#ù†r\©•Êëê6NÇe£}½ó:¯\ݗ­¶)×
ÛóCÁ8úše9(¬<¨€HÎnâoèÙ-3½Epð`¸h–åÐIòhfg„I\;ìžM©ƒ‹`MòÕd“|Ñ,ËÁ&qY9×N<¸„‹ükH€dUÍÃLޮžñuÐ%\VìÐ*_»ð,vч˜Ô
тSR¶­-ñuñ·p÷îJÙ7þ+:^
vË/ƒ¸ҙÎǘä«Y+~]·¦/:wÉ_£&aïxøïAI°ÐÊ*.éa#Ãt^;âßkt&Qùzq@"<Ï1.߫!ímð’Ñ?`|ý¡S4,v+3»u~Ê*¸6ï,\C«#f¨­t¡uÐä‚~	ðòõ|Å-†¿ÔúZªiâBS3D‹&òCj~"_/uŒ‚]â«U~8¾nZ{îÂ-ø	¶/LŸ¾¨	Ozè_?Z·¬8¿כ$£<¨i¶zG ÿê/DŽÃNë<M,©óÁcÅÕðĕlæo‘³fÑD.E“\×+¨óœæ‹VEÚYO!®‡šýE
CÙ ‚
7ÉWú×ïÐϞsƒ/ԄÙªáAä+ÅÉ{1uþi§uƒøÂüæ±}Uð˜Þ$O¾šD3z8¾=,Z»1þb¸ß_›Ñ
I™©æ¾Ò!wËxËq%áÚS	 _›Ñ
ZíŒtC¾bþ_<<nïõ^+%Ý@ÿzÀ_—Iç{ÅÁæýÓáeÞê’¡>j”¯.‚×ßˡå)I31̵q%ã‹ôðW:|‰ÅÓáNԲZyÞ+…hë6¤óˆçäë7r\SSá£Ü	ð©Íõ
͍ñ²d‡¢`pÞDøÂä¸R4‰­žÕýÝÆõºęٺÍqõaã¯(1¹ê_AÖ{}ôÐM;Ì`vcS˜IÎÜ֍ÆW¬I;l²—ݴC+}"+q¹Ååë¼վžۺaVç›-æ‡nâ²҇µ¢uL7s¬‡¡’oµ—BÎÿ_ϻüÐìXÅm·¢Vùr;.[Ñ
³s\³C†­·…¼·‰Ù ÏãJ«yo³…¸ìæü
+:o5?´4@`|zÚ2Îæïf÷ígD5‹ÃEÄõwÍNßËpù\ÆÎ¿ä«;ãÛ_2¾bÀ%ñÕ设Œ/'ü‹–Ýï‘_ýÀU+³Ã&t£C¸ª?8
g^;{ó&9󔃝ïg‡n¬;Iã
à5Š©´Ê@Ï8x½K4<'­´J:Ÿ¾~{¤ƿF«qIƒ¿uІ<â˔Σ]¥߷nÕH¸¯w.ЁË':󔃾2õt~Ø
¸g[L5smÉ׋àRåK¾J–Õ#>N!®tn™¸Qå…n”4 î_ÃßëMLæ0h‡ox¡´Âթz˜s¸îÐ[åÏ"_§/Š…·ºÆÀónëƴUb‡£µðø÷µp{͸bá¤g,üÕ\ÈW
òõòu·Þj]qM‹ƒ¿wiÑù³nã:Q³‘¯[‘¯Nà"Ÿï¶æ¬“ÕÁ#WïµÛãZp½†zø’v˜€|=‰>v{µÏÿdZÐGdTŸ¸îëåÒϓq%Ùáézø
ú×=ÈWªÕë,žêï/r1®$¾NÖÃÜïjà63¸ºÅÀÎc—ÁÓÆ_û¼âítþÎ@¸îπWþ4̬ò'—÷{Äåã÷(ãrJ$-	¿±¡¾qÐm¾H‘«ߢn܁ºÑé˱ð]üOÐÛY*ö¨nãtýð Gõ
§ê6լnSì®H6þr¢Ž]Ëô°ØÃzT[¬J|Å;„k«Ï{©RýÐ	¾¼Ô
'užtcx×wh‹:ïd}¾-÷õöy˜o8©óû<̝Œ˞Œ¿Úp_ÏéüÐ˾ž“ºáu\îmk>@[ÍÝÈ罴ÃLt^Ê-ó%ؐ®AK¬õ„ÀK®ë4€<-{|žpc&¥\´„!í©Ù
ÌÍ0”Ò҉´oé)NpQ>ƒñ®œñE<��Ãô“\a
;ŒhCþÕM¦‘Aà’ø:Á	__݃ૉñu„Ùa3GzŒÎKºñ=áãHç{2¾,ëÆðoaf¸ß􎇏^ùÅ®t³þ5¾n^{® G†AmçhÈï ¶÷œ^ùÅd¾¡«ó‹OB§«ÖÁÔ~GÍåNQ°65þÙ7þÉ;_Z“ñ”G„u]b  S4¼üˆ#¾üqùÆ"¸샣pÙë _Uh‡+S£àý>	ðž×|і^•Mpݩz¸ÏɍÍ֒{†k
òõ&ºA+W¨†NÕ]§`âŠ7|ÑJ#Í"Üz¦ÁÏ٤ øªAÝX×9ÞJŠ€œ^1Ê. ן¬ƒ;۸ pùu¾}$|‚ÿþ‡׺AþUÑ·œ®‡둯‰AØaM*ñ
ÿHŽ„÷¼æ‹p•7ÂO‘«ÛW–U¾˜Îç£n¼ƒØ>–¶PôZ7¯›ñœØÐì_ªܲnÜÚžxf lõ:?$ÿ"xÈÕ-ècÙjÛáê—w†wÿ5ó6®d|݈˜ncº¡ë_í"á»s3áQÞǕėO„Yg0†ÕC¶šÍ˄s3/˜Œ§†ëO|¬nÑyŒËcWÂà$øvûTÿÃ&fǕÇdãJÏq­‡+VLôûF7ƕ\ಱ ùÙ!/õîlœÒ%ȺÍqÎêvÔ¥zÔ!NìPWf´A¾ìê;ðÆWgY \ÇX\>É_=lÐyÉyë«óÜä2¾Ò øú<o}CõÃ䫳LçےnHqَ¾/y”]}=y>Š“>‘]ù¡Ô_>ކtƒ׾^º
ºÑVóÃÀçü
;øâe¼l—ñ8/ÅRÖÉ|Cp$íÛ)íÉN«!İSZrŽ>0-½F³ñhf(íOI{ožóZà"<©ì'µiÖe´—Íƣ½;éieÚdzÔk〫=ÕÌøŠeb®ÀE|U1¾ÎrŽ+Œá’l1žñ#³y²µz_g™òÎW'ÆUé૑ùñU*ã‹gÿêÀNò¯Df‡Z|U2\~[䜯vŒ¯d†+^…¯&Ɲ´Åé±Ãt^ÎW¨é|<ÓúH=”tCâ+tžVH‘é¼<~IþUsÿVè“ÒâÂ!7#
8Öùv—\çý;¥§¡ãÖÂ+´ež%	p 1¶á¹Ê'ÂR¯'7˜эn_ÃKgê!³‰m%E[>FàǑ§CˆmwR,C\+xÆuÕ:s ®¨h‚5>èU냴µ[³ØRø í²b¡46Î ®#ˆkcB8¬BÇZÎ+.j6ãçήl‚œjG\=ª› r'mñˆ|5D…AÃUŒ6¸±-‡|¯'£h4I¥ª	.­òÁü9ϾÈñ•Ø̶y¤mې¯rÄuq}O|¡tˆ‚<¯'£hãòÅØÆf˜Œ|e#¦‘µÍpòՙm1(0¾iGԍ³ˆi?ùr–‹|-ç•/²Ã0¦!®éˆ+Ï>ˆ)µ¡â%;¤-éÐX«Q7NƆùùڔ	yˆ+qÕñˆëò5b4jßT´ÉÄúWêF§:¤H[rÒֈ
ßߢ_ñªä_ˆ%«¼.EÝÌô°òçûAçPçk™Î!\d‡<ë<áB<9èS™Îg ®TÆW8ãËG[ÚÒ*lˆë jÆ&ü¹¹û†gÿ"Gl—¢
A\éLç£%¾(&ÓdCÄuŠt~@",Y6>â9?d“˜g oMBlC™n´§Õ,%G_:Su%Ü-«p?®D\1hwYhƒSŸ?.“ýq(<{gUä½u,—/c㔞ùBž²/N†Ä׆û‹·ò:@„F ,DÆ)Êú¡rœ"¯*Ǖ¡PgKacÊxq¥„+Tê‡g)²:€_Rýðçuù¸²Œ¯(zoEÕmôê½Àøª†ЩÏK|Iڑ Sï•t¾œů’ªjÕç•õÞPÐ
‰+=¾êØY!«÷–„P}>‘a‹ñÕÄø’t>Tê‡:¯ŒË4PÞ×ã½ïÆðèõõBµOdT7ª_¡ ò¾ž^ŸH©¡’J|%¨è†\çCI7:ÊòùD|^Ù'*áÜÕòCµ>lMæ‡z}¢Pž¿ÑQ‘o¨Ís÷õ΄ˆΧ*ø’ã:ßסüÐèüPÍå㯸ºáˆþŸ÷[ù_3ÄWIEND®B`‚‰PNG


IHDR66ŒEjÝIDATx^íÕ/«ÂPÆq¢q6áÍF_ÄêŠÌ“Í`|{F­7Þ«á‚,6bñˆ Ÿð»p¸è@Üaœ㳇'ƒ/²™ãADDôaš‹FBˆà[DòYÞ֨V žXA`[T®ä
][¢êpÓÖЁšhÃR‹»A˖¸D͠ô ¾c-îe[âúð•_€_-nèÒ[3ÔÂæ.…ùZØ޵ÿ:õ‡a{ïÁTJ¶rO?˰	(C&Y†
†z>ô¸cÆð
üÀQÎWÂbPš©+aGPš1ž±Nr®ò­èdÃư
(C6Y†õ†õ²ó`»ƒvrOï…"""""w;B ‡IEND®B`‚‰PNG


IHDR66ŒEjÝIDATx^íԡjÃPÆñÊ&[7˜Hõä"¶~j”™ª¸ˆ¹BŸ o0¹ÚÉUÔNªjâb¶B!äöGÑJ½ýü¸qáO8×ãݘIòڇ1,àK,ä[ß֨b0'ÄØB%M*m‰z†Z$0…'ñ;WË-q3‰úá‘ø{øTqð`KÜ;<6ÄßÁFÅÍ]z5Ç*lëRØ@…ýz.
3cØe;ò˜+ÉäÎA—aK0-YvV¶V:µ:îÆÃÆ0†!܇o(äô]	[Q֮„`”=ÿ˜;¶‚9G|cÖ‚iIÚeXÔbXÔeXf_1(—;{gq{ŸQêKٴWIEND®B`‚‰PNG


IHDR66ŒEjÝIDATx^íÕ/‹AÆñ[X¼¸×ƒ—/ú"¶yv³å’Í`|¾£V£Äf.YlÅâXq|ÂOdĆŸ…û[¾,³ûKˆˆèÍüN«!Ԡ#ѓ{¡«Q1,Ae‘YìZTΠ‘gš®DUࢬà~DÚüuWâ:5ƒ¯Œù'´¸=]‰kCé|s-®ëÓW³¦…ýûia;ßþuê†a{íŒôa*'Ù3²6eÈÐfXj0,õê|èqoÆ0†1ó2Œá kٗ°”fâKØá.ìÄ7æÀKà(ë7¿Š^†1Œa[ƒ2dm3¬e0¬e3,€lsÚʞÁDDDDD¼®Tvôd¿©ŠIEND®B`‚‰PNG


IHDR&$åõH¥ÉIDATx^í˜1kAFÏ>Xˆ„T!6A‹üA4>$•D	66¦°H%Xi´ð'<¬lK+е¥ØHФT+M²s?araÖÙÙADsaÞLqçî7¶’ÄßXàŸ;;‚–‡—`‘ñê0º÷ðî3dHbbæÊA+×oÝX<=wÆw$@H)ùm ±µ¹}áɣ§ȬCv°ƀsSSÇøöõ3‘
$”¨9uü(Àù‰™Eªªû7/^‹ã[Xºz«kƭ/ß3fm£ÕÇÏsÆV–ïÜ^8qò¸™h‹Ö…ˆÆlßêÜü`Hò3	ä{•	0,ì²ýéÃpmí@ìÒÌì,„ ]‡ ‚ˆ¤„Ì ʌ*‚`æpf Ãâªz‡éÉÀ|W*€jdµ›qˆ”€(‘á0†,ÚÚß÷UõÏt!f	HËRlâpU„s‡lö}mïY(§Ò
tYrU„“Àï 3±•ÁHFd‰±’%!ìHÈ!({e0\qْ9@jɁ2°ÌÊ`Ð6栢j5VáR'l³guÌGb!c©4?ÏÁz±ŒE€œ¥rÒÔk&5D¸~ÆB„ò夥ç©%9¤'×{Á̚§²PHÚx#m'×íö徱µä@ý¯ZV彤~`•–IZ7l_K¾FÐ2˜#Œs-dƮ8‡·>£Œn|d=“V´”û7)‚yRòvҤ•-9PbÌû¼cWHZ™¥PYc’z¾cÍJI˂È
–ð3¨×(ƒ_Idz¤¬1HF	E0#ìv Þd4¥é}ä–B
ږ eIõ^dúÀÞnm~NON ½ï :6´äÂ
nÉ‹@ÜRjEQ–HkëK
ð¦l´¾ޜù³õ‘©ÿö3Ô!Ø!Ø/·†aqZ¥eŒIEND®B`‚‰PNG


IHDR&$åõH¥<IDATx^í˜1‹A€¿÷&*X*æ@üb}ۈ¥¿@=ÁÂ"…µ"xZyÈAÁß`og
ÁRá¼DÐCÅdž›daqÙÝS3Í7o2_ޛ	33ã_lJ†¶ˁõ½W› Ѝ‚–��¼{ëÁ0
ö×^Ã÷o?m3‹PbNeë¯$0X»z¾X9ѯJ‹ sÖ􅭷[œG.Æ_=•ëWÎڵë—}Á$¢ؔ¤1bÑG`c}“›ŸKSÆ|‘ß*˻7¯ÿè‹yY]¬ƒ‹ÎÇOž‚ÐóôÏh*(óØTAÔç«ô¬I"SàsS( œ>w	Døð~»xxçMbÅÑѸ·á`åÃE•Éâ@€*VRQ—ÑDñy/­‹c‹²ƒàØJ hÃÆ_‰?¾!i‡[’±˜$\ÎãDœ.írÖ$§ 6G£Xœ€ŒqFJZI«ÆõÄc³ê¸–XíÓ.†EbŒyå蒱‰g,«\«˜Ëd–£UÌSŸ[®SÆòËѡ”qÉ/Gç=–_®],«œ³UÌ7cN¹®³ÌrÖéTºP&9§uý³l™“)÷QʬrÝK3ÊÑ1c
°l™ëž1ðóʽÖ=6þND ææR_‘°¸­úm¶Ê%M­¹	 6nm¯ö|ù€¨TރÕw"PRƒVß!̩‰³ùQõ1U
‡ØÙý0j>{¹°JÞ6†ÿíßPK±¥ØOù¼N9@¶!IEND®B`‚‰PNG


IHDR
BÆ*+IDATxڅÊ1¡ns
Àà±RÓ>¦²Yhš…f¡=…F¡Yl–…£zb§‡h5IEND®B`‚‰PNG


IHDR  Ùs²EIDATxíÌÁ	 ÀÀÎé4Ý\@  ›ü/ºµ6œ`BˆfHID˜Ð
`B÷h€øpׁFÈ	×ÄÂ×IEND®B`‚‰PNG


IHDRC„EIDATx^픱	AX5`à±ׂ©m؁½ˆÙtñ#ë0±]#n5Äÿ̎‰'xOˆ#SdŒ‰DO
Г„Qƒ˜Èaé*jœ¯Ò$mÐk†_ҝ՛²äæ	qañR朽!N4ÑpŒ„80{²Ö۱ýGòI5÷‘Ç҅/¬"a—P0z†Åƒ¨ãžFIEND®B`‚‰PNG


IHDRC„EIDATx^픱	AX5`à±ׂ©m؁½ˆ•üD&°{0ðØ5áV#AAüÿÀì˜x’÷„h12ÕAÆh‘HôÔ=I5ˆ‰–®¢Æù*MÒ}°fø%ÝY½)Knž/eÎÙâDƒ
ÇHˆ³'ûh½Û$Ÿ¤Qsy,]øÂ:!Fq	#¡ð”P»§ãIEND®B`‚‰PNG


IHDRC„EIDATx^픱	AX5`à±ׂ©mXÁ؋XÉOŒ¬ÃÄ<vD¸ÕHPÿ?0;&ždà=!ZŒLu1Z$=5@OF
b"‡¥«¨q¾J“´A¬~IwVoʒ›'ąÅK™sö†8Ñ DÃ1âÀìÉ>ZoÇöÉ'iÔÜGK¾°Nˆ„Q\BÁHèhŠ ¥BýIEND®B`‚‰PNG


IHDR``ŸöŸ«PLTEuuuuuuuuuÖÜ5FtRNSK&QF•IDATx^ÝÍ1
À0À:N ˜d‹'|Šà]1¾AKckŒ'‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HDsM?l ŠbªåIEND®B`‚‰PNG


IHDR``¶jPLTEuuuuuuuuuuuuuuuò¥1_tRNSK&“$¦˜W»IDATx^íÍAmCÁ/ÕL¡E†ðøS)„hN¹dï£}~±ƒ/ø{°‚Ÿê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒ¾HAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁ|¾oÿg¥2.2U¤IEND®B`‚‰PNG


IHDR``¶jPLTEuuuuuuuuuuuuuuuò¥1_tRNSK“&…©¼IDATx^íÍAmCÁ/¹L¡*(ˆǟJ DsÊ%{íó‹}|Á߃ý#ø©ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :èû‚ÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäÁçûö¤A<®æ÷ì*IEND®B`‚‰PNG


IHDR``¶jPLTEuuuuuuuuuuuuuuuò¥1_tRNSK“&…©¹IDATx^íÍ1CÁ/ù<
§P0€€0*Á0Ušl?Úçû:ø׃½üN§ƒÓÁéàtp:8œN§ƒÓÁéàtp:8äA† 2E!(‚AdŠ CP‚"ÈA† 2E!(‚AdŠ CP‚"ÈA† 2E!(‚AdŠ CP‚"ÈA† 2E!(‚AdŠàûýúhêØwÒ"'IEND®B`‚‰PNG


IHDR``ŸöŸ«PLTEuuuuuuuuu4pÇtRNS€ÎGþ”IDATx^ÝÍ1À ÀÀÿº"5­]¤¥
ÎY3ܼèŠñ
Z[ã`<‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"škúʧOßÉ:ôIEND®B`‚‰PNG


IHDR``ŸöŸ«PLTEÿÿÿÿÿÿÿÿÿdÂtRNSK&QF•IDATx^ÝÍ1
À0À:N ˜d‹'|Šà]1¾AKckŒ'‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HDsM?l ŠbªåIEND®B`‚‰PNG


IHDR``¶jPLTEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿw€AÙtRNSK&“$¦˜W»IDATx^íÍAmCÁ/ÕL¡E†ðøS)„hN¹dï£}~±ƒ/ø{°‚Ÿê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒ¾HAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁ|¾oÿg¥2.2U¤IEND®B`‚‰PNG


IHDR``¶jPLTEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿw€AÙtRNSK“&…©¼IDATx^íÍAmCÁ/¹L¡*(ˆǟJ DsÊ%{íó‹}|Á߃ý#ø©ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :¨ªƒê :èû‚ÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäAÁäÁçûö¤A<®æ÷ì*IEND®B`‚‰PNG


IHDR``¶jPLTEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿw€AÙtRNSK“&…©¹IDATx^íÍ1CÁ/ù<
§P0€€0*Á0Ušl?Úçû:ø׃½üN§ƒÓÁéàtp:8œN§ƒÓÁéàtp:8äA† 2E!(‚AdŠ CP‚"ÈA† 2E!(‚AdŠ CP‚"ÈA† 2E!(‚AdŠ CP‚"ÈA† 2E!(‚AdŠàûýúhêØwÒ"'IEND®B`‚‰PNG


IHDR``ŸöŸ«PLTEÿÿÿÿÿÿÿÿÿ—NîtRNS€ÎGþ”IDATx^ÝÍ1À ÀÀÿº"5­]¤¥
ÎY3ܼèŠñ
Z[ã`<‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"‘ˆD$"‰HD"škúʧOßÉ:ôIEND®B`‚‰PNG


IHDR0:ö™ÚáŸIDATx^ݚMNÂPEÀʈ2îF\:s cE†8qà
JWƒ+€8`Ú5Ø6$þÄçý’gÒ
½ô]gáChéûÙۿ)™\Ì1ØòÎ`FÐåÙdy~YžA–çGåùdy~YžA–çGåùdy~YžA–çGåùdy~Mž±>`\ ÿÐo˜Kÿ¯	X攬hpbn­ß.œñO1x0Çø»€8ү‘•	˜k§p
œ£jÀL0`öƒwÁsîYÀ1p¢œX@&YÀT8`j÷Âð(PX3p|€üOHý"Îåo£òdòòsʏÓwÕù`Ày5 £8¥TžÔOvrYÅ\É/-Š/îê/¯ïþG•Õ7üÍ6Ýä;hèšX‚ú¶Y°ØòÝ&©{£»
®J(¾òc´™g%b‚²FñL@o›Çm"0ó
æsÿQÓGκàdàä ¯žäþµ̿·[ÇØ@þ+ͧØaIEND®B`‚‰PNG


IHDR00Wù‡{IDATx^ÕÙ=NA‡ñ)„¸ˆ¶˜è1<j%…5	˜`¡•Ðmà*ÂÜJ	WPY$j6;>…oc²
ìÆý¿~žd?ޙq'÷«<Ôp#¼à
ŸðEÚ&`=<#…ÏPº€=<`ovÐGlõJML¬Z-àïðŠ$ðŠ]«Th!Q
8B¯PÁ^5 ¯Ð@¬0€W
°V¸‚Wˆ”jH•ÚðÊ¡zÀH=`®°Tðºô¾Ô¡Wõ—x®þ}Rÿ‘…ê£ĥ# .:̥h(Óœò†æNuK¹F`f(0´u+«ÄhX€âÁÖ
\V@“LPÉ
0͒^h,qøw½*Çë	Zp©\pt³ÖYö+¦¸MÌÙ?½1Îᐩ¬׬SÃå`ª¸źàáU¸¼Ì>±Ê1à¢L€"¤ÎózàLqÙêh#Ä3,ðýkÆÑFn[?ÁôÆâ“IEND®B`‚‰PNG


IHDR00Wù‡qIDATx^ÕÚ?NÂ`‡ñ.å6’TWLô€à$‰Î$l`‚ƒN^ÀÊU„;Ð £„+(‰‰š¦úü†&]¥ |‡Ïžáýÿ:Ç7ӯ5{ÇžÐA€SìÂÉ+
؄=4±£õ†;øª©-¸ª©G)˜å£¦ª«Ä(+˜‡ÊfW9À\ªDð•L[=`O9À4Ôzê	|ås¦¨<¨ŒÔ&ÚPø°€‰p3ŒÔqG}
Ô²ªp9‘(oæL(ÂI‚Ù3Õ#eª­z¨Oùˆ¯U²ZŠ[Y.ú[Ї;/ðº…ÀY`ʈU®×RWyا†x۟˜©lhLD8“7þyvüå™õ·
¸ÂlÍ[„kà¬: µ‡[LWüÕàûË|5X–‡&B$KîçC4áåùì±
ET ‹!Æø„cˆ.TQ„“×7fîô߯őŽIEND®B`‚