1W 1a11&1^91kS1\1j111H1> 1"1&1)111e:1?>1\1k1v1|1511Փ11611111111|1[1" 11i1#1K+121%51q:18G1G>4I>WT>$_>d>e>fl>s>x>>>>o>>г>>>h>>#>4>>e>I > >l!_%_^_y_;zb&{bP~bib́b;bGbbb{b#bQbjbWbbܩbbbGb7bb=bbbb@b%h&h'h(h)h*hP%+h~&,h(-h).h*/hV+0h',1h,2hQ.3h/4hD15h26h47h;8h0<9h<:h=;h?h3C?hD@hEAhIBhMChmQDhREh*TFhUGhjHhIh JhXKhZPhϿQh3RhSh ThUhVhWhXhYhZhw[h\h]hu^h4chdhehVfhghhh)ihtjhkhlh_mhnhohnph6qh,rhOshsthuhvh~whxhyhzh{h|hf~hhhhu hzj)j7*j*j*j[+jd,je-j.j8/ju0j0j 2j\2j(3j3j4j\5j6 j7!j8"j9#j:$j;%j<&j='j.?(jH@)jA*jB+jC,jD-jF.j9H/j9J0j&L1jL2jM3jP4jS5j}V6jW7jX8jY9jZ:jo[;j\j[^?j^@j7_Aj_Bj>`Cj`DjaEj_aFjaGjaHj1bIjbJjbKj"cLjicMjcNjcOjdPj'eQjeRjfSjmfTjfUjGgVjgWjOhXjhYjhZjTi[ji\j;j]jj^j k_jfk`jkaj)lbjlcjldjmejInfjngjfohjoij=pjjpkjpljqmjjqnjqojrpjcrqjrrjrsjstjtujVuvjuwjvxjvyj2wzjw{jx|jx}jNy~jyjFzjzj]{j{j/|j|j|jG}j}j}jN~jjjj%jjjMjjjj|j jhjjjjrjjj=jמjjj.jljjTjjjjHjjjjsj jj|jjjDjj_j jujjjjj8jjjjjpjjcjj7jjj>jj8jjVj jvjjKj%j|jjjjj\j*jjEjjjzj j j@ j 

$i18n{message}

$i18n{message}

$i18n{message}

// Copyright 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 chrome; if (!chrome) chrome = {}; if (!chrome.embeddedSearch) { chrome.embeddedSearch = new function() { this.searchBox = new function() { // ======================================================================= // Private functions // ======================================================================= native function GetQuery(); native function GetSearchRequestParams(); native function GetRightToLeft(); native function GetSuggestionToPrefetch(); native function IsFocused(); native function IsKeyCaptureEnabled(); native function Paste(); native function StartCapturingKeyStrokes(); native function StopCapturingKeyStrokes(); // ======================================================================= // Exported functions // ======================================================================= this.__defineGetter__('isFocused', IsFocused); this.__defineGetter__('isKeyCaptureEnabled', IsKeyCaptureEnabled); this.__defineGetter__('rtl', GetRightToLeft); this.__defineGetter__('suggestion', GetSuggestionToPrefetch); this.__defineGetter__('value', GetQuery); Object.defineProperty(this, 'requestParams', { get: GetSearchRequestParams }); this.paste = function(value) { Paste(value); }; this.startCapturingKeyStrokes = function() { StartCapturingKeyStrokes(); }; this.stopCapturingKeyStrokes = function() { StopCapturingKeyStrokes(); }; this.onfocuschange = null; this.onkeycapturechange = null; this.onsubmit = null; this.onsuggestionchange = null; }; this.newTabPage = new function() { // ======================================================================= // Private functions // ======================================================================= native function CheckIsUserSignedInToChromeAs(); native function CheckIsUserSyncingHistory(); native function DeleteMostVisitedItem(); native function GetMostVisitedItemData(); native function GetMostVisitedItems(); native function GetThemeBackgroundInfo(); native function IsInputInProgress(); native function LogEvent(); native function LogMostVisitedImpression(); native function LogMostVisitedNavigation(); native function UndoAllMostVisitedDeletions(); native function UndoMostVisitedDeletion(); function GetMostVisitedItemsWrapper() { var mostVisitedItems = GetMostVisitedItems(); for (var i = 0, item; item = mostVisitedItems[i]; ++i) { item.faviconUrl = GenerateFaviconURL(item.renderViewId, item.rid); // These properties are private data and should not be returned to // the page. They are only accessible via getMostVisitedItemData(). delete item.url; delete item.title; delete item.domain; delete item.direction; delete item.renderViewId; delete item.largeIconUrl; delete item.fallbackIconUrl; } return mostVisitedItems; } function GenerateFaviconURL(renderViewId, rid) { return "chrome-search://favicon/size/16@" + window.devicePixelRatio + "x/" + renderViewId + "/" + rid; } // ======================================================================= // Exported functions // ======================================================================= this.__defineGetter__('isInputInProgress', IsInputInProgress); this.__defineGetter__('mostVisited', GetMostVisitedItemsWrapper); this.__defineGetter__('themeBackgroundInfo', GetThemeBackgroundInfo); this.checkIsUserSignedIntoChromeAs = function(identity) { CheckIsUserSignedInToChromeAs(identity); }; this.checkIsUserSyncingHistory = function() { CheckIsUserSyncingHistory(); }; this.deleteMostVisitedItem = function(restrictedId) { DeleteMostVisitedItem(restrictedId); }; // This method is restricted to chrome-search://most-visited pages by // checking the invoking context's origin in searchbox_extension.cc. this.getMostVisitedItemData = function(restrictedId) { var item = GetMostVisitedItemData(restrictedId); if (item) { var sizeInPx = Math.floor(48 * window.devicePixelRatio + 0.5); // Populate large icon and fallback icon data, if they exist. We'll // render everything here, once these become available by default. if (item.largeIconUrl) { item.largeIconUrl += sizeInPx + "/" + item.renderViewId + "/" + item.rid; } if (item.fallbackIconUrl) { item.fallbackIconUrl += sizeInPx + ",,,,/" + item.renderViewId + "/" + item.rid; } } return item; }; // This method is restricted to chrome-search://most-visited pages by // checking the invoking context's origin in searchbox_extension.cc. this.logEvent = function(histogram_name) { LogEvent(histogram_name); }; // This method is restricted to chrome-search://most-visited pages by // checking the invoking context's origin in searchbox_extension.cc. this.logMostVisitedImpression = function(position, provider) { LogMostVisitedImpression(position, provider); }; // This method is restricted to chrome-search://most-visited pages by // checking the invoking context's origin in searchbox_extension.cc. this.logMostVisitedNavigation = function(position, provider) { LogMostVisitedNavigation(position, provider); }; this.undoAllMostVisitedDeletions = function() { UndoAllMostVisitedDeletions(); }; this.undoMostVisitedDeletion = function(restrictedId) { UndoMostVisitedDeletion(restrictedId); }; this.onsignedincheckdone = null; this.onhistorysynccheckdone = null; this.oninputcancel = null; this.oninputstart = null; this.onmostvisitedchange = null; this.onthemechange = null; }; // TODO(jered): Remove when google no longer expects this object. chrome.searchBox = this.searchBox; }; } // 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 GetAvailability = requireNative('v8_context').GetAvailability; if (!GetAvailability('app').is_available) { exports.$set('binding', {}); exports.$set('onInstallStateResponse', function(){}); return; } 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. app.__defineGetter__('isInstalled', wrapForLogging(appNatives.GetIsInstalled)); // 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 = {}; var nextCallbackId = 1; app.installState = function getInstallState(callback) { var callbackId = nextCallbackId++; callbacks[callbackId] = callback; appNatives.GetInstallState(callbackId); }; if (extensionId) app.installState = wrapForLogging(app.installState); 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 = require('binding').Binding.create('automation'); var automationInternal = require('binding').Binding.create('automationInternal').generate(); var eventBindings = require('event_bindings'); var Event = eventBindings.Event; var exceptionHandler = require('uncaught_exception_handler'); var forEach = require('utils').forEach; var lastError = require('lastError'); var logging = requireNative('logging'); var nativeAutomationInternal = requireNative('automationInternal'); var GetRoutingID = nativeAutomationInternal.GetRoutingID; var GetSchemaAdditions = nativeAutomationInternal.GetSchemaAdditions; 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 schema = GetSchemaAdditions(); /** * 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} */ 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) { var routingID = GetRoutingID(); 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 = { routingID: routingID, tabID: tabID }; automationInternal.enableTab(params, function onEnable(id) { if (lastError.hasError(chrome)) { 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]; var routingID = GetRoutingID(); // TODO(dtseng): Disable desktop tree once desktop object goes out of // scope. automationInternal.enableDesktop(routingID, function() { if (lastError.hasError(chrome)) { 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 == schema.EventType.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( schema.EventType.loadComplete, 'page'); } privates(node).impl.dispatchEvent( schema.EventType.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); var isFocusEvent = false; if (eventParams.eventType == schema.EventType.focus) { isFocusEvent = true; } else if (eventParams.eventType == schema.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 == schema.EventType.mediaStartedPlaying || eventParams.eventType == schema.EventType.mediaStoppedPlaying) { // These events are global to the tree. eventParams.targetID = privates(targetTree).impl.id; } // When we get a focus event, ignore the actual event target, and instead // check what node has focus globally. If that represents a focus change, // fire a focus event on the correct target. if (isFocusEvent) { var previousFocusedNode = automationUtil.focusedNode; automationUtil.updateFocusedNode(); if (automationUtil.focusedNode && automationUtil.focusedNode == previousFocusedNode) { return; } if (automationUtil.focusedNode) { targetTree = automationUtil.focusedNode.root; eventParams.treeID = privates(targetTree).impl.treeID; eventParams.targetID = privates(automationUtil.focusedNode).impl.id; } } if (!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); }); var binding = automation.generate(); // Add additional accessibility bindings not specified in the automation IDL. // Accessibility and automation share some APIs (see // ui/accessibility/ax_enums.idl). forEach(schema, function(k, v) { binding[k] = v; }); exports.$set('binding', binding); // 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 = require('binding').Binding.create('automationInternal').generate(); var exceptionHandler = require('uncaught_exception_handler'); var IsInteractPermitted = requireNative('automationInternal').IsInteractPermitted; /** * @param {number} axTreeID The id of the accessibility tree. * @return {?number} The id of the root node. */ var GetRootID = requireNative('automationInternal').GetRootID; /** * @param {number} axTreeID The id of the accessibility tree. * @return {?string} The title of the document. */ var GetDocTitle = requireNative('automationInternal').GetDocTitle; /** * @param {number} axTreeID The id of the accessibility tree. * @return {?string} The url of the document. */ var GetDocURL = requireNative('automationInternal').GetDocURL; /** * @param {number} axTreeID The id of the accessibility tree. * @return {?boolean} True if the document has finished loading. */ var GetDocLoaded = requireNative('automationInternal').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 = requireNative('automationInternal').GetDocLoadingProgress; /** * @param {number} axTreeID The id of the accessibility tree. * @return {?number} The ID of the selection anchor object. */ var GetAnchorObjectID = requireNative('automationInternal').GetAnchorObjectID; /** * @param {number} axTreeID The id of the accessibility tree. * @return {?number} The selection anchor offset. */ var GetAnchorOffset = requireNative('automationInternal').GetAnchorOffset; /** * @param {number} axTreeID The id of the accessibility tree. * @return {?string} The selection anchor affinity. */ var GetAnchorAffinity = requireNative('automationInternal').GetAnchorAffinity; /** * @param {number} axTreeID The id of the accessibility tree. * @return {?number} The ID of the selection focus object. */ var GetFocusObjectID = requireNative('automationInternal').GetFocusObjectID; /** * @param {number} axTreeID The id of the accessibility tree. * @return {?number} The selection focus offset. */ var GetFocusOffset = requireNative('automationInternal').GetFocusOffset; /** * @param {number} axTreeID The id of the accessibility tree. * @return {?string} The selection focus affinity. */ var GetFocusAffinity = requireNative('automationInternal').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 = requireNative('automationInternal').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 = requireNative('automationInternal').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 = requireNative('automationInternal').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 = requireNative('automationInternal').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 = requireNative('automationInternal').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 = requireNative('automationInternal').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 = requireNative('automationInternal').GetState; /** * @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 = requireNative('automationInternal').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 = requireNative('automationInternal').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 = requireNative('automationInternal').GetBoundsForRange; /** * @param {number} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {!Array.} 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 = requireNative('automationInternal').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 = requireNative('automationInternal').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 = requireNative('automationInternal').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 = requireNative('automationInternal').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.} The value of this attribute, or undefined * if the tree, node, or attribute wasn't found. */ var GetIntListAttribute = requireNative('automationInternal').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 = requireNative('automationInternal').GetHtmlAttribute; var lastError = require('lastError'); var logging = requireNative('logging'); var schema = requireNative('automationInternal').GetSchemaAdditions(); 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 location() { return GetLocation(this.treeID, this.id); }, boundsForRange: function(startIndex, endIndex) { return GetBoundsForRange(this.treeID, this.id, startIndex, endIndex); }, 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)); }, doDefault: function() { this.performAction_('doDefault'); }, focus: function() { this.performAction_('focus'); }, getImageData: function(maxWidth, maxHeight) { this.performAction_('getImageData', { maxWidth: maxWidth, maxHeight: maxHeight }); }, makeVisible: function() { this.performAction_('makeVisible'); }, resumeMedia: function() { this.performAction_('resumeMedia'); }, setSelection: function(startIndex, endIndex) { if (this.role == 'textField' || this.role == 'textBox') { 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) { 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.'); } automationInternal.performAction({ treeID: this.rootImpl.treeID, automationNodeID: this.id, actionType: actionType }, 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', 'action', 'ariaInvalidValue', 'autoComplete', 'containerLiveRelevant', 'containerLiveStatus', 'description', 'display', 'dropeffect', 'help', 'htmlTag', 'imageDataUrl', 'language', 'liveRelevant', 'liveStatus', 'name', 'placeholder', 'shortcut', 'textInputType', 'url', 'value']; var boolAttributes = [ 'ariaReadonly', 'buttonMixed', 'canSetValue', 'canvasHasFallback', 'containerLiveAtomic', 'containerLiveBusy', 'grabbed', 'isAxTreeHost', 'liveAtomic', 'liveBusy', 'updateLocationOnly']; var intAttributes = [ 'backgroundColor', 'color', 'colorValue', 'descriptionFrom', 'hierarchicalLevel', 'invalidState', 'nameFrom', 'posInSet', 'scrollX', 'scrollXMax', 'scrollXMin', 'scrollY', 'scrollYMax', 'scrollYMin', 'setSize', 'sortDirection', 'tableCellColumnIndex', 'tableCellColumnSpan', 'tableCellRowIndex', 'tableCellRowSpan', 'tableColumnCount', 'tableColumnIndex', 'tableRowCount', 'tableRowIndex', 'textDirection', 'textSelEnd', 'textSelStart', 'textStyle']; var nodeRefAttributes = [ ['activedescendantId', 'activeDescendant'], ['nextOnLineId', 'nextOnLine'], ['previousOnLineId', 'previousOnLine'], ['tableColumnHeaderId', 'tableColumnHeader'], ['tableHeaderId', 'tableHeader'], ['tableRowHeaderId', 'tableRowHeader'], ['titleUiElement', 'titleUIElement']]; var intListAttributes = [ 'characterOffsets', 'lineBreaks', 'markerEnds', 'markerStarts', 'markerTypes', 'wordEnds', 'wordStarts']; var nodeRefListAttributes = [ ['cellIds', 'cells'], ['controlsIds', 'controls'], ['describedbyIds', 'describedBy'], ['flowtoIds', 'flowTo'], ['labelledbyIds', 'labelledBy'], ['uniqueCellIds', 'uniqueCells']]; var floatAttributes = [ 'valueForRange', 'minValueForRange', 'maxValueForRange', 'fontSize']; 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}; } 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.} * @private */ axNodeDataCache_: 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(schema.EventType.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); } else { logging.WARNING('Got ' + eventParams.eventType + ' event on unknown node: ' + eventParams.targetID + '; this: ' + this.id); } return true; }, 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', 'makeVisible', 'matches', 'resumeMedia', 'setSelection', 'setSequentialFocusNavigationStartingPoint', 'showContextMenu', 'startDuckingMedia', 'stopDuckingMedia', 'suspendMedia', 'addEventListener', 'removeEventListener', 'domQuerySelector', 'toString', 'boundsForRange', ], readonly: $Array.concat(publicAttributes, [ 'parent', 'firstChild', 'lastChild', 'children', 'previousSibling', 'nextSibling', 'isRootNode', 'role', 'state', 'location', 'indexInParent', 'lineStartOffsets', 'root', 'htmlAttributes', ]), }); 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 = require('binding').Binding.create('browserAction'); var setIcon = require('setIcon').setIcon; var getExtensionViews = requireNative('runtime').GetExtensionViews; var sendRequest = require('sendRequest').sendRequest; var lastError = require('lastError'); binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('setIcon', function(details, callback) { setIcon(details, function(args) { sendRequest(this.name, [args, callback], this.definition.parameters); }.bind(this)); }); apiFunctions.setCustomCallback('openPopup', function(name, request, callback, response) { if (!callback) return; if (lastError.hasError(chrome)) { callback(); } else { var views = getExtensionViews(-1, -1, 'POPUP'); callback(views.length > 0 ? views[0] : null); } }); }); 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 = 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); }); }); 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 = 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); }); }); 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 = 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); }); }); 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 = 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); }); }); 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. var Event = require('event_bindings').Event; var sendRequest = require('sendRequest').sendRequest; var validate = require('schemaUtils').validate; function extendSchema(schema) { var extendedSchema = $Array.slice(schema); extendedSchema.unshift({'type': 'string'}); return extendedSchema; } function ChromeDirectSetting(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.private.ChromeDirectSetting.get', [prefKey, details, callback], extendSchema(getSchema)); }; this.set = function(details, callback) { var setSchema = $Array.slice(getFunctionParameters('set')); setSchema[0].properties.value = valueSchema; validate([details, callback], setSchema); return sendRequest('types.private.ChromeDirectSetting.set', [prefKey, details, callback], extendSchema(setSchema)); }; this.clear = function(details, callback) { var clearSchema = getFunctionParameters('clear'); validate([details, callback], clearSchema); return sendRequest('types.private.ChromeDirectSetting.clear', [prefKey, details, callback], extendSchema(clearSchema)); }; this.onChange = new Event('types.private.ChromeDirectSetting.' + prefKey + '.onChange'); }; exports.$set('ChromeDirectSetting', ChromeDirectSetting); // 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 = 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.setCustomCallback('contextMenusCreate', handlers.callbacks.create); apiFunctions.setCustomCallback('contextMenusUpdate', handlers.callbacks.update); apiFunctions.setCustomCallback('contextMenusRemove', handlers.callbacks.remove); apiFunctions.setCustomCallback('contextMenusRemoveAll', handlers.callbacks.removeAll); }); 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 API. // See web_view_api_methods.js for details. var ChromeWebView = require('chromeWebViewInternal').ChromeWebView; var ChromeWebViewSchema = requireNative('schema_registry').GetSchema('chromeWebViewInternal'); var CreateEvent = require('guestViewEvents').CreateEvent; var EventBindings = require('event_bindings'); 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 , we define events with suffix // (subEventName) in each of the . 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 // .contextMenus.onClicked behave as a regular chrome Event type. var ContextMenusEvent = CreateEvent('chromeWebViewInternal.onClicked'); // See comment above. var ContextMenusHandlerEvent = CreateEvent('chromeWebViewInternal.onContextMenuShow'); // ----------------------------------------------------------------------------- // ContextMenusOnClickedEvent object. // This event is exposed as .contextMenus.onClicked. function ContextMenusOnClickedEvent(webViewInstanceId, opt_eventName, opt_argSchemas, opt_eventOptions) { var subEventName = GetUniqueSubEventName(opt_eventName); $Function.call(EventBindings.Event, this, subEventName, opt_argSchemas, opt_eventOptions, webViewInstanceId); var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId); if (!view) { return; } view.events.addScopedListener(ContextMenusEvent, function() { // Re-dispatch to subEvent's listeners. $Function.apply(this.dispatch, this, $Array.slice(arguments)); }.bind(this), {instanceId: webViewInstanceId}); } $Object.setPrototypeOf(ContextMenusOnClickedEvent.prototype, EventBindings.Event.prototype); // This event is exposed as .contextMenus.onShow. function ContextMenusOnContextMenuEvent(webViewInstanceId, opt_eventName, opt_argSchemas, opt_eventOptions) { var subEventName = GetUniqueSubEventName(opt_eventName); $Function.call(EventBindings.Event, this, subEventName, opt_argSchemas, opt_eventOptions, webViewInstanceId); var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId); if (!view) { return; } view.events.addScopedListener(ContextMenusHandlerEvent, function(e) { var defaultPrevented = false; var event = { 'preventDefault': function() { defaultPrevented = true; } }; // Re-dispatch to subEvent's listeners. $Function.apply(this.dispatch, this, [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); } }.bind(this), {instanceId: webViewInstanceId}); } $Object.setPrototypeOf(ContextMenusOnContextMenuEvent.prototype, EventBindings.Event.prototype); // ----------------------------------------------------------------------------- // WebViewContextMenusImpl object. // An instance of this class is exposed as .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}; this.contextMenusOnContextMenuEvent_ = new ContextMenusOnContextMenuEvent( this.viewInstanceId, eventName, eventSchema, eventOptions); } var createContextMenus = 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() { return this.weakWrapper(function() { if (!this.contextMenusOnClickedEvent_) { var eventName = 'chromeWebViewInternal.onClicked'; var eventSchema = utils.lookup(ChromeWebViewSchema.events, 'name', 'onClicked'); var eventOptions = {supportsListeners: true}; var onClickedEvent = new ContextMenusOnClickedEvent( this.viewInstanceId, eventName, eventSchema, eventOptions); this.contextMenusOnClickedEvent_ = onClickedEvent; return onClickedEvent; } return this.contextMenusOnClickedEvent_; }); }.bind(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_; }); }.bind(this); // Expose .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) { // 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], rawSetSchema); if ($Object.hasOwnProperty(DEPRECATED_CONTENT_TYPES, contentType)) { console.warn('contentSettings.' + contentType + ' is deprecated; setting ' + 'it has no effect.'); $Function.apply(callback, undefined, []); return; } 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 = require('binding').Binding.create('declarativeContent'); 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; // 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 declarativeContent.SetIcon = function(parameters) { setIcon(parameters, function (data) { setupInstance(this, data, 'SetIcon'); }.bind(this)); }; }); 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 = require('binding').Binding.create('desktopCapture'); var sendRequest = 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(this.name, [id, sources, target_tab, onRequestResult.bind(null, id)], this.definition.parameters); return id; }); apiFunctions.setHandleRequest('cancelChooseDesktopMedia', function(id) { if (id in pendingRequests) { delete pendingRequests[id]; sendRequest(this.name, [id], this.definition.parameters); } }); }); 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 = 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); }); }); 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 = require('binding').Binding.create('downloads'); var downloadsInternal = require('binding').Binding.create( 'downloadsInternal').generate(); var eventBindings = require('event_bindings'); eventBindings.registerArgumentMassager( 'downloads.onDeterminingFilename', function massage_determining_filename(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; } }); 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 feedbackPrivate API. var binding = 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]; }); }); 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. var fileSystemNatives = requireNative('file_system_natives'); var GetIsolatedFileSystem = fileSystemNatives.GetIsolatedFileSystem; var sendRequest = require('sendRequest'); var lastError = require('lastError'); var GetModuleSystem = requireNative('v8_context').GetModuleSystem; // TODO(sammc): Don't require extension. See http://crbug.com/235689. var GetExtensionViews = requireNative('runtime').GetExtensionViews; // For a given |apiName|, generates object with two elements that are used // in file system relayed APIs: // * 'bindFileEntryCallback' function that provides mapping between JS objects // into actual FileEntry|DirectoryEntry objects. // * 'entryIdManager' object that implements methods for keeping the tracks of // previously saved file entries. function getFileBindingsForApi(apiName) { // Fallback to using the current window if no background page is running. var backgroundPage = GetExtensionViews(-1, -1, 'BACKGROUND')[0] || window; var backgroundPageModuleSystem = GetModuleSystem(backgroundPage); // All windows use the bindFileEntryCallback from the background page so their // FileEntry objects have the background page's context as their own. This // allows them to be used from other windows (including the background page) // after the original window is closed. if (window == backgroundPage) { var bindFileEntryCallback = function(functionName, apiFunctions) { apiFunctions.setCustomCallback(functionName, function(name, request, callback, response) { if (callback) { if (!response) { callback(); return; } var entries = []; var hasError = false; var getEntryError = function(fileError) { if (!hasError) { hasError = true; lastError.run( apiName + '.' + functionName, 'Error getting fileEntry, code: ' + fileError.code, request.stack, callback); } } // Loop through the response entries and asynchronously get the // FileEntry for each. We use hasError to ensure that only the first // error is reported. Note that an error can occur either during the // loop or in the asynchronous error callback to getFile. $Array.forEach(response.entries, function(entry) { if (hasError) return; var fileSystemId = entry.fileSystemId; var baseName = entry.baseName; var id = entry.id; var fs = GetIsolatedFileSystem(fileSystemId); try { var getEntryCallback = function(fileEntry) { if (hasError) return; entryIdManager.registerEntry(id, fileEntry); entries.push(fileEntry); // Once all entries are ready, pass them to the callback. In the // event of an error, this condition will never be satisfied so // the callback will not be called with any entries. if (entries.length == response.entries.length) { if (response.multiple) { sendRequest.safeCallbackApply( apiName + '.' + functionName, request, callback, [entries]); } else { sendRequest.safeCallbackApply( apiName + '.' + functionName, request, callback, [entries[0]]); } } } // TODO(koz): fs.root.getFile() makes a trip to the browser // process, but it might be possible avoid that by calling // WebDOMFileSystem::createV8Entry(). if (entry.isDirectory) { fs.root.getDirectory(baseName, {}, getEntryCallback, getEntryError); } else { fs.root.getFile(baseName, {}, getEntryCallback, getEntryError); } } catch (e) { if (!hasError) { hasError = true; lastError.run(apiName + '.' + functionName, 'Error getting fileEntry: ' + e.stack, request.stack, callback); } } }); } }); }; var entryIdManager = require('entryIdManager'); } else { // Force the fileSystem API to be loaded in the background page. Using // backgroundPageModuleSystem.require('fileSystem') is insufficient as // requireNative is only allowed while lazily loading an API. backgroundPage.chrome.fileSystem; var bindFileEntryCallback = backgroundPageModuleSystem.require( apiName).bindFileEntryCallback; var entryIdManager = backgroundPageModuleSystem.require('entryIdManager'); } return {bindFileEntryCallback: bindFileEntryCallback, entryIdManager: entryIdManager}; } exports.$set('getFileBindingsForApi', getFileBindingsForApi); // 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 fileSystem API. var binding = require('binding').Binding.create('fileSystem'); var sendRequest = require('sendRequest'); var getFileBindingsForApi = require('fileEntryBindingUtil').getFileBindingsForApi; var fileBindings = getFileBindingsForApi('fileSystem'); var bindFileEntryCallback = fileBindings.bindFileEntryCallback; var entryIdManager = fileBindings.entryIdManager; var fileSystemNatives = requireNative('file_system_natives'); binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; var fileSystem = bindingsAPI.compiledApi; function bindFileEntryFunction(functionName) { apiFunctions.setUpdateArgumentsPostValidate( functionName, function(fileEntry, callback) { var fileSystemName = fileEntry.filesystem.name; var relativePath = $String.slice(fileEntry.fullPath, 1); return [fileSystemName, relativePath, callback]; }); } $Array.forEach(['getDisplayPath', 'getWritableEntry', 'isWritableEntry'], bindFileEntryFunction); $Array.forEach(['getWritableEntry', 'chooseEntry', 'restoreEntry'], function(functionName) { bindFileEntryCallback(functionName, apiFunctions); }); apiFunctions.setHandleRequest('retainEntry', function(fileEntry) { var id = entryIdManager.getEntryId(fileEntry); if (!id) return ''; var fileSystemName = fileEntry.filesystem.name; var relativePath = $String.slice(fileEntry.fullPath, 1); sendRequest.sendRequest(this.name, [id, fileSystemName, relativePath], this.definition.parameters); return id; }); apiFunctions.setHandleRequest('isRestorable', function(id, callback) { var savedEntry = entryIdManager.getEntryById(id); if (savedEntry) { sendRequest.safeCallbackApply( 'fileSystem.isRestorable', {}, callback, [true]); } else { sendRequest.sendRequest( this.name, [id, callback], this.definition.parameters); } }); apiFunctions.setUpdateArgumentsPostValidate('restoreEntry', function(id, callback) { var savedEntry = entryIdManager.getEntryById(id); if (savedEntry) { // We already have a file entry for this id so pass it to the callback and // send a request to the browser to move it to the back of the LRU. sendRequest.safeCallbackApply( 'fileSystem.restoreEntry', {}, callback, [savedEntry]); return [id, false, null]; } else { // Ask the browser process for a new file entry for this id, to be passed // to |callback|. return [id, true, callback]; } }); apiFunctions.setCustomCallback('requestFileSystem', function(name, request, callback, response) { var fileSystem; if (response && response.file_system_id) { fileSystem = fileSystemNatives.GetIsolatedFileSystem( response.file_system_id, response.file_system_path); } sendRequest.safeCallbackApply( 'fileSystem.requestFileSystem', request, callback, [fileSystem]); }); // TODO(benwells): Remove these deprecated versions of the functions. fileSystem.getWritableFileEntry = function() { console.log("chrome.fileSystem.getWritableFileEntry is deprecated"); console.log("Please use chrome.fileSystem.getWritableEntry instead"); $Function.apply(fileSystem.getWritableEntry, this, arguments); }; fileSystem.isWritableFileEntry = function() { console.log("chrome.fileSystem.isWritableFileEntry is deprecated"); console.log("Please use chrome.fileSystem.isWritableEntry instead"); $Function.apply(fileSystem.isWritableEntry, this, arguments); }; fileSystem.chooseFile = function() { console.log("chrome.fileSystem.chooseFile is deprecated"); console.log("Please use chrome.fileSystem.chooseEntry instead"); $Function.apply(fileSystem.chooseEntry, this, arguments); }; }); exports.$set('bindFileEntryCallback', bindFileEntryCallback); 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 = 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; }); }); 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 = 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; }); }); 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 = 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]; }); }); 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 = require('binding').Binding.create('input.ime'); var Event = require('event_bindings').Event; var appWindowNatives = requireNative('app_window_natives'); binding.registerCustomHook(function(api) { var input_ime = api.compiledApi; input_ime.onKeyEvent.dispatchToListener = function(callback, args) { var engineID = args[0]; var keyData = args[1]; var result = false; try { result = $Function.call(Event.prototype.dispatchToListener, this, callback, args); } catch (e) { console.error('Error in event handler for onKeyEvent: ' + e.stack); } if (!input_ime.onKeyEvent.async) { input_ime.keyEventHandled(keyData.requestId, result); } }; input_ime.onKeyEvent.addListener = function(cb, opt_extraInfo) { input_ime.onKeyEvent.async = false; if (opt_extraInfo instanceof Array) { for (var i = 0; i < opt_extraInfo.length; ++i) { if (opt_extraInfo[i] == "async") { input_ime.onKeyEvent.async = true; } } } $Function.call(Event.prototype.addListener, 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); }); }); 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 logPrivate API. var binding = require('binding').Binding.create('logPrivate'); var getFileBindingsForApi = require('fileEntryBindingUtil').getFileBindingsForApi; var fileBindings = getFileBindingsForApi('logPrivate'); var bindFileEntryCallback = fileBindings.bindFileEntryCallback; binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; $Array.forEach(['dumpLogs'], function(functionName) { bindFileEntryCallback(functionName, apiFunctions); }); }); exports.$set('bindFileEntryCallback', bindFileEntryCallback); 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 = require('binding').Binding.create('mediaGalleries'); var blobNatives = requireNative('blob_natives'); var mediaGalleriesNatives = requireNative('mediaGalleries'); 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, }; }); apiFunctions.setUpdateArgumentsPostValidate('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; return [blobUuid, options, callback]; }); apiFunctions.setCustomCallback('getMetadata', function(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); // The UUID was in position 0 in the setUpdateArgumentsPostValidate // function. var uuid = request.args[0]; delete blobsAwaitingMetadata[uuid]; }); }); 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 = require('binding').Binding.create('notifications'); var sendRequest = require('sendRequest').sendRequest; var exceptionHandler = require('uncaught_exception_handler'); var imageUtil = require('imageUtil'); var lastError = require('lastError'); var notificationsPrivate = requireNative('notifications_private'); 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(that.name, [id, notification_details, callback], that.definition.parameters, {__proto__: null, stack: stack}); return; } lastError.run(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); 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 = require('binding').Binding.create('omnibox'); var eventBindings = require('event_bindings'); var sendRequest = 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, world!'. So we wrap the // provided text in generated root level element. var root = domParser.parseFromString( '' + input + '', '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(this.name, [parseResult], this.definition.parameters); }); 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; $Array.push(suggestions, parseResult); } return [requestId, suggestions]; }); }); eventBindings.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]); }); 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 = require('binding').Binding.create('pageAction'); var setIcon = require('setIcon').setIcon; var sendRequest = require('sendRequest').sendRequest; binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('setIcon', function(details, callback) { setIcon(details, function(args) { sendRequest(this.name, [args, callback], this.definition.parameters); }.bind(this)); }); }); 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 = 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); } }); }); 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 = require('binding').Binding.create('syncFileSystem'); var eventBindings = require('event_bindings'); 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); }); }); eventBindings.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]); }); 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 = require('binding').Binding.create('systemIndicator'); var setIcon = require('setIcon').setIcon; var sendRequest = require('sendRequest').sendRequest; binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('setIcon', function(details, callback) { setIcon(details, function(args) { sendRequest(this.name, [args, callback], this.definition.parameters); }.bind(this)); }); }); 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 = require('binding').Binding.create('tabCapture'); var lastError = require('lastError'); 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) { lastError.run( name, getErrorMessage(error, "Failed to start MediaStream."), request.stack, function() { callback(null); }); }); } catch (error) { lastError.run(name, getErrorMessage(error, "Invalid argument(s)."), request.stack, function() { callback(null); }); } } apiFunctions.setCustomCallback('capture', proxyToGetUserMedia); apiFunctions.setCustomCallback('captureOffscreenTab', proxyToGetUserMedia); }); 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 = require('binding').Binding.create('tts'); var idGenerator = requireNative('id_generator'); var sendRequest = 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 = 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(this.name, args, this.definition.parameters); return id; }); }); 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 = require('binding').Binding.create('ttsEngine'); var eventBindings = require('event_bindings'); eventBindings.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]); }); 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 = require('binding').Binding.create('webrtcDesktopCapturePrivate'); var sendRequest = 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(this.name, [id, sources, request, onRequestResult.bind(null, id)], this.definition.parameters); return id; }); apiFunctions.setHandleRequest('cancelChooseDesktopMedia', function(id) { if (id in pendingRequests) { delete pendingRequests[id]; sendRequest(this.name, [id], this.definition.parameters); } }); }); 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 Event = require('event_bindings').Event; function Installer() { this._pendingInstall = null; this.onInstallStageChanged = new Event(null, [{name: 'stage', type: 'string'}], {unmanaged: true}); this.onDownloadProgress = new Event(null, [{name: 'progress', type: 'number'}], {unmanaged: true}); } Installer.prototype.install = function(url, onSuccess, onFailure) { if (this._pendingInstall) throw new Error('A Chrome Web Store installation is already pending.'); 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( this.onInstallStageChanged.hasListeners(), this.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) { this.onInstallStageChanged.dispatch(installStage); }; Installer.prototype.onDownloadProgress = function(progress) { this.onDownloadProgress.dispatch(progress); }; var installer = new Installer(); var chromeWebstore = { install: function (url, onSuccess, onFailure) { installer.install(url, onSuccess, onFailure); }, onInstallStageChanged: installer.onInstallStageChanged, onDownloadProgress: installer.onDownloadProgress }; exports.$set('binding', chromeWebstore); // Called by webstore_bindings.cc. exports.onInstallResponse = Installer.prototype.onInstallResponse.bind(installer); exports.onInstallStageChanged = Installer.prototype.onInstallStageChanged.bind(installer); exports.onDownloadProgress = Installer.prototype.onDownloadProgress.bind(installer); PNG  IHDRTTaR PLTEtRNS@f`IDATx^1 0a%˒SdZD (ozm;Ǝ⮙zYE;CQ!bWàۚVU`]-j^қ&j5ʄ< j7)(rJe)IBK(AJnr.RC2$2GCRNUy 0׃C Z%h;o>8ܪ+VMIENDB`PNG  IHDR@(NsRGB IDAThZyp 9!#!ܗ - (2Жک "GBi@#L8C ȝ9v͢7ݳb[Pgx`0n:zoo']a>}(bXjh0*H:w_L0헃bysZQq8HNr0/gKyUTTUOͧ҈h_ʒy簚5Sjٕ4mzR(>O.S1>t`̇62,a0r 'Q lBiҮmh%2JoZ _qIi9ߕo9FՏR(7 M/UGz҄^{Jk #XP_Q2AON)1ĺ;S|Ÿhay*m^Fni*@*cR?[9@'i>)BBw{" \&oHd|@+~EzȢn^ R'0`wF!(J$LFea c:,Q Kbv; b}F@r/+D< 65j㊖_`Hz$,kNfh1:_32oxsy%:޷&!s{OFmjG:vY_pw*P\Ug *";xzòYvT$ACPG|wlP[/Z5G41cvly?RJ`[e؛#aQєRpHF)|U Łj#vEīa.|8w_)}2ݜ'2UT1kD؄^ 7ۍMx7x202C1j}% /WjVoZ(#Q>ىChM-np߯8Ϸ(k}9«5j[yy:/D9X P -Fjj ޑpLZȮtr[9T6~L}8)].zjM4ccXDaG=4қ2#֞V[:$(]7 PX'K Q.UH 漠@k5= %<1DKX,:O*R@JQ'֓y%.QN9 y9UۡROKGEЍZZwOGܸ*7v\$ %*2mcrR^OR(7*a@E;KxlYNu?ԝtlN!%.($䔋HQtfX?y$H?WX&JHT1ؗ5OG ]Π` YdcqRDic"D1+Jòa[A g(poAv ϵ3!Gjc:(.@-1\((c΢uчy+7`/٥5hш. MZfa9jEdc(B]Qis$hџz%"SɸvLNcݐBvDGڰ]MZ[]w<]ښ ڵ[*+(;:؃V .ۜnIENDB`PNG  IHDR@(NsRGB IDAThZ{xMWA"!WiHh2SA$ A=2FèiU~D~UM zţꑐw"!o&睵NzNNJBoz} WZ[n30e֭[966VJu~Y$Wccc֊+u>033[oll KKKkQRR'O@P%g9yYV]|ރ˰\AȏjRja3cV=7k]6]QPZ%1ϡYv7k]^T(1^u7Ҧ"PNbSkW+ l b.dH :aR[lkܴAiTz4ҴQTW?c0?uy>oJoΤ!RR\=s5S`31f\Չ[Ss+[V}9XP4N xSXCo3MN*؏?%[֒ttT?WXȧ~'ޥ_.(P%mx6J@5i@F bθv Mg%%801xZSP%)D>6N&򩴊. }] e*QxFuΟ$,H)V&z%ϡ?a`hd(N+\q =>abnNfϙ:L[7ghyBl8y^*i>֯Ǿ1O)[> Gbk JKKգGAՊ D~kvNo)K7I=weee]ɛrptt$mƞݻ1 pvv+Wacg7n ldX쉳qqհVWU!''>ȑ#zI???X|R޽@D 'W*;}oLB2Y^A~?{III6}_η& !777 --׮^%!kefcw X\mV ## X6yeBog|}cP)U {{{aB/W t#(SD߀[no233T()L-;1* >>CѽGw\|#f q!ViiiХqaC,]L=Wc׾\uCmm-/9173 < dy,荴0'B#$9 y,p]2<g T*!2y#ֵC.׿,/:1!(۷m'SG?!?CbR"X_}55XfP,\E\X2!8Hh!+,Yw߁ ?vaIȤI¸O֬Sv*>DB|hu(ZY[SMǵ+ר/ooLD~pruFԩrpoM+FQZ34_mr:ӡgSM0G+(1VVVCt?a<ݽ+АP|@)JNq__{YÚxe,ĉtFڴQTWhT#)P>/,,\,R2233`Gi%MЭkFځ4FcϞSG[>:zK,ݻ?+.3Z S;n NxڝwLPԙ!kI)C$ʲy#7/OH /3q(.~,T{zr4R|0Ȱ2'UEEE("xŋQJU+U[7o[rr޹ Oo^д-n%OA +dlyE",8 WJJ 0i{v So6o܄=v3mZzƎץ׬Z-0d /?͞_~ r8xЯ4!W 3F1NI*|tL2~HLHiu?~8 8wDWwJѵϨ~q=7i捛K٬foYQ=J uTȚi2g f oW泆=sʕ ZUXW#qeJ^,f*0~*=zJtԮS;4kԘՎ/%XC1 (*dOi,}aZ䃸>xH:wAJYs^"Ъy 17x@ehM P0Lp\ }ӦS ɘZ0Q m`,E _~fHW._f+_ jר NDйCo )T:kA8F 1cXӚ_p*5˘JʳClٴjҋkx>HJQ#K4!YCEj3wl.s(1$5.m/;Q[? <(N,yI^Y1Axϧ)Jh~ o779^1TH(40ȋ  C'B#hԇZ)tC?;S{V+tZ-Sϯ[\8nZt4AF]KdB>\I!MkCYpFg.Dފ+췖!Cmɇ`.8c_"S3~?Heá I[Uags;+Xi)* ncORw}Ctx0u]76y{Ga<=> jy2OxeiIENDB`PNG  IHDR@(k5IDATx^ձ 0aN!IJWQuP7hk{o_e>Ƕі*ZQ(6y o7 hM?@~]vMdM@\g.RڢzIENDB`PNG  IHDR@(NIDATxt]k۶Im۶m۶۵&mH6ܗSod$=3 RD&- _CHJL37 DΞ ?ׯ_񯋜=g M.8< A|%rs2s'wtzUCQq|F\Fqf(8g:!dG&4j@:: ڴ6B(K!f0E)6 [A{Tq`QIN;gϢ,y{Qa>C:hzXK@NTы0@ vnRTKG\% 4i'N{rjrwhYqfQr@]KPпNHcsVz8BQ5$#P@ OT(s@`hۯF@t@'PrjXݘw 82 r{耶'.d#P"2"$H0!y[|TPN48Tp):F@2R,jN' `@(H!ȹr8Ѓ8`!TP;:S5( #p@l!BF@@['I Th4ԆYΰkΕ`3 Z@2@e1܃dKUVu | A#^`Y3^N{;`e'iGdt!b ߃qd~ Jtv=ރbhy'̬A]FNpZ D%J̲*`{Zu1P !H-B$A>6FB-PN-34 4aZgz sH5 .(Uy5/Bd$}HEDZ "?~QzF:H91|T~((ZIZlMan"-nO% ,RS*0-}-h}}T x7ɀU-Xo~ hc( s "Z8篸4'͟ 9[["k}L<*+NJ'qF'Yip!^3CN>hEhnÇ$PC -Ew\Zjv܁Fސ(?zN7ЂyNoLgBk %dw@2sR4vZ9w@By. $TCPm0MhB P! Xh:I R!HZ}0B> 3I s}F}qhlUPhGBA>`]UT}$ (;. _{ OnQ0= uGAix#mHƚ6\j1z1)j/ky欦7!mAػՀ ]BrMjrOôLL`%[0X@a9z\v]z=`g<;Ɋ7tX;ank;Z~]zJ} S;ߑq5I\7 J:GD5qU:?Na4a7! dY,OL.qVACTp MG]}ޚˋEx Zb|cp}H Κ&a'/unxʋNp#%c(s3E7fAEwDTyO}1X2(4j$A>.ila&ԖQM28qxDMk8e+Iј%(Q8?dLpJTM `5 + 6N<&hQXȚ4C0-4$ SR *m'C*}Q &Mt3pIdg( ȘO/y U >*Ī|d`/UPk7P} lf!$HNW "U_xtW*M=Kψ6v92/{8˲C0d͢3|FXO̼@G>6DXq.F ޝZA`IZw-Q@-Ɉ K|Vt? &=ä?Yg|H+ LtO9r&詈WL}UJheT6A+Az\`ar,ŃbgIFӾa,@P+-T?nL/G`5M>I$_;] M{2pO> |~&ۦ{WIENDB`PNG  IHDR@(kIDATxb?m#° 8! weffnf(sf4L>eveWJokޛ7͛E@Pn[Qd`( +DBݒ;_DꍒL$ u32'T:^~H[I%(2Cǂ<4AV!)%}\>/6]Zc1{ָטܫ]+VRkt\q&g#Xu$EppNK^ދgFpU`N+S5k]j!5f5{亘nF$w0 &ծfGjPjYc|`ei|jUGp^kEs@(Rp^SN?:TtN0"Ƭ73M-9[ 2nB!-٢S@p9cSqg2&^TˍO-9~eVpP Og8^H (i:R%u/*fqYqKQCCz|#.ki/ !r*|J˥wJڧ:-yZ\㴽uSw٦nLo~~cu2g6U~.v߂ԧR"szչ?~@Ivcfy_yy|Pf?*F0-Ʃ5S91cO68dKy@Z_A15_j: ܜ7 zcG@ ~mKQPz :},`og*gP' RndfC7[B{b2Y3`\p3њFh .jѩyzK!QPɬ7_nla-@91n~,ØPT)EQk {͆I43ad8hg@ *jÙߞg~..REd2F"R(1Xw_DmO&O󖜞yƒq6=S"q @ՎJ|-XDItL/ /ǽ;x{8K%W/,.(0 A(/,K\WuC0g&HZ3 A$Hk?~k Ck=i3u-O6#[3 e@ D]hRG ~sB&dJ^wWB SCJ+í}R%OڣNg὚z v)oM|7g{2x S 9h>:ha/Ek pߑ+b L+janshP oV,qb+q.w ih?K') :y/鏷Ǩ_|0"潥Fһ00+2!Zy-R|?/ k -鯥LMp/@ `WPOz>a0wn~0pB3~`|zM!ѵlIj5-|:R=M#BŎPՆ;0PQwc+a`80 `U;@ZK[a?J~ߣ.oGutWdu2qyS:vfF''z ɾw;0؈ɁGޛICR^\\;&&c-j=4 Vu';2 d IENDB`PNG  IHDRpH IDATx^1 7ݙ$pb+TP PB*T(ύ8rP=*'[d+T9T֓e6]%DEB0f?(B(RX(Wx۸o%YIOؒ'S?RGޓ{N$H L(uه3%lzOOe03SVzǤ6$8}p;HbCSGd{%5\4B)5-gb+cJ۲)%Ȳ K6Un )ӡ'k5$PUjK.aú@[b]Z垺Uæ3 eD!H[!gE2t44@߬ϗi!ޒdK6*$OQm!UV#k\ru/>B`ՖEAD)a E*L/W|%_N} ]D #"B'7p%ԥ0 Y;z5t")&+.c]wEnY L%1mhgk;ulh/P@loyU9qAXFΕ}-h>4SA R"d)Su厾7Xc>W C?clɝIͳ]i={c mcG=d)_:yOgϪ<@B+HRGlmg4nB4E P"bL"  ROC'"sI KMWlH3/՞sI^!Qޖz"ˉO?n9>lH6҄HR  QaA)_T*u0L؎vъԱʔH£Anlv޽sso􇽛9>}}@.tfg輆=lHf^7},o[%Iʠ">R0ݜ gLVf)~cRt8Ph)::;fU)]I_jp%etH^zر\,|u;/ 42')*%GS!{ vogy%!c椌<O|u`lvL)=w>L{DZ2:~w7zyȢf1tiHhJcBZA_ Kj˅qpN^~qepYֈx?ckjOmXi?~cc&`z!kYC0kOE)- 튩JխBgT h. %u*~/~ep@\Z^` Q`0^SÏ e||o "ԋjLO4AETC+=;r1uSSE3a_7 :)0QGڂVԬ-F?1#<<,'t8Qοc -em-#s]TuŸpj B==.{꺰JJS 6wvap]h|ꭜ]}5x}-=cbec7H%ԁ ?7{[>Q$еk]+Ka S5NSO,0~Z FоlZ6 & 4~k+agm.۷n!8wxz㱦[%cW2ZʋPD41.K 5}l {{Y6YGqB/.*xk{-vx*Uׄ{IcY5l]P·V4L{ "*#KS6OKu+bb L&=<3OdsvȴiIҕDJwRl"/GÐ<$ ߇b !<*ς>ɜ̦E&׌Q *ݒQP"=;&_ llo VԡTlӪsRQ^ӈԊ!u**Lk}䆜KԢkanΝ;(TN%>jZvO#iCr}YwT R&=D W?L@emiiK#(@go |cF8!SuE)pWt]nݾ'&yaol>otw+uT&)3(JE,uQ9̀&dQ t W[G |aN]2.VP@9ev[ I^ MȬ+xE;p't|i0 [nK!*4#n H}ީ'dv5M]X}t[9Қ{inؓ%|=< V W^[ρE~)Z H/Z7x0D 9WxWZt',lCbm}SOCQ !#=v}@>*[%"`n^ Ta!b_Et:~ZU## >jqCrdᾧ_'Munj({,xy& }:.fJcXVs8(L$H >?n!(E^#yfz|'luhj"0v,Y!W N;X&b1YZjgxi7)pͬ ʂ[2'E *tjΐDeEEX[[Çؑ`D2Qw&#$89r>>ׯCaϮx)3Z[0{0Eߋ gŖMq$c03  R\T/?_3g⇇@k+"8P555P(/ $CooAYYx@PFp:7(ՕA}W+RǘQ֭}m.F'0(F?΋w&۷cifj ={͠2wݽC FSw֮Y??WR1hKyywpnO7nPJoUgSs~3II}Z #Q:]Ncc#2eK@}ϧ7Ƌv3UOyy9 @q_.#R87~>+0D*.`xhvˮ..*gd͇E"15tk#p唢`:eGPą!`s3֔ |ḫFcΝǐȷ߁t477C $;AeW3ދ:D׮]CmM-F/\Ƿ}`@G)II8zUD3%16P wrkoGxtBZJy{cM{s`9  -5Q4TjD TQxc83ʊe ap!-- (5tT=(PCf΄Νr,HG k[;}o4QU||1'3ݪ7u1CPj\x{ya(bU͇ZE}N S*pۖ0̚ L}zF)pmHJL;HQUU,~!΁)i'O*qyM#?B9spJ{pNYBJ9*XYXr[? ӫky&1X)dl, 7>:69qBZ6E*/(H )Os/BCBәѰ7_/x`!~ǩMKBBXDS&%$*M |?!lL2N~8< 9P"J@)P"J@(J@(A#Ȓ^g!Ak(IENDB`PNG  IHDRpIj5y{IDATx^1 /.xB.S4B"TP PB"TP PB*TP 4(JUjcN$*^(] + *xpxFM-nV@,n%{fN!TST[˯Z-%)mW:Pjkj~.xw\o \'(ꪪYO$*;gX޺a׶+yJ%胛79[׊|Men7,J+ݬv=}< >|m:;#?҂뛓<%;~1n8r-\g[[\AӧNhnn^0w`eKZa֪5a]dzgZ@9)7W7]Aak^XUOr/L+^h5_,^fN8w`<%%wJ'(+/X'bqUUA*jOh(́/| $H $bqr,6("z\(/Jkm͎:>gu|vg=^}iwnް03w۲edd!PǣRomm@DtSSjZ~cd&4ӧNYloz,*"z)'mhEi頜 w귝:nJg;G5i} ^=BwU뀂L&h44̌tuQ}> fDz!Nj$#'kn**=,'ucipm})FH8}9(>mkE 6k<43^bl˗/ӒSʐ%EEn[uv$7G$r |pyyx@\B3m^>kl tdx!Ni=@Ǒrwqeh}:wl9" D,]zG\Uėb Du(GRL "XumJϟCnh YOc:_Qk`(,t =s:]f@.]Ba@#cgG&-4VMNN[g fYXc~I \69:-]*Eis$>yR@fgMTUwtwu(d zG55)ILMKIEF "‘Fhyy96\!ɜRu63-Y%0nvA5n)S+[*LUyF5}?j|ݠA>Ǡ;;uuun.[wਘ'.Pd+2օǴԣ'2I|PPJgJ=CopMI$1h g CАR@/PƨWi d_ 1ͨD*QU DH f Aը, \pd/<8 2@4+@ U6-9yYM$!9zU2@m@JjNzU2@iwd 7mG: c$[:Q7P~@liI"TR.4nŐVGg%T9NI2@)vGXKqn.cؠ9>p P-9Hu6ksW|1s吤q3@߅"E8B3HI= Pp/%ynNu;^2H0Gwk(z5M7FS;Y P&\PZRHxEI ee2e2@LsìIENDB`PNG  IHDRpIIDATx^1n0ڮQ.!*iDSZe7xh3 AhQM*(W@7nd`ɦl#i!Dz.8H,Lr Ur~"th S'Iɹ5 hA_POx$whp|-p6HPA6V $HZD.K`ypb2)& ڵ̓P-s}SCS`.hv $?KtIENDB`PNG  IHDRpH.qIDATx}eY߻{|I8ā0P)J -%RE_(UAPT)?>4P!J(PH8!3x{^el,¨Q<>蝣#9ңDf~5ތcIo37:b>)>;Y\fp:uu5k >+6G|mm!LbE1E nꥈ ˁNk3D<%-Ūoʬ2rv}]=5Ќjt5*T;[7fqU]SHYۏ_{V(ʨ3}}}gr4o{o˔Yso_ yn1~'6B-T]7i4ji %8u.?^[QldFcxOL,,CktO_/}Vi̍B"15]dq) %p}۾OupCwEBF1 zjZ]ղ@ !@=toro5P> -BMFL! "P{v=?=\%PMP2alif\2?G>|)Ûz4fZILZoJtE$):wԛ|7?jkFU/!(YyCJr=GO~{ Gh5DG1v:ԹOih2ت ]=># D@!sqIFŸN=R\!ya|Ώ:ȃroN|A̋wNmX6% )GkO&"*C[bVMK! ݓY D߈H4 HLZDLDY<=EJף !".B׬0! DL" #AV̢K-REV;%nH^;Kmj2ݾl7bD'g4Rj֑a'STTͲtBu4EHU.b4D, 8"#`԰=ujZ8ӛt;vz]{14tv;O۟&j&vr\q͑ٞE RE3fj m۩Z}lD =F;Ӯ[_~7רIw~l~D)` /w7/׺E/4?p;se[^|.ή3,6;v+=iTczг{~hKŤgbiU{.>FyVJ$H_ Eꢅ.M-ouw8{'2: :M} @\Og=a1,lf˿n|)qp_l U]RxzzT,"( J)>o.iƱ4koi==y͕( (yvo{!v;W.Ư3*Y4Z!l xD(2dNH*f9"d9>VdUW Bd(YMe'?$}RGtSЬ(&O$Ys*EO@G_y0#jQjЃ_s}rRmG]s~wuЖ+mobDv-a:k!d&x=ZS"n~}+uURt$]4!"AfbQ!խM4YWx^!;_[fY[Nھ}e-x Y<߻ljQ@)6f߿I}ٍcoL+&W'ۨ _~KTx2A++iδk/w/se=DK6"&٪W?to펻|pǹ`k]绿 {SsV*C>Stc Cvcd DVN>zx۶Ƙ"RBC 3o{W2;tБ:eskTxx9:31?lN&ƌ?Q-'Î\~ls֖E`oW;}ǔ-9&[FU%_'80ck1T¢e2iQ1B Kc"ق#_ƙac {9vߞ2ꋹi^X `VG-bs;X٘WE{~bvV,Ч08"Kv97ӆnnF, ḁ2Mln,i65%0Ck63 }02+(E% (=BH]RBOD%dVbJ]w:`a̲RD&5T!(PSJɄ@l|\bI$3% EHaU=8 z:g }&$")IPa>!.*`.:u dea⊍J2ottÛ 3]ь :` bK9B7vjۚ+/D"Y,;|I/Հ)x<_Jrr /wÕ[dCA>z&E6o Cdtݓg"@ C78vFz R9AȮdu+ #S ^Bϥ;_{tTbQuU CBJ2amo~767@dϤQ/};ADHSC1/ Wai+>BA徤TxR(UhLPx|զ b,"@"blb  jN*j H)%8ո+_oeǿZD(NSԢRplFLˋATRFZO):7ôܗeO+ij\]߬D'&mh٭z7hdޚ,ۮ1ou76IT)-+/sWbi> rH}0s|]U#ÁE76cEV I0k_2W}ߵxu0;P*zv2BAP Cqe) tD`\x(J(Ą1]%^_ɥ4 )t " ]9s4T R5룴5k׬Y\fp::ݞܯ!nIENDB`PNG  IHDRpH IDATx^PT?DA (gMb>KJ$Ƃ A JY@,HpҗZZvw,qw1s9{s?٧Ceb@YX,P(  *.wv9"8|٩Saa11tS8NC#IkC? :V9sTW |?@ls2[ 0/?lL)ʿmmnΞ=9z}cLT&3G3{wADR'&,ƭR%-ݳ(LHvI1 }2\WJf3Z*rT`G٘uUU[00*hɮ] fjP@EP4PIYYB׮ uV͂In]q@@Iz*QiORI$}v'@/R %7V 'i--XFJЭq&#wTEE|CU_Qs5 *_eA,׿=w=s&LxUGo) Biy)kuN4X߻-ymtH~E<%tI2ձQr~Iz} }^CmWE%)mY%5◞-4&nk vwH++W!J@*Z ,x2HK@|ɍ阪֖ikM27D*["T99fLΰb6Lx$L~/↑$3f_4GX'lx+a}S'$GwL%;>6o-|LsXKbٳm ^b\ۉ1bPPZ2w"᭭܈Oc޺շQL_GM;82GGtXK9lM;ᖛ[!,>vGuM10(07߽#_БβǏj 3 h]@Nz^5 2 o%I(a,LN͝ɣWinq//\CW./Bovym&[F?-wgبbW 44xw8s$yAgt%1 4= C5Ms ؑG.D" =D[k=0wpT[hI^lm'3** ġ!uƍ`P oe 1He.A [~Bf|kn~ d? ئ ~ HOGFrO`FTє)^^ђ _pnC2g'<<-l0t}`QDAsHY 6 C]G֠kdhW4nAOCz#MXXjՏT,Wb'U`5ݪAj&#Px*5.v/YVdWGqVs۬Kw>k?aANe&պn1m}V9>`n7s"R`٩Jq+pN %ɞJT[ 3Ɯ5aH4f1\LP(PE)JJFn˃UzF ?EVNk TPœ{F)LrUɞE+(se{P%%kIdZ%<:|8sLSgT@1H|I>y((;"leHSmag9ܜh&htn`67Ey=>3A;`@}L _v?#4fJT@ɞM+lq҄Ѯ3Lr|~GViw`#Cb립7 kUiM:md>*,}i`(ggǷM;mN(zoRuAk[62鲄AA0*\6wbH^8B[ Jpx)'?0 g_4qV3T>XDN: qc{_q@Y,PV,P(  ee@翜}F]IENDB`PNG  IHDRpH IDATxՁ1}v}P@(P T@۠v4Ǡ'ZojJ@y8#I-֚mq>3333333333-gFyזd*VG鼆z),ȨȪtHJ@2( Y}t]j0#VFfukG;iէ^H.jME( &8A@ nQ>m Yd7!f@ v }`,V_R1&C>U$Ȧs&5Op* bpӗN^@mMk'ptuB^Rafk$*ˀy fv:~ơ+e@I94~hoɭ2Hgb,ϓ(Ü5?dM# zۅb<S2&z #Hnj^l2n8׎;av_\߳]|ߧ].I><<0H.-T{^=tCs”rC&]c5G_$?O$`hY?ʫDBF@+);s@L$'ÿۯ  `_$y<)0;eaD++Ao>TzϡC~i,cԻ#S7@?$B6쟉\ Fy(:E}~ Yvʄќ;淛4djyHq B(T:g&Bhn- {P?BsN1jW /<K< ȍ(E $=Q0UP՜V6w8: Թ'1E"Uk_")wqzCTz3?G _?r0IP`dOSn0ȡcUW%AD=olG.=~ơBABgG9R6.=,|쯕8C} S:MjWt՝S+PF-_FFa?Gv]ػogxKTTf~.84 Nk5CM9ovیӄDίYu}paMj"PNv(x;eٷ=S@i^m`v 0|T~Pe?~RCc| h<{+O4Ne*ny ih ޸I0 iOBŒV,[b`bglGI!ZiȡPbașНN`=MJ"C=%!ux׻{w u6m n}n[6D}w2{m. lGM:PAɺrݍ)?U 36N `8B,ŧ ٗ~cȁ73(&6NGa-2v54Nu37}{$77H2|, E>Tz #i^sQ-O&[g}e:)>< y/z'ChFZeݬ `qfMl T9kWO^ۛ7ƎU@0Xbm~mԺm͔5 n,/Б@}0U+sGFdS2sFDHCeL!D|Iбu( F|4}'$,ZR; tp2l"H$.H`MdkV f"BCrsM߱(g lj/c7[! {[)b=Sk Vlv.6}d] aȀCmR&mhSՈ2Y~], pB`wt(`!,y0w "iM3LZ-D V:)IAO2D-A&Q1NtӝUH?'0xܟAzwBtQ^œ<9L-{9!A-`[o9ؿǜ1( ֞e/ p20'Azk~k|,) n:,u@82)sb[tdזZQ OXj.{m7x~ӻ $%I/:2p)C^'nmgp&,J`[CDzMlYl{˅~Ay%]gw8zȱN1Ά{@|}3PA azF0@TCCߡ^{Q.%|Lހ@#ǥފ ,@ ɶˬ#*/?X' 2P]nq-L"}5 ֗ҊEx>L2y2eFWf0Fd9O+o(@@ P"(oEW2[d˘IENDB`PNG  IHDRpH.q;IDATxy]Wu{{5TI5TA%ɖmYvd[m<0 4mHHXM"tHM6xK6eK*ITRUzýg[wݧw[`-pyY;=g٧,7Dv[QLfi "-H.H."p\$ߑ"sH\<16S۞%thU Hx11eWMG p"tX8DļE4sDY"`ӟwNixśX+Ρ0 #bc-Cw1Vb ^3v<+L{" zvb@QJh@ Pkܲw TW b ! @, `* sKUE ؑoYɋXHg|`#P&4)˜}-\}իoUs8@f{ (.nK]+'zr]赠j1.B".- ^ԡMv !TpJ*VRIbjev~?01"O:T$<4X%C`fpXsPkoUc5ڌ$ Z/՝mf›EK x+*pk]ñqJ+'PQ1@^%EaȫƛITpU)֝Rh;: M߷F:t0QAVլ X1bsԾ[lr&%zZR*v MMܒ(eYԴpHfC yE0 $*ؚ89,R켤4@. r h89Fv$+i4faK׫:k'JiǘӮC qI)A~ Fr"j@^RqOZo.]Nc#҈c(MFq>t8 g6(8Ru`)˼ӆߢ3 k.HRx7XAXUH>MTg jB\p.S:P}Ç ưKhu1_كwSC}m0C CH !p"R; ™իUA"ڳ9>}ݍX$%Ǧg>=zD)5 YDkZYF()7BR(DaPo*oy'dO*._K;w+Qk(XϤ͂UX ͳO Br湠]ȑwJx.=w3GG֪T5Sa[MCPwm.#{ *s! |J1s sG0b+dׯ#} ]DLʼnFāhj3U*sf"Ǧ|Pk=_*G" [VM;u\RAٲp %`Ќѩ  yF0P݇Ee~,3Qf ESN,A qDE\X"0qɲHӛ" 0iH> bݍf~q&&y`K>z D<KK5U\zzFؔq0ɓ1Hcsŀ2ӷsfz @僸Q 54g.k#2,Д7_n'*oY05_b|p! >,crn/4/Rp!K6-(=5I߉wtpptn Po-y|b 딥,(8Gqrn>UK ("Ci$Pط;;CQ$AAcBP".vD/"MMt/׬U:޵6ښDy.;OM\v22rjKu7޴ {'OXb%+.AU955mKYa=⍬nh(p㏳zZ[yj-?}/QkXS}G~>Y{v]|\X]4Q @9 K%ҰnCP$:>ذ~=գsy&vƔmMUWe< Sw5fnu?}t+yl[j{ky칗n73}\mFd2:'Fx[\Rߒ#3׮#+m-w\~ x~$?yY(lYTcM1q8H`<"c/,V sdsYKM5#'~j||Geȧ :ʭ7n?K_M>w^7xr~j/ |G3=W82>bUWEcxhٺ>zwqsqױijewb/7՗๗0<> =3º7L(>Kq󇆩dU>_1T.wI3EU(y?5c Oq uu [6m$|w$@mmfu[i eP Ni"dPcڮɡ!Ʋ];ű3 ʠ*pq-k;y87;xH -u*۷{pզ<ږژذƬeEldC[+̀ N![P9ַ/G² =:9v l7o0CGG/xQ.'& ^}~<:,=Pv?Fȇ'&epCcƶ'YVd+ǥWA J@ biR5wCÇnقŲ5VLydCs9ш|]o ?OF(9ŷ,c1p?|E9>Udl6h"{ܻ gAL OvzRn8g={XqUy h e6rE݈SB:kM+?M33Ix ("DP+aJT"#c FA;(`=H@˼W*a) )P``"8>ۂ1(1`<&RA\D1ƠH(Hz[a &GE\5˺^|l Wpr_cyaTqֶ/L|ϒÿMe0g yV67-%37H|!֥k:pQO7$GRY gG^'x ,#Ւ4pP7qCM#W7UEA&\bO ^CS 9{qev_qmrmM47H%۞="vw(S?GFG?L{S3?D&ul3ǻwGE NYȺ(%BSdx ZT@MMh5RA@i IJ{s]|g?45sqh||Y;y{hol ؅W^d>}[2?DW`5s`tbccƈB6tuV(JMe8ܻ?rlQJKQƲ:挏$hWfNikn՝d\#ˁ!=6Zguܴy3=]]  5 DRY슊&"0&F8RH2\6HR݀i$ؿZJ(M+/fn<ζL}9w%%U~v+K(<34긢w-'fmn溛nld2qaHG6DJC]=_6N*|_ѹQ|9-K=mY`40nrcsOEAy<}GN֗L=cxHL%u*2Jk״]ÊƀDx[_dO8:!.dUg'dzk]kyou'qeljg-kX~=xyF Em&֦Dvv!u 0elbPjL bns R-H$xGwsrj|ۗxL[[9߲mp.>A=`(=K✗P߾̾}1h^~RD|V/㋏NAl:>W36? dCE={FP\u7}((-UcAèY UXtZhmq|lGdd,mXS=i(_}gxA=˭/RLmŠ֖6eoa]_?BՂ,XhTB;GǀxVa\bWb.)nl-? Z13Ӧ6 `"ܭr% g)z|VDC N5K201Sv++BU149J"si6.k>{|cw'rt@*z1UG>XGSCI<1t^k~IJ.,崧UrV}4#dؾ{'}4{%>[sֲٚ}xb3|ocP]Yu՗>YED6 :B4%WtT%(*B$ ƕ0s~\.*Ū8<R!<5W׽MtNM"MZ)d3(B |8FjHj4 Kw"d8ET*U!f^[̛KZ*Tgm,4+h WKZm&()@jftLi1\_^sD3p@(Kuމȉ虋I)@Tk0k?DoA~w]x߻P3jha;e(@6ԭ11&\,y9K8,j 1`$UL."` L'NRAc@~$jHÀSs^>w I.;{Y*793?39UWc=NUV27ʭB^P (5((Id?^qԸTt )5σK=/aȴQJ>qՕ"4ՆP(P*K{#GS qR\%p d3<~'T,N0$"Ac-Q-LF-OWhV[V}˹HjڿܘӡWEZdxM"-"-H.".""y"6GA|oVRr/zIENDB`PNG  IHDRpH ]IDATx^1 /B LQ"TP*B"TP *B"TgL8>BA"p0hRF۲/Bdd6QXEd]&[)o>@gjvx (!L^<䂁YQ{m$jkhf#"uqtt}MqDpD 1 c1; k!NiVNrkg\golnxȏ[^ 4Yހ c 5#e$}zC/}WU%P=S83[ zFeSS4pv<oGЧ ֦4?~x9#MYF] y!l nno `tM$@icC{^s+M1i:<+Miy $MQY-.{84j't6+PJ8 SS Pƞ$A6=HC BbO30*6@#d7F;^eDR%)!i@]B|tj>.^'w=(HP K%8HhlXobWt# W df~VCiu]oֆ^뾿_wH%@11mJUm{ k(b}3W#Aɘ4Z$!%[<]CC}uʘ7B/t K6bq(z-+@7~6ij(Qct'BOJꦁy4{2 KZvuOF]|dC EwЦYZci|$F7{~3i f;ȭ=k9t\-MiXZ^U7ª&%f{I6P%B &%~w1XCD\PZIJ<}O%JQU-q;-Y:MZo"!PQ;@P*Vi+@_ΒFO~$_GA'%(l^ PW7\^@'Dp)S<`Zj%Y'SC[k8$kơ@$ь53PLNZ.~yBqMQ4g?`ߔbU9Ӓh= P';;hR@bjpܯn;8R`FTݵr [bDI}ͰM%gbHPUڹ+@]$'-[3a94whRṃ4.Y5B!UXFݑ?г&B5؇AC@{fXPMwtiD;{f9*z'u,]y%KK=CPQ9QڵcA/!|Y}*@ (P (P T@P@5Gs9IENDB`PNG  IHDR@(NIDATx^JQ}.zZIGЕN!66.Dg …cH9!b6.3pp`=Wo`44Msth׌^i>j~pi#3HI^N3R3 _ |ޗ@ ! +ع> )^1LUf hL./i0;3k8򝽛7Vr>6(s@7h@TR ppL[swp) ͝jxOHůrR XL!ǀe@6 {M5 *  \ʶ_E5C ..V+AH(\΍ºq 0]7 36G"nfP/=G+0a@[p9CKh\gVĝb-4FOwo*Z:ABՙnNtu!q$MxRlɟeXDfc`ЛȘdjL|2^]81Ui?ÞEm;3{'[ MIDATx()4 OXh;;g:tCӄ %QP9%+a:섙b[q.ONT!ny7'Vdg!MkT٥71s"̙H-ʻ}t_E[뼻A#]y6d bWɺdKw{g<߭~LNfۆ!FwmԌ {g=d>feёN>urrqd!tF?ʥƾ1;og`Ỳ:~rgٳ4BEXcKG! %-c %!V<FBVeJ<Hzuyb@$m%"T4.,BexgH[ O]* 8b$,A4Aojj;)3tov}N4x`'W:EThq }:~ڻ5@o|:->Gg4MYF3sS>-XNUVD{tVr[ S$䆑 ɞ@@=:,-.zd. 9 T%-"1vZ^ۜOEL_ K}l2uTScR+VI~T[_2"׭U>*5Y)Մ}or -X /Ɛ3Rq|}2a՗% )K5u $}3ο2X%RM)@3k2{`3=[ǒ' z7/ˀj2 jE?a1R/`=kjVwyCj&QyX̤լB(,-B@u.aPEGlE"TeRW´lJA5+)h.SUBQFU)bU.I0*nj*tZo RWEe9 'Ub Car A.",Iۨh i0i FJ~oAf2!\F)y3V:R*()4$%KP,b#"_C03`Nݽn9^ǰe%SXs ͔r!" )Mb1a #Jgotm^/9WS) DǔTp6L@i ؿQJ9/n)l*O)O@Qԟl(tBn-Ѓ HÔC˺ " VQ'P GQؠ4= 3S gK< 3~NHQilO !Rxq7&_Fn>jyCJɑ(LPO|/ycSh<0THa3 wOoI!m27RFȡ Hcާp&)Tˆ4m p̣їaB& }Gӛ:LW4nЧʄR `hC%P8 #-) үպ1Y]lP>SN0+/ phaD^C1HQ>!ַ17QX6z@s~#j~1WC3 Yu^8rJX iUa1 WBDa-!omJR[q1B_U 8d~q?0Yq\#]3R/kҊጱ^׿fx䖺~Eu%P83TY>0_jKː k(o< RB5v@zǝg~as)iDUiSV% WV36ڬ~0=6tDB7l⻡G<na˚ jtJE9V˔ZɔAAwSx5D^kdohS^@Ň.*VfLIg'SE2*0=PN)~(n:H,#TDX.bT(lJQhӑMh"mPٝR(fSfyREei˨ðh7:@KIS-i2->~Z"J}a\JD/)~UUP5SZΡ'ʃMFr?SJ`77kuG`q-pJaHMI"y vJ )iw*߹/kEWJ5~T<^DD7%˵y3Pl6FX)ᒫhO׺bM^%ƯJY/pށ3o- QC)5!IFHfP.:JE7~s7yܢN{'TTo*R4҂ RfRu-\*Uc`+a(m {/R5nj`m[i^ģjȧWM{QZЊlZ6a5ޯh2,Z.D@ahE^Dw-V;!7"Jh OWh~ťz{ycBH(ښ,oJOvս&j 5v+$Q6-6oHG@=ow:;6g }alm8 +!FwDr?b3&o"#pG%>͈\Vgy0BOUbS ?^x"ѣ?n:ićqtHjB+2 [G@@\XC\81R8H3OyM%_@ bK3?C H^]&q^_ľ7y}q^_xĸwy}M{^KŲ7M{q^_WĀwľ7]޶WD0~dffA*"[k~9oh (ԵT>TFIENDB`PNG  IHDR szzsRGBVIDATX c`Ƭjjj@118߿+W$F1 fj-R  e|̛BCC`zA9!²Bbj#F0$$$&54 ;#gݺuAfQ-(qrP )QCfр8`7 `C˖-cadccwԦ<qJ9`iC`$WFCOd6iiU r``31,aКF `3i!-l3L툰0PR( 2 inݪ?*=D@%RP3IENDB`PNG  IHDR szzbKGD pHYs B(xIDATXݖ]Uvj%Ҹ6֏q`V\?߅ 6RD"_>,N"bQ>OV6q+.B$f_V|TM}JρS%PO'F}q$Xci J N?жK)U}GZC@l2 q ptm8kؕvv<7.g%dG,j[y1T* {9MMMe 0-TJYXXD\[[{S/ =g`1kZCƘ/ѕnY hF|+ mce}("7"-SʰV h"}<(0< t8zgqq-'TE5Gf9J {m+ Ɂ{j!V2Ƽ("AĖp]19Ațж"r1Ԗ˲c=>84֯b^Z]]V*Qez$Z |0ċl9T*~:bQRT[Ê1ƞOZfI ?F"D|>N)4d=M \>hybb\XО/iNIENDB`PNG  IHDR݈pPLTESSSi'tRNS@fRIDATx^ 0 Cpb Fhh PX  K9]r9Z*znK)RN`ZzIȔ(9ově.W4 vIENDB`PNG  IHDRV@AW_@IDATx{t}wÒ,ۖ.\^.vI)4 )1! BO9-90yjNJhBz*q]~+; XQ(Դu.)=+29>*=db?9Ҿ< BM;M3AHgLbsVu5rV XQ(Դ;&:6S~\~>…*7O?ϼW B4Xo`7+H!0X}aIC}[P+ חv2}QvobKw-}Hm} TR;֛fЭ#YSAG&0eO 5;x=se>B& `^jy/9acI\%/15 %}%?wIt~tƼ0M/9JK Mo&c ` ϼRQ4ݴK9`n!:>qIs^+#=XMRq:c$ O֧c@YHX{:cٵo1j!Av7[:\Q|-`鿩?UZV:\E t 2mF fVjk,F63OyS'3R:괊h$3LҨ|>16mFP)ƺYHZZ!bN]&q\׵>nEc` 2'ZֈԵ_ɾs"shk7oĺ baW $S=Olou o^}b)79u( oz; f!ckKwQzҵظ?sdۑ<;npUƙn9ӫ(:Ùz7NkM659(w#ݿ٩g$)&Xy3iM3g5xpik"KHdEYYz$k~{;"?nl]Z)G,~9[σ̸=z27mfC}bB6=RJLs+;m+pqM!_&W~zi-ET` k\1\uT5/;Ùʆ+"3>Q sf,G^9JqEuʅVX`[·_?/6hÓ{ )[$Y΁dSaE`Ks}CWT9vEGw}KnrgW̑*p5Lx&Th)Zz[T6@=yuJքۑM n1ĽG^wR8050= M޵me/Q8=*<1<{>@K+AQs8/ӼuLMZ}. ˝V\5"XTcc1VsoE]evYx|aCbQTUTmZK\}%fדw amM'ŎW}`Xh5NUc`8sUbum |}w^5(T7sa¤5ifyQxݎ `W#aE-ĊĎ>8m Tߵ ta*u;ۉh*b*FCC/k)!l>D+71am Ӕji'ܰϘ{g1oy7e[c\_ g7J ,I3XIouڰ_q0@[lؿom[B;N$XX =o908IZDyPu77:)`^KF㦲+h..}_@jW伕d({$(Q(>IkZ;t]=}[j;&O~6i& ,~LJb-j.[ʽMz~P`Q{M3Ȁl"*oR 6,gk#Tu@ V VN |"X |` kX(XrN:8 OC@7#TE G>4[x>&l\5?˶ 2\NLZu N BPv!(X<<8^ ><$6\N`^S>1+3>>TVt uVۈxGLtB.mmH2װ& Oَ O &Zoop8܃!Jg3GM[s\ZHˮ ꫶Pkk#Hdqaݨ O;Q"W꡸ICJ8u&>{.+ .7"N'd C|W" e" X% vKt/W0_a]V_܆( `;L|.RdE9N <#X⧱M Iw^޹\`]q@S)̂eC qdlR& :VKR}pI ag𭭭ϤTbo?Q;Fz  Jb< JDЯ(R2nQu_9Nz}%ϱyD%vm+?Rj+L@`<ݵk{,\@"8&r.Dѯq$)4p2 9*[`*IYS_ϘiVoKMhNdKX,vecI{<LNć@i6>(|Q2IoL}{Df7w-ĵPDLjCScG}0UUxYB LfmqtݕL&?p>whm2RorfggCT*/˲~`?]hc~~>V(WVVҊ3z ;;`uyޣh͌gl6D7~:~WW^L??zx? SO/]}w/^V}!@+\8`"L _'os˟F[VOGw)u&Y`j}MNu{ ܑÛNB"H?>< Z}_>vRqv?Ƙg!B܅K.h"}y4DpnY &'psg[_Z= Chps:~16fe.m$zgtS]FzE۴p5 fuN3~Oo #p3p:;qCμ^@3h yV>DOxk58 Y6lFiћH:{vvD7\B\I`3 obJ[:{! V>(vА@V=[v5ڇm._Aorb%ǿ-K@BA,X vfjnk5]=]A!Pggӆo&m R(g  _} &UNچơuhw(w?xvssxwuO~" 5SC} :`,Ɏ]O&9;ݣ;Yߕo{}`^⠸>5 B&]bLhZͷ @!^Ka^zF'qvk \6D e7yW'}Nw=e`\oہ{դ6ʏE-1ouh;|rf"'˓'?̈́2~ C!}}/ e 13Z1&YݢERCB\n(w `:߿{}}}-7b 62{ XR8&xX!?aaL6Xqи~)ԯI~U}=чjed-MFИ!)4w;?odn:- gPcgL@E0,!8\ƭ&L>CR!=`ML<aI}W@mXWAk@'4tյ&- \[n%kY*^Ě0V BF;YI'54{$9X|>oy=MQ;uE)>\U<8x]Bj06P[h_/}:!h%-NYkA]![Oz $nK*"h͠[ !l ~#! ɢ5e`lltk$3l>…䜄a}uӎ}}x݋>uV㤡YV}\fO  ,T?o; N&HSf=\}{ aB!_p7]%Y qE2 ژtZsA _'R[Y9IC>Wh[%[@&NF7Cg:¯B5Nn<:9ߵ/*4FqBšͰ}F}n(l65ɏGp w-dMI;d33Cw d)ghq\CPv91Y0s-W|S{G|[Zi;nhQ,N!Y{7' #ȵ`M?IHE] Pد(N+};?¶53HS[! dfPw$ ^ $Fr/shs1Ԟ,X*!S[Ì:Hl K%}+O&~& 6$Z$^琉o CdQȿ(k6!^[vq6s.H3Z% x8z͖-¨zW 2aWA[d<>Aߞ-PwHd3d9L88ZfgUkyKIgT_;`@ 1HC`2 ; (ມ%b$WY*v@>~eZbE^x5eZ,!߼>EA? }y.s?3YDl` Wgm_\B'^c@8v EAE6ċ+F"VJ.bX3DPg{ sǹ>@o?~ape9(?]ODPdYl ]$e0=RG]Xw2a hyXձE*pA.`M5WZog?qQ1YWE"ԾI*jC2j'eXw{)2(bD_"wm?*o'/_+To =)~Ui_@\ͧ?=-'>`0 DyW7S_eeY^L^D`$e{E]$>vB}#~ȃ9.g~xxصSc<'z- o=>Mc[½HI8<a-˒ e&uEz࿳ k"= j<=~5%\{0 ("*j?:ɀ'ID3"Lr1 $D8ᒽ?s:憅lz@# +0 6ɧ's|=,7A6:Nhk,v2C"-sω}'R=`BTL{Pc)R3)σ%`ꃝhתY,o&_w*}@Hf=p6x%`r$k y+7H,<TR7X"|2u>Ok{>p>!C>L_.# X"Y5K kf ]@OB.v}և} ~!2TթohM#@cp@Q".!# u|}hPŭ֔"A^L\v$SBYNz\\hP(`3 v{2Wm_mW'vn屸]Ayw|& )$SGuHwjbFާE `w~@na:cP]%냾b}l`ib,n<]wGkp]>x^ ݵkm6w`!#L,B48@ $`^ ~Mz|],`YV&t XJ-ϞV:KdiT)O̳an}65By Œ CfЛBvvDY1'ۏN$oi;,ՙߣox*J>M/9&f6ͬhC>/oifE$T#ZE1Y!,Ԭ OVM"k}bI#26q7/n?(S "(Z'C) @G7h"f*_jds/U ןa) ;]"}P3Boղ֕R# 4Za6tPCHI'QQC,¤ʃccHa#GW8Dz"d<.>_e*Q@{ /Ogk8Ww]mY1lCRHݦfB!`fOXعRSfٳH9c y$uw>4q۪1G'g?N/RV !8b҂ 2c܃ ߺk4cRR䛊W R+ OZ+c V,,+gz .{&z2!E._x*TzdT j,O 0?j2߬xAj<@λ+'ԑc&oN!;obsC$dY,ӗ|{x}t\x|?q.@ͣ~%nѽ柯??X\^TY(6MПJ1Vl۶uӠ6 .0-@ ϧ^М$86YJ5\q+B]|jyhY/%>e8? o/.garc:ƑE>DǪQqiT=%@T́'°xFMO"|n0]`wgT$`8MeA (Tƈ_xb8~R"@33cW;b)o\o+/DR Ow>.8ֲ\/ q2}/}NC\OQm`$T%k JTiFQƘUo_L~99y[)%~P4`@~m?}||T_K ߗ b(0}<.^^"qPUj;xhН&^mˠb 0^,zXlrрє@.dՔ yD+ʸ?,_O''?TJ*b Oe"U1R7''6@(c\qnO؄aTߣ8ڈw|_WD;Yƒ.O"$T*Nq,4B-*RR&ExOu8­+@wh,Xa=]Yyk4$aRpd%#G1X-EIpF8;;#~-wJ@p׃Ni rP,#oJHڪ %~&=~-5`߇Af)5{pS<JbKYՊ}5j|B%8ͭE8|@VZ[P&ArfxUEMC!8OvhH8 KЂntG֗CߋE80EN~(pXdk%_Ib 9Y5_-]5<?ՙ/(cXEp!}Y?&(M"~_B<{ aH{8xdOE TE dr(9rp}~q)iK59|u}yag|ΫKYJt@Ѳ$? |P'&ϠW?T Gǽ], >|0gYhF`q9g(` Ygqz~޾-lU9JPP(C*<c'i 2H:!<>ɦ[0fXv VGEiP5է1P#E(`0bZ&`: ™YfJVhXڈ+ˣbM\B.8Aɦ(*0ˋF*.>X AjWxiˬW0,, e**hhS\j5LJ`1 H7˼Li^z uj[YߍQ7y.xaaiFhxIB[[CeiΥ3kht}S -E`Bjб= sˑH.]?;d!OzC;F]%@_#}~~n%1/QaOyZ7Ga:$= P?g 7/>{_LJt3YGa;O8֩;d3:G9D0P%qzz}?mj t^.z&e{|j,Y- c1K.aF~hZAI/*n@8d0Ik,L=5 [F=:QS/!@=RA SQ0A9˽LT ߑLZlN#r@$Ԁ .eXx\A;_MPF;k!ܗd >['b"^]P>VY2\ڌ&RmN'׺.ZvH-iJi sia2ڂ5Azep ^^Tʿ:˂a%$̟_M'W"a kSSܨɢ/]scI¸TV\w[49Ǚgg'օ; <7" *=eZ*D u i}ZU-ؿdOI7%OϢg0pSXe5L v)vh?!tBz0WaÂd ~h1ޚc1b]b{[78Ń!@+#OΌ͇]_u}~Jݠ ]DsWyZS#8ւ"dL T~+Tދs@ IQ$+Q|ݗ?u5gP:[#,"hp7}ߥI ͂ td֟';AX}-ꇞ :YNSEM[1zAzu+(SD e=nZ]UڷҞG;4<#h4G[/c@>{l, bۿK!2vA1<x0ZHYlTq]L_uy)}l,:|:ԷA<@rT,7{նC=~tN-)hP(PJK 6#]h>i:YjV-rx`0Q@C@2 Ј \ڪڀ 1VAKz\wGq#G59#!:, ףC!Sei͝ackr=l%'-9z"xG8]bɧۏ7Mۣ4I3HjLѸEWZA0\5ۓ- VN-0$҈B9k=Z,nv7o4/z6ez޿݊ z0E_ m$4 / [/ 7'~B2 !R=@#:BgR,~w;״,{轨i.+\rFg>@_o* iiX#j{J'~k!>F#%=% jEV.`CG+$sa}W+YC`cƁ&*d'$#!L0ڥqIb׳bͥ\&ow λfA$Ϳo}(3̾4r/HUmN_z;f+ I|&1.}8ϐ 'C#{un- 4  emEoŒ~u=Y}ߛM&dRP,$@xi-+ڧ%C~$ߓ$ 5qgw֯*?Ԡq9ܔ륕yOyKQBw$`{M]DH3$Wm"B({{k"Lя:,dp$9*Pxp WUDW<{$FY^zD Lg= "\] ѫV @* I'G9B;H,VoWt2AH&H#'6<߫Z\I?>ryY^$%k F$b«E`#Cmxb|0$2 iS-2Gb. zMBX}9AD~ӇD`E'}y лCKOߟͦǃ꯵qb{oU$&^YRtX>!f`IkUBj0HH< }kfEuzv1{uj6!(B2Bi}>x[z:ܪ=8_56˾D$u?n/F_GXɀ #'9x~S@r桟$AlU(a˄IV'4:>922x3p]m<.?::>ft|z>^'T|a,m$ c gժtHz>!#WO_v+&BȢ4FU'է3ϟTۜEb$xyAףӱIR~5c>D|wa9Mt Eš~wH: 81VoJBh-&)"$ 5D#;tkg^vޞW٨~^[FTǏS0G G6W{Dž^S?:HI  z4jHFq6 w)*jNv|k$41 yo=Fٌ*:Ysn -cS>/_?ùr%I<@# T"!ϻODM'-}y#`%b|חOwTPO+B'` ? ,H" uNY:BMiAe9D&&؍izrYQBd$qeaޒMaI.w99ŧ#1HB@##GvIimaom(-ISڦ!M/=|KrIa( D aE'C8d " lq^NhxޖZ qk^_~.J v:65\ $X MYwmzAСI6T^rbV@a:x\?_=i9k[ދ7273U%`ktRAz/J / %ۀ>?n U!;B7T4K F!#Ay,B&[ 14{^nlj|6@߀B, MBwNή; p5>X|yD'$ AA/JYU\cQӣEH`|}Vh9+/?H|HP5D AWą11&nt3Z|!3a3>ϱ9;6\g\g_NTuW0|22jԾ¾NOE,"E1A#4F a}` !21XץcאƧm߉fApR%Բ8rt~7S/pO n@`FY9Kt!\H "a `%:M'n8iG$Eay 5_0=Ҭ>ɡj`UCqs,]&6!馹G[367Usӫhv` uxyz#A#`̘1/%D2R;FgS},ӭ|ɺk#ާ} coGͩ=@=7A+'?pcX 5ch^@0(c!:hh!` ۨm  3>~d;RksZ_k0Ԝ r@U{/?7 .FGIJ@d_ۆe]%F^6a4)7; ivn'߰[FpM[jL9{p\E& _z[[S$(v걬Qk@$u!6&L1K I{|"//ƄupF je5SF2% 5Լ Crl,r39~h}vCíu - w17x? %v!ݾX351cr,ԚGzޡf9֯\KYw_gO޽z{n MhIɐS05H #Ӟm)@N |q0hFh=E*J3Sӵ[s~ujw+ Cr /_sfFpo}>X)[A Il<r$=@H&#:0оkZiI!_}N;0 Z(r.n ͞|Kɫ{x$};> ҷp4O's.H ~\1M3zU X,s]2::&PM 6V 6Z2lxmH$Bj?`#Z e{Q^[[{y߅qF- F؊hf/n~ pZLs<v+?9=` lmXlGA{:Zi>O\ 8ԑN閎 6ዟ;?_AzuiirNNNrQxJ 0 K;R ݳ&@JlF&u]YXXxFW#,+u5XHpQ!])1\,..f ;==&߲d2 D333+7ࢠCScFhaH@wУ'86 4piӭp<(pWCvHh0,; 됚PE N?^h-q&*: Q#VMܑN /` ņpn->IaۧAփ\     @5ZaIENDB`PNG  IHDR>aIDATx^I[[k|!ui` !V2)BIV=/&̇}c`ZX:gmMv^m=KvZ}؞iBA'@&Yy^w>Y^?cUQ\kejpe✷vmB>+NuNTr׷N9J{FJ*ޝm Yx|bh/(mt*3qPV~Uۛu0F"ѻX(gaaƹ]flW#p\]^7W7.i]> E=r x"du07{\SU7W%,ΑSm#Ⱦ-}H@ =hic8ܬ×:gv-4Uuh`~a#Èc;us L]:|Uh[5/s<$/ ]~[Wdnm.k|uZiv!` FFn^l~]91:Ww5>ls_ Q* /zS=}fݚD}>zeE% 5yvdt>)PXb߫06@}h-9w q~߼dlsv o}IX^MQi$tē(zomE]cYH {GRȩOtHg}ǀE+ 힗. yP)%Kyݛ7rךmR م&ZXbY޳U`g u)ZG?>x'/7 to4z- CuDmfu3e3m t/W7<>͓(2pױH%JyO ʊMp;7k޶uL+ɇ3o>llF?5ԸROL' @YldKk,kB3ʝF/9mDՃ@DK=GjYk-~+EK}V[sl>,r:vJ۷_lmL~^m:jl?NL.Oapɟ󫨩 fn6ŀb_Xr_[WZ7+k:8G}1|㚼z盘\o{{'msuB4pmy,+;QJ0KHE>1T1HcnەoտO×oF~K:dS<րDP:&0b@[~W}c`c ^qﹶqB ۈ4Pƞ'$ZO/"$iX0>qe F ^ψXˆumf`bj9NvM~/'a%S`%1 %svV/(%@k/LB #+OL_~I4Q*ĽҦ5\S<2,s6M=wo}š3BFK(dHxXlU8'l-nV zD6.ÂT.C@ C6T,(uLK3 rWcr^2Q+0Rb_0:/h wOkFS"EShp̴H9u=.~xמ  Er F[hiy%tbBT!+hi"lIyda^Iv $CefRϙy%%2+ м)a`s B3_Rԙ];F|sd{3אdHP,gN')PWmns^5GElEM6k'bY{c䬷o5~n#sH8- dS|N D-k:'$ inb{۰/l8.㪆JʪHÉS䕉%:HzXD<$'=׊pU m ڷ3MVPܲ^ ?O-[br xjPIeR7I'c`\0۸5e6Į;mm'͘׹k 93ވYAFwMO A-rhXTQvsrJVPV`2*>]NbB5Mc(idq{na3U\hmseҡ<DF"(ƿa0%'O$`+_ U jZeY۸,SD|=a$-JA~IxU\y '] f=ؙT$~>a/5iJ "s҈O+3'xUФYxm(2(#IJg(jQVt\hHvWN6"jLKQ2ȴc'Fd#d ݳH ʀ)E|6a0FB"Èg/WMNF*z.:y>MU&D'7m9X <2S2EdE_._?{ݟa((:K77AqF=TVd*̗,h$U^Yx`%5px)~J.?ĺIZBawg'{`oWuoe&u+ @j5,Wx~]e,\F˨}c84h5~KvyI.}ϴ{2iL-r;5/.l.z;=-,D#KOvWB73fČ R_ X<\G_W+128n'gV#)'ͷ"oĔ0.0#g \L{Ҍ9OP/L)E3rVWVE'r6C/EBXEj;/Z6ǐ K]VbϔI|m0XILT0<$ $Y6r' 0,:L$9|UĈ$x 2&ʗZ=b%HQS8!*&A(*T`_rr LqhaJQ›b/nE=9@B^'"@%<jaTb܉Cĕ%vI1Ƀ 74d2C"ђTXI'ђ6Yp% U٦HTQlz^@*Vr ̖>V#Xl[bbu|Y{{'~x;U}zV OӾVcNFY&?- ze<^X(vq`++ߗ/=KᩪϏcJ ]nn&w wW7#;>CXb)<+Q6ҜhqݤMeRXHwRY օڥUkYnXbH8IG19LԤ0M<3pIgdSb9>ՄAL ~bܼƓK_ԓs$~{O:8[<)cd<IXbG2gEB-W[J&A֐r+|״%:Xe  &WHpr]4A@3{X^St 0dzrGJ6W De*W~}MbBP:?1%L]& Oe5TCGKďbq}es{]Sdžd1+ ]s4a\pvqoh؝|[mGw<'D_446Y!>@ _\\~4{ǞAdlj%7 >iaDˆ;2t! Hے0& zlgT* T9/ -W^ə!K~Q;ǂ ;)tMxm8`2wȸ˯sLy?,ۉ4j y~mjm$rv !+mp); \V/>(guh "ߺ )_&Hؑy xtCj@P㢽|mbIT'B.pr)(-0B)/Hlr2HRb+RM2 p!qc `FjnwC Y/}DxsRӾXzqit`(bI.]0rg: Ḙt&7{4B(k82yL5c j;"aK@תj/29YO S-E<. $eC'%.<9Xg u#3CcCLI5imX%c V-vIENDB`PNG  IHDR&&4!%UIDATxֱ 0 A-i9+(AFH #Bsf!_ k?#e̘1cƌ3v &]*ڪ  ޮSIENDB`PNG  IHDR``j PLTEjjjgggiiijjjfffjjjiiiiiikkk5! tRNS*WS sIDATxء58dTDp4$3W-'w;,yT LX2F@ @P/~L81'EOkIENDB`PNG  IHDR BIDATx^kQw2IZk- q'+uԊEq… MJpa)*iQ|mMҦ4LÝIp!ΜK"„fΞ Xxd3L*ΫǽH&T%"2L8aGMgZ%mu«CzS*D U- = %t%pؑHU ;ط;PXy"CD B+ICcnPP=fO BOOh^g wlVXR |$_ /ndnTj*5gLc+pï$r2g|* h sBXװ+ȲUT(_ J1ٺ*AB={?F 0;,'vKIB?Y~-RK2 4#uz(B]Uz,@&Ș)L#gEPޚ_w ZW0=|@\$>&Ж سS&{X?%xp2Ub!qBNX7&b-LAku Z,[bXaKB8+oKfm^GobI?U^cP/93󗠛"d6c99XpI-H<@TRƑ`9G3ya_)eb8~úh'|6s &%|M a\ =^i%ɐ TT V83IENDB`PNG  IHDR>acsCl0`MbKGD pHYs  IDATx 1tLdM˜hhGNjz@ @ @ @ @ @ @ (pIENDB`PNG  IHDR>acsCl0`MbKGD pHYs  IDATx!Of "P(E4o4Q"DDA!Illwlwr|<+s66Yu&T?[:s27U=Z]vyU,Vugc3Xcu `W7ݶ83uUgmrnKS=R]չ:asXj- `RTGm|flV7v07uVglnK]ݯx 3XSuɓ:S8Utv:) `o5ǩsX8N@[ eu7?yKOL ?CخU=yN6x1dh^ s/ suVS=|"fh>58E 5c 1c1c1&v!:kIENDB`PNG  IHDR>acsCl0`MbKGD pHYs  IDATxϋVU13q$DOq)jiĕF%pN"m72  s܁wӼs{}ys]@DDDDDDDDDDDDDDDDDDDDDDDDDDDCcB rF'@1p;ל 0x=9K{|^SA`3Y@Q]g6koם -`G(@ |謷8 <p[~Do)B O`r$$QݦѲ0P{}πҢ#@;O l0_e{G6'%Ԃ`#`L)@A`5~x-vrB??lz b> 0n `\o +>5ɆOX M l(yDj}*ЏOL+.O+;X@Om*fʮ}  l˜W|y P;}aH ?&UI/CEt"6W ?'ƐZ ? `}p짆9y p(8Թy p>8Ö OǾ~HG S )tp싛ؠ ~((~ pΟ`7`ֺbP`2U !-a=ໄ1G6T/MQ'ЉV&wXD~N}g\3|84 mRLA *Dd )^CyHT $}H}7& jjo#Gf(A xXṭwA ˚0 $~?+c:&Av>}iTNm)`r F$m_5 csFy{7C jw\ !p~ 0 \>r)?<.;|V9#`Y zIENDB`PNG  IHDR>acsCl0`MbKGD pHYs  IDATxkA;hxI\@/%"'=zqM/ =( FA9 H_A !*>ݦ_aƞꞆ7KNIo8Sw$}!J =}\lLaj /T Kr]J2)~dd,7B%5!@%=|Vп靊75w :d13eJPgLHHF2@%~TD2I&A({R& _)g 1ktF͒ɧ~tI Ez$$_%Xˤ @^3WէUHn:9heKК&K~({0%h%H){~u$سJ1{&VW) A=ϐQWHS %`%Kxݰ=w(/L y,Yk^w3ٗl`9.ir$eɝEi#@`kVZ$p-=mF8%hQ K?' N )} Sgso┠iA8%< N y:ݞ"@S\>%$S+X6u!@)r{mP|^R#"R1]x<.C"$H%VBJ o {4 B / 57t @(A[B @ -&[u`S-I:pO7G )N&Y!rXxJ :H0$ȸ  X uKPMCel/OQ{a{ MJFSSS%%Cm uH8n٬x(☬Hw$3% p < `>lL Axk_I$8q,3mH$8go<-42Ij e&ÏDPW@["Y_0OPz)Ï@jVEd.XNoIENDB`PNG  IHDR00WcsCl0`MbKGD pHYs  IDAThMN@P/`WڄB.z4K W~$J4v:4fl@A GZtND;JmP0_k2uVb;C^;N ͸138K  `f dFB T W+P4/ſ 4iU0W?@#%>:%gGUF+Pc^R :R r}:֦s*&r>LKWIENDB`PNG  IHDR00WcsCl0`MbKGD pHYs  IDAThMN@P/`WڄB.z4K W~$J4v:4fl@A GZtND;JmP0_k2uVb;C^;N ͸138K  `f dFB T W+P4/ſ 4iU0W?@#%>:%gGUF+Pc^R :R r}:֦s*&r>LKWIENDB`PNG  IHDR>acsCl0`MbKGD pHYs  TIDATxAjacH[Q  ݔхx;=CWP7A B*TL3˗w~?HI,dCIvt`d ?Hr _4Ij] Ē$ɠ&[3 Ʌ<,2;I |sVCWyjEvi X=F @ @ @6I&ydI&yf :M+yõ+\q A ?=R|G}+-b(#ن x; @ x#ApnA`EtkQ `n^p-o >Wwܞl1lg e$^M+#####@ @ lQ?-r6EG~N-65H2W˦ucK]zI$$X™$45JrҒ䰩]$y[>7s0Jr,[dIENDB`PNG  IHDR>acsCl0`MbKGD pHYs  Ʒ.TUV } A+A+(bT͹dNN}0˞QIgf̊\nW#|"`c sQAxV45`)*=GrB"o"(=X)9q+9_aD@xl{G.Bh@ 8G #@p/ӆ@< 8G.p 8 =,|?o97TC֘J=j5.ЈBp0@@h h,a4}? `:TBP4%(`RO r]lp짋%v>&h@`2Z@} S _OahʬQ-x 9QB Z5`\ Rrɷod15M#\ pY8p=Z>,`6p&G #@p@ 8G #@p9 ؍&ज़L_M`qGw\/mSG"i@wE "z)(kӁub"p#p#p#8JY~"yE4NIENDB`PNG  IHDR>acsCl0`MbKGD pHYs  IDATxܱ  +PPNweD$囶G @ M/`_ ~/`@ @ @Q @ @0 ʩ4y@7IENDB`PNG  IHDR>acsCl0`MbKGD pHYs  IDATxڱ E̙ ,w6yUtXM~@ k @  ! @ { @ Kʩ4y{IENDB`PNG  IHDR>acsCl0`MbKGD pHYs  IDATx[MQLJaf눔Kry3&OI!ID.o(4 e4"n 5%"&rd܆|+I^{~N^^{}DK$"A9F1+y ${%LjcW'g3 $@-e'Hڙ >Pde-5>De-M>De-m>e!          b#"y(i\l,J ~uldS,:dd $STKJIz @|VXշb DD)@*%\LIKz"@+fHIJ2[g$%{$Ґ୑ n6_2ݮ~)8-$%Y47NrI$;Cht x@\ !A>Gn$85W A5JZɔtN2lJ z +z10DCJ >$-}! +?1hRiz\@:-@*͒Y>E[rߊ-)R~VA/ W+Q,E0y$Uz|8Ph$fQFr=OǼU\R[*/pE2cZϣ( B )uk"E흊Z  >É7 Z PSQQg"D[9s%Oqf`V \Gu@H˕;LUԙir{7:ۢXhvԨB4a'urYDz8-Bݎ 3 W0Qc%VՊ=zGv{ZW5J X +T). 5n8jTf\5&opu<n\09uQcc11'_(GjG3/{$@{Y=`*/9Ɨ:HZ_V4u& lv.x׀=u*v}1k- t ^y6Gt=> 1hkW2K':IENDB`PNG  IHDR>acsCl0`MbKGD pHYs  "IDATx[UUqJ%̐h%=DхJ({ +hXTv { K $#rtF{YAe>~>kk}ƌ9x[NZ_>wt88u+* A{YU ;`u/*jXYQv9P + հ2TN3#m PPPP # p /)]v8(v9gE8x"(@"*"\|70C`1(p# tZ' Puѱ5^R`T7x8vՂT8w WJAn/T,p5pP#p+pZ_*@M˾>L`4W_<lm+0*?|&8X< Й *@k\2DRJ+@kpV2WehmOxќsKH |/t462'.a@G>#ii8 q.R4`0sƴU{$= LӀ43?g:@nYx_ۀA:,ĸ"hnbgbL $tz H, Y N,:egffl -x>S ]8%ci~1+&v`87?Lk27WHVafb-(S/SwX]l^Fm͝?;S˲ XSsdOZ\`M([QCΔ#"""""""""""""""""""""""""""rt[!IENDB`PNG  IHDRRlcsCl0`MsRGBIDATxkWqN |`\((_c("7nT\(.ܨTK҄&&6&mLh[tι,7wΙ33AS-@ @ @ @ @ @ @ @={vcf͚5/_/QgPQo߾}|̙+V^wc_ bgg甃}Yj@r~]OPs~=s:T1Avqľ@ uqľ@ə\)R\Kt||( _ |Zr 6۲eΝ;g/_ݻ?9+a<{  mݺuŋ ={q֭Yy|pƍhp is7ob6 f.\xU"T\O{^xý{\ĉvKlw @311$7B#Xnݻ&TVLu>xرcZBB*ollϿZN>.+p1~WGV$qUK s, @<Bӏ92{`hhG(Rtw N:K߈+U@XQDK /۱c[9*"@Wjܹ`\riuT#|1;rU ?xs΍m۶mv!lܸq>'8eY6m`I@k4V rNbPj] \ իWoeL30Um#W R?tD+C9KSĩP՞k{puN@'s@-q,u,mEt@"șɉ{Sat>%S Fvʺ^@ggT]ߊqѶβv>iO+@jZ/}>n/|8|~)}=1mK-@ @ @ @ @ @ @ `' @ OIENDB`PNG  IHDRRlcsCl0`MsRGBxIDATxoMY;5TA{DR/^ăDܫLv:S(Z8kszznq{]?}Ъd@ @ @ @ @ @ @@ @ ̋/z?>~ş͛~LQUYw?vcccI&c٬4e.1h5eOuC4!ƖuNd0LcK:G)R9cG?  E @@o>A!ZgΜZz4вLOO߻}={5[(gϞcǎq͛-͛7{>uł ^|5kLmذ֭[:ps^ݸqޞXߚxpȑ @/[Ӯ]tuuaOn]bG! Yk׮:}P__ߓrȣ;w!e˖W^훚*?U=L @˗+TׯXh^UVM_rΝ;,Y3lM*0G,"3?u"ˢzM.@Lч18 Vݶm[sR`7+Q 19irwޱ:AX5 `[!-q.>|8kr1]g=Yo-l'j ~)ʉ E:WG%nܪn9١ss&A$JiN gS t @Q,ˉ5Rq4/_|r׮];qp[[T9%r$%SND۩T@^h%8Ρ=8&Y>@B*RU}C@-\$& 4u8r%u4{5a{"١V~X*3ݞ6ͩD+uJNuMHlUŲ>,{t @IHerc @cf9rq*5[C.]ꏬJ '0.i+W,n #7b =RJƹC' ƛ! P^.afTC>//^L.=XGZS4^5s %Mm합Y-J& "KOl/u=J]k$/M3uTi6Q1F z$Dv("VR#W* svIuRLm?>c(DZ--@J+6Ք>*u}|DErQ"@ ReX=k-@,{◿Y' JE=1q*ĘD'f\k ` @ @ @ @ @ @ @ A $qeIENDB`PNG  IHDRRlcsCl0`M IDATx[LUWDjm Mhľ؉IMZjM&`L/0 bF5F4ɀ %BQ$V8ĈpQ(=(Q׬5|ss/k74V8o-a>` r$qqp8'99 . #^뢿@I7пD_CPIfh-4F?j8?qr9U>.}=9'S'qå^K"6hN ^c f4{=`kj4aӭaM5>SQ.?5N;b:v@G{dK @5-&@ZA{|מMc4R/ CsJ<=؋)&-OG՝ LDBkHO}e$AARK9V>1ϩ h[ųEJCZ⼎Ph 6ֹ9M4Q`7]0hh.} O M oOO~oi^+)+Ljruh h&f\&s;<`vmKh0[M[, lD\1AVă vsʇb+؃ M$$8w 6 t &IqKx9 Ż!@)$iCсd$:%ؔs;lLwBLHJH>Eg;Pd 9; @~^9(.P|Ea"Z&QTV O﫴,g&u [BfggJMc`$]"&''9svJ-:(Q {&K.e/_F"#!@;l۶=xRh , --?~uuu!d3) Q^ drSpVPP?~ɉHHFdѢEܹs@NfG"/(XlܸݹspӇE/`ܹuttr G(V,_]z9PBY'Inn.knnFMPoAbY,` C*(}]ݺu uE`WTTZ[[Qgg %.pHLVYYZ;Gc0Ơ8 `yfv=` #GN^f`' &+Wdׯ_Gcg p$v=z>XO`FLӧف`2"&b8= r `~v~ֆNxV@%K`8ߢaSJDLn݊QO D)HC]0#Pp~TL& .dgϞgC'![lذY"A!)9a &GPBxW 燤Xp !Q}0O< W! ߸-hA`߾}ɓ':E]_/^[;:C!=ίt!ɦM<  @nΟ?[ <Cˢ,!A߆jn޼2(>\1Vy F`+l߾555iW]?-[Ʈ\pb@D׳u@ F"=.?s 䃌Db(ޣ5|>PzMt@0Ms' ` Ve+rsmi tϗB >jUtl042[jFs ^ࣇ^\z8]kI׆CGuI>{N@ +JLR.r]{;}<^r}@W\4rЇM&`vޯsr޿[V-~IENDB`PNG  IHDR>acsCl0`MsRGBbKGD pHYs B(x;IDATx횿oe?oA =[AQ;KD@j"!wx2eH4EH,'Z1%BHgeDl%CJIr>h.{;%85_ FN}ApsG[fs*]pgeKo6z!ӯc2 &xf8w1Ǹl6qMչyBD@˗zM/6Wz60 W$>Ƙ7&8=@M6+Z{7niAJT(~$@Iߑt q|I,=|߿+i,)7ƔJ>8./Up"0W|&@򭵟Y>8.O$>|p\>8.O˗xO, Ƙ'Nt"0%+ʘϻwe> Pް֞acsCl0`MsRGBbKGD pHYs B(xwIDATxOheߣu1 z,^ b)g6!Bxo҃ C2B`A1D`ъmĒAL6;|?γλJhjt96IeZלs%jf_KZHt1I͎ û I/Kg\jC{Nqax%=弤86s M~hfK ~O_ҙ(o EӒ>랖Jx)N 4}8I+,R-+Af.3@Zh$&ז1/4 z}%̎KoA譃y=#[lQ\'#I4RF$[y<냒5$I+X}SQ6w^]ċ;eق Rߎqlԝsu433MeG)}kSZLO:77[@ewùy>Fn5\.>$F<55{}EJrszۓp:EQo/}@@g/sE1eE<6}XCsfKyZvcz>v&&&b^<ԭomm={}ƻ8{}Ex) ç:}JrBH>T*tQM:f R_3k׾۰9ݥRi9' XߎlwnЋ^~= <p>~#hs߷܇[ NK^zZomjyyР=IO'lIISo\JHd5˲g%No{,ˎ&Ire' \̎*ĺ/ZՖvUl a6yIwO9/i$[Z틁^twEIiPߪjt\cg[Zs]0$-i$&m,:~=IENDB`PNG  IHDR>acsCl0`MsBIT|dIDATx=j[Q5lmL/@IpmHuZ7C`p Htȅm]'~qax_rm6-ˋyk$""32z˫_۞qL0N"bZ;<3#bsm*tzZe櫿93WJ&` ("zIDg^7~7i/ˋiW@k|3JN8J̻1*>*a.K0\L"X,n&ɇ׾ge^~DĻm0۟_DQDeOǶ7RfH)RP }LlV.@)DBJ@)JB;JP ЎP z"@)n @e6B*З]f%BJ@)DB@)D+о*P (>g,RfJJ /i@6IENDB`PNG  IHDR>acsCl0`MsRGBNIDATx=nQa&qT eAqeXJD %{`'TQH ;羖R${9"B@@@@@@@@@@@@@@1M9?m?ݮλj4}[,ֻFo'=U~2~u&%]LB&:.L&!vC @g& Ρ I]Pم$`®s(d0a9tva2 J:0Lu%]LB&:.L&!vC @g&}.`:lK=N~ w4zZ=_>0 ~I%7Np}l6V ù]rd[7[gD |G |8,7w\-][D#p|Ev`(;GfxB-?\# p.?tW pa_ETjxc,:FP L-^WI=msUPI<@@@%~ntYCk?7yR?#(~zܗp_z4L8 zx4xR G- zxԷdl=8e}C@@@@@@@@@@@@@0x&"jcIENDB`PNG  IHDR>acsCl0`MsRGBbKGD pHYs B(xIDATxKa;3IQ %B&bx,u$Td$%CtX:!( QYP3oN]vtGw_}>ww7/(ccc=7%]+餤 J}k5f;{cA0P.KJ:h$ɹ(~t0ƌrt"[-of짂tQ:Rf:EY2Ë@ @ @ @pNOOm[ߟ;@ !1F@ Gsgۭg9@ v3\g6~0GGo,3tΧrsw)] sI9ql(lAVcS&fggg=Io3^'I46fbے0ێ$ɝ(3 @*JX,HZ`YXEFwZ-)3)r\B@Č_6Rz#Q8cnY{}D|zc}5 >t,5& QaLiөoHHQAT]#_T! )j2Ȱim5JW?JuO v۶BB(ETsX4Ě%D_@qoFIENDB`PNG  IHDRr ߔcsCl0`MIDATx^Ag\Q{7!RB(a(eha4UV颺(2dJB em>5^s2ͳsN@8@ b<#( )A/0u N 7Q }5_D F|N1%bgT0TP"9piJ& XPXHgHKEY`YPհX8kG22pғmiZzAbF+<0:{Aڱ"E=ʫ8A `'cFs;segiÁ-\5=٠bCL  e[` Pq {+ +c.hJIcGu K۾<~ :{}vg_viT? M|2N}i c9:wqΎnrqg;&wp @`Wbs"<^o2Ϋ^kk."Qm__^3d H8QE씝`*1w60nQ9\r$Bљ}DjZ}PDKJF^ޥ܈Bj -5ry(Ɲ]3}SeDsu{SG/]IENDB`PNG  IHDR7XIDATxcAn*x=XtFxSQ"K.-'%PirLwH#crdit3iIENDB`PNG  IHDRJ~scsCl0`M^IDATx^ӽKBQEXQD&H[CK4ED2Dc9CP$DmHPaAz@S(3c&K;N ЇeLxEPd7R䨑$A )NƸ&'Kq9,!3L3#!2H\ VG+Pe@dxYB l I(]v5~%}&Bo`yiN Z h4 eXS,fy#J[%ud; ąIn&W< x@b *xS|BQ YV$dxǍ6 Ff?)ڀhds(>IENDB`PNG  IHDRJ~scsCl0`M_IDATx^ӻKQ7LZŭ!Ab-jPCcSej(- J.'8{ پ%BG782M1 AUxHJCNq25@/a$AAP l/ifp`B}@A80=6 4D8A*bQ: jEILErX9`1C)>J3OXLVC29n@I4xK~z&kW< x@b |s(3,C̲H)ۏ3߮ q)A̩;vIQ`?iOi#IENDB`PNG  IHDR̰,EIDATx^ 0 +/IsG @4D @4D @4D D @4 @4D @4D @4D D @4D@4D @4D @4D D @4D@4D @4 @4D D @4D@4D @4 @4D AZ4G6*6 @TZ4ޓ dEC*=]BZ4fOeTl25%tz Ȇ{ {w"WKa,!$)Daiܯ='G=*Ch T1+ΆTTĻo; J|49nɺ ~aNE)dՇw!4l`ŽB|x@ ưGV>#Q7NB [ޅ;:i(i8!@v5؏аѮQ_ Pа``75=[&|+ `` :=H 88 M<{@' l452 `sΡ0/g "#4ITylujlE0:t p6CChp2 r daChl"1 )^2͔ /%4F ="u/g蓑U qgPg "6h 38Q`X3҆RVYVDpu5 h<' y㝥 18Jgc?BAQ0GYC9 NST8KBHHWVmWzs{ڧO缺^5F!gP2,YGTHJ1/\8qI EF@>vmP 5,b66!4bmxAVgTXcڀX8` ;HX6D; Rpn%;  cPh2,qDi-6g'FCI|Қ2EHm }h𦄷%$g$3޼Ċ(I'ݿ3TTوƔ"Dbpxk8Rd4mXQmCI~Y$#*/dw4&6El )aO:UG0@GTkt  K N.2Kpq6H]Bc{B`Y:8n!,lIޘ\#gPFz;J\ @C2GFb `9ZX%IrGpq36f:'02Ƨ7T5|&S':NJ7=x?_ Uw,c_kӓmBqw|_[ 1HOx1©FglR- eS z/B .$27SQWGhde|O ௏R~~kȔu^LC!pl떡??|}h6\umT0qսtǯc_FH}#Lcɖp`)Eo FtGߜ}t&@;azSPf8;MƆŖ ܇l"B$Ze.3 ZQʉLìɡI0^lm`8(K44?-`s)U_J4q%P SV]`*7&:5L5c49n%לL4T'>R?߉c߫v-5Koԕ2@@nCXpE5W94dw>þks \O0FP3iWe Y#0 7%>!#YD0[#t}F82@Ԑ^#t3?aFr<{` 8{q<"<5v&qSPj~|F<5gYM1To< NQZ`/LCTf}JF@YUbOɇ~+(kyhLC|ҵG4y=Oj]%8쿮WXԢ6Z͍qY,rBE1?5[b8 @]4T[%A\CuB4}hMOeJQPsLe\ 6P8#EZLj1ã'GE x`gzMs-}ryt Gpե|xMJq?`\}{z?1 =U1+tiPoy=c8jAKi*п`>bl\_@k*ɛbhM:ʕ_~eЧ*40r`m*Z"4FƢko_ *o+tyߧBK fngj`?_ihLY\Q4aPZi@4PxFx#UH[L1Q :WU#\/zj 'i?] Amcʭu/}(#“Ag1 kOB`ZEWMv-A[ @5id46hN$j[o7M~IQ4^%C$i:^?1 0EbLccy4 gDxOH *:EMh h h  hh h h h hh h h h hh h h h h  h h h h  hh h h  hh h h  hh h h  hh h h h hh h Y¢D#?yғ A~yq<]ĝƼ8P )WhLu M4vD$H.RnU|4=) ?)yQAՔQw4ul[M'Lc=ZQWui[ڢ(PWLc W4p%+d5Bօi9DvVMq6cIJPG wBw8eO&5dϢy0 U0&9u(XIGN0JP\tOD)Q1͇*`mfd:UJ/Ju4HB/LcϐsMY}YLC(k9R QOe}Rp@>s]`'Q\ wr|פfkC4EUeo"`ae{~IC`j*Ϣ 2riNF| @Eӕ'y%سi=s2qA_tʻrLC@zX\5smd*f+io$IYUA0FՈ.#ӓc{bqp-ZBWɄPaaQIP k/Fj k[QVZ}LCSFPtP Ӓ)-U> "Y+0 s-&j]2mb0eXa [JH hFעbx[;>G r5\iD^:__SUJ5Fʕ6xxnErB^)(!&KSIG]Cf8Uo˗nA۰f1ojaf|Z+Yz*}7rXTW a ~O|yK'+.h " 6u{'l8ۉαPN{I|~d@s|.z-W0WHl}*J 6^gO8Ho00"+46Xp!֘09ʘp@#P`Wş26XW.20`J|9 \*fa h8x#eGBBh0,Q3 VgkrOaBvtBꔠB 8* 1@&h31:<# z0i|FJ[`'ߛC#tsB7r4`D˓$S~jSB'娊0pyB. pƢ4p 8!Pð&/Oֶ-0ׅʸFpu hOHhTÜ q%{ nb\".ѐJSdc * Kg?Q=S2K 0'7t嫁$Xku:j=uAqTF`Ś!H5_['{u"g\1e}&IF-[Xh=)y(@;lHkP@#*^ȏa wpI |!t064ঐCkAv` x0`w+ڡ!h`MU F0lP>hب;#w|W}d}l0Qx۫+ 9,,>0jvQ@ˆSY|`A@A>Ys'rP|Dg+x4(|oϐ=e^ A ѐu>T3%X AK/mp*@~l{e$OH3sh[ yve=׈FSfW2!Ee.#(:D @4D @4D D @4D@4D @4D @4D D @4D@4D @4 @4D D @4D@4D @4 @4D K.V+IENDB`PNG  IHDRQgPLTE1MtRNS JB@ErG9!% 8 7:"A4/6*,;o5KU3CF]jn#p(4qIDATx^=k[1NJ@a y[ mLߠ[HRcMU* *~Q{̺⺮G6.gU.7}z5fyx>=W#uh<QZFJ8cJ]H]ˈz>QL5ܷ՜":[#\j3 Lcl>r8xjes mJ5 (uWZ|k(~ SIosu{p]Wg=+#F[+MO.WF4]7'8H@5vr>1߅D8;ܙv2`|&U^Ԕ4 +^B//i~@h%3t6;C [fL'HVB@AKmlB„FbAXO[Fi q,uh@4 0K'@16 Z/%(w IENDB`PNG  IHDR&&4!%fIDATx^JPG>7Ԃ3};hw:/Phgmz-՚I&.ĕq tG"sāy[}$Ly}_\}pǶ sL N|EpRo KZYžkkrFo-,Ʋ,ڙe'YVѾӖ٩\.O8^dire.ϼsh-Gdile[V.}[չeαs-nzW|F1OƍAE2Rڭ{ i{4+ʪj@0WzlU-Qީʲ=RJL~(Zr0 FtmO35RU  3A 0O"%SmIENDB`PNG  IHDR{` IDATx^ݍw$3dI$!#!*ZV*.V,*K]"*U+EʊZAuQX,Vb%{HϙsvOI2O~ןys_zd2@F #dy4@F #d:`&8pl@{.D%XzO,QxqQ0"E@{1TH}+GDډS4kAiɴ/UMo"m, pN,i{_SR}+l"$Ҭ]('x8ǐk46n҈%paПɷ<)msfxm@[ #&rƜ<1jrۀ0hR^1ת JH% 舙cxUY䓨/* J8Rs0Q7R)gL\| "l_UAo~(`\^/TPsT*r&`R~ߔyz-I"\ 5$w0d<̨e^٧ʢ>D`FCS{/ʲRl>Q&3h??势8qS"F@O\БPlHYV|?URd% T'w}*$9ex/*Dٷ`} Y~-z]̜K>\BPkwTS[D&18X]kҞ*y5Џ79aUEB|W'M8PN:8S*Yt/$Yp^"Tn{U<}@~b'`M y/|z˫a:V?/+ ?Le@E9"܂Qe2 &L%DKMu=SGe7(Ruw0~DYptoẍ́OOHc0@/n\FJl zڄgg4`w{֛Pc̅/tkfB/4bq~'q79XU< 77]B v@ןACP󂥌 ~@wΜ1Q? ]VPK˒YP/]aBg,]Xk%[ZLJkz57PUaE@s` >H{/6K (!3 -w76PgQ@_3Jςo9\hBmjzM^ ]*ϭ3gAY/p|[sNP筪_G^;ie@6n~/zVm2 6R + dzkjٲٚ?VsJW0$^zS'2 &т^Z5qe@^d[Q\j@JE Ƶʀ:Л'׸M~k\Cw j?2 5ǎ*gk9$YPXj@$pz̸p#׸\]DxrI/I=fzH>=Ӌ5Kq5 o~⾋0b M #_Cf i#8q^㚫׸4羱=V?hOGyի&:ꦛ?.\]S(g dFD%_* |o?h(c8Y$GY552A$wq#H׸~2"S/>r9d0ՠHNxA#8@ןq|/O<>~u (¯}Hu/ёYM1~}}trr=>ɷ-g48='OlLE\gW8ݩlI+!7p%OQdƓN p&MVwS@<8:I4}]$_T1X\MYlɪq 'QQv_HJD0|];M5;3;Am$;QL?"p;'d0 eHuM&EBP;٧m#ٳ3\đ},a$zOW-#XXU:A8>r˦ Y5`̖"9Qs YՕW‰gP_U6d FЗ]{94>\wGsQ$QX\]}=E4=M%##ĮO`KM"g̻Bv@7>SHԓk(&8"F? &'(#o|qdsº@0c䌰tyPd-[X2{koH҉'EK~t^/~QDIDY!9vtSL) y2tS]c}CC}FUw/xl*I%y4ʝL .arbŚϭrOWۂaߧR w<^,.|1GM!ap #l2I/>a=G^H&41  &$#h"qBW/cLn'N\z?Y,HcfA Me7UWu*" 4W82 ^l Ј'+Qa gĔf-7T08&NjN)-L`0 V@*Wn-)g xM@hg \=V/ZH@hv7(qed :H9uMX 5}n] {:@כ@O3 ̅ &XĒFmw@m($0F<$>&Ћt.in2ÏYH@h kMOL pʇ" 4,o1)O%&إ+Μ1O`%@ e+M Ҳd9Ŗ%Sd)"OE‚u<$@`G@`7|u|!e~w] %pjj}u~D0c]ms1$6 N~2҉/ s q[֟.< jO0~F$NYsRuKH ~b 3/4F\unxصrWHh)]}#եl-NK&M2C/ݻd6@ 89_ۙ4K YuU2): #H#O>K~r/\p%lb^XEoP>s[՞Rg|e)%71$'1I~3>񯿩m9Uw)7S(r@"Q 7$ЏL01TQJ)"ro*_+A8D#dRIO~I%$CX,_hC$^K$nq@O @F #d2@F #d2@F #dF&46IENDB`PNG  IHDR{`7IDATx^{x2LHȁ0@$HHHb]nJZ<PK+Ru"ZiZ(xU UQg/}ꖐyy}g2ɼ?T%R R R Re*@*@*@* 0] 8uPاo?݉>"!NNH!LrwdЇ$M8n@t]x&Tr8bʩκMu+ϣ2'=DL)K䶗^ػAOڎ޺'~2]HH=@ؼ8q# 7ZZ?/a1 k?^P?VR+)&d"qv?2^1u_iы<8 lFv{CjG>j*E ?7+M7uWϣtM@e~/ p:47t3%0ŁxغQu,iЗNuH/pRʼn^֪:(GLI}ƍC?9:0UNgI$:X50DųZ[U1?d(4`*z]%_/!0'j*HՈ)AŁF)|oI)DjTߧ/8RM@S\ēw |YŚ0̐U+ys 0xIdfeIi 4A{v+瓬1iUeϮ  (1UY;zh d%d 49*˳j! o*~5I&T{i $G_*>߫B߉D>ɚxͨw彷}a& ,.S1)H ׫m 8qKh5ǎfk 8%6-r5`Y #&]M.4`IqE:;wgFx?pMg y^y*M@XT\DA塚g㟩bI' +t57gsTj/xʀ<* aĒE[[yv=O& x>Hީ D8U"S9 ȺѰb 5M& MM4 bv} yԚ՚` &x?5`Aq 1raOV(ycS Z?N` 1x||P}Ss  "^'K:s4@i:%@{(#SȠt&8qb2?8M@@I?n[2 M@XE`w8aŷkJe.5㋖P kēIٝL Ҳ?}DXE{Z[M 0o1%,@ew/om3@E2@iM/i ǘAq|M@XJ`ժ6e8} ۇM 0}& $Pc&:j2kVAO!,%v2 uu\pM@Xuh6uO*rEWS  Zɳ(ҷJI?GS +$џ juP9rV ڸAC+s 'Ѝ\^yʯ, կnTZ@D'&e@>yVH&Ue@p8p~pw%y'm{]/z& z0&xtI$n$w <Ɔ_]e@<pƒXE_12B ҉ZD)s㦏j5 pbH/( Ī?Z|i׏j{=}ogG?5 ʀ|'/\%GG y[dS߭I#&=Fgwꅚ@$2)}յG|q hRHŝw= dG[ @>^7';MX;;bk_j@?jҖel$;'?vIt}{O;7Q2r;f/ٻkE?Qɐ_ߓ%D8f]p`M$۷PN8;.IgV<Ƈl8ҝ9 ۔"inFIxpy\.ޥtq~]ve$sxph2e$r}Hd5sM#iS\M> _FeH6vGi0f?>ur 38 ɠH#TM_mlء?~}^q h#(#)6{n"cR1 |CP`W #q^ֻ?1P0bԼpv5< 1ȻF&)q7]l,nS\FwN5΂B\Fz#c+׻<2YR+.Sm,݉׬^7".L+u|eI2ŲAYXO ڞ4UW +8HA,yvmAIENDB`PNG  IHDR sIDATx^1 ѽh#D._eLCd- >9 8T`FS sT3|a#?Hx', & $F %h6BA]IENDB`PNG  IHDR sIDATx^ԱjPƔh [rv(w"(j`T A}s|r 0RYB8qppypU 2k[lejMIP6fDODXl7KP< @H{M3+2L3 d%Ďr+sSSs+{K+ y>m%!<ΤyHWaF[!΍R0ȡc+8> 4y%IENDB`PNG  IHDR'ՆLIDATx^1 @ϵp 0@OU4䁤65+jFڌi3S0P2C30^.H+|懝B:0IENDB`PNG  IHDR V%(IDATx^M 0g16m@B&1O0Aw2p3 &L8 A&,jY*Xh*XXhHV5rǐ;n ̓e\:.q%,'yhWD*ET%/ ~l5Vg& 0;`<Y?*MAV &rCeQ {5GY" a(0J YC"KW"wj"HaB-H f`_58V@sǑWas3>2͐`Lx `SQp;^?7O3 yᨙcQ3 yN= g_!o7 v6^IENDB`PNG  IHDRMIDATx^ձ@%H&i$.H8!U4lj>֜+z w!IQ!Ӊ:AtkuЉh˸%+͈l"ݴEY~t߮LOfnAurlƣ%vO :P` UC*ׄ"'Z"HaB+H fh`h_59V@sQas:OuJ#nFnt 0~x `}uyr:6뿮͚VǃS9нllh`!/.}h/d:Q:NutUޣIENDB`PNG  IHDR s4IDATx^ݒ۪0EWNV⩈wTir|uq2+3d0"`1>²9;2E-'%B=GFqa7t$L84I-.`Vc~;C-sF_bj %=k ThRRFjBDaTkTl %SP;+$Br)X0Vƒˡ<9`"R2 3)*WqRH!Uk^ŵdJDjw΄\ذdIS; V}JF 9gOsAYQR`[:gIENDB`PNG  IHDR s_IDATx^ݓ?k@@`Z2EAP"EpQuQAmpGKn}w3B>r֍%xa=daĊ*qj?OHRg"߫|B7P$GSْǻݔhJGcb):^ [-4*r$avhph#1 P 4>pGh8B FN^:D$J2h_5ɈTxsC“K?_(b!K^+5B*eM%j%3`\|85N#ECGh v, `D$_IENDB`PNG  IHDR sIDATx^ݒKrQšE6UE7'q٥\Ї}`c`Xtpp=V=?쑣Fu'X:k>wl|Έ$f8b'#Rɒs V^@Bc8?W\m:k m7qLTݤȶ=ūQ1݋{mhd 4Ш Qq#rhFKO`P"@tȋpE,b& \K } u0(l!hdM qމAR󊊧–">KC2Pp̽, Q]pK6T`H)cS$44g@3* #UlIENDB`PNG  IHDRHHUGsRGBIDATx[hUwf^l^J!(TھThI6ꃊ>(mTlS_DžHAMKA[QAh)(yiL77w,\v9s.=;sΜoHX2Jɟ]m qR#PP[-R o}BL>t Pjy/!%T?e}9. i?^GOUSJY/ Cq"yζ3Dak G泇-AǸ ؊fPnثosk8 ye^e ;jЬ }fP^u^گDcĽD2I7ƕ)^^]ͱi5@|J.5Di]j5gξvV5ztd/ofkʒ<ܼAƓŎ߾eMQJl!@#W+iEA# pevjb^SSkDLIϞ*BAJoqV )VIZ/{c}-Rdp|,n_ٿ=oqc{崯׺6|MB>J15K^_CLb0Up`hMpfZ8(T(h-r^9\lWS֪0Nr'1dr"t_mj7_M ׹gq5J|6T/j|RT<_U 9_ѥݻN;g}ZPk͗Q=1u` S[`~CIENDB`PNG  IHDR sFIDATx^ 4\EE/V Ah@ T0`4 sYIENDB`PNG  IHDR@@`UpIDATx^ @t6 !@ x@,C01$8 @$8 @N @ @T="xH!IENDB`PNG  IHDRPX PLTEZZZZZZR\tRNS+NIDATx^10t)11/.Nzϋzr}F3V@# f+L0ä́.&0 L(`B P&0 L(`B Pz6  k mIENDB`PNG  IHDR66Ej&IDATx^ԱjPvtfgߡkVw'w7ǂK@G:>@Q\Ԃ>4dx9G?DDDO5LE$y ay?$%gD* ףثoav{\9&lW.-Tg}].$/)s9\xa K#c؀yY2,cIeb;e1a æ pg(a?`YQ`1 cc:˰Űna%A[9> 8בSIENDB`PNG  IHDR66Ej$IDATx^/QuwtѦ`ڍb]lvA'SA?b4? Wx#x;xrCDDf~ T3/QuXy`Eu&l:ijBЂhRŅt={C&ja5mվrBbjp9l'Qg/awư;2 ș$0I,\S~0l yFe%F9sIQ+f2a c%$úúImDDDDD|*:}YIENDB`PNG  IHDR66Ej%IDATx^ԭQqFfjb^Ŵ{^F5,,FXw.awpÜxS|^Lm& aY.Q ؀aEF7DnЁg= G5/"Le>M!|a+V`4aB}Ʉ|%.0ߑ1@dg @ 8 xܟ01aT`'}W61I ;Wb1;D1a ۂ820eXaĠGo\F֗6IENDB`PNG  IHDR66Ej$IDATx^ԱNAaAВk4t&5Ґ^d{Fu苐G:EӎpfEQFOk=HFԣ"#s. +j@w:?0{Aܧ6%H.A)- ,S ;sXy9Dڳ3lDd3l0lڙ g0iE*Kaϸ,akžXgLqZW,e!Y̰AA̰ A YC_<6wIENDB`PNG  IHDR66Ej&IDATx^ԱNAFaQԒ +4t&`s0q|| 1(La{L}Za}X "VV1{?La S3 QlKY–-k}_^X0)LaX "úúEUpYA3߳]?j{lIENDB`PNG  IHDR66Ej%IDATx^ԽjAa--mD\B.R xZjk喋Ԁ)>+Tp9~eBRQm؁y`Т  BUlo[wQu8 0S#}O(>VK>mT{}G7>$ ;fnl0=#SHH"g\X2wvvN?301a4a 'y6v\pV#301,cI2, _3(?RIENDB`PNG  IHDR66&LVIDATx^ohU9`#]~#?2gzL3c!#l4AX,I'"lɹrHldJn"~m`5bVRvƝ$s!N胵?vs13Y0% B*%"zo-a-|sP=M )yyT/dYhd{iwP]B Es0wd-pX{vZ.KD|-gR}1fX"\FbIܻ߳ԏ$09um2y#Nlb1 j؈ 80B. cM#2yvzMc k#:1WEqDXIC$4lDUp5/H}Auu pSȣ4(5^kU)V# 衮X=A # XFfaqrs`G4zaidB4{azV|d:{Y9Ҭ^+4X_ RчwAX1,"aCq0F!ȃ#b/R `-eI!Ґ=D,h_bܖ|9Se#>̓م YF*E,rJ)a[#eGƒ E&bDC#1Ғ'r0q\G\ & !N,&$#Q`^M850%.VG[\8le j#M."(ԹG4ZG!bccl^N1ƬŎO8;VIENDB`PNG  IHDR66&LVIDATx^}hUs6os4X j6+`i6h b$Ӌnm"P'H4hmDopxg|pyrʱNVl?SOF#^`=hF^63HES8 ,bI6Wr4E>=kP}0F :8mANQkuT4@x;%PAȳ/´f؊LbۖzUfs|v̽W lB*k2Tt4`?RbGІ :MKTvtl?̏F3f[\ɴY?7IfRy|f<WJ,a/:{RߙQU,f ؍`~yPlbhp9U#l ݳ.U49k֖G.bbS,&B7j1dݎ؈;NVkNI#1tY}Buuq8p$h @뉰؋=QT,~X,l5˜0d"\SbWfA]k3V$lqDؠɱ!Dجc=3_٣N͹J?qu7 8ϙ ҀfYe'3"BE؞y9<}WuSgG 5 b f3 -F&("}ly'ěp [m |JTѾE o-"Q4>X3"e9^ GЀT-X/Ҽ=0mY6J;l@M{*7C,GHtPC:G l-Ksܥ ^-1\@[ʬzy`Ͳq#L!8F;C*j~7Av"L_؋0 !g`cL3a1#lA9&rg!IqgnNT%3O{@HG iV+VTN"tN-/VA]WѯL"Z)l„ԔK 4U`fA V)~`P1SqekDOB6g?փNge 0’P^#@.Z9t2no̶Kt&E\DLRify_rb#E1'O,Z:4Uka C?ǀ=IENDB`PNG  IHDR66Ej$IDATx^ԿjAaGl }4E>`eب^Oq[baf7gcA?d,!""g~J`s5*YB rC ݬE F7D 1+xzD% ={5!M'S56QaKֹc2䰝FtǾnv!a+l@dg}@ ;: ;xܟ01a4a}7b|%b~4G-+2a cđϰðϰ" aYC S,0lIAY¶`(k_R1a ۃd2lb1l2 op|`Qά """"jCIENDB`PNG  IHDR66Ej&IDATx^1jAq5kRZS{~K )zRD;Bfv} ?9G""';y C|d5+07I"NVBUZPmXBߣWQ_P{s@E%a sPawj9l'Q'(ݱawư; 0)șaK"aGaG301 L Z^~(Ӽ('b1s01l ƒ˰Ű˰"`bV,>@DDDD ?eIENDB`PNG  IHDR ~6ze `IDATxO\qC:_EcCL梶.+Ֆ% ptuQ6U s^Dz2j$ VMZ< `pÌchUwzt$b{H]y}ŹPTԆD X>wc (m  D% 䚕\M<DZg}̵Lbp,ˣRQ5r#I-?u|X d\]ܒ,\kA=bW.߼-6[sKύk]U'\KId6K"z PI 47%\Ӹ*H+'lCGC^jZWRR.^_EIіz cRjR}I_C^}Ur=!y}C sx(%W ˒?F^f&v0M9jUf{ 5F[IuoԜC 䲺^GIիC >y?t_{j}}l b\z"}>G-% 5gCs>PkA7RPK1!kνǒkC >Qr^/1\JA7suJg'߿dQ^Gғ eB)Rr>u:*Rqdq9%rVɵ륟ۜ9*9=5QGC_rϱluk#KQc<>k碻Ģχfs#?/Мt9\Xg0>eFwH2efK:jÛ)C4\4D0F'%C _a-5搗\%!bҳ]'&gSQի oC_Ěԫ .='ϕk1ϥ^HrU1+MU.%ך.9i争%.Υ0|9.zK*zk< X_sRQDQz},3)<+|=7U^Ih'yzXP0(4Cm.kKJ0O^El#hO?x7q GIի[ \Kr 5j\VKr;ӆvx}Ii\kI~Lapn1`[֫Er^y_\ai-ǢUĎa[˦>,kw0hQAiE> >[և}y##ÒlyC귨-O2 g(aX)#ٗ-= 6lZ_ڴ9@~Y|~Wy[桚#Â;vԾ&[G˱+ε,:W\\EuZ/_L_Dq)]$~QCpZi}y#z\-GG>%z`kF.086 r5P \ >rb䪝<\Kt}oZᗃAW ׎`9*זA:n[<)|Q;^ޚ؝;c R/72Ȣ4,2 ,egޟ/5L ؎a,#0Q^!T%xh7eZ%QZ=WAV3fp}zCeI Wg\}(&~LK'k+1k 0R}X!W~B2Qqn'4GP)p97 e9 K3yT2'xʡa1͍*θ~B21GԇKry$84xa^kK6 +\_rLnDK^593\ⴹrZ7땋C?{k1/{8\(ǿ־JjƐ-#V_2[ù|OscDs׎R>G&\QFЊ?ն5}Q.{Ku_9bD:$2ݗ[Y_CCeО_=7"V>؇#_a(z} ~1_/Ɛ+7xP=`^E47%W~}ef!s~9j_5 &!V?΅9p>-$E늳Y{˶Gڪڭrybc' i6u= =%!$!c=zhߞo)Tْfss=+sՁK+@粷?^guGvjqHk\XCzd$CaEa^q!=Brhs{51C:rxȵ#q \^W8_!1|F]a8=ʯ\^eqx{=1J0b5=$\sgo{ʻ)'=䪗!_eKS. gx& {:x$v(_%װ}^\c9l蘎h>v;r;թӴU)'q]c~~xli#+_ciЪqo Ƴy#Rökdd!W*zȕ+e劀Kc +7~>)J#Wn'q (k90b|OrYTd2ư o 399ky3qF3ד.ʥ/CNWi\-g8/ N. 4su㚚旝nCU.-[5rU:CY~ՅUtcbbB 1E:/hUf%h|šn=A{5s!ƻQpukp1C<Z1$qUrXG/:bp_q!\nACꨈ8.n(9y 㰜+_*͗%B2*ԽhbPo8CZ%F*n؏_F/BKfB_A7u..s |}j/Sl=cmkIt+\*/M_up\\5>{vX5yC.&ם4(W+_:|\?`Wof׹6`n(suf4mꆍaOxmh,>fr_^wg̸]oPOJ\+׃Ϯ=+5<,?UPʒ_U Ņ{F߭u:W/h7_klB|DLZ]\ȥ/ D;56~A/庇gM+ ESqߌ-q(ž3".vz :h~-ֵ`YyH\YJ.~[\&>ئ._q(6/;.!g\hH$Tht_ES Bs"]=?DqH/4ؠ~׎v{Ti8Ѭچ {G3bѾ~s_Ѝkθk_{pz9B^e%Rt8n燅!4M{ ;.]z效lM8GT2O_n rA^rLX쬱bu3ƻX2lV6 ۗ n]sɼ\6x\333~B_qK~ġ \ȯf^xOwgW q6SZ/~"W _{h ?΅{.~yh\fğ_}.-by/t^|\^_qA69\_JUl\qYk3AFFWW-ӯ+ELV<₦616 \ o~'n ӆ2ab}r3  \5qcaʍbͿ\z\2ұ_!>h58/>+\G>1!%1z- WA\7جo8BEEc:qu|bj0׸_G?q7^-k6H*}k_5t5c̀5ep/o}4UƣTϒ}=C{l?KHa :wy%C7mKj*a!]u]si?::0*a:nDžɭ|Gzq#j+\r=!{._l¾S\x,N.;`us\'_glhu8Ġk\0:F_Hr=  \\:ΐ+ G2j/b(pLg>C̙̾ޠssdE/ԹNzDO/vFڸxΗ Rcˤ,{E-E6Gnrf`MD\Od{ьV.&.뤄 {8`3.;CaO{t.:G  \.pɸ~ǡG\y7T:t\mῇ=}^Izkt:M}OfifU1 c$}|t.FzS}wҜ_S ta,?xڴq}̰ϡC]ї&#n3erYNVY[,3|le\bs}|mŎ<~wݖ\MWlv2ɅgIԭ8, .Y" fFfL1,g dUj= W8tuV\eژW_0r9u#;denZ2C:A_ bZD '\ex-k9׍ez`ڜNp;6ŹQa\d\IbmJGjen:OW_gp\넌+ Zr Y=DVzHdW Z>ld|T_wZԵ(p<>Y*684O7׽o{}JyŅ@й|P搫l1XAqP###"Xk׮Fss3 ?L/4dp %^/jFGG5x7mT˹ppBnkrйqPɹ\+X!1/|}HĿrg\㗹!_ߐʼn ms 8ݠs59}W\ %$QLzWJN-\P\7Ò}j,Q/Uh1W˾`T8hLif|OuT &y\ksM. kXSfpݚEdk!7h; {k|國\Do~y2Wte\_grcluj{g\7uZ1+Eͬz7iyIF~srlն/}94qMmMkΝ;nܸaFMM; ȶR p{Rgn#$W G!k\A /X5u+(UT(ZXUgP$_D7F<! [~q.+X=lW+1%mayn\ZJ}_␵nv(u u ݨn@aGWM re\y%WݠWqFׇ!£kYAj7enjpkUaMk G\u kXKf[*r,\{:j\\&_%W.O=$4G%_ l!>_/7̿>D޽΅Gq2\Քy 6?u}CW?ϿrԿ\6}D5>m͡Y6\ƯJaBmΟ?oA4 ֩xV*aqKİ\@%\Ia2 W/\(P%\ a[pqCpU(r%9qX .žs~v4оys~o3[\.=$"r0#.ĖJ~mQPEL7-sⰒK=OJE݈%sLQ7*}Xo8W׍\qR1b>%So3]wq}3aY}nBCŎ/5^rsM&,:JIaelsڢU),!\q _ig\{$Go\opI f\g\yKظf_Pq|*_}.q(8ץC?u_}57)ӱL!y}0pATt#ɑ %y`<˵dϭ̯n'u\)!nM N%Ky<2]؉]U낄0b[}?%\}2W9tqGXߞoŔ?4Û>z(U)h=tÿkZtu> VG!_9~_\~ó8ܑk~=}>aH*<\G?{gyT?@N> L'_♀XBdW&S؎0Kb KjI'vlcN$$ &ERgJMUDssޗ-ziڬkbbbzmTVRM|CqnԾ/U@a\o%e,þ(PUHZGm߿C}7_ݦ< tv'־iuTW#n5z՟?wܕǟ]q2W#[+ąwBo*pz!XnZUbzpRrܞ_F28,x+yo^mmJ&[7^ba^lWW7H JI)>\> qa}G^ 2*~~Hڧ >'w"N{gJ?p^\*p˨ Wj=EeK~ AP|*%ЫUfrBk"vhq(NZ^mۙfK2zšD`dU=-ztKE"g_۷owN&sojj[0~Ue ]\ .K\&F^F0ڴqaw~5WqNc%\]/* |vծ_$DZn1|r"W;ů5fίgdMZo\TJWnWZˢZ+8땧+z? :z7O^ѫw]|~gV<D\ 5zeՋk:u?]zҹhs:6UZzǘJ)5`wL5$p}pkG녵u5;^*z 8%!8fCZ:a"εTpĴީӹ$}ToY,aٗrE &XS Q^o`OӋ#`" },z .,"Cf2+L-"+L뗰eov+kTpEf z-uWTrՃ 3o徱d>Ò au<׈jik Ms ~hɯ3<1"a3ƕ>닡Í'^ikD7Q˂ 8J #EE9,\tqGW&6=7Kaqr B 8x;?n:82qYV\LF׏eYk.8?eK3W*m׋"eY=uf?a˒ZSV?\[/ϯҮl*e\z!Wr)¥=gЋ7Vؗ|C۾q/!=uf7wA/3V[J. ~,. rLRn[%fJ3rߐzIؿH}#p_qWpMWBՌsl9ݤWi&܅~I3#xCQRm۬ů 644t́ /\7 sw_So^6qYskppPo̘\"ԫeyD}~L;ׯ,27[?,58| FA()W9CZ>v(8,%b?,"}%S_eu#z"y }Ə?hFzѷ`Cz4: 64Wf7 nJQFbP/przaz*1_kFU1"S*u{@/Fb"<-6_/,,,a`uӤ *B% b:^ZN^}j#'כ-.0Uj:z7~^ZB?eΙo# #C|RT{e9 l+@6.V^zMhFKzhp1Wi~ՒrTͣnUJ}awY Ы:u+`r$zqHueyIrL_5 S: \B?by^3ZBߨ:|HC/L|-\u.J8S ^|q@F Nﯼt{;Yeiueii Z}TU釉D7|lꇍ~"಼>OeQCF8l^\'Ig8N_M\X~Hͤ\-:=5E~a&PO0(F##ü|לءx ~D!\`dRX_$mĆ\ !WA8{ WP.8F0k fի0Ⱇt_3o" ruE_AR:"nF. 15;;kr}%~B/̢FO_UL( qd"Ð20^hyhtMAF.yk~4\A\LR 6ⲌiJx4N5y\oR)%\5~k_\ O La-L.A~"Q^q8ڿTq uoQ 'ogL:[FE^B/+1C5) N&/SpzMppi4(M.cSqSHs~9\\1Rq89u`s)/zD"޽{m۶7䫲r_mF5ey핣18Ε/ b Ut%?8&8$ؿ.K\^Ђ>Hsz~yhʢc_9IqHQF/{gNFd DL^"ಿ*>dWԽ"ͯ 51M'QE~hKpW"Խ6⚋+p ٢\޿pK~3L^w={,]v]O0< vH<Sv+䲄^]z)HM_A"թk fͯ.F`ѱcu ~e2:6Wi~!W7P'fS㚝qIPS]/ 1s8^/BNR?>\8Ot1gbjb_&{{H qKW_&Ջ+D_^}9Ș_uR~sjj꺃&ق g6Ԡ+6~ytة \F\g:SsҬTlդso~`6I8li,~H_M/B:nj"ȯDe`a=@ڧ I>!/05"FԾr#E%v .h(PSzɅ$NjP]\ISmzAFקoܿzSbHR.`~YMl12~H:i!7_\s\ߌnM00rUV;SI 6sX,F^ qUǠס&kVa-iEUEB-aԇ,Һ׬B ]1Wa7jL.*u_&ક>rz'Ѓɽ͖$< Z" S3!jHjL(֋^ E/\h/xFLHu/jWHj_9֒at>_ľQŨ.~="944tCa [:g8`xf Le\ \>|LCR!W]-0\Lq([T+׹+2rl@+Ws+ .q3k~/"߈8u]Q>UD"FKe~IsE5}eH>pȯa'Us ^Lw$`Jo‚ 5׹jˌC\~ܪ+2ϵ]} 0>sMWQR߈HPLzCduz1Hk <**%+"|>J%0L/šzF/8FKq X=-`###&XpՈgup?ֱ^pU-ʵ_uR/q^^z(|c7p,\z=}4k\Ka5W-Ȟ_\jF@^Ɲaik,}YJ.zH."*%EpUkw]2 G9%Wjj\K5W_2A~U Zٕ:JpU.:J%}=f^pfѫ7\UWv&7U|ssiu_6l,zuϑF-Q֒7=n?fҋ72 :Tf3YM5B\"k-:wڹςe\5r+WFzmЮW,!zљ_V\>8WڹZQz~7\4隆'=~cבֽIYpnnƕOQʵůbk}\m~u\\+OrOūWK5:wFrm8ϫZYơ{kN}yW{=}u?)zWyD\y\r.]R\8\EW>o/Zz#W^Z҉/Hf3PyuAfju+ԡpÆݓ-hluF>5 \pˌ6m\/}ȩ+y: .oÌCRJWp8L%&h# x5 yB.Ey5M5::w _^6A,wžv&%u#N^u/z7z}r?$"CayVvvK/fW?ȯ68\X.v4 >/罚k EWGԇz^f_njK&YqEE,l_x6m UqX-\qX=O)%}- M>UD_vUvEUJUdAR{1ŷ/4N=_)EM^w΄}Sm\вt\VR_rkxLWdrQRS:.8*^旝J" WEᇦ^EUSN29˧R[UBpR|s/B2b9^QA~L!t׀w߽a`Yl&,-wWb>0XV)]/\Y?;44tr}ŰB˦2w.K&^wRpkO~hDŽ^"ѫG^wסk}4q=5Wh/|=4Pի'zqثe^xo|y!J2_SQ~!LnVZN3|"7wZ.~-&={~Y2air=kkz8Dmlz\=\=C 2zn%\y'{Vظ|7׀rpq)| ٛ3 %:V"/~2g8wD=Y[9!rZϳÚA=zs`Hn v&;v)**n@]~_&CXpl\Y6)ښPW<_^&bի{d!Pv;7a_XiڹNڸ _ǿYFjg\ڞkP:}c_v먱,\?TkSmB_r·fn:1YGɋRf>"GB\XMz6۹q=PolLbrfQW1YCµ qzLR W8K5zmµz|g~\O~닡1u/|޿>T/C_)+[- Uϱ zn8|P<@<*kl_[sm#̱q^z5δ9@=ϋĢY)G B*U΋I9/NdZ"EbK\-CQv @ʌEŝ  A f@LFe}t=8UJ%b7=[}˔qluuՒh^a֯9{uJ2ښkנpq$s=x@5ET#ËɅH\VwԐ~\7g7tG0D =W>+Yq8CsPtG2kD.r _^㪇\MKk zxD EQ<Z_#s~#c̐5ƅ1ۆ6\6O>נ>@?4LL\Y cp!pb_|BqqwIB +kyjLˋdck` o:kI(.}6:yzX)Wsq׉NpDuc('aJt?0gZG)u󾸏bH ǯaƸ*?\nક%x-Yl&< )Tvr" :\۔-\._1Cp= 왘qUSlwEp!Գv"V'Jͯ酜L>,㓫Z*%-Gk\2*kf_~tJYF"םVmnzWZ*7WRVe~0#@~R|U.z_>D"%B7zz_|QIg}(eg+_p/hD1 +M+.km2mr!gSElZ5r1f\LJ̢XO:.}D7h&X&[np0亻$:*}p_ge$!_54>Ƞ;\GэmRG#Νtf^J}H+gɕ|PW %7}^_`uX\z-)8t=Q0cnzXSuTu ucO|ݠ/7/[oߦCPzvKWCK+҈_/ W%bWNYm\s/W@FǕ3̢+W2\;c.FM~I]6W]d#9-#&q=l56~5ƹ_'=sD-7^+E]D~]>{}Qf;sƚߐִ5qB w%Sh6]\4yKb#AsG/>K~d%t\ ԍ]tq8(3h:%TidžWWC:ooBrjxeb!^\vc>Fy6ݐW#hs y~NIz(?Os0d?@tCmtkv\z=A5>A\ðc bҸ:̅WK_uJHY_#[\RԾa j…빚\Rڴ㸌#\w+\ŋëj&s]rͯ8luMUC7~I7۵\qGpqsWޒ^ā1({?[z5;KR=5aIvGkm.h-%@3B"ժ|G(D$aqv"Eq#s!ڧ \e0.coZ3D/W\!EQIگ,}6e I%犿np\SWW C%l(Qϯ\פPݷV piL&b½pOT7y'uDRTܹ/W9BQRuXdbIqޢ/KY WCϝ\b _ru+P|rTqDs|u\ٺzu9痀:`/v>e25[C\Z ipyaE(㗆w塇!_/Ϩmo(ZH_͢7d.h|:v@؋71ߐυ 1њŕye9GxN+ZT5Լr7}'i땏\yeg_qaN4 \HZ4\-r: &tCa 0iF4,F\en:55P~oEHJ_[a39l5^Cgד>v\!;+<*,jĵ7u}QGEu_cpE?Db-ÌPW+5D=`Qmr!ە%ggg6k@I rܣ޽{J+ikٍ ϔd<.o2ը,/.W:nh/5WW.G>kq_)Č&e"ԍeqkM>wΟQϟRVo+/~zӏeeMᅱuWݎᄥ5#dZS\+Yk/͕Q[NY+p)e#;Bf%Lqe7,ndV )Ѝ]^YD볛Y!%,aD =<6bzZoz`1_7}Z>\ogd \-z㻉K {"vC2}̵U~æBK]>tsBΟyZ7e?kЍR_X\bM.ٚFp- qfCМ:ܷԳxhKP\{ŌCh[Y2Dp{}97<WL]Rn\{fD<\Wt/S(p31PW* |Ä.:>JE?\0āgQW/ukeˤnlgr1lC7&D C}e}vXDS pAcSu# }ŏe^cp% "q%|!cW]6 JȯZ\ &9W"j={~4][uüCQB᪔ Fn666((G$7 w)!V6Ņe\^\gUzF0_N.  +kЋ [XXpr!#6_ prqtOV\۔˅XoƯc50Gr /+n*eU/_[kH\U Fzzl lp>m vFЍAnR&gݾhZ/rېaA:dJ,fpdӣ *HW21e=30qTf\7 ﮪ7xr (gս&8~\5{rq\n/-d=Z=Z֚P qPBq~SvdqK7Mp]0z Zp܎Cf_`nլ;oɅ{Vko$O&l.lu9g!|ƐN78~/!g؀-*!b);oW+XxWA8.go믛3.|s3bl]iy; 9.oij^Ye V./&X_zZ!J\A?z_p|=_|&O~y/Kֽ~P6aE~/`r GjCQ;Y3_ C\p ?dr6_Eҍ~zAB ԽtF׉4vp8 1<.\!u= TK@H=nȯB*M ܋9;'#ຍ{^y툸CDC\*a~EŅ{MD5lw\׭ *P7#gqCULX9eQp!c͂ƴ.Xx:9",(WB9^9\ &׸o|1\u#ǗoTP7gڄQq^ : ˲LwS({O~9}QLϳQe!xt=#jTVNQ\!Ms/QgM&±qǘ1ř8­1 uWySꕕGϯ۔`aC!\ ͛0x›ͮ\ k^.k|?n\\(>F"Xgp+ )V/k* EOcMrGe-@7"jz0׍i8x|wD:?1Wcdzx|h\وɈQ~/OrKʾ`owgFvq8"ҋ%$w{iaHѿmVZ){lJԋ*hjnZ &vRbԘTz*53sOZmw~RpRvr^}}y >1UJECMq_:S5&F&׏gyqTip8QN}˿WŜ kIze޶;'v&Rb}m"3*u5NFiهg0"֙R&Ȃu"5Uw%:l /t+Ŭs\_n.G+XDp|-:Pɯ9%{k+9-5#wZ at"t+9[]qnln39FepSqn{]$aa#yTʲ2X3,0jټ7[^wck1dQ^A31dQ߸9Q`<'`^#q̱AN{- γ-+ߨq9l59~G^饾o p/yPqkK1{`澡?Ld7[E۠Vg9p?zxǍUTKzЫ 36{X# <4ȃ5k9#+fȼvz[岦pVk/E z96:r}`?{'Xs `^}:tk\7=d ^50r` ce{f&Or@zD)pIKӋ_!]pDv:̈" Iz?<\_3SQy顗㵯ѫ Y՝.kj y<~3cWE\_+5T^ma̳:ܿL%qC}cp[+ >{Bub8OwWF'AW.u1{+s]>#>[}lZt:sy󨄥N)Um>,el1(0- 2|g^?/ kP6ӝx]IUYpu+ ,9ͱc.y04exHO,xjzͱV}fvÜM̱«C͒~EfN}(+蒾~~g? h@5+://o}KΗ*hWyϟq/A{_1Cm?OI>Qy+ ŵ:|_Vx2]1 .yN,C^r+_r@W6ey+|/QK9!IENDB`PNG  IHDR66EjIDATx^/Pqq6F_`|{F7,6b p@a㳇'/ADDaFB[DY֨VXA`[T ][pЁhRA˖D͠ c-e[__-n[3.Z޵:a {TJrO?˰ (C&Y z>c QWbP+aGP 1 Nrdư (C6Y `vrO"""""w; B IENDB`PNG  IHDR66EjIDATx^ԡjP&[7H"~jBo0UNjb B!GJ½qO8ݘIڇ1,K,[֨b0'B%M*mzZ$0';WË-q3{Tq`K;<6F]z5*lR@z. 3 ce;+AaK0-YvVV::0!܇o(] [Q֮`=;9G| ciIeXbXeXf_1(;{gq{QKٴWIENDB`PNG  IHDR66EjIDATx^/A[X/"yv`|Vf.YlXq|Od[,N!Ԡ#ѓ{Q1,AeYZTΠgDU~DuW:5' =]kCs-Wia;ua {a*'36efXj0,|qo01 2 kٗfK.7K(7^1a [2dm3e0e3,ls ʞDDDDDTvdIENDB`PNG  IHDR&$HIDATx^1kAF> XT!6AA4>$D 66H%Xi'n|d=V7)yRvҤ-9PbcWHZ¥PYczcJI˂ 3(_Idz1HF E0#v4}B ږeI^dúnm~NON:6 n @RjEQHkK lޜ3!!/aqZeIENDB`PNG  IHDR&$Hw D~xxMbÑ`E@*VRQDy/cJh_?!i[$\D.r$6GXŒqFJZIcX.Eby蒱g,\dUS[Sѡq/G=_],U7cNrTP&9ul)QʬrK31c l1=6NDR_m%M  6nm|Tރw"PRV!̩Q1U 0j>{ J6PKON9@!IENDB`PNG  IHDR B*+IDATxڅ1ns R>Yhf=FYlzbh5IENDB`PNG  IHDR7IDATx^eϱ A ׁ\d `t` }Z؁ ʀ0[&K#vtnG ':W %.‹$$9@M2 Ifba"o'{ƪ&X&;*;9)+rA"G_; 3IENDB`PNG  IHDR szzIDATx^JPEc+߲M$jWTQ|WB"8qorѦ'lde$G`kb&LdLVȋR9q00n) ay Gkx}s-S P|m{1m;`Ԃ~*!ȇ"yZγI0 XD~c,"w9?wݴ9Mm i#6ǁ,a}Z 奷?EL#(;B#(VpDzV!ф8H Y"YGINOIV`@6p!0f5?IENDB`PNG  IHDR sIDATx^=K@ᛍur]gQʢ("66&[1n.sQN>0HP|r\6ŏ 'U"7Bch;~ Gܮ#6}@)sUr2¶s7q4OTO~~d`& R$x1Mx0Tm }w3O K_(^8rhq@4 p$, 0 ql @ľ%YZq$>#Xu%Zb-l{IyIENDB`PNG  IHDR sIDATx^ս 0Q&1.H7p 8{GtQGn|~ =&ܱ=w/ 0}e1@5 AuhyZ 9 \Ɂlrh"KHR`Lf h[X' h LILH a(=Pр:ȏ:󜷺tIkčbGUQ κ ~}IENDB`PNG  IHDR sIDATx^ս 0Q&1Yƀ,H7p 8{GtQGn|~ =&ܱ=w/ 0}e1@5 AuhyZ 9 \Ɂlrh"KHR`Lf h[X' h LILH a(=Pр:ȏ:󜷺tIkčbGUQ κ K+IENDB`PNG  IHDR sIDATx^ 0Fq&e! "`75))m󎤿ҏA'WzX|%~ e pW iy\4k@'d)Y(C@K>#%k0J3 xQ`#! %%:D t2=4{\9(֤vJUU-Fus oج&5iWIENDB`PNG  IHDR szzIDATx^ @y;vȆ F͡Y%1]Ȓ"˩.+n$ y'+&9-E ~Cyw O@@[B@x QZv&IENDB`PNG  IHDR slIDATxݕ @ t. :m0@bFB=SƂ X!* Y@؝z}D Gts{})Qo\< 8 @ǨhIFqIENDB`PNG  IHDR shIDATx^ݕ1 REH)r-9!J N`@qb'y_05~Z߰ZoJWWa,Xp7> {IENDB`PNG  IHDR s`IDATx^ݕA }F"?9aa$!7BЂa٘ء^OZ4c%קn@,X\/$YmEIENDB`PNG  IHDR$$K PIDATxA av m¥' H've BA Sˆz,7XD1CHP!$)2) :Zf ao#h–#L6_ @UIENDB`PNG  IHDR$$K PIDATx^AN@q<팩+=MPHH8 yЙB5&nwK?IWS/C SS"[v⃦|jmۥ!Qc tp׸y5/P̫W󽝁{_Fb;Po1$[@4b-'ԏԞ pRyKP p;ۺ=L9 :vnh$׆vn(u33J({b7*`; 29@!%3yjC Sk<&v-&Lψ)&ZE(Q՝'r%qLޔxEdU.D4]%#UQTmWP25գJNvjuk._/ۏRIENDB`PNG  IHDR$$K PsIDATx^?NQqJ;؁'.5zcBɒ-,捓l&.0 O!7yU!p İ3DToAmHh;CPX,_4`94@^K=r(껡{};l\+Qq^8Bf_hJ )}Z:P#E*<Tl"0:Ht[Poգ&C Ee*ԏTL)'TX"᥌T(l$MDJr :Bg(ڡͩ[)P\bîIfh(2Bj&5PjeP 3w`~-RIu+E\&a~p> 'S|IENDB`PNG  IHDR szzIDATx^Ŗ;o@h+@z^gGPP .%TTHxW );#1Xюf;5!ĩ*ET-WAre3cpn#G{ip0wbf+rsM w|FOgFelm/f{Z`O >_m,Kxs `(v| x!3w\Y6DH\sw{b-j}Ҩb1u Fjtki=n7L3AF<vVB( &_Ixfs0Z%7\ * p9(7bWɀ sb5H_!8%'ǜQMu>pk L8(\P|FMZߕ: /nspG^#T@l쭬6p)fs G! ;{;$nG'(@m3y!ℸB }=CTQN&/!ExzrO\VylhϽL+&rBk#^.Q7F;=Oe V;[Q$_{ ޙwp"/OA~<)ɽ~z$KQblj" j0Xְ!j'Z„ ΡŪWka/# .8Ԫ( KjiQ ߬ ,\9-=<ܡFCߥBеyr͊92j˜>ŐV"Dܱ;O|p 8D@mY#`xٜAj\~/1d^^PYcŨk?Eni(57!} _Rx̆2f4 j` N&{UHvNSXKg ju q&}}!5 Px<[mmxmj<;G`րZ o 4K\N>Kjg5(wOה\І.8d?jF;fϴL>nnX%|:~$;ɻ:P6@Ip}@Es%?Wtx qܤD&F@5M7I$uC7CuâZ &IENDB`PNG  IHDR sIDATx^͕1@E7C;zj-P h!GAZ+ff`jo=՘=o^^x((d k꼄I*I=fDi42ni4'2Rt.oà kW9>`GyckPP e(l5qdF%Enn:R0- $Qŋ$^ea,96P(X@E T.XW[k z乧IENDB`PNG  IHDR sIDATx^U1@nXhEoc+H-%ZxO>AY`X.\dfag9S=P/iU^a~ȪȺ G ĀU: Y8Xp$ i_X_1C>۾\D1(vp4atS==6JӒҵ&W.:hg ->̻`͕,pO&#(r#ɭ,_&^d9Pv@E T.XW[o\KebIENDB`PNG  IHDR sIDATx^J@X^Ro.EEPaWzX_@w=>AཅCLI #f&7`F1"F; c&`lsK[84(X)/knWo&>j}]?GZ j2eßt < R@$ nɌ ORe;rl>- pFvApxQqXa \v/%(/x~ES&s?VVJVX;z, n*n2d䠠&n/q7җWy䃾}4%⯊~m\/zv wT`d3[H P#wǺ H @,D5$biK\u\>Sm9püC3ukY׬a&n$yUyfGUWyT3TI}^:8@{ rZA8KWֺ BdJ[I/jz,DO_2L/+"6 e--ص2פJu~ c~d#+ku׹MK"HGX^YDx/,TcayiѶ;ڶU @c 1R|IENDB`PNG  IHDR sdIDATx^J[AIPR7FsR|l  BIڍB+/m"+l}O/uƹ/0H"gi(O- !cIP>@?7wC@o96om&B@+話!=" "yyr#;ADe9_prGz{Qrmxݽ,ɭ7P5ie }M LK̵2~5v#.#bvG̑]߂BQ a2=̬`V|s1஬t.گ{>\ +{%J`e%pf_?^y|AX—XNqٌ0|# A\Kފ ȐP76)%u+6ybSV%y/i8.݀auu<0ԍY6J;xkTy##:p\ACq%8a 6v 0CL3ܒ1)YV,)SBFO^&!L_iǵ T: mIENDB`PNG  IHDR sEIDATx 4\@ /6`BfHI `BhpׁFÈ IENDB`PNG  IHDRCEIDATx^픱 AX`ׂm؁t#0]#n5̎'xO#SdDO ГQa*j$mk_ҝ՛ qaR朽!N4p80{۱GI5҅/"aP0zFIENDB`PNG  IHDRCEIDATx^픱 AX`ׂm؁D&{05V#AAxh12AhH=I5*M}f%Y)Kn/eD H'h$Qsy,]:!Fq #PIENDB`PNG  IHDRCEIDATx^픱 AX`ׂmX؋XO Zo'iGKNQ\BHhBIENDB`PNG  IHDR`` PLTEuuuuuuuuu5FtRNSK&QFIDATx^1 0:Nd'|ī]1AKck'HD"D$"HD"D$"HD"D$"HD"D$"HD"D$"HD"D$"HD"D$"HD"D$"HD"D$"HDsM?lbIENDB`PNG  IHDR``j PLTEuuuuuuuuuuuuuuu1_tRNSK&$WIDATx^AmC/LES)hNd}~/{:::::::::H A A A A A A A A A A|og2.2UIENDB`PNG  IHDR``j PLTEuuuuuuuuuuuuuuu1_tRNSK&IDATx^AmC/L*(ǟJ Ds%{}|߃#::::::: A A A A A A A A A A A A<*IENDB`PNG  IHDR``j PLTEuuuuuuuuuuuuuuu1_tRNSK&IDATx^1C/< P00*0Ul?:׃Ntp:8Ntp:8 A2E!( Ad CP"A2E!( Ad CP"A2E!( Ad CP"A2E!( Adhw"'IENDB`PNG  IHDR`` PLTEuuuuuuuuu4ptRNSGIDATx^1 "5] Y3ܼ Z[``\ oK X攬 hpbn. O1x08ү kp jL0`wsY1pX@&YT8`j(PXp|OH"odsʏw`y58TOvrY \/-//G76;hXúY&{ (cg%bFL@om"0 sQGκd̿[@+ͧaIENDB`PNG  IHDR00W{IDATx^=NA) 1<j%5 `m*J WPY$j6;>oc ~d?ޙq'1L"zLqh#3,kFn[?IENDB`PNG  IHDR00WqIDATx^?N`.6TWL$$l`N^U; +(&] |:7ӯ5{ AS+ ؄=4;-G)(+fW9\DL[=`O94z |s<&PpqG} p(oL(I3#ezOUZ[Y.[Ї;/Y`ʈURWyx۟lhLD87yv l[k: [LW|5X&B$KC4 ET!c.TQ7főIENDB`PNG  IHDR22? IDATxZ TUU> Nkehi-\=F)SY-W& "LC lt-_XBqF " y?./Ξ;C( Tڬo~!v={HPPxKeeeMMMNwL&v#P^^2h0a6B}|L 7_y5y"쬈/Ljor{/~E(11hVe_Qv#N.GabuQ'u-FF?~lfd46Bq\V<}pR#q w Oõ*n)imMmo"E[mfr&{A\&+̙V4Lz(o*Fulc&}6\@[`S2l qH;$v67 3b 6ذg!Mi 4̏ ׺ֱ}צ.n@[UjWSEcUJ|!q'< %Tfm3s )3^XVS4$УG8dS0 κɳA6 ae36Yo쎧[GQ[ D3>!uC -w :TAOKJJv:t6[oRoP#./Ε' c;JIe'cPȯJal7.2e\62xh^wo~J^|o.LR4rpz3ά5 ܬǧ?]˴iӤk׾"3ja6K{Hߠbe v*h" 50̠7\jkJioܧkҭ[X/ IF#9sH˖-C]}W^=::`VVV,v\v".iqK."twt'8Lž'$$x#2bĈ;׭[`K? L>]*ҠAA:p>^^^ҢEs c-@ ]Œ %D̈~I#Gq [Skjjk@ $wqw\ܰ5XFN<{nǞZJ]͛8_\!~h?IENDB`PNG  IHDR226@:IDATx^JbQ{EoD+"eX ZвlS~ z_w, zCZpwz39,;pa~pAGW̥Ckψd/3Adϗ..ΗE^!1g ;a&21㫄H&2Sx"LBa<D'tffMq#:0&8Wq DP$qϊ"|@znTg4GK~mB830a4ZǎMJ-|GTP83Q :xNS/Di /u ^4$*!k&K?.OW""̣y𻆂tΤ;2%FãmHyDXox5b!o?  (ZcID[b*(b~䰈`޵Qnfҩ%yf]\gbIwQgv]4 3UW=3"*aftCSyzO7{m&af 2UBGiLq넎7J6n7f܄q3UB܌p#nF%ݎ0f30Ska5"fJ`8ƚJiafED(KFrZPGA2/!A"ļd,^3  #$:h.MIENDB`PNG  IHDR226@:jIDATx^_heO4]׮跑]Wl*xU !0U"(ƉQo'nNJ?l/4R*N^tkeh.X=>yyM}@~9I>x\PXTP&]x)]E;q*Y*C9HQ2Tp 7ƭ9mrX@$(N)"'s{!҃_&h 9to5S,D _u[uh@4P13KLCU T%_$H܆C1']eE@?gCAո"Dtr6^R112*NElѼC~U->D9H?qVBƀ(E>qЀ)IdMu%" QJM!\Qֳ+XJطe@-vc#gIl饜C^ `q%[xg k<эbxVܨDZMHz1Lrfȱד3 A6]A4yP1PA6jC+OKysil!"BhFsّ^l1 AR@qǮO/B,%{1H/9/dԘA.R@T/}5a >XjQfK[<Ȇ(-09y(*e)"wίIVrJ+%A6g鋣ץ=Rlu?d)חЅ,{"|v-fΏ糔C:r+SCzKV)DKRw}4Ÿ vR cC2FC، :h'{ن3}+?)Bt0̻  h4x+ 𓾺44者o9Dy'1at x =ُGmhA9Dr5نF;:hF=jP!Nhz_AM.ԄFW!? ?A0z!* /䃗BuUK %y B LcIENDB`PNG  IHDR22?IDATx^Y pUK ZP*Z(`VES- RhF* "%R!{B $ l/dݗwN5LjL=3ޝ=<)5keu@dʕ4C|l6Ns%@\vww655GG_CC%Kyon>&iBggVy= qV?VVV$**'::ZHHHMLL^RR2fy#LSqV ]`Aƻ!.].\0 ׿( 5b,c 2VZ`6i<]2ʘsf{;{BB+vK!a愹5=>scH9ܹs}̙#QYQ1c+X%ۥVv˦e]R4]dx{Y jd;Q^hkm D4q3l[FR%'˛6ɳKYdԩmx{Y=Bzq `GM'QTX8n^w"ncJsyl8rD}_\d?H F1KK=98V۝,EUUY9?#06RKmt_*Kl9<#iw۰aPE(Htlc2 :9JęED՞=-?_؛p>x{9Y%e#CcNJ!C|4adpA#z?7;mƍ:W!.dkBE"J6LɅw]#8{picmgʚxɂg ӬtV6:b'Q+KvqK-[6CӃVL*|[ׅ4H$֬"D *inthGEFK3ɵ'5'"_=W˟:84I:/PA.eCFԓ\`=hZkj "B{CF&EeU}A!q#Dw8q@C ~5553QXn)ֆ ݷa.D=(`d" @Gw˂UعYz:Q&H]#125 裏2ڪqm*@cPsf<`C (&C*g t?//<䓂EM|a&J֮L#:@&"ի[CHv4f? !sI0I ٌԌ'\>P LC @K ;V.ДPu-]*<7ӉP  *N>ЭW<0وY#Oj-"Σε<>? #|buT/86s&kA ٸd'kH#ÆFFGzTd s L6#5p ־fAA} ? 3f/P(Pl딊5]9F[K_{KІtZ, #A ɀKl9uJaO }MuS{ƃu y|Az>:-!+4D(y &N*wL%+lFvܪN h)'J4YM5, >=;ẂmXت&NkoE #; Ns4>maIId+7J RB6nv.CTi:OCPGK^CDגa@ O @ل-*!vn}u"M:.a1 aD~LCǠ6H-yV-2#l](vj{sN,T${ BeM02* @ Q!hs* [3; d (+uR򃲃Zj-Ŷ #4c:1M&eA4EvR^HNѬ/dR T܊|f"A 1 DDLT\dlt GCdoqԇq @ J a"/"$˂+%d.?(7tQ4}f,lӉ (MQP0j=?AC(C8{<ǟSxl+?D-`8muu׉F:((4@P`{kH.Yw)YkI]44hq:oTXkN>ydX[ggrP2h DMpO8 9Jt %t*ga&N  -E)l|o~ONyiMM{cKvn(W)=2n-inCE͚PAyרhc潱m߶mϺ&M41o޼i,f2_ !802H U,ٌ8DlanuǴ6i5H 7b߶zj_c-Jlܩ<"z Oe;XJ O{R Xc B8|Z\Q2 v_}UeV>N+n/((xu3N/cBnQ lѝ Q充QiRR;5MSGEyK#!=#ARb=G{?2ThGCfG/GmL/2Z471,2ZZ@-UUQY2 W9Rj`v4 x$ R, [ HtA_ZݬL~;v,MuFFƝuEYYYbL"㚰pO 9O?-B OLNYgD-)!?^3f!ᇚ8Z!PPhSPtȖـr ]xUC 9;[v^ #S /'$uuK uf?^8uԠGQ;k BJVt{"ÜF\7۹sm~uoׂjkƾ`!-.׆=f+3,Vk&X_M֎kV@?LKKc 7B9}RSSyz쐐~8h<iq2;#` NX@ H '%%^vDvkT0|ehlٲEٍF\\ܤӧO/,--}'/BZ{@^(ߢ& O@x뭷~=hk5 0?-"U`\FɅ0Gւyhh \,g!x\T<]Q^V|g B RBz$Ԭ—uK NIe'1i0ŢLQ"L`~~>,S=AȢJYO@K+l c>#~{3^KA /J¹nhj@gl^S2O6Jra= =AAf<|RUQX%=TM@cʚtA?(50ufZT*ޤwLAvh2.,Fȼ,? Іem29fsCoo?x$}믐,瞄M^1C_.H+JXQσ^Fsj[z ',ȼyz)"FdRYwv9h*kOH( TT\(6VD 7rIJFi,kP-*+Mc~v\6{|;a2/aAHV-P:ƥf^Ww'$Xj]FV'#\ߵ?.&|#v#im3 1՜;2zgǡ m6,k'=#a1޾~.KvC4DHLP.)IH ,JbI+!SGܐ۷bQB5y!ct߱g?zc_cݞ7 6c Û!=gQrʄ zFt0Ž+l :x6]7_#*uYFa=Ƀ%Eɪącqefk5p7OS[j8rECYòXݓ^à,DĤc05w5\|-ͳחQǛd[m.;T~1Q+f ӕ.}~km uHؤ Fe9C}}((J1ኪGcKeYEPsj!-uc L֍ .lI"(%pL:DHeذ{\,{FT>\5p 4sJVRAaRb)(Y&pQQ)tIi$&Kw!yEМDQ#YS7%'%QxXʪW0'"!!71R[mdP̒5lLj',r"L\K%U>NLdwe5K(l4QG%dn}t9J";{?!UP`\S^Dqq_TDiiuOTVjc%_?F#QZ8b`JBah_IENDB`PNG  IHDRѝcsCl0`MIDATxc  dp6IENDB`PNG  IHDR$McsCl0`MIDATxc @BȲSƩyIENDB`PNG  IHDR$McsCl0`MIDATxc 2@CWƂxIENDB`PNG  IHDR@"&IDATxca _82 "~AF?@ "10\%q0IENDB`PNG  IHDRnIDATx^=/A3&$D#AK:Ej*ՆҎ)<[۝3Rդ5cxR5qمuc5|fC^OZ/\5͹1JUbsb龿c9̱nw. $ f8T-0]>~.nn62F=^EINܹśnK箝S hTm?އ᧾b4I !"EŸҷ k:Z>@=}d +E P#a7D8҂ vIENDB`PNG  IHDR./ CIDATx^jPyGCݷu&Ku[S.CG.YZc3ߦ'&C|I bK7ia6,Sd qF s qzf.@!LċТCK~/gƻ]A'8 ےxB F4M;Ox.L'׼<\k^yy&˿8"S=IENDB`PNG  IHDR=IDATxc L , @ePjIENDB`PNG  IHDR.]IDATxI0DbL )tc jR*aQу hw`v:61w @~p^\!_8HKk@kkXde${A ;"4 d8>8 AM&H AFJ (1Ox"Y*l>lS5'T (<`~ɟѢA\;DZׅ1P%$5$qei\51}Μ 1'Hu3~nܝ}6w^rn[u܂x?s b 9OpxIENDB`PNG  IHDR@"IDATxcd0D  { IENDB`PNG  IHDRnIDATx^л A F]/b#V[l8#y9gG\x@L6t\x0'GF-K$lp0QnP9+ns^ ;sW ۈi Y/'\"IENDB`PNG  IHDRnIDATx^ν @E᳻nARؤIL):8 AE0rOg Olt45ՙmie`CM? Nzlf-Q\x;qBуW#Q\|%'Oqb61/$/^R>//_%IENDB`PNG  IHDR./ IDATx^ @ D16UuA scgAB?Y4uz%TqCk\WE)ރ4=DS4=@s4=@s4=@crB69iT=%5]/\K]IENDB`PNG  IHDR9f)iIDAT8 DѡJ(X*t;b8n삳1<ۙ20mEpϡ1idmjcl 3lKس``]$hs>:aIENDB`PNG  IHDR9f)IDATx^1@F0&@\ p*wDW EC͍{2K#2q q#nU8g.*-d܇xHC7%.ė,N#s9sqG+E-%H%`hGŀ!K ~1$2_ 4IIENDB`PNG  IHDR9f)IDAT81 @Ek-R؅,@bPqV٘ p *' iB@n}|9Qu~ήm Eh4n7o;ոƽC4|G.z :,!eqN+HMh`HwH1$|/jrIENDB`PNG  IHDR9f)IDATx!0@7@/Z85Y%z1\'Y --Y=;tKԓc1o ǝXH Nj# R/Kbw8x c-0 7l>_^%xlڵf%NoVrxUOf[!IENDB`PNG  IHDR;0IDATx^1 @Eb x O"*FQA KQ+h-ؙ{|> #W{SB}a OÌ!!q96(-)8bg&GII3Qʀ.8m¸ p5a{4a kx0mge1ٱW[[]3IpY6ɸ'5vn٭hIENDB`PNG  IHDR;0*IDATx?/Aݜ\ɉH".قƟܷP)Dr(0j%%j+zf3l37H[1dɇrʄwL~>%+p7xp"&ڕ]E$Q4Ew۝[S; Nufw8}c.8ֆ6,N gdx9sC '8ᅵǓ.XO>s+WH~Gl#_i &`fY$T4}̸:8ɴ#PNUq4!Ԅ_] q6IENDB`PNG  IHDR;0IDATx=J@F“'ik le~a2#i&ps;cz/m `ɧr L+GH_d/yh~9pQw As{`:S|j޹Aƣ0•W8[.tj֫ORhT]GWIsq蠋NmX@BaޒPOCa#C/?2P/IENDB`PNG  IHDR;0IDATxcxbEl@< ;YlX1t0H/ Y 3Ty 2lL-NɣZ.ٛ/&@˗,Hicd,4oeؘXPBY= nKU,CIENDB`PNG  IHDR;0#IDATx1J@Y"6ŠUw`!x -ьAu8#n40 LȬZ*W`:}:̴e+GVuS,K} BIENDB`PNG  IHDR;0IDATx^=@{!D"hcca7Ĉh䖖nFPu QAgpFl&>2{G7ą8\ZEdS3h&7 QIAb@DBJFe) baLIIENDB`PNG  IHDR $BiIDATx^KaGY݃Dj͸֭-w x:(vPOR (B^# ]f>,/ev "s~fa?Hܔ2H^nmg)Gm˰Q4*!wq0]ĀRg-y(q+&)34'/5 5X|y 񖈏F$jyV>ϷX&l9y5zާ+b>-z+B FxIENDB`PNG  IHDR $BiFIDATx^J@@ m+D&iVADD,E>^K5=0tfdQhm&QUTEyWUboX8tXSkiʧä|TApT)a^iA Rx &L݁w h>bn#'txp:7`1aGynBM :?<ٞp&MbvR1IN4qfrvyE I4kg{obADD:Oӹĕ&qYLłh1AWc/'"bH%$0)_[;P~[ƮqMyiӄ7mKx}IENDB`PNG  IHDR $BiIDATxݕ+aeٛ Gq Qe"JPa.aRJU24[j;0>n_TKtJ]B˛],#8y+ݿ2K5(1!3D$^IɩCI1hS#CC4U $+)3Ѓ$^&1a\LQ`Yx7}C .U6=t08=}qO_ƒ)yV{#YFDԧ>;?J8Sԧ[?TKd(:: ŁJ`5d W%l;v,^" x ~BHDWI|O ky3O  dZmNDj%& (Mif"* wFi4MDxYAzTi%rIENDB`PNG  IHDR $BiIDATx^?kSQC.jAw!(5S&7`Ҋ 5 AD|'.PD(B()ziդGBn{PD).oze&`:L7 #=6¬@8Ƕb£,|c.`e+Wyd ڗG|UQm| /Yޠ:'pgJDےWfy $!9 pq~/8s%zriɓgiPezܓj_;Wbo^HP!M4OU8oQD@~!tAO^=ţRϮ!j B4sԏBⱾ(P(u=ˤ=~RqP&/ H!( ް-@݌G tM_ $@ <_2 ix.tBYIENDB`PNG  IHDR $8IDATX혻QW"O %q齈 A$**OՋuutb&}`&9>b"t>3mrO&= q@ omeYZm:z 5H[@c^mHpppp;^ɥdjharmrˁÉ|*/t@ E"Hk"*OGH69< pL}IENDB`PNG  IHDR $8IDATx^MRQ 'A/P (N'E` #7BCPjd/Ѫ e \Lf?,Xks.<^ʿp{޻RHqL]w} ߡt(r@{D`0&po:< ~M\tI6'@<ge K <[@لG>T KV^łbHd6033Á9PN@ @9Ul6x^J%V ,"|>3@i4NC& )P"xV& lCP($9b^W7$Lh4ncee KrۍZ&4lLXDD"`$_[[Vȵ b1F9BAȵ ;;;#) v@.Ed'?Ok9]R^~I&9wOHW[|{s{ZK Pk 74bF1pIStuiJ8(r}IENDB`PNG  IHDR $8IDATx^KkZAbCWn6VJnλI*ua[i"P,K ]DAW.E*DƖyE X(=pHR,$ 3moockad2$rA\#BI[@"Ztpp@l?ggg)9ΙLH| '''R2@lV1"?pܘɷ@D)=pŀşFGk9p} }P)JCp<|KlYi"r\“1 N Cθ?ch̸1 αCT B!cT#, .ēIENDB`PNG  IHDR $8IDATx^Kkav/QRQd=(B+p!Ԃ !6 n **[q$ql)Yf!w~\暛7$a=}ѠZ&08+)`lRەdpo6$pHmt:) p;vtzzJ\rxXӑF!ZMBq qd2 n2T*V"nnn#p8r `ٌ8XR*Ib1DpHXd>D'Fplf',"#dz,å`XE*E, W?Z^ X]l=%ax(`7\ķwRf7 XWܼ>мwđ XO_BaP\IENDB`PNG  IHDR $8@IDATx^헽J@F.C\M >?(ZV>`+nAfrLd6n8pϙ+0}Vwͳ|Ȥ y6N7e(p_9rc ip'eZ?e@ icp w otHHHH~dn`-ןP/Mp=_U0$(<̈0ܵ<`te&fVj&֥ܟQE6"bS3YG~eC:XUnhy&p?J2 -jIENDB`PNG  IHDR $8IDATx^!@ajz &p 7$j0pj Y [0/)kTxvOv:"n8w!弚GB{48o'UU%2 @1@1"h@9Dh (@ P,Y^r`u mP)|?iƈbi@+vNxӞ6 ߾!0)bIENDB`PNG  IHDR $BiIDATx^?0M:,&L Lp' 'dU4]-no|gHr\<*ɑ;yEܵOSo>z)lTnazPo@8xNf|ؿ)NAl(R2e($ݏ%D(@ kbIENDB`PNG  IHDR $BiIDATxcO!.001SL^p?⇲^Ca?xhC€[@g$@W0€QF 5`ԀQX(? P}E܀GJ6 1Cp%Gˆʕ bAR4Us ’IENDB`PNG  IHDR+h!.csCl0`MfIDATx^ӽ 0 i(A9h;yڇL:E׸_t#7BcKVmgI}md;\V:ؾW`kYv;[(.ojC\s~5IENDB`PNG  IHDR+('csCl0`M IDATx=AWYq;k\EtBa-Gp 9D֓1ɿ7[j,y!CX/kh40IYQo|y͍~ϸr;V16X>Xc{>č7~{v u;mNJŶƕ&w(*%tsvk3MB>(p,"sT`n5tu-Wk1ZAǢfA *rk8IENDB`PNG  IHDR+('csCl0`MIDATxcXjfac30NO@`P,dž ~aw,C|A|w,ai;ӡtr,IbԱt迟?;x4ѽѶ]@;:UA=б@J1x0cC feIENDB`PNG  IHDR |l%IDATxc+o\pI0ᒐ%C?cagj&IENDB`PNG  IHDR |l%IDATxc+_\pI0ᒐ%C?Vr.IENDB`PNG  IHDR |l"IDATxc|+C\pI0/Na7zIENDB`PNG  IHDR |lHIDATxcep P&fL .CY6L nL Ff db`K/ %a.WIENDB`PNG  IHDR |lIIDATcg|J΀EBU4+;!, 7 #3210I$rkPIENDB`PNG  IHDR |lLIDATxc ? i%KOwRPPɚPx$˜P p)a9HJ CbF/:IENDB`PNG  IHDR |l+IDATc `c`a)Kx\v%o$:6*IENDB`PNG  IHDR |l)IDATc `f`a)HS<.;xC7 3~IENDB`PNG  IHDR |l"IDATxc|+C\pI0/Na7zIENDB`PNG  IHDR IbK IDATxcP8/YAHIENDB`PNG  IHDR IbK IDATxcP83I9IENDB`PNG  IHDR IbK IDATxcxP8y1IENDB`PNG  IHDR vIDATxc qJC$)<IENDB`PNG  IHDR vIDATxcg oÓIENDB`PNG  IHDR vIDATxc ? qJ2#IaRIENDB`PNG  IHDR IbKIDATxcQ8/e>IENDB`PNG  IHDR IbKIDATxcQ83v^emIENDB`PNG  IHDR IbK IDATxcxP8y1IENDB`PNG  IHDRB |`IDATxα @@F'D\Wz TFCg]W{ <6Ii15ODiB` HzL HMxy 57Qx4L2IENDB`PNG  IHDRB |_IDATxλ @ \#;۠\L*6=8Y7ጻ:|Ǵs&y-ڼ@a\NFJB6P\䍮|IENDB`PNG  IHDRB |_IDAT8cX32 QG鈇YQ1-:y8!9_#Au a` IENDB`PNG  IHDRBFIDATcXtɀ GׂdsdIENDB`PNG  IHDRBFIDATcX?tɀ GAJIENDB`PNG  IHDRBFIDATcX32 5)wՌ7IENDB`PNG  IHDRB |MIDATxcb`9bNtv jgڵt.ePĈt , ($21348V"IENDB`PNG  IHDRB |MIDATxc`8110aA }2 t¿`p p DqĎQG@lA*-IENDB`PNG  IHDRB |IIDATxc`812830a[t?egCsC:;@gC!04J#v:L%i皴IENDB`PNG  IHDR |lIDATxcπPS Ŀ8$~96<IENDB`PNG  IHDR |lIDATxcπPS Ŀ8$3+8IENDB`PNG  IHDR |lIDATxcπPSĭ8$x6ϷIENDB`PNG  IHDR |l;IDATcπ0P_AASRFL IDX`g "UL*+XLIENDB`PNG  IHDR |l:IDATcπ0P_AASLtfNL I &X`g c`*&JN;IENDB`PNG  IHDR |l7IDATcπ0P_AS}fLZ07/vZ0//+;8$@i$IENDB`PNG  IHDR |l%IDATxcπPS Ŀ3*]$=/=IENDB`PNG  IHDR |l$IDATxcπ01PM Ŀճ@ K ,XͫϪIENDB`PNG  IHDR |lIDATxcπPSĭ8$x6ϷIENDB`PNG  IHDR Vu\3IDATxco44 ٗIj"Ih9$&PIENDB`PNG  IHDR Vu\2IDATxc i<*iNO$ӏHo4 VY .AIENDB`PNG  IHDR Vu\.IDATxc|C4ܺu4 vu?Hck`B(4+IENDB`PNG  IHDR Vu\pIDATxc?2zp ߿ǀ77 0318'TwAffFDԼD{YX832 w0C1HC!@ d&␢IENDB`PNG  IHDR Vu\lIDATxc?2zp PPAVF3,Ҳ}8٘kQwlea GP### bbVb4 L ! EQaYR.IENDB`PNG  IHDR Vu\qIDATxc? ֭[=zٳgx(ix!q~|<};w4cL ? P&t&@M|9##,40B5@&YS||IENDB`PNG  IHDR Vu\:IDATxcb1 O$h"1Di` 3p" Z;,hIENDB`PNG  IHDR Vu\7IDAT(c"333 `0j`ddܫi8=UWTO?"I4X v 7^{IENDB`PNG  IHDR Vu\.IDATxc|C4ܺu4 vu?Hck`B(4+IENDB`PNG  IHDR IbK IDATxcP8/YAHIENDB`PNG  IHDR IbK IDATxcP83I9IENDB`PNG  IHDR IbK IDATxcxP8y1IENDB`PNG  IHDR l="IDATxc? |߿ϟd TAIENDB`PNG  IHDR l=IDATxc?2zp Pw錭YDIENDB`PNG  IHDR l="IDATxc? ֭[=zٳgd PA|IENDB`PNG  IHDR IbKIDATxcQ8/e>IENDB`PNG  IHDR IbKIDATxcQ83v^emIENDB`PNG  IHDR IbK IDATxcxP8y1IENDB`PNG  IHDRB kIDATHcX`ſ߿֕o31`1Xx+^(Ć+ i[7/7g@f_?ܱYFi z0#+( a9 `3ZIENDB`PNG  IHDRB kIDATxcX`ϰ߿֕o31h`1R<[W~3 ͛ P []_7/7g@f_?ܱYFi z0#+( a9 DQ0 bOIENDB`PNG  IHDRB kIDATHcX`gϞ kѣnoW?.0 ϟ?#% >|H\@g|Νg.#΀7o83> YGOg@f_'|& xG\# XF( H%IENDB`PNG  IHDRB +IDATxcZvſ߿֕o3L0Rr~=kIENDB`PNG  IHDRB +IDATxcZvϰ߿֕o3L0RKȅ{MIENDB`PNG  IHDRB *IDAT(cZvgϞ kѣnoW??N/ޥ;#IENDB`PNG  IHDRB kxIDATxұ EQ+RKֶv1P@=ÿ[5a &v6 9suٲƘbgdE1!T |Bx~:"B2 A)B >\ЩIENDB`PNG  IHDRB kwIDATx^ұ EQ+R 6b11F #=N^0/hWAʷ$…Yk kJ.bIy0g <B!4cB| 1oIENDB`PNG  IHDRB knIDATx! FaHlr &4me y5-tc{/D2[A*DY1,B8$AD !]CZ @|疨TIENDB`PNG  IHDR Vu\*IDATxc?)`0jAߤi+*/ޣIENDB`PNG  IHDR Vu\)IDAT(c?)$`_$Oh`#Ci8+& $IENDB`PNG  IHDR Vu\*IDATxc?)`0jA[nÇixوa(XIENDB`PNG  IHDR Vu\\IDATxc?)l@cXlXXq ̌S!&v/Oc M j< @f&IENDB`PNG  IHDR Vu\WIDATxc?)l@cXL2]8p  L q_ACSHcIENDB`PNG  IHDR Vu\NIDATxc?)l@cX d~ŚaGbAXYى 4Y4##PF= .IENDB`PNG  IHDR Vu\2IDAT(˱ @ ј(R Qt`lǰ-HwۂT6* IENDB`PNG  IHDR Vu\.IDATxc?)IphŌ P, *ĮIENDB`PNG  IHDR Vu\*IDATxc?)`0jA[nÇixوa(XIENDB`PNG  IHDRԭ csCl0`MIDATxc```e`[IENDB`PNG  IHDR!}4csCl0`MIDATxc`d0f`e``2 A0#{s IENDB`PNG  IHDR!}4csCl0`MIDATxc`b0fd  @ s=lIENDB`PNG  IHDR?csCl0`MIDATxc`d IENDB`PNG  IHDR?csCl0`MIDATxc``eIENDB`PNG  IHDR&$HIDATx^[UU}vtt33/E=hfv!Rz0!",,z*"4QgF訓6gf{]bpyr!(˺~k>o,) aՒ.`~`oF,"„K/GVXN(" ">=nڸ-/F%'S> 2m #g*WQbnISFh3'j 2DCzpX-%XNֹϻ͸~FZ`& DpI<1X_+NMs/>UljSSSu ;hm"݂0,[B(T)LxKڛ:Y|iT-޶%Xv|1gv~b/78pYJܳr5QL6+(NS.&17J:·ʐOF}\05&z\[Ajo :VOcesqz1ޒSv<11V4Vհ8}G*;"c*?'9p+ -Id۸h4lC>KO.:>鄲ѩ۠% -ɱ(UR ,ڽmm`5b5.{[l)L`ZT?ZH$!1={zw**W[h 2k1W.Fg |Pƒ0z7B[ˑ < Q7]-8!"8~:z[G)FlAgb1^zxbr@RP룴*CC9`:pYshn M³b TkA>JwcC/ϧ̓;'2g+)%O?v14Y+ٲN=I(1Y72e2*spSuK*f W[w&I)k_pQt .|Gf,y(wFT)G #FS-R ':G901r1$ ZJHmQ@G`o0ܸx[QYƉ𝏑&"w\wM3Θ0A`4V x8h`łpg \}Xys5.>p+b,  {ko\ qKIENDB`PNG  IHDR&$HbIDATxKlTUޡRQyȃZ dhqC ܸW>acD>D##1&ƨ b[ 4SΝs^`:1ړv~s˜e8"?VaQMP rbZq oUnl| x fAND#<^qA}kJ^+N[GĨ,>YC {0)o[})[Ǝ :ؾ3~U,C͑ q5ɮvѻ\=MZGك+đܮpH9Uv\1*(6#1 8?|9[{K+W4;+d?i^(rFaFJ;53 1yFϪ%7twQsyXxN1MEgqʤVԚ>Aک-}S|MKͶ湑96&Zlq9[ߜҠ>}w3:ؐơ%;TPeܽy/MReKɭ{+m-G'0aUsT ffu<2ʊ+e VACTƴ^2)vńf} .3$f:&MNNM*E9X>>=X֔N>Y^0>;u!v6} `deO\l`iδClx;/4 'ywhfK t5=pZgZj vgpBnwZ_+NĦ pЩΡY>itt4`8]c1w^Z8c ,+bKJE=ruL$V[ҁ#ڦ%[8*@8cyQ,~NC,q'`>fb8ԬU ,c xgE-؟=b#o IENDB`PNG  IHDR@4=csCl0`MIDATx^Ԙ銝E=#nŨWaPaРH ޔup\ɥ)36ֺt^m@Ȩ$5w4wFƨH5QlkK| p0 f4F"w>nԜU 8V V68S Rw>ZػD_MCQ#7x2e$;po abl ۙ: P%7<,xm!^ӘkcS\ZVKPD55 )߾oUw69Z/• ;"QCGԭŽ ]81;C%b"->GA*fз|uf) x.\ݫLyBWhZ5#o~T%1'd f(R lp7(o|O *]F{4oRAl웇XnfjDz5PbVbqxR/kS+pl **l{Jtج{ܺ}ltn,ƚSUl!TI˜xݭ ŎȯRdAnW6wV+v1GQ.EX'G}:> )*5lQBnp"O[Nf)gVW49#QppX;u@둼tb7#SG1ضmo" |<0Zȋ^Hlͩ28~I^BU~ny؋lXʚRzJ'gՑ=L~gff_G3KbS'˷zCp`v;='q a[r @IǢg7b!1e$ D==$ޠ>}ąsoJboƷ<||ܓ~d7RTƱ \?M GbQÅ`P?-[a*!`E^#;F'nbͅ$ # ԥmp0:k 8vd)Ec^W>!& M?>̤0cE$Qmɓ't8|YlMUM쫻$fF/Ղ 6{`&k:Kn~rl_Ä)!U[q՗Wp3c(vq؍xŚN8H}T\Uy[Y!<{\ǪWΠQi7Y QY[\A.:g 9 P{*f`+- `!}X)3VeɎ=;6c:Z 6i"/V(h @!? xZ0G׮]S$P/k |H_(KBnP 8lI҇iYJIENDB`PNG  IHDR@_XcsCl0`MPLTEݚݛޠ᜵ߝߞࡺ♳ݟ᜵ޝߜޡᠺᚲݛޞߚޝߛݟᚴݚޟޞࡹ᜶ޢ⢼⥿夽㤾䥿䦿奾䢻㦿䤽䢼㣼㣽㡻⤾)CIDATx^Ir1SR9N,a[j] 7lm>W.Z4ǽ%s RU4wFhH/_YӺQČ]l&†qa3Af3;c.D@ƘA!0B@ Jiu6W?vٯg0(*| ك/b@ Q"_vKekץ7jmsV滽lFZ8Ku@PP LU#QpEInzu= T&*^I{Z.۷X;ck><7~:-3cB&hAvZ`|ZjtB$ HIoϙhIENDB`PNG  IHDR.ucsCl0`MbIDATxc-D%@I+0`-jxJ %Dڡa `%t5S3#x[. XcZcsGIENDB`PNG  IHDR.ucsCl0`MjIDATxc={v#-D+W{Y$p4$//)1,K@b0HаW0QtyYBR<-@FK,PcZc]d(`IENDB`PNG  IHDR-YIDATx^ɱ P@3+PђR=!HBeg)Cuz%Z}2.V/3Xz1=_(P"morRt6C0UIENDB`PNG  IHDRı%IDAT(c@0*bdAI(j#FQÈW4Rqf;6QIENDB`PNG  IHDR-WIDATx1 0C@:*dx1^sE_Q"Kv(^Ƃՠ opʤ*D]=WUn?& ?HIENDB`PNG  IHDR-VIDATx^ɱ რ2inGN|I,<1sqgeϨxuK(aW(@CE~ ? GIENDB`PNG  IHDRı$IDATxc@0*bd0#F61DQ1Q-^ LIENDB`PNG  IHDR-ZIDATxɱ P@3X䫕@(" xOy]M~k{zV-FFK+PlRM28/IENDB`PNG  IHDR-ZIDATx^1 @wF!4'((h*_.{G5=$n4@Gv lČZBc*Ea[p^r[IENDB`PNG  IHDRı$IDATxc@0*bd$FQ1lQd<Q-"V5{IENDB`PNG  IHDR&2saNIDATx^OHTm5O0S}4F,& $hJD;R">hcng JBT4C T׹͝{Lg|+`gvK%(ƙAzoK޺HbL[6tCזc޶Vo.!965>êELru8|w|/[`3௳k 1%rZĶ36cN@G3`}T1xp Ѳ7 8-IQjU"9Y5=r=Ub.jQ #q T\넋ˤo];sӏ(y?l9? AlfqEvC"0w. q)Vnm |(-WJq߾ĕ9ayeՔ] _$NT1LHE!ʄ`%I2DֽM!S6K4ۓ-vg&%뛥3ɆC)n&)̔A?D n"lVɨHSY$Z cW[ٌI5Y: f=u4Gz)RɃ& wyhdz!i#WB#7sn!J>dpQpc8ȟ&+MjEOSrLQ|"Ow IʔH.x20()+|+Qd3@0D$}1%ɐTJg0in=ZE~^YKaoIbl3)0" e1If󿘟 QIENDB`PNG  IHDR&2sadIDATx^ֽn@ `/P1J]*Kɉ)o03<@ -#d`o.YrDnW4p|[:6ܓRc@ՁiZN !=$< : nz0=W7M^cl`WjoЂϵv7.~5srPjwppn& YyHU+ZGDH Fp~G"㲎S$򥚲/$ 7R0!`cfO |G>cOH <%tI]7WԂqdm˚R訓p~)4}7M`şSz|SjtŅRU~J?X&`IENDB`PNG  IHDR(csCl0`MRIDATxc`H/NdHi@ QM 31!M@~ڞtMz)N2ire|9@&soL<ܾDfW X\`VUũq@hst0gqg5` 0ͦ",.V,?;} X\]i3`qA^_ӺSbxy6^F\-`q %NZ=YcېI†a<7WcYx"`H,+'h\tK8 o0&I$j4{TTNݔ77 ْq!4QUUd2hu[L{^>BYLWpS_ Fa鰀1C jу^B$)"늢RUm )p5e=n>S~a03)k+Lk b5n3Wi$$1*z>`'IENDB`PNG  IHDR $8IDATx^MHT]ƛ1{GPBD-pQLMGaȅ?6.ZZmQdn u!sEm`PbkFO; ½zQ%ƒ9;sA2@i" *uqn:9iQDD͛7oG׿<<< 9bK g1Szii~ l'ȥZ8NcqCCc0d2 AZ8nJxhhKR6\p1+z ɩ@-p րM 7FhR=,72])L&ԔD"^) 7ԙO/T8nQ__/Bhkk#& w \XV>J! bբ0zzzD:Vhi \EoӢGT <# *gt{n43P5088(:;; G>F-FHeE䴶* ƀ_r@{{;93`t MȈ-@K@q`gg'jYO4@ @Kc\]]x )dxܔtc(51ɗNM166%tD-b}R -,,|S2^\\T 7hi Vͽ3s5c3 4juzc})h(OCy8@ D\z! NQtU])<+p 7*^p;UUOb})& .8ViMxl6[}F?N}-'7Z8 L]+xON|,b1s!j5+WPIIl[.y$E$"1s!7WcW 5fAP4'pU`1r՘jfbG."h'`1rL} ߕ1MLIENDB`PNG  IHDR $5PLTEggh\\] ``a񧧧ԷӲ)-7tRNS%#! 4k 0A B  b_ 3\-IDATx^͓z@Q -Ľ*ĵt!ȗ=Lc(ZN1Y0d M6b9@\WE ۓ@"81aed!RMcb_-(ph\x iM/bML5 ]7̮q"RI! ڈJĮ"+.u 10VG|Z> y0 ?75=bIENDB`PNG  IHDR $8IDATxV]HQ[;P /tI %iRSS^X7v 4nTؼJEPa^h`OG|sMv}眝)؉⿁7GD Yg yۄBx,q6`2!Mښggg/bA.jP{,gtDdr}}=Ҍ8rQZp$d-v{aף»J3Zp KxF{ڍḍ\ęrk(..Av' &`08)O8 \۞nhD5h: J8x<}bnh@+Ҁ:00Ti󬱱 V]] `g@ Ѐ4 (X=khh`_u[[a M.@Z2*uu5 Z0+++cMMM.+ x`###]iَMVWW!.7Nh@$#Z.2t:q TUU @Z2Kfrjkk @+;=!w[hЊb `yy(i9cccB-r}zz5 BnBqz{{֖5 LiY}}+4"s#!GAZ244fsceeeQcu>CbА$ hLxnD1?F^-4H봬*JOR?18 h pZm͖'YpSfC#@ AGre1 {% n!E VND/{.p@\B0թ spp`r G-89%%L----`g!A-V.i Bvj^/2H Cry2q A+8Oy6y"q !E-\@O0|㱔$ )A$$[ fzIENDB`PNG  IHDR $8UIDATx^KH\W[ HѦM|DڐDZiIXpNhtp]v[wRp1](ZGy5 FՅ.yE? O1kY KG V<5IdM; -N&&&SSSG333/kb䨡z/kzfgg,,,H$E9 C/)87]PuttԫHBjAjnK;[Rw~ennNVVVH \F2 @`-M.;qO\pF<wumޞ_̏g[fc sE}}}R__/@V+1r1 7 d?~i9bEl6Kuu5`ML~ 8ɡ݁1vvv [[[HEEW/6M`M'7h x^?dDt^1rR^^.n[ p|ZYY9\ZZ242dEq jZZZ1Zׯg[դM?d؈P\PSUU57hlFv{B֦n 77.-hmmMz n¡!`B k@ QZ zA.pbkoo^=p+1 l68*Z].W9jWOn428==M: .AndddD8 HOOx<FګpF4z(b6W~rz{#9>>Ŭ Ύ^4Ҿ޼yU'upe:ӟ?,*199,Bp)q8n4b3Φjy0ebC/p 7  M(3Ɔ@j顗+ N*B[L0ϟO.C ekbPK/pTk}&c~ٯaqr`M5CA/xl<X#GL8.ӌ|»& j.PBBUkbyTBT,%IENDB`PNG  IHDR $8!IDATxMNP 0 !Mt7S=($Pc6Z&'s{˲֊2i@e!}/GEt:51Ē#bӹ5MM, L&9 "OT*G5\A,\8ܦWz~*d'#p%I/j'؇@…@.p p<' 8v5exx Mh(٫D_1h8`Z훹@@0m{n4r2PJA hdLIen4r2pH]hZa6[6|@XU!Bk@$ j<4gTn_?Fys 'ht&TC,>d}"Z<^)ep !Ę7-7Ж,8rk჉eߦ>_ޮ7C&xF Ɉ(NIFyʶѬ3b%')6?D@<-=IENDB`PNG  IHDR $8IDATx^MHa]5!P䡢2 ̢C^8bȃZDE^>5$ =Xb废:֗: 8{ٙWWq+*o:HvR/)HRbC8`'Oo5is|nn^8PZ\JI=u=-M CM4 c sA-zHRt u"fR LD\I7)O sZY?18!IENDB`PNG  IHDR $8 IDATx^Kh\UmSlbk…Ņ)-v@h$$$1$.AjQ݊!D0>DX)ujMk6M&ܹG=sn.I@|p8~=!"?n𿻼EɯԯtFiN) PCfU]|wіXcXZzH{Ο8mB2<۶cSKx'^ 3sdY7QӋ1_j8& x<_3xܲ,x'nqަ5FC7 ^ַ]7-5OފϏ6Fp"!ijjߏ9֌AB|1=ill2Ę9dvvu`1ŤAx%OuOO/$,. n||\"sQ2097=v@B?v|9e:beW1K v~ɷWқ:Sy :V}gs9O6/p൯ʛEs8@̱&PK SkCܩto[y7O:~D 1f5jGi@0VQڭ^1sQz=iǎl[+ @Yƃ8i]:[IENDB`PNG  IHDR $8IDATx^mH]e j}alVhzmA^3L+5l -i,* ZEAP2 ~0a%+pLV.FnwZr=>=s]s?Rz\1D1LqLz}G#oHԬ(S'ێчg='%`E8*1UeD:>e c%-@_\UIUUe c+RK_N,p<J0t`9fLaֶ` x%=K |k `C/oPR*FnF"ڴ뙉^tψ639?#`HV6L&W![v?_x><5 VU@;+>޻k*e {G"Y fRJmCjLmaGNOڪ ƶ"D(mr`M~FCYȨ3h`V3/CTE7IENDB`PNG  IHDR $8lIDATx^KL\U[ݸи WiRKZ1$@BW!Ia#$0хJCML[2faf`&`58eh sB]|}y9pDDS <6p<: n()GP{_~BBjB>2.__P-zeqqQ~?`LaZzîbvޟGdNn B*x\ rPKp-v ƛWڛT3%lzKqt%wfj&F+ \pOo[7pϼ۝qd}}e8-=LN9і̨_*++%''HUU1rF tN;{V+VQQ!RXX(%%%11)//_kNrh3}EL+++HAAc5F-K؏!YXX~``@t"*@\^^ iW(&5u'@!khh`LPHn424R.W{!+**j2b@˶R=5eee ~ظu{r ^-@-+oa~ݴpxx+xjFFF(;&{O{]#Y86ᄻWi(!wH9\ Z[[[Ξ8he2`1&YؐQiooa@:::dllL677pFcG3S]M};SNӟc-0#D0&fYM}[Z@ރ7}dY#pQ;/~LqC/p 7҉Npj;/H$Zzep wg^f7waA^.t%&{?*nIM&N ?6~ a ƢQkePp˹FVHQ^.eg[Op`YC)5ƵcX 2%%<}I 'JE!Rt /6[{ٕ.0JŽ}A-f.B`ɒ227صr;X9s*} }a{/ Bh١IdfiTҩReB8jEp(ܣpb`dlS2́|X>'=P+"V43%^fIENDB`PNG  IHDR $8YIDATx^KTQƵ6-6C\ Z . WFƿ 0ӌLP7)EE&|8_9CEi1|{04{Ęk穥^xm;Q`0(ӊ9j^,K.0?uڰމᐹ9 r=€l`^Y۞X띸$K€vdݬCқ  &l<2hb8NӟژH=a[ i]%P`tz(X,V0aし)6c(`EMj&WבH`)| 2 &l<2(Wl}rF"I#kϦ^`#ӑ.a:Vp$2G ˝Â ;C){UGX֍r" I BV7ܢ ̜4H1ݹг,Oۨ| !\cNzaÄHQ`].ןTc1G O3Udmv*UU-b5#WYm SiA%JIENDB`PNG  IHDR $8IDATx^kAݵn/DQ#&,R"VR =x1zԳzRX+(zi͟P=WZjM<_Q>bfMBv}~0j?Mӥ`t!]$!Gx̋0M {_*J7 cAmOCG^=]V5c.jP 7:{{{-0ܟL޾Q*xgVO$Ʈ2TOx `&\P(, C`5N.Oz; mEQ:YN\~W/J0־;"xRŶy`+@r`\w`KU\-t0 tbl%,wN WV>'!id*zA'sK^) `B$aקRVivI׍k"dM0s2B&"pt ~,F:mRӶt(^ԤD77W?_brsIENDB`PNG  IHDR $8DIDATx^KQƋ ABtQI  KJe !IxVȌ[ Qq?-q檢.˜#s/0- 0{a' p}v^gfX0aqRZa\g X0fI:G ?|>F&l<:*@4EY6xUȉ`;N /]s~~g0Yx PRRj;Yl<:}+_-KZ閫].&^u[&&&~.C1.@wwO=j^{{{ןiY6۱|]ѥgw,41,u|b333ߥ7a FFF>hhx"9 X0aq\ĸ\͟ZZza D.`4 (5v%5C/&,@9; FP_bkHQk $^J!vwwqr|LWCcc_?ڽ#bkPKzގ ꚛ bk #ӟf牮MRePtQ/*a35g:3lIENDB`PNG  IHDR'+csCl0`MRIDATx^ PBRGڰ'ra0'"-ZEJ-j + ܜ99H='F~I;) V0g]]&7v df&Jo2~2 ">?(cIENDB`PNG  IHDR j=~IDATxcoO׶YwaoJόO=n_N#UU`o??7 kAekg``A4YC[g ~@11xt(@ sXV[(IENDB`PNG  IHDR&DIDATxcD0tp(ϫIENDB`PNG  IHDR &WU{IDATx^11 džJ'x!  {)E3lS5I5I5Ibi4t5rdt#zRr,3=\M4In,j7tz듌}F14~1\u~n"]^IENDB`PNG  IHDR &WU{IDATx^11gHSڔqiy4Y)_sF6E m,mm?n4/P$Jv۝e•qQ"ˀ祽zQGQR"Id"niI(ۙg;m<շO]~b4~HWEQIENDB`PNG  IHDRy$IDATxcȠ $}[Aq X!IENDB`PNG  IHDR j=pIDATcπ X@Lq00сܾ H.&vGļ-?J(mr1NUH7413,+hbpIENDB`PNG  IHDR j=nIDATxc20股62pTwӅeL[7}Ec? H }/uw& B亮G5pQgz`ZeIENDB`PNG  IHDRy$IDATxcda``dE%<%3-˥ IENDB`PNG  IHDR j=UIDATxcƠ +5910Ȣ?<4< Q>`"A߱s<< ?r?0!VA#49}>IENDB`PNG  IHDR j=YIDATc`AJndQMeTACua VCg``A.39c+g s@X VA[4 YkIENDB`PNG  IHDR&DIDATxcag``a`@%!,4P#LMNBٶIENDB`PNG  IHDR &WU{HIDATxc/ 0 Q!V8-b ڢ,b ";)N;o&ִDa(1G+B#OIENDB`PNG  IHDR &WU{DIDATxcag@6O0`FL XT)ΈEh*c;)t'd *)db+IENDB`PNG  IHDRy$IDATxc/P"C&~doIENDB`PNG  IHDR j=^IDATxcL/!RL U \̙Π @Ϥb!\ e@feBaA!%gIENDB`PNG  IHDR j=^IDATxc/Eg U TʙlT?DP t9+"=W3LAχ._ ]P94LCJ!;;X>֬A0AE8>! |7>ZAZ ٥ f|^ Gvㆰ4 m(LQ'`yW~r_4>HO\?\2,c$o03;ly{}񬫈X*F&X`#a1$6Qj4={h> |<68bBrWq?(?Gr\sDLwDMaΔ"~5L6O[@PU@6"NUXsZ92X!ټkĸNxmA؂!#$0}di9CzpgĈFk5rސFY=b-0*ad*l}YnAO`()X +\ #","VIEӊXr zΣEd2.BZyѼ: wc^-Y6qF o֌\=ϊC^z6ON5o畀~y]a @VYoy~;8K^q~x~~4Ay)}/O?mk@S.\/|f^lvC?",9#/1p4w0úͿ4fsUBaxb'HfH1*2jywf%yw_lfwR=&B\(daH"DhHP!H`’% 3.A}6`A6V\ytt8!kLF#rdJ?QDr;f "UbL%C3"1BgGWV*'uAL/1l:Ȓ#1V7 6VH!Izƒ\[!Fpz`-^IR.)3m"K9HMX` ūeR:Y9^{?"5.,/)$PAHڟ"(Z)5aR0/d' , .&z]K{VdTJSRTQ8`XzV RXB"GU4' ک |+PR=DpY=W„P:Ĝ?L"@'9Y=B, $G9D!ȩI=O)}ZXuԂĪuu Og9LUazXɶ p[IENDB`PNG  IHDRll0IDATxcπ!H q@&,& h)t!IENDB`PNG  IHDRll-IDATxcd%Hc A$ D $2 H&a ?k,|IENDB`PNG  IHDRlA6IDATxc@ȈE!,耉R@0c+k$ox$εIENDB`PNG  IHDRll%oFIDATx^AjA.@{9t oϣM;+j^a?8;;;;;0NL Ul1 환2az*F=0-irRzRlWb H RbJI aK+$i%)/uXΪQU')0-AQڕk1+Gi /cAxTY!J\x3X1JR xObRXN1YJiM9,ƊRiK0JHcR>JXJRY1 n]1g iVlYeƩ)Jl PA-KXrTP`WUta?E;LPC!0 2QwT5b*ӲsrH$fY-ΞGTa2DPJCE  Av9!a}WRX XKw yf^Lf9QΨ zW9.%iXLLbj@X=K@2xqk%1nS&Rp_1`L6O } >c>djAx&L}ҸY^U,aqYʶ VgbMdu'&ɸθXxaD+ٟ&>6,/xS0Ni /0n>Ua렑f(a70%Ԃa"=F:Z=t \k#DcCb9.XE\IұoS~v H _K&4r M Q c폿ɋ8/ˋ^698ê51f0ؓ!Øi &bL\Ʋj'hL aa2T`^c8gYn͉14B%trEÈ*3l_ż&FqϧVG17IENDB`PNG  IHDRll%oFIDATx^Ɏ! d}Q2*AOH`5#}5a kXְ5a_lvlK,-&ۂS "YH=졨 @VrDΣ 8 40ਅe#=?^n1pd18' I7$W=1{S^G6B@\NsgI/9 _7\BsXR6(9[@㝄܄~ cG(*NK Kp-]~r0UzI2 8^tAŌ]p~G:u;|p.Vn79UT#9ǭa)[K3"_[C[;KNX]~ahSd& ,h؎)!f$h: &OV] :_ l2˦iW ݀|Ɛ3+Ϧ|hUҜ)h], e+v=-i4V`7 obf$U^$fh2s=i<Ӫe8ϯ㇡م?>b'n}-zfۃw;)MfCXnšRWR^q'D\I͇E]q@K& =qHh=a"0`Hy$J`A|҈+q"/,)cC2N=Zb,JsS}0XaČJf=)k)I|d2Ά=[`*p"r|2c~3"BLY;XjA2X|ʄpde0f^%D@Lmİe~ʀ[21V$$63]hcy`S{\%^}ʄiH  0=%dzX >.$EL~0q*SƼ $hy`bqv[ L90iKvaGGr 9̮AL~㷁eHʨEߌU?x+IENDB`PNG  IHDRr>]N7IDATx^[[Uge9IL)T8hx@J^ET"^ Zi;9N1]. ˽쫇|Y?['}x3Lih83 T.9of)䧿p!?) bgoO2Pl8YD~J(6M\7.B.2s?pf-fЮ*"壸uU99E\WD$ *_vr6t\㸚#oJ0ŁnXx84F!CF$a[w9cCWĹ1#߭LE$aKC⾾8B=)rr} ySO{t24rd3'1| ycOb&{`93WDL@,$ }}7xUwLe8ףOm]|g@eW6KS|q]_[`:w[A0a_!^-ֵyae v= cм^>eOɎ?X8lj 5o2M:'N)ֿ]_e@b1#S攡b+7IzLӚ#dmL <2 1B f'; ADiE݉Ї֜jlis&B~Ȁg2 ? r%a (\|ːbe+ t:ᢄ|1`:-,GyN~'ޏk~Oi!X.F>Yż&:Xns,GwH1^Ȼ[@$[ȭ@_870@5ld;Iww2g2;y`, 1f%#$pJ X뛪E.#)G9$d+@X0ݦB %OY4Cӗ' !sZEWM9a=f%vG?B߮ E(V߈C-@ٖ/(ђLRdt# p e)gY-{$ȴDYw_gb{8IENDB`PNG  IHDR>rRIDATxKT]>gtСL-){BLH!袺.2LM*Pk t;sV֞4o}) @ĘU}a9owVۓ}4d:5b\(<٧$`>6s .:]_cxu,ˑ;gdG@Lj@1gq x6<@"ENfW X&0y.=?rRIDATx^nAP%,SK#p `; 3qViJ*(uϡm# .LvN]` ` ,w5l\H 7H!55ΩpE8'+u'mRpqv)q>.bIw'SgU(mMS=K,ܢm33ĥbWGvK?u]ƤE8 K0 gaO2xٌsR9t48zT(zqz*v3N> ec+eWgmr{ sZ4#2?3#/>]\Ǽ#N~pƑ?.Z05N# @[3e䇘:8'n͸8N^ .q ''`T'?05Vf(`}w4eL ] KO8=Ă_MB>?M9cS>&\c=c WEU<5 'Zz 7O2P&wuAZ#IjgZz [:~62=_!քSx=u],`jk[:o-8 k^&.aM"ee{]2 >Q[W@Z5/3/&X5a)8l%B("q9pV~E&.tx7wa:zUmZ!t2t0E*rm/Kp o ~~bi|qAI};]N7IDATx^ij@ іNSr-Pn *Cw΁<2(Bd9 {H"s$`)r  9|/HWFyɐ i uu6&Ng @jv'?ԕ@9>Y^QOuȰx< 'vRn?YNcp 4~[8;E W)6Zu EDZhզ HRCi1xw?>3u'Vw#IENDB`PNG  IHDRDGIDATxc , | XQ^GIENDB`PNG  IHDRDGIDATxcd"2¿D)Fk IENDB`PNG  IHDRi4IDATxcH $k1IENDB`PNG  IHDRF]IDATx^̱0}1M;MBԂf %ȹx֗y?@|v7K}ۜ)O E4Nf1j jD9"2?Tc IENDB`PNG  IHDRF`IDATx^̱ 0ы8@ZhdA \8N;~(vf2O&$6&Z Uq8 Ab@n!(txQ__:6 .Lԓ<IENDB`PNG  IHDR*Qg IDATx^A@geee Q+ؤݺm:Igx08!e #m2vwT< ori/ G4@;n䭦:*nQղ#7$o4hI~;ּ|QSMqL5{g< S~Y`3I.[|*!Ȗ>NV K8jZ(Ƙ*NV|ԅN+'*ږr(Ez|^/GM Ө"KK%dKުW:u5rTXtJأH* 9e"{ب%˨ƲS^'#maWl. ʣevըDZdG#X (}2*2L_\T6IENDB`PNG  IHDR*[.IDATx^]KA߸/n^HQApث;M]5ssw !$/?laȲC?Ls nh,y .h0j hYP3bpACBp@aゆ!P:|0J^HcFl Dœx8%e#.JcP2YN*9@iBTzPႂ WfO`o #\+eIENDB`PNG  IHDR*[0IDATx^MKBQҺ/Pf,ًdnZD 5 QEgQ@E@cD΃P)Cq8 B;vni)5 Vj@$# 8Rj@Qj@p pVO`AGW"aL<*rD 1S,2\ѣjth_Txe"BX o<);.@L?