5] 5e55R5]5wm5Iw55Y5d5j5p5s5{w5+z5u545֨55 5755555555 5"5v4585=5K5O5Y5 a5j53p5v5y555595d55P5`5Zs5{555ӝ55F6Ah6hC=jCLnC0vC{C3C.CC(D8DDD D DZ D Dm D D D Dy D _' _/ _J _IK 8c4L 9c)P :cSS ;cGV c\ di` dd de dKg dh di d5j ddj edc fdM gd xiv yi zi[ {id |i" }i' ~i]1 i3 i: i? iD iK iM iWR iBV inY ib] ig il im iv ik i> i^ i i i i i i i i i iʩ i i i i! iR iI i0 i iF i` id i i i iH i i; i i i i i i i i i? i i iY i i# il' i4+ i, i- iP/ io i i i] i_ iԠ i im i6 i iƧ i iߩ i i$ i i i1 iU iv ij iB i i iu kz k k5 k k9 k k k k k k` k< k k k k k' k_ k- k$ k kX k_ kP k& k k k k6 k k kH k k kS ks ki k k k k k= k k k k. kl k! kT$ k' k+ k0 kH5 k9 k< k? ksC k D kD kE kE knF kF kG kJH kH kHI lI lBJ lJ lbK lK l9L lL lM lM l1N lN lN laO lO l P lhP lP bQ iiiiisitiuitiuitisiii|i|iiiiiiii|iifkPNG  IHDR szz IDATxb UE Dq?A:Y,Z 8%n@362wd7}LyIAL=c|d|~~wX/)Q{{v'9:{a#IVD`#:ߗ⢮(7MAlɝz6zT_>*ꅞj|ಛs/_߶6ځη4Jw/C9gy/vzb:V#j֞Qh>SbG lV*_mF!ڢ.:qFgt0 xG|j v6 >WӅ9f'7'+(-O=xdBIfm:ˣ:`gB`MzH|P x]H@l 1"g#mGd}c"CHʥm!u:;#ilCϛ86 '"9-y(;2_H+4CW2饴QHd\gO܍ҁoӿc2$f|9?IENDB`

$i18n{message}

$i18n{message}

$i18n{fileName}

$i18n{message}

// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the app API. var appNatives = requireNative('app'); var process = requireNative('process'); var extensionId = process.GetExtensionId(); var logActivity = requireNative('activityLogger'); function wrapForLogging(fun) { if (!extensionId) return fun; // nothing interesting to log without an extension return function() { // TODO(ataly): We need to make sure we use the right prototype for // fun.apply. Array slice can either be rewritten or similarly defined. logActivity.LogAPICall(extensionId, "app." + fun.name, $Array.slice(arguments)); return $Function.apply(fun, this, arguments); }; } // This becomes chrome.app var app = { getIsInstalled: wrapForLogging(appNatives.GetIsInstalled), getDetails: wrapForLogging(appNatives.GetDetails), runningState: wrapForLogging(appNatives.GetRunningState) }; // Tricky; "getIsInstalled" is actually exposed as the getter "isInstalled", // but we don't have a way to express this in the schema JSON (nor is it // worth it for this one special case). // // So, define it manually, and let the getIsInstalled function act as its // documentation. var isInstalled = wrapForLogging(appNatives.GetIsInstalled); $Object.defineProperty( app, 'isInstalled', { __proto__: null, configurable: true, enumerable: true, get: function() { return isInstalled(); }, }); // Called by app_bindings.cc. function onInstallStateResponse(state, callbackId) { var callback = callbacks[callbackId]; delete callbacks[callbackId]; if (typeof callback == 'function') { try { callback(state); } catch (e) { console.error('Exception in chrome.app.installState response handler: ' + e.stack); } } } // TODO(kalman): move this stuff to its own custom bindings. var callbacks = { __proto__: null }; var nextCallbackId = 1; function getInstallState(callback) { var callbackId = nextCallbackId++; callbacks[callbackId] = callback; appNatives.GetInstallState(callbackId); } $Object.defineProperty( app, 'installState', { __proto__: null, configurable: true, enumerable: true, value: wrapForLogging(getInstallState), writable: true, }); exports.$set('binding', app); exports.$set('onInstallStateResponse', onInstallStateResponse); // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom bindings for the automation API. var AutomationNode = require('automationNode').AutomationNode; var AutomationRootNode = require('automationNode').AutomationRootNode; var automation = apiBridge || require('binding').Binding.create('automation'); var automationInternal = getInternalApi ? getInternalApi('automationInternal') : require('binding').Binding.create('automationInternal').generate(); var exceptionHandler = require('uncaught_exception_handler'); var logging = requireNative('logging'); var nativeAutomationInternal = requireNative('automationInternal'); var DestroyAccessibilityTree = nativeAutomationInternal.DestroyAccessibilityTree; var GetIntAttribute = nativeAutomationInternal.GetIntAttribute; var StartCachingAccessibilityTrees = nativeAutomationInternal.StartCachingAccessibilityTrees; var AddTreeChangeObserver = nativeAutomationInternal.AddTreeChangeObserver; var RemoveTreeChangeObserver = nativeAutomationInternal.RemoveTreeChangeObserver; var GetFocusNative = nativeAutomationInternal.GetFocus; var jsLastError = bindingUtil ? undefined : require('lastError'); function hasLastError() { return bindingUtil ? bindingUtil.hasLastError() : jsLastError.hasError(chrome); } /** * A namespace to export utility functions to other files in automation. */ window.automationUtil = function() {}; // TODO(aboxhall): Look into using WeakMap var idToCallback = {}; var desktopId = undefined; 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() { if (desktopId === undefined) return; var focusedNodeInfo = GetFocusNative(desktopId); if (!focusedNodeInfo) return null; var tree = AutomationRootNode.getOrCreate(focusedNodeInfo.treeId); if (tree) return privates(tree).impl.get(focusedNodeInfo.nodeId); }; /** * Update automationUtil.focusedNode to be the node that currently has focus. */ automationUtil.updateFocusedNode = function() { automationUtil.focusedNode = automationUtil.getFocus(); }; /** * Updates the focus on blur. */ automationUtil.updateFocusedNodeOnBlur = function() { var focus = automationUtil.getFocus(); automationUtil.focusedNode = focus ? focus.root : null; }; automation.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; // TODO(aboxhall, dtseng): Make this return the speced AutomationRootNode obj. apiFunctions.setHandleRequest('getTree', function getTree(tabID, callback) { StartCachingAccessibilityTrees(); // enableTab() ensures the renderer for the active or specified tab has // accessibility enabled, and fetches its ax tree id to use as // a key in the idToAutomationRootNode map. The callback to // enableTab is bound to the callback passed in to getTree(), so that once // the tree is available (either due to having been cached earlier, or after // an accessibility event occurs which causes the tree to be populated), the // callback can be called. var params = { tabID: tabID }; automationInternal.enableTab(params, function onEnable(id) { if (hasLastError()) { callback(); return; } automationUtil.storeTreeCallback(id, callback); }); }); var desktopTree = null; apiFunctions.setHandleRequest('getDesktop', function(callback) { StartCachingAccessibilityTrees(); if (desktopId !== undefined) desktopTree = AutomationRootNode.get(desktopId); if (!desktopTree) { automationInternal.enableDesktop(function(treeId) { if (hasLastError()) { AutomationRootNode.destroy(treeId); desktopId = undefined; callback(); return; } desktopId = treeId; desktopTree = AutomationRootNode.getOrCreate(desktopId); callback(desktopTree); // TODO(dtseng): Disable desktop tree once desktop object goes out of // scope. }); } 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 === desktopId) { 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(childTreeId) { var targetTree = AutomationRootNode.get(childTreeId); // If the tree is already loded, or if we previously requested it be loaded // (i.e. have a callback for it), don't try to do so again. if (targetTree || idToCallback[childTreeId]) 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. automationUtil.storeTreeCallback(childTreeId, function(root) { privates(root).impl.dispatchEvent('loadComplete', 'page'); }, true); automationInternal.enableFrame(childTreeId); }); 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 ' + changeType, e); } }); automationInternal.onNodesRemoved.addListener(function(treeID, nodeIDs) { var tree = AutomationRootNode.getOrCreate(treeID); if (!tree) return; for (var i = 0; i < nodeIDs.length; i++) { privates(tree).impl.remove(nodeIDs[i]); } }); /** * Dispatch accessibility events fired on individual nodes to its * corresponding AutomationNode. Handle focus events specially * (see below). */ automationInternal.onAccessibilityEvent.addListener(function(eventParams) { var id = eventParams.treeID; var targetTree = AutomationRootNode.getOrCreate(id); if (eventParams.eventType == 'blur') { // Work around an issue where Chrome sends us 'blur' events on the // root node when nothing has focus, we need to treat those as focus // events but otherwise not handle blur events specially. var node = privates(targetTree).impl.get(eventParams.targetID); if (!node) return; if (node == node.root) automationUtil.updateFocusedNodeOnBlur(); } else if (eventParams.eventType == 'mediaStartedPlaying' || eventParams.eventType == 'mediaStoppedPlaying') { // These events are global to the tree. eventParams.targetID = privates(targetTree).impl.id; } else { var previousFocusedNode = automationUtil.focusedNode; automationUtil.updateFocusedNode(); // Fire focus events if necessary. if (automationUtil.focusedNode && automationUtil.focusedNode != previousFocusedNode) { var eventParamsCopy = {}; for (var key in eventParams) eventParamsCopy[key] = eventParams[key]; eventParamsCopy['eventType'] = 'focus'; eventParamsCopy['treeID'] = privates(automationUtil.focusedNode.root).impl.treeID; eventParamsCopy['targetID'] = privates(automationUtil.focusedNode).impl.id; privates(automationUtil.focusedNode.root) .impl.onAccessibilityEvent(eventParamsCopy); } } // Note that focus type events have already been handled above if there was a // focused node. All other events, even non-focus events that triggered a // focus dispatch, still need to have their original event fired. if ((!automationUtil.focusedNode || eventParams.eventType != 'focus') && !privates(targetTree).impl.onAccessibilityEvent(eventParams)) return; // If we're not waiting on a callback to getTree(), we can early out here. if (!(id in idToCallback)) return; // We usually get a 'placeholder' tree first, which doesn't have any url // attribute or child nodes. If we've got that, wait for the full tree before // calling the callback. // TODO(dmazzoni): Don't send down placeholder (crbug.com/397553) if (id != desktopId && !targetTree.url && targetTree.children.length == 0) return; // If the tree wasn't available when getTree() was called, the callback will // have been cached in idToCallback, so call and delete it now that we // have the complete tree. for (var i = 0; i < idToCallback[id].length; i++) { var callback = idToCallback[id][i]; callback(targetTree); } delete idToCallback[id]; }); automationInternal.onAccessibilityTreeDestroyed.addListener(function(id) { // Destroy the AutomationRootNode. var targetTree = AutomationRootNode.get(id); if (targetTree) { privates(targetTree).impl.destroy(); AutomationRootNode.destroy(id); } else { logging.WARNING('no targetTree to destroy'); } // Destroy the native cache of the accessibility tree. DestroyAccessibilityTree(id); }); automationInternal.onAccessibilityTreeSerializationError.addListener( function(id) { automationInternal.enableFrame(id); }); automationInternal.onActionResult.addListener(function( treeID, requestID, result) { var targetTree = AutomationRootNode.get(treeID); if (!targetTree) return; privates(targetTree).impl.onActionResult(requestID, result); }); automationInternal.onGetTextLocationResult.addListener(function( textLocationParams) { var targetTree = AutomationRootNode.get(textLocationParams.treeID); if (!targetTree) return; privates(targetTree).impl.onGetTextLocationResult(textLocationParams); }); if (!apiBridge) exports.$set('binding', automation.generate()); // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. var utils = require('utils'); function AutomationEventImpl(type, target, eventFrom) { this.propagationStopped = false; this.type = type; this.target = target; this.eventPhase = Event.NONE; this.eventFrom = eventFrom; } AutomationEventImpl.prototype = { __proto__: null, stopPropagation: function() { this.propagationStopped = true; }, }; function AutomationEvent() { privates(AutomationEvent).constructPrivate(this, arguments); } utils.expose(AutomationEvent, AutomationEventImpl, { functions: [ 'stopPropagation', ], readonly: [ 'type', 'target', 'eventPhase', 'eventFrom', ], }); exports.$set('AutomationEvent', AutomationEvent); // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. var AutomationEvent = require('automationEvent').AutomationEvent; var automationInternal = getInternalApi ? getInternalApi('automationInternal') : require('binding').Binding.create('automationInternal').generate(); var exceptionHandler = require('uncaught_exception_handler'); var natives = requireNative('automationInternal'); var IsInteractPermitted = natives.IsInteractPermitted; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?number} The id of the root node. */ var GetRootID = natives.GetRootID; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?string} The title of the document. */ var GetDocTitle = natives.GetDocTitle; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?string} The url of the document. */ var GetDocURL = natives.GetDocURL; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?boolean} True if the document has finished loading. */ var GetDocLoaded = natives.GetDocLoaded; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?number} The loading progress, from 0.0 to 1.0 (fully loaded). */ var GetDocLoadingProgress = natives.GetDocLoadingProgress; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?number} The ID of the selection anchor object. */ var GetAnchorObjectID = natives.GetAnchorObjectID; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?number} The selection anchor offset. */ var GetAnchorOffset = natives.GetAnchorOffset; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?string} The selection anchor affinity. */ var GetAnchorAffinity = natives.GetAnchorAffinity; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?number} The ID of the selection focus object. */ var GetFocusObjectID = natives.GetFocusObjectID; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?number} The selection focus offset. */ var GetFocusOffset = natives.GetFocusOffset; /** * @param {string} axTreeID The id of the accessibility tree. * @return {?string} The selection focus affinity. */ var GetFocusAffinity = natives.GetFocusAffinity; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?number} The id of the node's parent, or undefined if it's the * root of its tree or if the tree or node wasn't found. */ var GetParentID = natives.GetParentID; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?number} The number of children of the node, or undefined if * the tree or node wasn't found. */ var GetChildCount = natives.GetChildCount; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @param {number} childIndex An index of a child of this node. * @return {?number} The id of the child at the given index, or undefined * if the tree or node or child at that index wasn't found. */ var GetChildIDAtIndex = natives.GetChildIDAtIndex; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?number} The ids of the children of the node, or undefined * if the tree or node wasn't found. */ var GetChildIds = natives.GetChildIDs; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?Object} An object mapping html attributes to values. */ var GetHtmlAttributes = natives.GetHtmlAttributes; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?number} The index of this node in its parent, or undefined if * the tree or node or node parent wasn't found. */ var GetIndexInParent = natives.GetIndexInParent; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?Object} An object with a string key for every state flag set, * or undefined if the tree or node or node parent wasn't found. */ var GetState = natives.GetState; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {string} The restriction, one of * "disabled", "readOnly" or undefined if enabled or other object not disabled */ var GetRestriction = natives.GetRestriction; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {string} The checked state, as undefined, "true", "false" or "mixed". */ var GetChecked = natives.GetChecked; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {string} The role of the node, or undefined if the tree or * node wasn't found. */ var GetRole = natives.GetRole; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?automation.Rect} The location of the node, or undefined if * the tree or node wasn't found. */ var GetLocation = natives.GetLocation; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @param {number} startIndex The start index of the range. * @param {number} endIndex The end index of the range. * @return {?automation.Rect} The bounding box of the subrange of this node, * or the location if there are no subranges, or undefined if * the tree or node wasn't found. */ var GetBoundsForRange = natives.GetBoundsForRange; /** * @param {number} left The left location of the text range. * @param {number} top The top location of the text range. * @param {number} width The width of text range. * @param {number} height The height of the text range. * @param {number} requestID The request id associated with the query * for this range. * @return {?automation.Rect} The bounding box of the subrange of this node, * specified by arguments provided to the function. */ var ComputeGlobalBounds = natives.ComputeGlobalBounds; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?automation.Rect} The unclipped location of the node, or * undefined if the tree or node wasn't found. */ var GetUnclippedLocation = natives.GetUnclippedLocation; /** * @param {string} 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 {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @param {string} attr The name of a string attribute. * @return {?string} The value of this attribute, or undefined if the tree, * node, or attribute wasn't found. */ var GetStringAttribute = natives.GetStringAttribute; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @param {string} attr The name of an attribute. * @return {?boolean} The value of this attribute, or undefined if the tree, * node, or attribute wasn't found. */ var GetBoolAttribute = natives.GetBoolAttribute; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @param {string} attr The name of an attribute. * @return {?number} The value of this attribute, or undefined if the tree, * node, or attribute wasn't found. */ var GetIntAttribute = natives.GetIntAttribute; /** * @param {string} 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 ids of nodes who have a relationship pointing * to |nodeID| (a reverse relationship). */ var GetIntAttributeReverseRelations = natives.GetIntAttributeReverseRelations; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @param {string} attr The name of an attribute. * @return {?number} The value of this attribute, or undefined if the tree, * node, or attribute wasn't found. */ var GetFloatAttribute = natives.GetFloatAttribute; /** * @param {string} 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 = natives.GetIntListAttribute; /** * @param {string} 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 ids of nodes who have a relationship pointing * to |nodeID| (a reverse relationship). */ var GetIntListAttributeReverseRelations = natives.GetIntListAttributeReverseRelations; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @param {string} attr The name of an HTML attribute. * @return {?string} The value of this attribute, or undefined if the tree, * node, or attribute wasn't found. */ var GetHtmlAttribute = natives.GetHtmlAttribute; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {automation.NameFromType} The source of the node's name. */ var GetNameFrom = natives.GetNameFrom; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?string} The image annotation status, which may * include the annotation itself if completed successfully. */ var GetImageAnnotation = natives.GetImageAnnotation; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {boolean} */ var GetBold = natives.GetBold; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {boolean} */ var GetItalic = natives.GetItalic; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {boolean} */ var GetUnderline = natives.GetUnderline; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {boolean} */ var GetLineThrough = natives.GetLineThrough; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?Array} List of custom actions of the * node. */ var GetCustomActions = natives.GetCustomActions; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?Array} List of standard actions of the node. */ var GetStandardActions = natives.GetStandardActions; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {automation.NameFromType} The source of the node's name. */ var GetDefaultActionVerb = natives.GetDefaultActionVerb; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @param {string} searchStr * @param {boolean} backward * @return {{treeId: string, nodeId: number}} */ var GetNextTextMatch = natives.GetNextTextMatch; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?Array} A list of column header ids. * @return {?number} The id of the column header, if it exists. */ var GetTableCellColumnHeaders = natives.GetTableCellColumnHeaders; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {?Array} A list of row header ids. */ var GetTableCellRowHeaders = natives.GetTableCellRowHeaders; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {number} Column index for this cell. */ var GetTableCellColumnIndex = natives.GetTableCellColumnIndex; /** * @param {string} axTreeID The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {number} Row index for this cell. */ var GetTableCellRowIndex = natives.GetTableCellRowIndex; /** * @param {string} axTreeId The id of the accessibility tree. * @param {number} nodeID The id of a node. * @return {string} Detected language for this node. */ var GetDetectedLanguage = natives.GetDetectedLanguage; var logging = requireNative('logging'); var utils = require('utils'); /** * A single node in the Automation tree. * @param {AutomationRootNodeImpl} root The root of the tree. * @constructor */ function AutomationNodeImpl(root) { this.rootImpl = root; this.listeners = {__proto__: null}; } AutomationNodeImpl.prototype = { __proto__: null, treeID: '', id: -1, isRootNode: false, detach: function() { this.rootImpl = null; this.listeners = {__proto__: null}; }, get root() { return this.rootImpl && this.rootImpl.wrapper; }, get parent() { var info = GetParentID(this.treeID, this.id); if (!info) return; return AutomationRootNodeImpl.getNodeFromTree(info.treeId, info.nodeId); }, get htmlAttributes() { return GetHtmlAttributes(this.treeID, this.id) || {}; }, get state() { return GetState(this.treeID, this.id) || {}; }, get role() { return GetRole(this.treeID, this.id); }, get restriction() { return GetRestriction(this.treeID, this.id); }, get checked() { return GetChecked(this.treeID, this.id); }, get location() { return GetLocation(this.treeID, this.id); }, boundsForRange: function(startIndex, endIndex, callback) { if (!this.rootImpl) return; // Not yet initialized. if (this.rootImpl.treeID === undefined || this.id === undefined) { return; } if (!callback) return; if (!GetBoolAttribute(this.treeID, this.id, 'supportsTextLocation')) { try { callback( GetBoundsForRange(this.treeID, this.id, startIndex, endIndex)); return; } catch (e) { logging.WARNING('Error with bounds for range callback' + e); } return; } this.performAction_( 'getTextLocation', {startIndex: startIndex, endIndex: endIndex}, callback); return; }, get unclippedLocation() { var result = GetUnclippedLocation(this.treeID, this.id); if (result === undefined) result = GetLocation(this.treeID, this.id); return result; }, get indexInParent() { return GetIndexInParent(this.treeID, this.id); }, get lineStartOffsets() { return GetLineStartOffsets(this.treeID, this.id); }, get childTree() { var childTreeID = GetStringAttribute(this.treeID, this.id, 'childTreeId'); if (childTreeID) return AutomationRootNodeImpl.get(childTreeID); }, get firstChild() { if (GetChildCount(this.treeID, this.id) == 0) return undefined; var info = GetChildIDAtIndex(this.treeID, this.id, 0); if (info) return AutomationRootNodeImpl.getNodeFromTree(info.treeId, info.nodeId); }, get lastChild() { var count = GetChildCount(this.treeID, this.id); if (count == 0) return; var info = GetChildIDAtIndex(this.treeID, this.id, count - 1); if (info) return AutomationRootNodeImpl.getNodeFromTree(info.treeId, info.nodeId); }, get children() { var info = GetChildIds(this.treeID, this.id); if (!info) return []; var children = []; for (var i = 0; i < info.nodeIds.length; ++i) { var childID = info.nodeIds[i]; var child = AutomationRootNodeImpl.getNodeFromTree(info.treeId, childID); if (child) $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); var info = GetChildIDAtIndex(parent.treeID, parent.id, indexInParent - 1); if (info) return AutomationRootNodeImpl.getNodeFromTree(info.treeId, info.nodeId); }, get nextSibling() { var parent = this.parent; if (!parent) return undefined; parent = privates(parent).impl; var indexInParent = GetIndexInParent(this.treeID, this.id); var info = GetChildIDAtIndex(parent.treeID, parent.id, indexInParent + 1); if (info) return AutomationRootNodeImpl.getNodeFromTree(info.treeId, info.nodeId); }, get nameFrom() { return GetNameFrom(this.treeID, this.id); }, get imageAnnotation() { return GetImageAnnotation(this.treeID, this.id); }, get bold() { return GetBold(this.treeID, this.id); }, get italic() { return GetItalic(this.treeID, this.id); }, get underline() { return GetUnderline(this.treeID, this.id); }, get lineThrough() { return GetLineThrough(this.treeID, this.id); }, get detectedLanguage() { return GetDetectedLanguage(this.treeID, this.id) }, get customActions() { return GetCustomActions(this.treeID, this.id); }, get standardActions() { return GetStandardActions(this.treeID, this.id); }, get defaultActionVerb() { return GetDefaultActionVerb(this.treeID, this.id); }, get tableCellColumnHeaders() { var ids = GetTableCellColumnHeaders(this.treeID, this.id); if (ids && this.rootImpl) { var result = []; for (var i = 0; i < ids.length; i++) result.push(this.rootImpl.get(ids[i])); return result; } }, get tableCellRowHeaders() { var id = GetTableCellRowHeaders(this.treeID, this.id); if (ids && this.rootImpl) { var result = []; for (var i = 0; i < ids.length; i++) result.push(this.rootImpl.get(ids[i])); return result; } }, get tableCellColumnIndex() { return GetTableCellColumnIndex(this.treeID, this.id); }, get tableCellRowIndex() { return GetTableCellRowIndex(this.treeID, this.id); }, doDefault: function() { this.performAction_('doDefault'); }, focus: function() { this.performAction_('focus'); }, getImageData: function(maxWidth, maxHeight) { this.performAction_('getImageData', { maxWidth: maxWidth, maxHeight: maxHeight }); }, hitTest: function(x, y, eventToFire) { this.hitTestInternal(x, y, eventToFire); }, hitTestWithReply: function(x, y, opt_callback) { this.hitTestInternal(x, y, 'hitTestResult', opt_callback); }, hitTestInternal: function(x, y, eventToFire, opt_callback) { // Convert from global to tree-relative coordinates. var location = GetLocation(this.treeID, GetRootID(this.treeID)); this.performAction_('hitTest', { x: Math.floor(x - location.left), y: Math.floor(y - location.top), eventToFire: eventToFire }, opt_callback); }, makeVisible: function() { this.performAction_('scrollToMakeVisible'); }, performCustomAction: function(customActionId) { this.performAction_('customAction', { customActionID: customActionId }); }, performStandardAction: function(action) { var standardActions = GetStandardActions(this.treeID, this.id); if (!standardActions || !standardActions.find(item => action == item)) { throw 'Inapplicable action for node: ' + action; } this.performAction_(action); }, replaceSelectedText: function(value) { if (this.state.editable) { this.performAction_('replaceSelectedText', { value: value}); } }, resumeMedia: function() { this.performAction_('resumeMedia'); }, scrollBackward: function(opt_callback) { this.performAction_('scrollBackward', {}, opt_callback); }, scrollForward: function(opt_callback) { this.performAction_('scrollForward', {}, opt_callback); }, scrollUp: function(opt_callback) { this.performAction_('scrollUp', {}, opt_callback); }, scrollDown: function(opt_callback) { this.performAction_('scrollDown', {}, opt_callback); }, scrollLeft: function(opt_callback) { this.performAction_('scrollLeft', {}, opt_callback); }, scrollRight: function(opt_callback) { this.performAction_('scrollRight', {}, opt_callback); }, setSelection: function(startIndex, endIndex) { if (this.state.editable) { this.performAction_('setSelection', { focusNodeID: this.id, anchorOffset: startIndex, focusOffset: endIndex }); } }, setSequentialFocusNavigationStartingPoint: function() { this.performAction_('setSequentialFocusNavigationStartingPoint'); }, setValue: function(value) { if (this.state.editable) { this.performAction_('setValue', { value: value}); } }, 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); }, getNextTextMatch: function(searchStr, backward) { var info = GetNextTextMatch(this.treeID, this.id, searchStr, backward); if (!info) return; var impl = privates(AutomationRootNodeImpl.get(info.treeId)).impl; if (impl) return impl.get(info.nodeId); }, 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); parentID = parentID ? parentID.nodeId : null; var childTreeID = GetStringAttribute(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).nodeId; $Array.push(childIDs, childID); } var name = GetStringAttribute(this.treeID, this.id, 'name'); var result = 'node id=' + this.id + ' role=' + this.role + ' state=' + $JSON.stringify(this.state) + ' parentID=' + parentID + ' childIds=' + $JSON.stringify(childIDs); if (childTreeID) result += ' childTreeID=' + childTreeID; if (name) result += ' name=' + name; return result; }, dispatchEventAtCapturing_: function(event, path) { privates(event).impl.eventPhase = Event.CAPTURING_PHASE; for (var i = path.length - 1; i >= 0; i--) { this.fireEventListeners_(path[i], event); if (privates(event).impl.propagationStopped) return false; } return true; }, dispatchEventAtTargeting_: function(event) { privates(event).impl.eventPhase = Event.AT_TARGET; this.fireEventListeners_(this.wrapper, event); return !privates(event).impl.propagationStopped; }, dispatchEventAtBubbling_: function(event, path) { privates(event).impl.eventPhase = Event.BUBBLING_PHASE; for (var i = 0; i < path.length; i++) { this.fireEventListeners_(path[i], event); if (privates(event).impl.propagationStopped) return false; } return true; }, fireEventListeners_: function(node, event) { var nodeImpl = privates(node).impl; if (!nodeImpl.rootImpl) return; var listeners = nodeImpl.listeners[event.type]; if (!listeners) return; var eventPhase = event.eventPhase; for (var i = 0; i < listeners.length; i++) { if (eventPhase == Event.CAPTURING_PHASE && !listeners[i].capture) continue; if (eventPhase == Event.BUBBLING_PHASE && listeners[i].capture) continue; try { listeners[i].callback(event); } catch (e) { exceptionHandler.handle('Error in event handler for ' + event.type + ' during phase ' + eventPhase, e); } } }, performAction_: function(actionType, opt_args, opt_callback) { if (!this.rootImpl) return; // Not yet initialized. if (this.rootImpl.treeID === undefined || this.id === undefined) { return; } // Check permissions. if (!IsInteractPermitted()) { throw new Error(actionType + ' requires {"desktop": true} or' + ' {"interact": true} in the "automation" manifest key.'); } var requestID = -1; if (opt_callback) { requestID = this.rootImpl.addActionResultCallback(opt_callback); } automationInternal.performAction({ treeID: this.rootImpl.treeID, automationNodeID: this.id, actionType: actionType, requestID: requestID}, opt_args || {}); }, domQuerySelectorCallback_: function(userCallback, resultAutomationNodeID) { // resultAutomationNodeID could be zero or undefined or (unlikely) null; // they all amount to the same thing here, which is that no node was // returned. if (!resultAutomationNodeID || !this.rootImpl) { userCallback(null); return; } var resultNode = this.rootImpl.get(resultAutomationNodeID); if (!resultNode) { logging.WARNING('Query selector result not in tree: ' + resultAutomationNodeID); userCallback(null); } userCallback(resultNode); }, findInternal_: function(params, opt_results) { var result = null; this.forAllDescendants_(function(node) { if (privates(node).impl.matchInternal_(params)) { if (opt_results) $Array.push(opt_results, node); else result = node; return !opt_results; } }); if (opt_results) return opt_results; return result; }, /** * Executes a closure for all of this node's descendants, in pre-order. * Early-outs if the closure returns true. * @param {Function(AutomationNode):boolean} closure Closure to be executed * for each node. Return true to early-out the traversal. */ forAllDescendants_: function(closure) { var stack = $Array.reverse(this.wrapper.children); while (stack.length > 0) { var node = $Array.pop(stack); if (closure(node)) return; var children = node.children; for (var i = children.length - 1; i >= 0; i--) $Array.push(stack, children[i]); } }, matchInternal_: function(params) { if ($Object.keys(params).length === 0) return false; if ('role' in params && this.role != params.role) return false; if ('state' in params) { for (var state in params.state) { if (params.state[state] != (state in this.state)) return false; } } if ('attributes' in params) { for (var attribute in params.attributes) { var attrValue = params.attributes[attribute]; if (typeof attrValue != 'object') { if (this[attribute] !== attrValue) return false; } else if (attrValue instanceof $RegExp.self) { if (typeof this[attribute] != 'string') return false; if (!attrValue.test(this[attribute])) return false; } else { // TODO(aboxhall): handle intlist case. return false; } } } return true; } }; var stringAttributes = [ 'accessKey', 'ariaInvalidValue', 'autoComplete', 'className', 'containerLiveRelevant', 'containerLiveStatus', 'description', 'display', 'fontFamily', 'htmlTag', 'imageDataUrl', 'innerHtml', 'language', 'liveRelevant', 'liveStatus', 'name', 'placeholder', 'roleDescription', 'textInputType', 'url', 'value']; var boolAttributes = [ 'busy', 'clickable', 'containerLiveAtomic', 'containerLiveBusy', 'liveAtomic', 'modal', 'scrollable', 'selected', 'supportsTextLocation' ]; var intAttributes = [ 'backgroundColor', 'color', 'colorValue', 'hierarchicalLevel', 'posInSet', 'scrollX', 'scrollXMax', 'scrollXMin', 'scrollY', 'scrollYMax', 'scrollYMin', 'setSize', 'ariaCellColumnIndex', 'tableCellColumnSpan', 'ariaCellRowIndex', 'tableCellRowSpan', 'tableColumnCount', 'ariaColumnCount', 'tableColumnIndex', 'tableRowCount', 'ariaRowCount', 'tableRowIndex', 'textSelEnd', 'textSelStart']; // Int attribute, relation property to expose, reverse relation to expose. var nodeRefAttributes = [ ['activedescendantId', 'activeDescendant', 'activeDescendantFor'], ['detailsId', 'details', 'detailsFor'], ['errorMessageId', 'errorMessage', 'errorMessageFor'], ['inPageLinkTargetId', 'inPageLinkTarget', null], ['nextFocusId', 'nextFocus', null], ['nextOnLineId', 'nextOnLine', null], ['previousFocusId', 'previousFocus', null], ['previousOnLineId', 'previousOnLine', null], ['tableColumnHeaderId', 'tableColumnHeader', null], ['tableHeaderId', 'tableHeader', null], ['tableRowHeaderId', 'tableRowHeader', null]]; var intListAttributes = [ 'lineBreaks', 'markerEnds', 'markerStarts', 'markerTypes', 'wordEnds', 'wordStarts']; // Intlist attribute, relation property to expose, reverse relation to expose. var nodeRefListAttributes = [ ['controlsIds', 'controls', 'controlledBy'], ['describedbyIds', 'describedBy', 'descriptionFor'], ['flowtoIds', 'flowTo', 'flowFrom'], ['labelledbyIds', 'labelledBy', 'labelFor']]; var floatAttributes = [ 'fontSize', 'maxValueForRange', 'minValueForRange', 'valueForRange']; 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]; var dstReverseAttributeName = params[2]; $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; } }); if (dstReverseAttributeName) { $Array.push(publicAttributes, dstReverseAttributeName); $Object.defineProperty(AutomationNodeImpl.prototype, dstReverseAttributeName, { __proto__: null, get: function() { var ids = GetIntAttributeReverseRelations( 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(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]; var dstReverseAttributeName = params[2]; $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; } }); if (dstReverseAttributeName) { $Array.push(publicAttributes, dstReverseAttributeName); $Object.defineProperty(AutomationNodeImpl.prototype, dstReverseAttributeName, { __proto__: null, get: function() { var ids = GetIntListAttributeReverseRelations( 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, 'getNodeFromTree', function(treeId, nodeId) { var tree = AutomationRootNodeImpl.get(treeId); if (!tree) return; var impl = privates(tree).impl; if (impl) return impl.get(nodeId); }); utils.defineProperty(AutomationRootNodeImpl, 'destroy', function(treeID) { delete AutomationRootNodeImpl.idToAutomationRootNode_[treeID]; }); /** * A counter keeping track of IDs to use for mapping action requests to * their callback function. */ AutomationRootNodeImpl.actionRequestCounter = 0; /** * A map from a request ID to the corresponding callback function to call * when the action response event is received. */ AutomationRootNodeImpl.actionRequestIDToCallback = {}; AutomationRootNodeImpl.prototype = { __proto__: AutomationNodeImpl.prototype, /** * @type {boolean} */ isRootNode: true, /** * @type {string} */ treeID: '', /** * 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 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; // Validate the backing AXTree has the specified node. if (!GetRole(this.treeID, id)) return; obj = new AutomationNode(this); privates(obj).impl.treeID = this.treeID; privates(obj).impl.id = id; this.axNodeDataCache_[id] = obj; return obj; }, remove: function(id) { if (this.axNodeDataCache_[id]) privates(this.axNodeDataCache_[id]).impl.detach(); delete this.axNodeDataCache_[id]; }, destroy: function() { this.dispatchEvent('destroyed', 'none'); for (var id in this.axNodeDataCache_) this.remove(id); this.detach(); }, onAccessibilityEvent: function(eventParams) { var targetNode = this.get(eventParams.targetID); if (targetNode) { var targetNodeImpl = privates(targetNode).impl; targetNodeImpl.dispatchEvent( eventParams.eventType, eventParams.eventFrom, eventParams.mouseX, eventParams.mouseY); if (eventParams.actionRequestID != -1) { this.onActionResult(eventParams.actionRequestID, targetNode); } } else { logging.WARNING('Got ' + eventParams.eventType + ' event on unknown node: ' + eventParams.targetID + '; this: ' + this.id); } return true; }, addActionResultCallback: function(callback) { AutomationRootNodeImpl.actionRequestIDToCallback[ ++AutomationRootNodeImpl.actionRequestCounter] = callback; return AutomationRootNodeImpl.actionRequestCounter; }, onGetTextLocationResult: function(textLocationParams) { let requestID = textLocationParams.requestID; if (requestID in AutomationRootNodeImpl.actionRequestIDToCallback) { let callback = AutomationRootNodeImpl.actionRequestIDToCallback[requestID]; try { if (textLocationParams.result) { callback(ComputeGlobalBounds( this.treeID, textLocationParams.nodeID, textLocationParams.left, textLocationParams.top, textLocationParams.width, textLocationParams.height)); } else { callback(undefined); } } catch (e) { logging.WARNING('Error with onGetTextLocationResult callback:' + e); } delete AutomationNodeImpl.actionRequestIDToCallback[requestID]; } }, onActionResult: function(requestID, result) { if (requestID in AutomationRootNodeImpl.actionRequestIDToCallback) { AutomationRootNodeImpl.actionRequestIDToCallback[requestID](result); delete AutomationRootNodeImpl.actionRequestIDToCallback[requestID]; } }, toString: function() { function toStringInternal(nodeImpl, indent) { if (!nodeImpl) return ''; var output = ''; if (nodeImpl.isRootNode) output += indent + 'tree id=' + nodeImpl.treeID + '\n'; output += indent + $Function.call(AutomationNodeImpl.prototype.toString, nodeImpl) + '\n'; indent += ' '; var children = nodeImpl.children; for (var i = 0; i < children.length; ++i) output += toStringInternal(privates(children[i]).impl, indent); return output; } return toStringInternal(this, ''); }, }; function AutomationNode() { privates(AutomationNode).constructPrivate(this, arguments); } utils.expose(AutomationNode, AutomationNodeImpl, { functions: [ 'doDefault', 'find', 'findAll', 'focus', 'getImageData', 'getNextTextMatch', 'hitTest', 'hitTestWithReply', 'makeVisible', 'matches', 'performCustomAction', 'performStandardAction', 'replaceSelectedText', 'resumeMedia', 'scrollBackward', 'scrollForward', 'scrollUp', 'scrollDown', 'scrollLeft', 'scrollRight', 'setSelection', 'setSequentialFocusNavigationStartingPoint', 'setValue', 'showContextMenu', 'startDuckingMedia', 'stopDuckingMedia', 'suspendMedia', 'addEventListener', 'removeEventListener', 'domQuerySelector', 'toString', 'boundsForRange', ], readonly: $Array.concat( publicAttributes, [ 'parent', 'firstChild', 'lastChild', 'children', 'previousSibling', 'nextSibling', 'isRootNode', 'role', 'checked', 'defaultActionVerb', 'restriction', 'state', 'location', 'imageAnnotation', 'indexInParent', 'lineStartOffsets', 'root', 'htmlAttributes', 'nameFrom', 'bold', 'italic', 'underline', 'lineThrough', 'detectedLanguage', 'customActions', 'standardActions', 'unclippedLocation', 'tableCellColumnHeaders', 'tableCellRowHeaders', 'tableCellColumnIndex', 'tableCellRowIndex', ]), }); function AutomationRootNode() { privates(AutomationRootNode).constructPrivate(this, arguments); } utils.expose(AutomationRootNode, AutomationRootNodeImpl, { superclass: AutomationNode, readonly: [ 'docTitle', 'docUrl', 'docLoaded', 'docLoadingProgress', 'anchorObject', 'anchorOffset', 'anchorAffinity', 'focusObject', 'focusOffset', 'focusAffinity', ], }); utils.defineProperty(AutomationRootNode, 'get', function(treeID) { return AutomationRootNodeImpl.get(treeID); }); utils.defineProperty(AutomationRootNode, 'getOrCreate', function(treeID) { return AutomationRootNodeImpl.getOrCreate(treeID); }); utils.defineProperty(AutomationRootNode, 'destroy', function(treeID) { AutomationRootNodeImpl.destroy(treeID); }); exports.$set('AutomationNode', AutomationNode); exports.$set('AutomationRootNode', AutomationRootNode); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the browserAction API. var binding = apiBridge || require('binding').Binding.create('browserAction'); var setIcon = require('setIcon').setIcon; var getExtensionViews = requireNative('runtime').GetExtensionViews; var sendRequest = bindingUtil ? $Function.bind(bindingUtil.sendRequest, bindingUtil) : require('sendRequest').sendRequest; var jsLastError = bindingUtil ? undefined : require('lastError'); function hasLastError() { return bindingUtil ? bindingUtil.hasLastError() : jsLastError.hasError(chrome); } binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('setIcon', function(details, callback) { setIcon(details, function(args) { sendRequest('browserAction.setIcon', [args, callback], apiBridge ? undefined : this.definition.parameters, undefined); }.bind(this)); }); apiFunctions.setCustomCallback('openPopup', function(name, request, callback, response) { if (!callback) return; if (hasLastError()) { callback(); } else { var views = getExtensionViews(-1, -1, 'POPUP'); callback(views.length > 0 ? views[0] : null); } }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the Cast Streaming RtpStream API. var binding = apiBridge || require('binding').Binding.create('cast.streaming.rtpStream'); var natives = requireNative('cast_streaming_natives'); binding.registerCustomHook(function(bindingsAPI, extensionId) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('destroy', function(transportId) { natives.DestroyCastRtpStream(transportId); }); apiFunctions.setHandleRequest('getSupportedParams', function(transportId) { return natives.GetSupportedParamsCastRtpStream(transportId); }); apiFunctions.setHandleRequest('start', function(transportId, params) { natives.StartCastRtpStream(transportId, params); }); apiFunctions.setHandleRequest('stop', function(transportId) { natives.StopCastRtpStream(transportId); }); apiFunctions.setHandleRequest('toggleLogging', function(transportId, enable) { natives.ToggleLogging(transportId, enable); }); apiFunctions.setHandleRequest('getRawEvents', function(transportId, extraData, callback) { natives.GetRawEvents(transportId, extraData, callback); }); apiFunctions.setHandleRequest('getStats', function(transportId, callback) { natives.GetStats(transportId, callback); }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the Cast Streaming Session API. var binding = apiBridge || require('binding').Binding.create('cast.streaming.session'); var natives = requireNative('cast_streaming_natives'); binding.registerCustomHook(function(bindingsAPI, extensionId) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('create', function(audioTrack, videoTrack, callback) { natives.CreateSession(audioTrack, videoTrack, callback); }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the Cast Streaming UdpTransport API. var binding = apiBridge || require('binding').Binding.create('cast.streaming.udpTransport'); var natives = requireNative('cast_streaming_natives'); binding.registerCustomHook(function(bindingsAPI, extensionId) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('destroy', function(transportId) { natives.DestroyCastUdpTransport(transportId); }); apiFunctions.setHandleRequest('setDestination', function(transportId, destination) { natives.SetDestinationCastUdpTransport(transportId, destination); }); apiFunctions.setHandleRequest('setOptions', function(transportId, options) { natives.SetOptionsCastUdpTransport(transportId, options); }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the Cast Streaming Session API. var binding = apiBridge || require('binding').Binding.create('cast.streaming.receiverSession'); var natives = requireNative('cast_streaming_natives'); binding.registerCustomHook(function(bindingsAPI, extensionId) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest( 'createAndBind', function(ap, vp, local, weidgth, height, fr, url, cb, op) { }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. var Event = require('event_bindings').Event; var sendRequest = require('sendRequest').sendRequest; var validate = require('schemaUtils').validate; function extendSchema(schema) { var extendedSchema = $Array.slice(schema); $Array.unshift(extendedSchema, {'type': 'string'}); return extendedSchema; } // TODO(devlin): Maybe find a way to combine this and ContentSetting. function ChromeSetting(prefKey, valueSchema, schema) { var getFunctionParameters = function(name) { var f = $Array.filter( schema.functions, function(f) { return f.name === name; })[0]; return f.parameters; }; this.get = function(details, callback) { var getSchema = getFunctionParameters('get'); validate([details, callback], getSchema); return sendRequest('types.ChromeSetting.get', [prefKey, details, callback], extendSchema(getSchema)); }; this.set = function(details, callback) { // The set schema included in the Schema object is generic, since it varies // per-setting. However, this is only ever for a single setting, so we can // enforce the types more thoroughly. var rawSetSchema = getFunctionParameters('set'); var rawSettingParam = rawSetSchema[0]; var props = $Object.assign({}, rawSettingParam.properties); props.value = valueSchema; var modSettingParam = { name: rawSettingParam.name, type: rawSettingParam.type, properties: props, }; var modSetSchema = $Array.slice(rawSetSchema); modSetSchema[0] = modSettingParam; validate([details, callback], modSetSchema); return sendRequest('types.ChromeSetting.set', [prefKey, details, callback], extendSchema(modSetSchema)); }; this.clear = function(details, callback) { var clearSchema = getFunctionParameters('clear'); validate([details, callback], clearSchema); return sendRequest('types.ChromeSetting.clear', [prefKey, details, callback], extendSchema(clearSchema)); }; this.onChange = new Event('types.ChromeSetting.' + prefKey + '.onChange'); }; exports.$set('ChromeSetting', ChromeSetting); // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. var binding = apiBridge || require('binding').Binding.create('chromeWebViewInternal'); var contextMenusHandlers = require('contextMenusHandlers'); binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; var handlers = contextMenusHandlers.create(true /* isWebview */); apiFunctions.setHandleRequest( 'contextMenusCreate', handlers.requestHandlers.create); apiFunctions.setHandleRequest( 'contextMenusUpdate', handlers.requestHandlers.update); apiFunctions.setHandleRequest( 'contextMenusRemove', handlers.requestHandlers.remove); apiFunctions.setHandleRequest( 'contextMenusRemoveAll', handlers.requestHandlers.removeAll); }); if (!apiBridge) exports.$set('ChromeWebView', binding.generate()); // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This module implements chrome-specific API. // See web_view_api_methods.js for details. var ChromeWebView = getInternalApi ? getInternalApi('chromeWebViewInternal') : require('chromeWebViewInternal').ChromeWebView; var ChromeWebViewSchema = requireNative('schema_registry').GetSchema('chromeWebViewInternal'); var CreateEvent = require('guestViewEvents').CreateEvent; var GuestViewInternalNatives = requireNative('guest_view_internal'); var idGeneratorNatives = requireNative('id_generator'); var registerElement = require('guestViewContainerElement').registerElement; var utils = require('utils'); var WebViewElement = require('webViewElement').WebViewElement; var WebViewImpl = require('webView').WebViewImpl; var WebViewAttributeNames = require('webViewConstants').WebViewAttributeNames; // 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'); var jsEvent; function createCustomEvent(name, schema, options, webviewId) { if (bindingUtil) return bindingUtil.createCustomEvent(name, undefined, false, false); if (!jsEvent) jsEvent = require('event_bindings').Event; return new jsEvent(name, schema, options, webviewId); } function GetUniqueSubEventName(eventName) { return eventName + '/' + idGeneratorNatives.GetNextId(); } // This event is exposed as .contextMenus.onClicked. function createContextMenusOnClickedEvent(webViewInstanceId, opt_eventName, opt_argSchemas, opt_eventOptions) { var subEventName = GetUniqueSubEventName(opt_eventName); var newEvent = createCustomEvent(subEventName, opt_argSchemas, opt_eventOptions, webViewInstanceId); var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId); if (view) { view.events.addScopedListener( ContextMenusEvent, $Function.bind(function() { // Re-dispatch to subEvent's listeners. $Function.apply(newEvent.dispatch, newEvent, $Array.slice(arguments)); }, newEvent), {instanceId: webViewInstanceId}); } return newEvent; } // This event is exposed as .contextMenus.onShow. function createContextMenusOnContextMenuEvent(webViewInstanceId, opt_eventName, opt_argSchemas, opt_eventOptions) { var subEventName = GetUniqueSubEventName(opt_eventName); var newEvent = createCustomEvent(subEventName, opt_argSchemas, opt_eventOptions, webViewInstanceId); var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId); if (view) { view.events.addScopedListener( ContextMenusHandlerEvent, $Function.bind(function(e) { var defaultPrevented = false; var event = { preventDefault: function() { defaultPrevented = true; } }; // Re-dispatch to subEvent's listeners. $Function.apply(newEvent.dispatch, newEvent, [event]); if (!defaultPrevented) { // TODO(lazyboy): Remove |items| parameter completely from // ChromeWebView.showContextMenu as we don't do anything useful with // it currently. var items = []; var guestInstanceId = GuestViewInternalNatives. GetViewFromID(webViewInstanceId).guest.getId(); ChromeWebView.showContextMenu(guestInstanceId, e.requestId, items); } }, newEvent), {instanceId: webViewInstanceId}); } return newEvent; } // ----------------------------------------------------------------------------- // WebViewContextMenusImpl object. // An instance of this class is exposed as .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', ], }); // ----------------------------------------------------------------------------- class ChromeWebViewImpl extends WebViewImpl { constructor(webviewElement) { super(webviewElement); this.setupContextMenus(); } } ChromeWebViewImpl.prototype.setupContextMenus = function() { if (!this.contextMenusOnContextMenuEvent_) { var eventName = 'chromeWebViewInternal.onContextMenuShow'; var eventSchema = utils.lookup(ChromeWebViewSchema.events, 'name', 'onShow'); var eventOptions = {supportsListeners: true, supportsLazyListeners: false}; this.contextMenusOnContextMenuEvent_ = createContextMenusOnContextMenuEvent( this.viewInstanceId, eventName, eventSchema, eventOptions); } var createContextMenus = $Function.bind(function() { return this.weakWrapper(function() { if (this.contextMenus_) { return this.contextMenus_; } this.contextMenus_ = new WebViewContextMenus(this.viewInstanceId); // Define 'onClicked' event property on |this.contextMenus_|. var getOnClickedEvent = $Function.bind(function() { return this.weakWrapper(function() { if (!this.contextMenusOnClickedEvent_) { var eventName = 'chromeWebViewInternal.onClicked'; var eventSchema = utils.lookup(ChromeWebViewSchema.events, 'name', 'onClicked'); var eventOptions = {supportsListeners: true, supportsLazyListeners: false}; var onClickedEvent = createContextMenusOnClickedEvent( this.viewInstanceId, eventName, eventSchema, eventOptions); this.contextMenusOnClickedEvent_ = onClickedEvent; return onClickedEvent; } return this.contextMenusOnClickedEvent_; }); }, this); $Object.defineProperty( this.contextMenus_, 'onClicked', {get: getOnClickedEvent(), enumerable: true}); $Object.defineProperty( this.contextMenus_, 'onShow', { get: this.weakWrapper(function() { return this.contextMenusOnContextMenuEvent_; }), enumerable: true }); return this.contextMenus_; }); }, this); // Expose .contextMenus object. $Object.defineProperty( this.element, 'contextMenus', { get: createContextMenus(), enumerable: true }); }; class ChromeWebViewElement extends WebViewElement { static get observedAttributes() { return WebViewAttributeNames; } constructor() { super(); privates(this).internal = new ChromeWebViewImpl(this); } } registerElement('WebView', ChromeWebViewElement); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the contentSettings API. var sendRequest = require('sendRequest').sendRequest; var validate = require('schemaUtils').validate; // Some content types have been removed and no longer correspond to a real // content setting. Instead, these always return a fixed dummy value, and issue // a warning when accessed. This maps the content type name to the dummy value. var DEPRECATED_CONTENT_TYPES = { __proto__: null, fullscreen: 'allow', mouselock: 'allow', }; function extendSchema(schema) { var extendedSchema = $Array.slice(schema); $Array.unshift(extendedSchema, {'type': 'string'}); return extendedSchema; } function ContentSetting(contentType, settingSchema, schema) { var getFunctionParameters = function(name) { var f = $Array.filter( schema.functions, function(f) { return f.name === name; })[0]; return f.parameters; }; this.get = function(details, callback) { var getSchema = getFunctionParameters('get'); validate([details, callback], getSchema); var dummySetting = DEPRECATED_CONTENT_TYPES[contentType]; if (dummySetting !== undefined) { console.warn('contentSettings.' + contentType + ' is deprecated; it will ' + 'always return \'' + dummySetting + '\'.'); $Function.apply(callback, undefined, [{setting: dummySetting}]); return; } return sendRequest('contentSettings.get', [contentType, details, callback], extendSchema(getSchema)); }; this.set = function(details, callback) { // We check if the setting is deprecated first, since the validation will // fail for deprecated types. if ($Object.hasOwnProperty(DEPRECATED_CONTENT_TYPES, contentType)) { console.warn('contentSettings.' + contentType + ' is deprecated; setting ' + 'it has no effect.'); $Function.apply(callback, undefined, []); return; } // The set schema included in the Schema object is generic, since it varies // per-setting. However, this is only ever for a single setting, so we can // enforce the types more thoroughly. var rawSetSchema = getFunctionParameters('set'); var rawSettingParam = rawSetSchema[0]; var props = $Object.assign({}, rawSettingParam.properties); props.setting = settingSchema; var modSettingParam = { name: rawSettingParam.name, type: rawSettingParam.type, properties: props, }; var modSetSchema = $Array.slice(rawSetSchema); modSetSchema[0] = modSettingParam; validate([details, callback], modSetSchema); return sendRequest('contentSettings.set', [contentType, details, callback], extendSchema(modSetSchema)); }; this.clear = function(details, callback) { var clearSchema = getFunctionParameters('clear'); validate([details, callback], clearSchema); if ($Object.hasOwnProperty(DEPRECATED_CONTENT_TYPES, contentType)) { console.warn('contentSettings.' + contentType + ' is deprecated; ' + 'clearing it has no effect.'); $Function.apply(callback, undefined, []); return; } return sendRequest('contentSettings.clear', [contentType, details, callback], extendSchema(clearSchema)); }; this.getResourceIdentifiers = function(callback) { var schema = getFunctionParameters('getResourceIdentifiers'); validate([callback], schema); if ($Object.hasOwnProperty(DEPRECATED_CONTENT_TYPES, contentType)) { $Function.apply(callback, undefined, []); return; } return sendRequest( 'contentSettings.getResourceIdentifiers', [contentType, callback], extendSchema(schema)); }; } exports.$set('ContentSetting', ContentSetting); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the declarativeContent API. var binding = apiBridge || require('binding').Binding.create('declarativeContent'); if (!apiBridge) { var utils = require('utils'); var validate = require('schemaUtils').validate; var canonicalizeCompoundSelector = requireNative('css_natives').CanonicalizeCompoundSelector; } var setIcon = require('setIcon').setIcon; binding.registerCustomHook(function(api) { var declarativeContent = api.compiledApi; if (apiBridge) { // Validation for most types is done in the native C++ with native bindings, // but setIcon is funny (and sadly broken). Ideally, we can move this // validation entirely into the native code, and this whole file can go // away. var nativeSetIcon = declarativeContent.SetIcon; declarativeContent.SetIcon = function(parameters) { // TODO(devlin): This is very, very wrong. setIcon() is potentially // asynchronous (in the case of a path being specified), which means this // becomes an "asynchronous constructor". Errors can be thrown *after* the // `new declarativeContent.SetIcon(...)` call, and in the async cases, // this wouldn't work when we immediately add the action via an API call // (e.g., // chrome.declarativeContent.onPageChange.addRules( // [{conditions: ..., actions: [ new SetIcon(...) ]}]); // ). Some of this is tracked in http://crbug.com/415315. setIcon(parameters, $Function.bind(function(data) { // Fake calling the original function as a constructor. $Object.setPrototypeOf(this, nativeSetIcon.prototype); $Function.apply(nativeSetIcon, this, [data]); }, this)); }; return; } // Returns the schema definition of type |typeId| defined in |namespace|. function getSchema(typeId) { return utils.lookup(api.schema.types, 'id', 'declarativeContent.' + typeId); } // Helper function for the constructor of concrete datatypes of the // declarative content API. // Makes sure that |this| contains the union of parameters and // {'instanceType': 'declarativeContent.' + typeId} and validates the // generated union dictionary against the schema for |typeId|. function setupInstance(instance, parameters, typeId) { for (var key in parameters) { if ($Object.hasOwnProperty(parameters, key)) { instance[key] = parameters[key]; } } instance.instanceType = 'declarativeContent.' + typeId; var schema = getSchema(typeId); validate([instance], [schema]); } function canonicalizeCssSelectors(selectors) { for (var i = 0; i < selectors.length; i++) { var canonicalizedSelector = canonicalizeCompoundSelector(selectors[i]); if (canonicalizedSelector == '') { throw new Error( 'Element of \'css\' array must be a ' + 'list of valid compound selectors: ' + selectors[i]); } selectors[i] = canonicalizedSelector; } } // Setup all data types for the declarative content API. declarativeContent.PageStateMatcher = function(parameters) { setupInstance(this, parameters, 'PageStateMatcher'); if ($Object.hasOwnProperty(this, 'css')) { canonicalizeCssSelectors(this.css); } }; declarativeContent.ShowAction = function(parameters) { setupInstance(this, parameters, 'ShowAction'); }; declarativeContent.ShowPageAction = declarativeContent.ShowAction; declarativeContent.RequestContentScript = function(parameters) { setupInstance(this, parameters, 'RequestContentScript'); }; // TODO(rockot): Do not expose this in M39 stable. Making this restriction // possible will take some extra work. See http://crbug.com/415315 // Note: See also the SetIcon wrapper above for more issues. declarativeContent.SetIcon = function(parameters) { setIcon(parameters, $Function.bind(function(data) { setupInstance(this, data, 'SetIcon'); }, this)); }; }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the desktopCapture API. var binding = apiBridge || require('binding').Binding.create('desktopCapture'); var sendRequest = bindingUtil ? $Function.bind(bindingUtil.sendRequest, bindingUtil) : require('sendRequest').sendRequest; var idGenerator = requireNative('id_generator'); binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; var pendingRequests = {}; function onRequestResult(id, result, options) { if (id in pendingRequests) { var callback = pendingRequests[id]; delete pendingRequests[id]; callback(result, options); } } apiFunctions.setHandleRequest('chooseDesktopMedia', function(sources, target_tab, callback) { // |target_tab| is an optional parameter. if (callback === undefined) { callback = target_tab; target_tab = undefined; } var id = idGenerator.GetNextId(); pendingRequests[id] = callback; sendRequest('desktopCapture.chooseDesktopMedia', [id, sources, target_tab, $Function.bind(onRequestResult, null, id)], apiBridge ? undefined : this.definition.parameters, undefined); return id; }); apiFunctions.setHandleRequest('cancelChooseDesktopMedia', function(id) { if (id in pendingRequests) { delete pendingRequests[id]; sendRequest('desktopCapture.cancelChooseDesktopMedia', [id], apiBridge ? undefined : this.definition.parameters, undefined); } }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the developerPrivate API. var binding = apiBridge || require('binding').Binding.create('developerPrivate'); binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; // Converts the argument of |functionName| from DirectoryEntry to URL. function bindFileSystemFunction(functionName) { apiFunctions.setUpdateArgumentsPostValidate( functionName, function(directoryEntry, callback) { var fileSystemName = directoryEntry.filesystem.name; var relativePath = $String.slice(directoryEntry.fullPath, 1); var url = directoryEntry.toURL(); return [fileSystemName, relativePath, url, callback]; }); } bindFileSystemFunction('loadDirectory'); // developerPrivate.enable is the same as chrome.management.setEnabled. // TODO(devlin): Migrate callers off developerPrivate.enable. bindingsAPI.compiledApi.enable = chrome.management.setEnabled; apiFunctions.setHandleRequest('allowFileAccess', function(id, allow, callback) { chrome.developerPrivate.updateExtensionConfiguration( {extensionId: id, fileAccess: allow}, callback); }); apiFunctions.setHandleRequest('allowIncognito', function(id, allow, callback) { chrome.developerPrivate.updateExtensionConfiguration( {extensionId: id, incognitoAccess: allow}, callback); }); apiFunctions.setHandleRequest('inspect', function(options, callback) { var renderViewId = options.render_view_id; if (typeof renderViewId == 'string') { renderViewId = parseInt(renderViewId); if (isNaN(renderViewId)) throw new Error('Invalid value for render_view_id'); } var renderProcessId = options.render_process_id; if (typeof renderProcessId == 'string') { renderProcessId = parseInt(renderProcessId); if (isNaN(renderProcessId)) throw new Error('Invalid value for render_process_id'); } chrome.developerPrivate.openDevTools({ extensionId: options.extension_id, renderProcessId: renderProcessId, renderViewId: renderViewId, incognito: options.incognito }, callback); }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom bindings for the downloads API. var binding = apiBridge || require('binding').Binding.create('downloads'); var downloadsInternal = getInternalApi ? getInternalApi('downloadsInternal') : require('binding').Binding.create('downloadsInternal').generate(); var registerArgumentMassager = bindingUtil ? $Function.bind(bindingUtil.registerEventArgumentMassager, bindingUtil) : require('event_bindings').registerArgumentMassager; registerArgumentMassager('downloads.onDeterminingFilename', function(args, dispatch) { var downloadItem = args[0]; // Copy the id so that extensions can't change it. var downloadId = downloadItem.id; var suggestable = true; function isValidResult(result) { if (result === undefined) return false; if (typeof(result) != 'object') { console.error('Error: Invocation of form suggest(' + typeof(result) + ') doesn\'t match definition suggest({filename: string, ' + 'conflictAction: string})'); return false; } else if ((typeof(result.filename) != 'string') || (result.filename.length == 0)) { console.error('Error: "filename" parameter to suggest() must be a ' + 'non-empty string'); return false; } else if ([undefined, 'uniquify', 'overwrite', 'prompt'].indexOf( result.conflictAction) < 0) { console.error('Error: "conflictAction" parameter to suggest() must be ' + 'one of undefined, "uniquify", "overwrite", "prompt"'); return false; } return true; } function suggestCallback(result) { if (!suggestable) { console.error('suggestCallback may not be called more than once.'); return; } suggestable = false; if (isValidResult(result)) { downloadsInternal.determineFilename( downloadId, result.filename, result.conflictAction || ""); } else { downloadsInternal.determineFilename(downloadId, "", ""); } } try { var results = dispatch([downloadItem, suggestCallback]); var async = (results && results.results && (results.results.length != 0) && (results.results[0] === true)); if (suggestable && !async) suggestCallback(); } catch (e) { suggestCallback(); throw e; } }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. var Event = require('event_bindings').Event; // The EasyUnlockProximityRequired object is just a stub that has an onChange // event, which is never triggered. // TODO(devlin): Remove this once the preferencesPrivate API is fully removed. // https://crbug.com/593166 function EasyUnlockProximityRequired(prefKey, valueSchema, schema) { // Note: technically, extensions could intercept this through a setter on // Object.prototype(). We don't really care, because a) this is only for a // private API, so we shouldn't have to worry about untrusted code, and b) // this is an anonymous event, which exposes no attack surface and will be // exposed to the extension anyway. this.onChange = new Event(); }; exports.$set('EasyUnlockProximityRequired', EasyUnlockProximityRequired); // Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the GCM API. var binding = apiBridge || require('binding').Binding.create('gcm'); var forEach = require('utils').forEach; binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; var gcm = bindingsAPI.compiledApi; apiFunctions.setUpdateArgumentsPostValidate( 'send', function(message, callback) { // Validate message.data. var payloadSize = 0; forEach(message.data, function(property, value) { if (property.length == 0) throw new Error("One of data keys is empty."); var lowerCasedProperty = property.toLowerCase(); // Issue an error for forbidden prefixes of property names. if (lowerCasedProperty.startsWith("goog.") || lowerCasedProperty.startsWith("google") || property.startsWith("collapse_key")) { throw new Error("Invalid data key: " + property); } payloadSize += property.length + value.length; }); if (payloadSize > gcm.MAX_MESSAGE_SIZE) throw new Error("Payload exceeded allowed size limit. Payload size is: " + payloadSize); if (payloadSize == 0) throw new Error("No data to send."); return arguments; }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the Identity API. var binding = apiBridge || require('binding').Binding.create('identity'); binding.registerCustomHook(function(binding, id, contextType) { var apiFunctions = binding.apiFunctions; apiFunctions.setHandleRequest('getRedirectURL', function(path) { if (path === null || path === undefined) path = '/'; else path = String(path); if (path[0] != '/') path = '/' + path; return 'https://' + id + '.chromiumapp.org' + path; }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the image writer private API. var binding = apiBridge || require('binding').Binding.create('imageWriterPrivate'); binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setUpdateArgumentsPostValidate( 'writeFromFile', function(device, fileEntry, options, callback) { var fileSystemName = fileEntry.filesystem.name; var relativePath = $String.slice(fileEntry.fullPath, 1); return [device, fileSystemName, relativePath, callback]; }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the input ime API. Only injected into the // v8 contexts for extensions which have permission for the API. var binding = apiBridge || require('binding').Binding.create('input.ime'); var appWindowNatives = requireNative('app_window_natives'); var registerArgumentMassager = bindingUtil ? $Function.bind(bindingUtil.registerEventArgumentMassager, bindingUtil) : require('event_bindings').registerArgumentMassager; var keyEventHandled; registerArgumentMassager('input.ime.onKeyEvent', function(args, dispatch) { var keyData = args[1]; var result = undefined; try { // dispatch() is weird - it returns an object {results: array} iff // there is at least one result value that !== undefined. Since onKeyEvent // has a maximum of one listener, we know that any result we find is the one // we're interested in. var dispatchResult = dispatch(args); if (dispatchResult && dispatchResult.results) result = dispatchResult.results[0]; } catch (e) { result = false; console.error('Error in event handler for onKeyEvent: ' + e.stack); } if (result !== undefined) { keyEventHandled(keyData.requestId, !!result); } }); binding.registerCustomHook(function(api) { keyEventHandled = api.compiledApi.keyEventHandled; // TODO(shuchen): override onKeyEvent.addListener only for compatibility. // This should be removed after the IME extension doesn't rely on the // additional "async" parameter. var originalAddListener = api.compiledApi.onKeyEvent.addListener; api.compiledApi.onKeyEvent.addListener = function(cb, opt_extraInfo) { $Function.call(originalAddListener, this, cb); }; api.apiFunctions.setCustomCallback('createWindow', function(name, request, callback, windowParams) { if (!callback) { return; } var view; if (windowParams && windowParams.frameId) { view = appWindowNatives.GetFrame( windowParams.frameId, false /* notifyBrowser */); view.id = windowParams.frameId; } callback(view); }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the Media Gallery API. var binding = apiBridge || require('binding').Binding.create('mediaGalleries'); var blobNatives = requireNative('blob_natives'); var mediaGalleriesNatives = requireNative('mediaGalleries'); var sendRequest = bindingUtil ? $Function.bind(bindingUtil.sendRequest, bindingUtil) : require('sendRequest').sendRequest; var blobsAwaitingMetadata = {}; var mediaGalleriesMetadata = {}; function createFileSystemObjectsAndUpdateMetadata(response) { var result = []; mediaGalleriesMetadata = {}; // Clear any previous metadata. if (response) { for (var i = 0; i < response.length; i++) { var filesystem = mediaGalleriesNatives.GetMediaFileSystemObject( response[i].fsid); $Array.push(result, filesystem); var metadata = response[i]; delete metadata.fsid; mediaGalleriesMetadata[filesystem.name] = metadata; } } return result; } binding.registerCustomHook(function(bindingsAPI, extensionId) { var apiFunctions = bindingsAPI.apiFunctions; // getMediaFileSystems and addUserSelectedFolder use a custom callback so that // they can instantiate and return an array of file system objects. apiFunctions.setCustomCallback('getMediaFileSystems', function(name, request, callback, response) { var result = createFileSystemObjectsAndUpdateMetadata(response); if (callback) callback(result); }); apiFunctions.setCustomCallback('addUserSelectedFolder', function(name, request, callback, response) { var fileSystems = []; var selectedFileSystemName = ""; if (response && 'mediaFileSystems' in response && 'selectedFileSystemIndex' in response) { fileSystems = createFileSystemObjectsAndUpdateMetadata( response['mediaFileSystems']); var selectedFileSystemIndex = response['selectedFileSystemIndex']; if (selectedFileSystemIndex >= 0) { selectedFileSystemName = fileSystems[selectedFileSystemIndex].name; } } if (callback) callback(fileSystems, selectedFileSystemName); }); apiFunctions.setHandleRequest('getMediaFileSystemMetadata', function(filesystem) { if (filesystem && filesystem.name && filesystem.name in mediaGalleriesMetadata) { return mediaGalleriesMetadata[filesystem.name]; } return { 'name': '', 'galleryId': '', 'isRemovable': false, 'isMediaDevice': false, 'isAvailable': false, }; }); function getMetadataCallback(uuid, name, request, callback, response) { if (response && response.attachedImagesBlobInfo) { for (var i = 0; i < response.attachedImagesBlobInfo.length; i++) { var blobInfo = response.attachedImagesBlobInfo[i]; var blob = blobNatives.TakeBrowserProcessBlob( blobInfo.blobUUID, blobInfo.type, blobInfo.size); response.metadata.attachedImages.push(blob); } } if (callback) callback(response ? response.metadata : null); delete blobsAwaitingMetadata[uuid]; } apiFunctions.setHandleRequest('getMetadata', function(mediaFile, options, callback) { var blobUuid = blobNatives.GetBlobUuid(mediaFile) // Store the blob in a global object to keep its refcount nonzero -- this // prevents the object from being garbage collected before any metadata // parsing gets to occur (see crbug.com/415792). blobsAwaitingMetadata[blobUuid] = mediaFile; var optArgs = { __proto__: null, customCallback: $Function.bind(getMetadataCallback, null, blobUuid), }; sendRequest('mediaGalleries.getMetadata', [blobUuid, options, callback], bindingUtil ? undefined : this.definition.parameters, optArgs); }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom bindings for the notifications API. // var binding = apiBridge || require('binding').Binding.create('notifications'); var sendRequest = bindingUtil ? $Function.bind(bindingUtil.sendRequest, bindingUtil) : require('sendRequest').sendRequest; var exceptionHandler = require('uncaught_exception_handler'); var imageUtil = require('imageUtil'); var notificationsPrivate = requireNative('notifications_private'); var jsLastError = bindingUtil ? undefined : require('lastError'); function runCallbackWithLastError(name, message, stack, callback, args) { if (bindingUtil) { bindingUtil.runCallbackWithLastError(message, function() { $Function.apply(callback, null, args); }); } else { jsLastError.run(name, message, stack, callback, args); } } function imageDataSetter(context, key) { var f = function(val) { this[key] = val; }; return $Function.bind(f, context); } // A URL Spec is an object with the following keys: // path: The resource to be downloaded. // width: (optional) The maximum width of the image to be downloaded in device // pixels. // height: (optional) The maximum height of the image to be downloaded in // device pixels. // callback: A function to be called when the URL is complete. It // should accept an ImageData object and set the appropriate // field in |notificationDetails|. function getUrlSpecs(imageSizes, notificationDetails) { var urlSpecs = []; // |iconUrl| might be optional for notification updates. if (notificationDetails.iconUrl) { $Array.push(urlSpecs, { path: notificationDetails.iconUrl, width: imageSizes.icon.width * imageSizes.scaleFactor, height: imageSizes.icon.height * imageSizes.scaleFactor, callback: imageDataSetter(notificationDetails, 'iconBitmap') }); } // |appIconMaskUrl| is optional. if (notificationDetails.appIconMaskUrl) { $Array.push(urlSpecs, { path: notificationDetails.appIconMaskUrl, width: imageSizes.appIconMask.width * imageSizes.scaleFactor, height: imageSizes.appIconMask.height * imageSizes.scaleFactor, callback: imageDataSetter(notificationDetails, 'appIconMaskBitmap') }); } // |imageUrl| is optional. if (notificationDetails.imageUrl) { $Array.push(urlSpecs, { path: notificationDetails.imageUrl, width: imageSizes.image.width * imageSizes.scaleFactor, height: imageSizes.image.height * imageSizes.scaleFactor, callback: imageDataSetter(notificationDetails, 'imageBitmap') }); } // Each button has an optional icon. var buttonList = notificationDetails.buttons; if (buttonList && typeof buttonList.length === 'number') { var numButtons = buttonList.length; for (var i = 0; i < numButtons; i++) { if (buttonList[i].iconUrl) { $Array.push(urlSpecs, { path: buttonList[i].iconUrl, width: imageSizes.buttonIcon.width * imageSizes.scaleFactor, height: imageSizes.buttonIcon.height * imageSizes.scaleFactor, callback: imageDataSetter(buttonList[i], 'iconBitmap') }); } } } return urlSpecs; } function replaceNotificationOptionURLs(notification_details, callback) { var imageSizes = notificationsPrivate.GetNotificationImageSizes(); var url_specs = getUrlSpecs(imageSizes, notification_details); if (!url_specs.length) { callback(true); return; } var errors = 0; imageUtil.loadAllImages(url_specs, { onerror: function(index) { errors++; }, oncomplete: function(imageData) { if (errors > 0) { callback(false); return; } for (var index = 0; index < url_specs.length; index++) { var url_spec = url_specs[index]; url_spec.callback(imageData[index]); } callback(true); } }); } function genHandle(name, failure_function) { return function(id, input_notification_details, callback) { // TODO(dewittj): Remove this hack. This is used as a way to deep // copy a complex JSON object. var notification_details = $JSON.parse( $JSON.stringify(input_notification_details)); var that = this; var stack = exceptionHandler.getExtensionStackTrace(); replaceNotificationOptionURLs(notification_details, function(success) { if (success) { sendRequest( name, [id, notification_details, callback], bindingUtil ? undefined : that.definition.parameters, bindingUtil ? undefined : {__proto__: null, stack: stack}); return; } runCallbackWithLastError( name, 'Unable to download all specified images.', stack, failure_function, [callback || function() {}, id]); }); }; } var handleCreate = genHandle('notifications.create', function(callback, id) { callback(id); }); var handleUpdate = genHandle('notifications.update', function(callback, id) { callback(false); }); var notificationsCustomHook = function(bindingsAPI, extensionId) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('create', handleCreate); apiFunctions.setHandleRequest('update', handleUpdate); }; binding.registerCustomHook(notificationsCustomHook); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the omnibox API. Only injected into the v8 contexts // for extensions which have permission for the omnibox API. var binding = apiBridge || require('binding').Binding.create('omnibox'); var registerArgumentMassager = bindingUtil ? $Function.bind(bindingUtil.registerEventArgumentMassager, bindingUtil) : require('event_bindings').registerArgumentMassager; var sendRequest = bindingUtil ? $Function.bind(bindingUtil.sendRequest, bindingUtil) : require('sendRequest').sendRequest; // Remove invalid characters from |text| so that it is suitable to use // for |AutocompleteMatch::contents|. function sanitizeString(text, shouldTrim) { // NOTE: This logic mirrors |AutocompleteMatch::SanitizeString()|. // 0x2028 = line separator; 0x2029 = paragraph separator. var kRemoveChars = /(\r|\n|\t|\u2028|\u2029)/gm; if (shouldTrim) text = text.trimLeft(); return text.replace(kRemoveChars, ''); } // Parses the xml syntax supported by omnibox suggestion results. Returns an // object with two properties: 'description', which is just the text content, // and 'descriptionStyles', which is an array of style objects in a format // understood by the C++ backend. function parseOmniboxDescription(input) { var domParser = new DOMParser(); // The XML parser requires a single top-level element, but we want to // support things like 'hello, 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('omnibox.setDefaultSuggestion', [parseResult], bindingUtil ? undefined : this.definition.parameters, undefined); }); apiFunctions.setUpdateArgumentsPostValidate( 'sendSuggestions', function(requestId, userSuggestions) { var suggestions = []; for (var i = 0; i < userSuggestions.length; i++) { var parseResult = parseOmniboxDescription( userSuggestions[i].description); parseResult.content = userSuggestions[i].content; parseResult.deletable = userSuggestions[i].deletable; $Array.push(suggestions, parseResult); } return [requestId, suggestions]; }); }); registerArgumentMassager('omnibox.onInputChanged', function(args, dispatch) { var text = args[0]; var requestId = args[1]; var suggestCallback = function(suggestions) { chrome.omnibox.sendSuggestions(requestId, suggestions); }; dispatch([text, suggestCallback]); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the pageAction API. var binding = apiBridge || require('binding').Binding.create('pageAction'); var setIcon = require('setIcon').setIcon; var sendRequest = bindingUtil ? $Function.bind(bindingUtil.sendRequest, bindingUtil) : require('sendRequest').sendRequest; binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('setIcon', function(details, callback) { setIcon(details, $Function.bind(function(args) { sendRequest('pageAction.setIcon', [args, callback], bindingUtil ? undefined : this.definition.parameters, undefined); }, this)); }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the pageCapture API. var binding = apiBridge || require('binding').Binding.create('pageCapture'); var handleUncaughtException = require('uncaught_exception_handler').handle; var pageCaptureNatives = requireNative('page_capture'); var CreateBlob = pageCaptureNatives.CreateBlob; var SendResponseAck = pageCaptureNatives.SendResponseAck; binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setCustomCallback('saveAsMHTML', function(name, request, callback, response) { if (response) response = CreateBlob(response.mhtmlFilePath, response.mhtmlFileLength); try { callback(response); } catch (e) { handleUncaughtException( 'Error in chrome.pageCapture.saveAsMHTML callback', e, request.stack); } finally { // Notify the browser. Now that the blob is referenced from JavaScript, // the browser can drop its reference to it. SendResponseAck(request.id); } }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the syncFileSystem API. var binding = apiBridge || require('binding').Binding.create('syncFileSystem'); var registerArgumentMassager = bindingUtil ? $Function.bind(bindingUtil.registerEventArgumentMassager, bindingUtil) : require('event_bindings').registerArgumentMassager; var fileSystemNatives = requireNative('file_system_natives'); var syncFileSystemNatives = requireNative('sync_file_system'); binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; // Functions which take in an [instanceOf=FileEntry]. function bindFileEntryFunction(functionName) { apiFunctions.setUpdateArgumentsPostValidate( functionName, function(entry, callback) { var fileSystemUrl = entry.toURL(); return [fileSystemUrl, callback]; }); } $Array.forEach(['getFileStatus'], bindFileEntryFunction); // Functions which take in a FileEntry array. function bindFileEntryArrayFunction(functionName) { apiFunctions.setUpdateArgumentsPostValidate( functionName, function(entries, callback) { var fileSystemUrlArray = []; for (var i=0; i < entries.length; i++) { $Array.push(fileSystemUrlArray, entries[i].toURL()); } return [fileSystemUrlArray, callback]; }); } $Array.forEach(['getFileStatuses'], bindFileEntryArrayFunction); // Functions which take in an [instanceOf=DOMFileSystem]. function bindFileSystemFunction(functionName) { apiFunctions.setUpdateArgumentsPostValidate( functionName, function(filesystem, callback) { var fileSystemUrl = filesystem.root.toURL(); return [fileSystemUrl, callback]; }); } $Array.forEach(['getUsageAndQuota'], bindFileSystemFunction); // Functions which return an [instanceOf=DOMFileSystem]. apiFunctions.setCustomCallback('requestFileSystem', function(name, request, callback, response) { var result = null; if (response) { result = syncFileSystemNatives.GetSyncFileSystemObject( response.name, response.root); } if (callback) callback(result); }); // Functions which return an array of FileStatusInfo object // which has [instanceOf=FileEntry]. apiFunctions.setCustomCallback('getFileStatuses', function(name, request, callback, response) { var results = []; if (response) { for (var i = 0; i < response.length; i++) { var result = {}; var entry = response[i].entry; result.fileEntry = fileSystemNatives.GetFileEntry( entry.fileSystemType, entry.fileSystemName, entry.rootUrl, entry.filePath, entry.isDirectory); result.status = response[i].status; result.error = response[i].error; $Array.push(results, result); } } if (callback) callback(results); }); }); registerArgumentMassager('syncFileSystem.onFileStatusChanged', function(args, dispatch) { // Make FileEntry object using all the base string fields. var fileEntry = fileSystemNatives.GetFileEntry( args[0].fileSystemType, args[0].fileSystemName, args[0].rootUrl, args[0].filePath, args[0].isDirectory); // Combine into a single dictionary. var fileInfo = new Object(); fileInfo.fileEntry = fileEntry; fileInfo.status = args[1]; if (fileInfo.status == "synced") { fileInfo.action = args[2]; fileInfo.direction = args[3]; } dispatch([fileInfo]); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the systemIndicator API. // TODO(dewittj) Refactor custom binding to reduce redundancy between the // extension action APIs. var binding = apiBridge || require('binding').Binding.create('systemIndicator'); var setIcon = require('setIcon').setIcon; var sendRequest = bindingUtil ? $Function.bind(bindingUtil.sendRequest, bindingUtil) : require('sendRequest').sendRequest; binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('setIcon', function(details, callback) { setIcon(details, $Function.bind(function(args) { sendRequest('systemIndicator.setIcon', [args, callback], bindingUtil ? undefined : this.definition.parameters, undefined); }, this)); }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the Tab Capture API. var binding = apiBridge || require('binding').Binding.create('tabCapture'); var jsLastError = bindingUtil ? undefined : require('lastError'); function runCallbackWithLastError(name, message, stack, callback, args) { if (bindingUtil) { bindingUtil.runCallbackWithLastError(message, function() { $Function.apply(callback, null, args); }); } else { jsLastError.run(name, message, stack, callback, args); } } binding.registerCustomHook(function(bindingsAPI, extensionId) { var apiFunctions = bindingsAPI.apiFunctions; function proxyToGetUserMedia(name, request, callback, response) { if (!callback) return; if (!response) { // When the response is missing, runtime.lastError has already been set. // See chrome/browser/extensions/api/tab_capture/tab_capture_api.cc. callback(null); return; } // Convenience function for processing webkitGetUserMedia() error objects to // provide runtime.lastError messages for the tab capture API. function getErrorMessage(error, fallbackMessage) { if (!error || (typeof error.message != 'string')) return fallbackMessage; return error.message.replace(/(navigator\.)?(webkit)?GetUserMedia/gi, name); } var options = {}; if (response.audioConstraints) options.audio = response.audioConstraints; if (response.videoConstraints) options.video = response.videoConstraints; try { navigator.webkitGetUserMedia( options, function onSuccess(media_stream) { callback(media_stream); }, function onError(error) { runCallbackWithLastError( name, getErrorMessage(error, "Failed to start MediaStream."), request.stack, function() { callback(null); }); }); } catch (error) { runCallbackWithLastError( name, getErrorMessage(error, "Invalid argument(s)."), request.stack, function() { callback(null); }); } } apiFunctions.setCustomCallback('capture', proxyToGetUserMedia); apiFunctions.setCustomCallback('captureOffscreenTab', proxyToGetUserMedia); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the tabs API. var binding = apiBridge || require('binding').Binding.create('tabs'); var messaging = require('messaging'); var OpenChannelToTab = requireNative('messaging_natives').OpenChannelToTab; var sendRequestIsDisabled = requireNative('process').IsSendRequestDisabled(); var forEach = require('utils').forEach; binding.registerCustomHook(function(bindingsAPI, extensionId) { var apiFunctions = bindingsAPI.apiFunctions; var tabs = bindingsAPI.compiledApi; apiFunctions.setHandleRequest('connect', function(tabId, connectInfo) { var name = ''; var frameId = -1; if (connectInfo) { name = connectInfo.name || name; frameId = connectInfo.frameId; if (typeof frameId == 'undefined' || frameId === null || frameId < 0) frameId = -1; } var portId = OpenChannelToTab(tabId, frameId, extensionId, name); return messaging.createPort(portId, name); }); apiFunctions.setHandleRequest('sendRequest', function(tabId, request, responseCallback) { if (sendRequestIsDisabled) throw new Error(sendRequestIsDisabled); var port = tabs.connect(tabId, {name: messaging.kRequestChannel}); messaging.sendMessageImpl(port, request, responseCallback); }); apiFunctions.setHandleRequest('sendMessage', function(tabId, message, options, responseCallback) { var connectInfo = { name: messaging.kMessageChannel }; if (options) { forEach(options, function(k, v) { connectInfo[k] = v; }); } var port = tabs.connect(tabId, connectInfo); messaging.sendMessageImpl(port, message, responseCallback); }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the tts API. var binding = apiBridge || require('binding').Binding.create('tts'); var idGenerator = requireNative('id_generator'); var sendRequest = bindingUtil ? $Function.bind(bindingUtil.sendRequest, bindingUtil) : require('sendRequest').sendRequest; var lazyBG = requireNative('lazy_background_page'); binding.registerCustomHook(function(api) { var apiFunctions = api.apiFunctions; var tts = api.compiledApi; var handlers = {}; function ttsEventListener(event) { var eventHandler = handlers[event.srcId]; if (eventHandler) { eventHandler({ type: event.type, charIndex: event.charIndex, length: event.length, errorMessage: event.errorMessage }); if (event.isFinalEvent) { delete handlers[event.srcId]; // Balanced in 'speak' handler. lazyBG.DecrementKeepaliveCount(); } } } // This file will get run if an extension needs the ttsEngine permission, but // it doesn't necessarily have the tts permission. If it doesn't, trying to // add a listener to chrome.tts.onEvent will fail. // See http://crbug.com/122474. try { tts.onEvent.addListener(ttsEventListener); } catch (e) {} apiFunctions.setHandleRequest('speak', function() { var args = $Array.from(arguments); if (args.length > 1 && args[1]) { if (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(); } if (args[1].gender) { console.warn( 'chrome.tts.speak: ' + 'Voice gender is deprecated and values will be ignored starting ' + 'in Chrome 71.'); } } sendRequest('tts.speak', args, bindingUtil ? undefined : this.definition.parameters, undefined); return id; }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the ttsEngine API. var binding = apiBridge || require('binding').Binding.create('ttsEngine'); var registerArgumentMassager = bindingUtil ? $Function.bind(bindingUtil.registerEventArgumentMassager, bindingUtil) : require('event_bindings').registerArgumentMassager; var sendRequest = bindingUtil ? $Function.bind(bindingUtil.sendRequest, bindingUtil) : require('sendRequest').sendRequest; 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]); }); binding.registerCustomHook(function(api) { // Provide a warning if deprecated parameters are used. api.apiFunctions.setHandleRequest('updateVoices', function(voices) { for (var i = 0; i < voices.length; i++) { if (voices[i].gender) { console.warn( 'chrome.ttsEngine.updateVoices: ' + 'Voice gender is deprecated and values will be ignored ' + 'starting in Chrome 71.'); break; } } sendRequest( 'ttsEngine.updateVoices', [voices], bindingUtil ? undefined : this.definition.parameters, undefined); }); }.bind(this)); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the webrtcDesktopCapturePrivate API. var binding = apiBridge || require('binding').Binding.create('webrtcDesktopCapturePrivate'); var sendRequest = bindingUtil ? $Function.bind(bindingUtil.sendRequest, bindingUtil) : require('sendRequest').sendRequest; var idGenerator = requireNative('id_generator'); binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; var pendingRequests = {}; function onRequestResult(id, result) { if (id in pendingRequests) { var callback = pendingRequests[id]; delete pendingRequests[id]; callback(result); } } apiFunctions.setHandleRequest('chooseDesktopMedia', function(sources, request, callback) { var id = idGenerator.GetNextId(); pendingRequests[id] = callback; sendRequest('webrtcDesktopCapturePrivate.chooseDesktopMedia', [id, sources, request, $Function.bind(onRequestResult, null, id)], bindingUtil ? undefined : this.definition.parameters, undefined); return id; }); apiFunctions.setHandleRequest('cancelChooseDesktopMedia', function(id) { if (id in pendingRequests) { delete pendingRequests[id]; sendRequest('webrtcDesktopCapturePrivate.cancelChooseDesktopMedia', [id], bindingUtil ? undefined : this.definition.parameters, undefined); } }); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Custom binding for the webrtcLoggingPrivate API. var binding = apiBridge || require('binding').Binding.create('webrtcLoggingPrivate'); var getBindDirectoryEntryCallback = require('fileEntryBindingUtil').getBindDirectoryEntryCallback; binding.registerCustomHook(function(binding, id, contextType) { var apiFunctions = binding.apiFunctions; apiFunctions.setCustomCallback('getLogsDirectory', getBindDirectoryEntryCallback()); }); if (!apiBridge) exports.$set('binding', binding.generate()); // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'chrome/common/media_router/mojo/media_controller.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('mediaRouter.mojom'); var media_status$ = mojo.internal.exposeNamespace('mediaRouter.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'chrome/common/media_router/mojo/media_status.mojom', 'media_status.mojom.js'); } var time$ = mojo.internal.exposeNamespace('mojoBase.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'mojo/public/mojom/base/time.mojom', '../../../../mojo/public/mojom/base/time.mojom.js'); } function MediaController_Play_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaController_Play_Params.prototype.initDefaults_ = function() { }; MediaController_Play_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaController_Play_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 8} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaController_Play_Params.encodedSize = codec.kStructHeaderSize + 0; MediaController_Play_Params.decode = function(decoder) { var packed; var val = new MediaController_Play_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); return val; }; MediaController_Play_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaController_Play_Params.encodedSize); encoder.writeUint32(0); }; function MediaController_Pause_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaController_Pause_Params.prototype.initDefaults_ = function() { }; MediaController_Pause_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaController_Pause_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 8} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaController_Pause_Params.encodedSize = codec.kStructHeaderSize + 0; MediaController_Pause_Params.decode = function(decoder) { var packed; var val = new MediaController_Pause_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); return val; }; MediaController_Pause_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaController_Pause_Params.encodedSize); encoder.writeUint32(0); }; function MediaController_SetMute_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaController_SetMute_Params.prototype.initDefaults_ = function() { this.mute = false; }; MediaController_SetMute_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaController_SetMute_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaController_SetMute_Params.encodedSize = codec.kStructHeaderSize + 8; MediaController_SetMute_Params.decode = function(decoder) { var packed; var val = new MediaController_SetMute_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); packed = decoder.readUint8(); val.mute = (packed >> 0) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaController_SetMute_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaController_SetMute_Params.encodedSize); encoder.writeUint32(0); packed = 0; packed |= (val.mute & 1) << 0 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaController_SetVolume_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaController_SetVolume_Params.prototype.initDefaults_ = function() { this.volume = 0; }; MediaController_SetVolume_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaController_SetVolume_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaController_SetVolume_Params.encodedSize = codec.kStructHeaderSize + 8; MediaController_SetVolume_Params.decode = function(decoder) { var packed; var val = new MediaController_SetVolume_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.volume = decoder.decodeStruct(codec.Float); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaController_SetVolume_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaController_SetVolume_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Float, val.volume); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaController_Seek_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaController_Seek_Params.prototype.initDefaults_ = function() { this.time = null; }; MediaController_Seek_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaController_Seek_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaController_Seek_Params.time err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, time$.TimeDelta, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaController_Seek_Params.encodedSize = codec.kStructHeaderSize + 8; MediaController_Seek_Params.decode = function(decoder) { var packed; var val = new MediaController_Seek_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.time = decoder.decodeStructPointer(time$.TimeDelta); return val; }; MediaController_Seek_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaController_Seek_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(time$.TimeDelta, val.time); }; function MediaController_ConnectHangoutsMediaRouteController_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaController_ConnectHangoutsMediaRouteController_Params.prototype.initDefaults_ = function() { this.controllerRequest = new bindings.InterfaceRequest(); }; MediaController_ConnectHangoutsMediaRouteController_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaController_ConnectHangoutsMediaRouteController_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaController_ConnectHangoutsMediaRouteController_Params.controllerRequest err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaController_ConnectHangoutsMediaRouteController_Params.encodedSize = codec.kStructHeaderSize + 8; MediaController_ConnectHangoutsMediaRouteController_Params.decode = function(decoder) { var packed; var val = new MediaController_ConnectHangoutsMediaRouteController_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.controllerRequest = decoder.decodeStruct(codec.InterfaceRequest); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaController_ConnectHangoutsMediaRouteController_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaController_ConnectHangoutsMediaRouteController_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.InterfaceRequest, val.controllerRequest); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function HangoutsMediaRouteController_SetLocalPresent_Params(values) { this.initDefaults_(); this.initFields_(values); } HangoutsMediaRouteController_SetLocalPresent_Params.prototype.initDefaults_ = function() { this.localPresent = false; }; HangoutsMediaRouteController_SetLocalPresent_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; HangoutsMediaRouteController_SetLocalPresent_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; HangoutsMediaRouteController_SetLocalPresent_Params.encodedSize = codec.kStructHeaderSize + 8; HangoutsMediaRouteController_SetLocalPresent_Params.decode = function(decoder) { var packed; var val = new HangoutsMediaRouteController_SetLocalPresent_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); packed = decoder.readUint8(); val.localPresent = (packed >> 0) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; HangoutsMediaRouteController_SetLocalPresent_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(HangoutsMediaRouteController_SetLocalPresent_Params.encodedSize); encoder.writeUint32(0); packed = 0; packed |= (val.localPresent & 1) << 0 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; var kMediaController_Play_Name = 44114504; var kMediaController_Pause_Name = 1274683295; var kMediaController_SetMute_Name = 105381973; var kMediaController_SetVolume_Name = 134206653; var kMediaController_Seek_Name = 1279461926; var kMediaController_ConnectHangoutsMediaRouteController_Name = 1326967599; function MediaControllerPtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(MediaController, handleOrPtrInfo); } function MediaControllerAssociatedPtr(associatedInterfacePtrInfo) { this.ptr = new associatedBindings.AssociatedInterfacePtrController( MediaController, associatedInterfacePtrInfo); } MediaControllerAssociatedPtr.prototype = Object.create(MediaControllerPtr.prototype); MediaControllerAssociatedPtr.prototype.constructor = MediaControllerAssociatedPtr; function MediaControllerProxy(receiver) { this.receiver_ = receiver; } MediaControllerPtr.prototype.play = function() { return MediaControllerProxy.prototype.play .apply(this.ptr.getProxy(), arguments); }; MediaControllerProxy.prototype.play = function() { var params_ = new MediaController_Play_Params(); var builder = new codec.MessageV0Builder( kMediaController_Play_Name, codec.align(MediaController_Play_Params.encodedSize)); builder.encodeStruct(MediaController_Play_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaControllerPtr.prototype.pause = function() { return MediaControllerProxy.prototype.pause .apply(this.ptr.getProxy(), arguments); }; MediaControllerProxy.prototype.pause = function() { var params_ = new MediaController_Pause_Params(); var builder = new codec.MessageV0Builder( kMediaController_Pause_Name, codec.align(MediaController_Pause_Params.encodedSize)); builder.encodeStruct(MediaController_Pause_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaControllerPtr.prototype.setMute = function() { return MediaControllerProxy.prototype.setMute .apply(this.ptr.getProxy(), arguments); }; MediaControllerProxy.prototype.setMute = function(mute) { var params_ = new MediaController_SetMute_Params(); params_.mute = mute; var builder = new codec.MessageV0Builder( kMediaController_SetMute_Name, codec.align(MediaController_SetMute_Params.encodedSize)); builder.encodeStruct(MediaController_SetMute_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaControllerPtr.prototype.setVolume = function() { return MediaControllerProxy.prototype.setVolume .apply(this.ptr.getProxy(), arguments); }; MediaControllerProxy.prototype.setVolume = function(volume) { var params_ = new MediaController_SetVolume_Params(); params_.volume = volume; var builder = new codec.MessageV0Builder( kMediaController_SetVolume_Name, codec.align(MediaController_SetVolume_Params.encodedSize)); builder.encodeStruct(MediaController_SetVolume_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaControllerPtr.prototype.seek = function() { return MediaControllerProxy.prototype.seek .apply(this.ptr.getProxy(), arguments); }; MediaControllerProxy.prototype.seek = function(time) { var params_ = new MediaController_Seek_Params(); params_.time = time; var builder = new codec.MessageV0Builder( kMediaController_Seek_Name, codec.align(MediaController_Seek_Params.encodedSize)); builder.encodeStruct(MediaController_Seek_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaControllerPtr.prototype.connectHangoutsMediaRouteController = function() { return MediaControllerProxy.prototype.connectHangoutsMediaRouteController .apply(this.ptr.getProxy(), arguments); }; MediaControllerProxy.prototype.connectHangoutsMediaRouteController = function(controllerRequest) { var params_ = new MediaController_ConnectHangoutsMediaRouteController_Params(); params_.controllerRequest = controllerRequest; var builder = new codec.MessageV0Builder( kMediaController_ConnectHangoutsMediaRouteController_Name, codec.align(MediaController_ConnectHangoutsMediaRouteController_Params.encodedSize)); builder.encodeStruct(MediaController_ConnectHangoutsMediaRouteController_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; function MediaControllerStub(delegate) { this.delegate_ = delegate; } MediaControllerStub.prototype.play = function() { return this.delegate_ && this.delegate_.play && this.delegate_.play(); } MediaControllerStub.prototype.pause = function() { return this.delegate_ && this.delegate_.pause && this.delegate_.pause(); } MediaControllerStub.prototype.setMute = function(mute) { return this.delegate_ && this.delegate_.setMute && this.delegate_.setMute(mute); } MediaControllerStub.prototype.setVolume = function(volume) { return this.delegate_ && this.delegate_.setVolume && this.delegate_.setVolume(volume); } MediaControllerStub.prototype.seek = function(time) { return this.delegate_ && this.delegate_.seek && this.delegate_.seek(time); } MediaControllerStub.prototype.connectHangoutsMediaRouteController = function(controllerRequest) { return this.delegate_ && this.delegate_.connectHangoutsMediaRouteController && this.delegate_.connectHangoutsMediaRouteController(controllerRequest); } MediaControllerStub.prototype.accept = function(message) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kMediaController_Play_Name: var params = reader.decodeStruct(MediaController_Play_Params); this.play(); return true; case kMediaController_Pause_Name: var params = reader.decodeStruct(MediaController_Pause_Params); this.pause(); return true; case kMediaController_SetMute_Name: var params = reader.decodeStruct(MediaController_SetMute_Params); this.setMute(params.mute); return true; case kMediaController_SetVolume_Name: var params = reader.decodeStruct(MediaController_SetVolume_Params); this.setVolume(params.volume); return true; case kMediaController_Seek_Name: var params = reader.decodeStruct(MediaController_Seek_Params); this.seek(params.time); return true; case kMediaController_ConnectHangoutsMediaRouteController_Name: var params = reader.decodeStruct(MediaController_ConnectHangoutsMediaRouteController_Params); this.connectHangoutsMediaRouteController(params.controllerRequest); return true; default: return false; } }; MediaControllerStub.prototype.acceptWithResponder = function(message, responder) { var reader = new codec.MessageReader(message); switch (reader.messageName) { default: return false; } }; function validateMediaControllerRequest(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kMediaController_Play_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaController_Play_Params; break; case kMediaController_Pause_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaController_Pause_Params; break; case kMediaController_SetMute_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaController_SetMute_Params; break; case kMediaController_SetVolume_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaController_SetVolume_Params; break; case kMediaController_Seek_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaController_Seek_Params; break; case kMediaController_ConnectHangoutsMediaRouteController_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaController_ConnectHangoutsMediaRouteController_Params; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } function validateMediaControllerResponse(messageValidator) { return validator.validationError.NONE; } var MediaController = { name: 'media_router.mojom.MediaController', kVersion: 0, ptrClass: MediaControllerPtr, proxyClass: MediaControllerProxy, stubClass: MediaControllerStub, validateRequest: validateMediaControllerRequest, validateResponse: null, }; MediaControllerStub.prototype.validator = validateMediaControllerRequest; MediaControllerProxy.prototype.validator = null; var kHangoutsMediaRouteController_SetLocalPresent_Name = 1649448561; function HangoutsMediaRouteControllerPtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(HangoutsMediaRouteController, handleOrPtrInfo); } function HangoutsMediaRouteControllerAssociatedPtr(associatedInterfacePtrInfo) { this.ptr = new associatedBindings.AssociatedInterfacePtrController( HangoutsMediaRouteController, associatedInterfacePtrInfo); } HangoutsMediaRouteControllerAssociatedPtr.prototype = Object.create(HangoutsMediaRouteControllerPtr.prototype); HangoutsMediaRouteControllerAssociatedPtr.prototype.constructor = HangoutsMediaRouteControllerAssociatedPtr; function HangoutsMediaRouteControllerProxy(receiver) { this.receiver_ = receiver; } HangoutsMediaRouteControllerPtr.prototype.setLocalPresent = function() { return HangoutsMediaRouteControllerProxy.prototype.setLocalPresent .apply(this.ptr.getProxy(), arguments); }; HangoutsMediaRouteControllerProxy.prototype.setLocalPresent = function(localPresent) { var params_ = new HangoutsMediaRouteController_SetLocalPresent_Params(); params_.localPresent = localPresent; var builder = new codec.MessageV0Builder( kHangoutsMediaRouteController_SetLocalPresent_Name, codec.align(HangoutsMediaRouteController_SetLocalPresent_Params.encodedSize)); builder.encodeStruct(HangoutsMediaRouteController_SetLocalPresent_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; function HangoutsMediaRouteControllerStub(delegate) { this.delegate_ = delegate; } HangoutsMediaRouteControllerStub.prototype.setLocalPresent = function(localPresent) { return this.delegate_ && this.delegate_.setLocalPresent && this.delegate_.setLocalPresent(localPresent); } HangoutsMediaRouteControllerStub.prototype.accept = function(message) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kHangoutsMediaRouteController_SetLocalPresent_Name: var params = reader.decodeStruct(HangoutsMediaRouteController_SetLocalPresent_Params); this.setLocalPresent(params.localPresent); return true; default: return false; } }; HangoutsMediaRouteControllerStub.prototype.acceptWithResponder = function(message, responder) { var reader = new codec.MessageReader(message); switch (reader.messageName) { default: return false; } }; function validateHangoutsMediaRouteControllerRequest(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kHangoutsMediaRouteController_SetLocalPresent_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = HangoutsMediaRouteController_SetLocalPresent_Params; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } function validateHangoutsMediaRouteControllerResponse(messageValidator) { return validator.validationError.NONE; } var HangoutsMediaRouteController = { name: 'media_router.mojom.HangoutsMediaRouteController', kVersion: 0, ptrClass: HangoutsMediaRouteControllerPtr, proxyClass: HangoutsMediaRouteControllerProxy, stubClass: HangoutsMediaRouteControllerStub, validateRequest: validateHangoutsMediaRouteControllerRequest, validateResponse: null, }; HangoutsMediaRouteControllerStub.prototype.validator = validateHangoutsMediaRouteControllerRequest; HangoutsMediaRouteControllerProxy.prototype.validator = null; exports.MediaController = MediaController; exports.MediaControllerPtr = MediaControllerPtr; exports.MediaControllerAssociatedPtr = MediaControllerAssociatedPtr; exports.HangoutsMediaRouteController = HangoutsMediaRouteController; exports.HangoutsMediaRouteControllerPtr = HangoutsMediaRouteControllerPtr; exports.HangoutsMediaRouteControllerAssociatedPtr = HangoutsMediaRouteControllerAssociatedPtr; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'chrome/common/media_router/mojo/media_router.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('mediaRouter.mojom'); var media_controller$ = mojo.internal.exposeNamespace('mediaRouter.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'chrome/common/media_router/mojo/media_controller.mojom', 'media_controller.mojom.js'); } var media_status$ = mojo.internal.exposeNamespace('mediaRouter.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'chrome/common/media_router/mojo/media_status.mojom', 'media_status.mojom.js'); } var mirroring_service_host$ = mojo.internal.exposeNamespace('mirroring.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'components/mirroring/mojom/mirroring_service_host.mojom', '../../../../components/mirroring/mojom/mirroring_service_host.mojom.js'); } var mirror_service_remoting$ = mojo.internal.exposeNamespace('media.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'media/mojo/interfaces/mirror_service_remoting.mojom', '../../../../media/mojo/interfaces/mirror_service_remoting.mojom.js'); } var time$ = mojo.internal.exposeNamespace('mojoBase.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'mojo/public/mojom/base/time.mojom', '../../../../mojo/public/mojom/base/time.mojom.js'); } var ip_address$ = mojo.internal.exposeNamespace('network.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'services/network/public/mojom/ip_address.mojom', '../../../../services/network/public/mojom/ip_address.mojom.js'); } var ip_endpoint$ = mojo.internal.exposeNamespace('network.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'services/network/public/mojom/ip_endpoint.mojom', '../../../../services/network/public/mojom/ip_endpoint.mojom.js'); } var presentation$ = mojo.internal.exposeNamespace('blink.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'third_party/blink/public/mojom/presentation/presentation.mojom', '../../../../third_party/blink/public/mojom/presentation/presentation.mojom.js'); } var origin$ = mojo.internal.exposeNamespace('url.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'url/mojom/origin.mojom', '../../../../url/mojom/origin.mojom.js'); } var url$ = mojo.internal.exposeNamespace('url.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'url/mojom/url.mojom', '../../../../url/mojom/url.mojom.js'); } var SinkIconType = {}; SinkIconType.CAST = 0; SinkIconType.CAST_AUDIO_GROUP = SinkIconType.CAST + 1; SinkIconType.CAST_AUDIO = SinkIconType.CAST_AUDIO_GROUP + 1; SinkIconType.MEETING = SinkIconType.CAST_AUDIO + 1; SinkIconType.HANGOUT = SinkIconType.MEETING + 1; SinkIconType.EDUCATION = SinkIconType.HANGOUT + 1; SinkIconType.WIRED_DISPLAY = SinkIconType.EDUCATION + 1; SinkIconType.GENERIC = SinkIconType.WIRED_DISPLAY + 1; SinkIconType.MIN_VALUE = 0, SinkIconType.MAX_VALUE = 7, SinkIconType.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: return true; } return false; }; SinkIconType.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; var RouteControllerType = {}; RouteControllerType.kNone = 0; RouteControllerType.kGeneric = RouteControllerType.kNone + 1; RouteControllerType.kHangouts = RouteControllerType.kGeneric + 1; RouteControllerType.kMirroring = RouteControllerType.kHangouts + 1; RouteControllerType.MIN_VALUE = 0, RouteControllerType.MAX_VALUE = 3, RouteControllerType.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: case 3: return true; } return false; }; RouteControllerType.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; var RouteRequestResultCode = {}; RouteRequestResultCode.UNKNOWN_ERROR = 0; RouteRequestResultCode.OK = RouteRequestResultCode.UNKNOWN_ERROR + 1; RouteRequestResultCode.TIMED_OUT = RouteRequestResultCode.OK + 1; RouteRequestResultCode.ROUTE_NOT_FOUND = RouteRequestResultCode.TIMED_OUT + 1; RouteRequestResultCode.SINK_NOT_FOUND = RouteRequestResultCode.ROUTE_NOT_FOUND + 1; RouteRequestResultCode.INVALID_ORIGIN = RouteRequestResultCode.SINK_NOT_FOUND + 1; RouteRequestResultCode.INCOGNITO_MISMATCH = RouteRequestResultCode.INVALID_ORIGIN + 1; RouteRequestResultCode.NO_SUPPORTED_PROVIDER = RouteRequestResultCode.INCOGNITO_MISMATCH + 1; RouteRequestResultCode.CANCELLED = RouteRequestResultCode.NO_SUPPORTED_PROVIDER + 1; RouteRequestResultCode.ROUTE_ALREADY_EXISTS = RouteRequestResultCode.CANCELLED + 1; RouteRequestResultCode.MIN_VALUE = 0, RouteRequestResultCode.MAX_VALUE = 9, RouteRequestResultCode.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: return true; } return false; }; RouteRequestResultCode.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; function MediaSink(values) { this.initDefaults_(); this.initFields_(values); } MediaSink.prototype.initDefaults_ = function() { this.sinkId = null; this.name = null; this.description = null; this.domain = null; this.iconType = 0; this.providerId = 0; this.extraData = null; }; MediaSink.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaSink.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 64} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaSink.sinkId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaSink.name err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate MediaSink.description err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, true) if (err !== validator.validationError.NONE) return err; // validate MediaSink.domain err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, true) if (err !== validator.validationError.NONE) return err; // validate MediaSink.iconType err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 32, SinkIconType); if (err !== validator.validationError.NONE) return err; // validate MediaSink.providerId err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 36, MediaRouteProvider.Id); if (err !== validator.validationError.NONE) return err; // validate MediaSink.extraData err = messageValidator.validateUnion(offset + codec.kStructHeaderSize + 40, MediaSinkExtraData, true); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaSink.encodedSize = codec.kStructHeaderSize + 56; MediaSink.decode = function(decoder) { var packed; var val = new MediaSink(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.sinkId = decoder.decodeStruct(codec.String); val.name = decoder.decodeStruct(codec.String); val.description = decoder.decodeStruct(codec.NullableString); val.domain = decoder.decodeStruct(codec.NullableString); val.iconType = decoder.decodeStruct(codec.Int32); val.providerId = decoder.decodeStruct(codec.Int32); val.extraData = decoder.decodeStruct(MediaSinkExtraData); return val; }; MediaSink.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaSink.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.sinkId); encoder.encodeStruct(codec.String, val.name); encoder.encodeStruct(codec.NullableString, val.description); encoder.encodeStruct(codec.NullableString, val.domain); encoder.encodeStruct(codec.Int32, val.iconType); encoder.encodeStruct(codec.Int32, val.providerId); encoder.encodeStruct(MediaSinkExtraData, val.extraData); }; function DialMediaSink(values) { this.initDefaults_(); this.initFields_(values); } DialMediaSink.prototype.initDefaults_ = function() { this.ipAddress = null; this.modelName = null; this.appUrl = null; }; DialMediaSink.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; DialMediaSink.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 32} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate DialMediaSink.ipAddress err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, ip_address$.IPAddress, false); if (err !== validator.validationError.NONE) return err; // validate DialMediaSink.modelName err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate DialMediaSink.appUrl err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, url$.Url, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; DialMediaSink.encodedSize = codec.kStructHeaderSize + 24; DialMediaSink.decode = function(decoder) { var packed; var val = new DialMediaSink(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.ipAddress = decoder.decodeStructPointer(ip_address$.IPAddress); val.modelName = decoder.decodeStruct(codec.String); val.appUrl = decoder.decodeStructPointer(url$.Url); return val; }; DialMediaSink.encode = function(encoder, val) { var packed; encoder.writeUint32(DialMediaSink.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(ip_address$.IPAddress, val.ipAddress); encoder.encodeStruct(codec.String, val.modelName); encoder.encodeStructPointer(url$.Url, val.appUrl); }; function CastMediaSink(values) { this.initDefaults_(); this.initFields_(values); } CastMediaSink.prototype.initDefaults_ = function() { this.ipEndpoint = null; this.modelName = null; this.capabilities = 0; this.castChannelId = 0; }; CastMediaSink.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; CastMediaSink.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 32} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate CastMediaSink.ipEndpoint err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, ip_endpoint$.IPEndPoint, false); if (err !== validator.validationError.NONE) return err; // validate CastMediaSink.modelName err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; CastMediaSink.encodedSize = codec.kStructHeaderSize + 24; CastMediaSink.decode = function(decoder) { var packed; var val = new CastMediaSink(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.ipEndpoint = decoder.decodeStructPointer(ip_endpoint$.IPEndPoint); val.modelName = decoder.decodeStruct(codec.String); val.capabilities = decoder.decodeStruct(codec.Uint8); decoder.skip(1); decoder.skip(1); decoder.skip(1); val.castChannelId = decoder.decodeStruct(codec.Int32); return val; }; CastMediaSink.encode = function(encoder, val) { var packed; encoder.writeUint32(CastMediaSink.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(ip_endpoint$.IPEndPoint, val.ipEndpoint); encoder.encodeStruct(codec.String, val.modelName); encoder.encodeStruct(codec.Uint8, val.capabilities); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStruct(codec.Int32, val.castChannelId); }; function MediaRoute(values) { this.initDefaults_(); this.initFields_(values); } MediaRoute.prototype.initDefaults_ = function() { this.mediaRouteId = null; this.presentationId = null; this.mediaSource = null; this.mediaSinkId = null; this.description = null; this.isLocal = false; this.forDisplay = false; this.isIncognito = false; this.isLocalPresentation = false; this.controllerType = 0; }; MediaRoute.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRoute.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 56} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRoute.mediaRouteId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRoute.presentationId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate MediaRoute.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, true) if (err !== validator.validationError.NONE) return err; // validate MediaRoute.mediaSinkId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) if (err !== validator.validationError.NONE) return err; // validate MediaRoute.description err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 32, false) if (err !== validator.validationError.NONE) return err; // validate MediaRoute.controllerType err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 44, RouteControllerType); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRoute.encodedSize = codec.kStructHeaderSize + 48; MediaRoute.decode = function(decoder) { var packed; var val = new MediaRoute(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaRouteId = decoder.decodeStruct(codec.String); val.presentationId = decoder.decodeStruct(codec.String); val.mediaSource = decoder.decodeStruct(codec.NullableString); val.mediaSinkId = decoder.decodeStruct(codec.String); val.description = decoder.decodeStruct(codec.String); packed = decoder.readUint8(); val.isLocal = (packed >> 0) & 1 ? true : false; val.forDisplay = (packed >> 1) & 1 ? true : false; val.isIncognito = (packed >> 2) & 1 ? true : false; val.isLocalPresentation = (packed >> 3) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); val.controllerType = decoder.decodeStruct(codec.Int32); return val; }; MediaRoute.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRoute.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaRouteId); encoder.encodeStruct(codec.String, val.presentationId); encoder.encodeStruct(codec.NullableString, val.mediaSource); encoder.encodeStruct(codec.String, val.mediaSinkId); encoder.encodeStruct(codec.String, val.description); packed = 0; packed |= (val.isLocal & 1) << 0 packed |= (val.forDisplay & 1) << 1 packed |= (val.isIncognito & 1) << 2 packed |= (val.isLocalPresentation & 1) << 3 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStruct(codec.Int32, val.controllerType); }; function Issue(values) { this.initDefaults_(); this.initFields_(values); } Issue.Severity = {}; Issue.Severity.FATAL = 0; Issue.Severity.WARNING = Issue.Severity.FATAL + 1; Issue.Severity.NOTIFICATION = Issue.Severity.WARNING + 1; Issue.Severity.MIN_VALUE = 0, Issue.Severity.MAX_VALUE = 2, Issue.Severity.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: return true; } return false; }; Issue.Severity.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; Issue.ActionType = {}; Issue.ActionType.DISMISS = 0; Issue.ActionType.LEARN_MORE = Issue.ActionType.DISMISS + 1; Issue.ActionType.MIN_VALUE = 0, Issue.ActionType.MAX_VALUE = 1, Issue.ActionType.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: return true; } return false; }; Issue.ActionType.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; Issue.prototype.initDefaults_ = function() { this.routeId = null; this.sinkId = null; this.severity = 0; this.isBlocking = false; this.title = null; this.message = null; this.defaultAction = 0; this.helpPageId = 0; this.secondaryActions = null; }; Issue.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; Issue.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 64} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate Issue.routeId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate Issue.sinkId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate Issue.severity err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 16, Issue.Severity); if (err !== validator.validationError.NONE) return err; // validate Issue.title err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) if (err !== validator.validationError.NONE) return err; // validate Issue.message err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 32, true) if (err !== validator.validationError.NONE) return err; // validate Issue.defaultAction err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 40, Issue.ActionType); if (err !== validator.validationError.NONE) return err; // validate Issue.secondaryActions err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 48, 4, new codec.Enum(Issue.ActionType), false, [0], 0); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; Issue.encodedSize = codec.kStructHeaderSize + 56; Issue.decode = function(decoder) { var packed; var val = new Issue(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.routeId = decoder.decodeStruct(codec.String); val.sinkId = decoder.decodeStruct(codec.String); val.severity = decoder.decodeStruct(codec.Int32); packed = decoder.readUint8(); val.isBlocking = (packed >> 0) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); val.title = decoder.decodeStruct(codec.String); val.message = decoder.decodeStruct(codec.NullableString); val.defaultAction = decoder.decodeStruct(codec.Int32); val.helpPageId = decoder.decodeStruct(codec.Int32); val.secondaryActions = decoder.decodeArrayPointer(new codec.Enum(Issue.ActionType)); return val; }; Issue.encode = function(encoder, val) { var packed; encoder.writeUint32(Issue.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.routeId); encoder.encodeStruct(codec.String, val.sinkId); encoder.encodeStruct(codec.Int32, val.severity); packed = 0; packed |= (val.isBlocking & 1) << 0 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStruct(codec.String, val.title); encoder.encodeStruct(codec.NullableString, val.message); encoder.encodeStruct(codec.Int32, val.defaultAction); encoder.encodeStruct(codec.Int32, val.helpPageId); encoder.encodeArrayPointer(new codec.Enum(Issue.ActionType), val.secondaryActions); }; function RouteMessage(values) { this.initDefaults_(); this.initFields_(values); } RouteMessage.Type = {}; RouteMessage.Type.TEXT = 0; RouteMessage.Type.BINARY = RouteMessage.Type.TEXT + 1; RouteMessage.Type.MIN_VALUE = 0, RouteMessage.Type.MAX_VALUE = 1, RouteMessage.Type.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: return true; } return false; }; RouteMessage.Type.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; RouteMessage.prototype.initDefaults_ = function() { this.type = 0; this.message = null; this.data = null; }; RouteMessage.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; RouteMessage.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 32} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate RouteMessage.type err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, RouteMessage.Type); if (err !== validator.validationError.NONE) return err; // validate RouteMessage.message err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, true) if (err !== validator.validationError.NONE) return err; // validate RouteMessage.data err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 1, codec.Uint8, true, [0], 0); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; RouteMessage.encodedSize = codec.kStructHeaderSize + 24; RouteMessage.decode = function(decoder) { var packed; var val = new RouteMessage(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.type = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); val.message = decoder.decodeStruct(codec.NullableString); val.data = decoder.decodeArrayPointer(codec.Uint8); return val; }; RouteMessage.encode = function(encoder, val) { var packed; encoder.writeUint32(RouteMessage.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.type); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStruct(codec.NullableString, val.message); encoder.encodeArrayPointer(codec.Uint8, val.data); }; function SinkSearchCriteria(values) { this.initDefaults_(); this.initFields_(values); } SinkSearchCriteria.prototype.initDefaults_ = function() { this.input = null; this.domain = null; }; SinkSearchCriteria.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; SinkSearchCriteria.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate SinkSearchCriteria.input err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate SinkSearchCriteria.domain err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; SinkSearchCriteria.encodedSize = codec.kStructHeaderSize + 16; SinkSearchCriteria.decode = function(decoder) { var packed; var val = new SinkSearchCriteria(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.input = decoder.decodeStruct(codec.String); val.domain = decoder.decodeStruct(codec.String); return val; }; SinkSearchCriteria.encode = function(encoder, val) { var packed; encoder.writeUint32(SinkSearchCriteria.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.input); encoder.encodeStruct(codec.String, val.domain); }; function MediaRouteProviderConfig(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProviderConfig.prototype.initDefaults_ = function() { this.enableDialDiscovery = false; this.enableCastDiscovery = false; this.enableDialSinkQuery = false; this.enableCastSinkQuery = false; this.useViewsDialog = false; this.useMirroringService = false; }; MediaRouteProviderConfig.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProviderConfig.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProviderConfig.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProviderConfig.decode = function(decoder) { var packed; var val = new MediaRouteProviderConfig(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); packed = decoder.readUint8(); val.enableDialDiscovery = (packed >> 0) & 1 ? true : false; val.enableCastDiscovery = (packed >> 1) & 1 ? true : false; val.enableDialSinkQuery = (packed >> 2) & 1 ? true : false; val.enableCastSinkQuery = (packed >> 3) & 1 ? true : false; val.useViewsDialog = (packed >> 4) & 1 ? true : false; val.useMirroringService = (packed >> 5) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaRouteProviderConfig.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProviderConfig.encodedSize); encoder.writeUint32(0); packed = 0; packed |= (val.enableDialDiscovery & 1) << 0 packed |= (val.enableCastDiscovery & 1) << 1 packed |= (val.enableDialSinkQuery & 1) << 2 packed |= (val.enableCastSinkQuery & 1) << 3 packed |= (val.useViewsDialog & 1) << 4 packed |= (val.useMirroringService & 1) << 5 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function RoutePresentationConnection(values) { this.initDefaults_(); this.initFields_(values); } RoutePresentationConnection.prototype.initDefaults_ = function() { this.connectionPtr = new presentation$.PresentationConnectionPtr(); this.connectionRequest = new bindings.InterfaceRequest(); }; RoutePresentationConnection.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; RoutePresentationConnection.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate RoutePresentationConnection.connectionPtr err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 0, false); if (err !== validator.validationError.NONE) return err; // validate RoutePresentationConnection.connectionRequest err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; RoutePresentationConnection.encodedSize = codec.kStructHeaderSize + 16; RoutePresentationConnection.decode = function(decoder) { var packed; var val = new RoutePresentationConnection(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.connectionPtr = decoder.decodeStruct(new codec.Interface(presentation$.PresentationConnectionPtr)); val.connectionRequest = decoder.decodeStruct(codec.InterfaceRequest); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; RoutePresentationConnection.encode = function(encoder, val) { var packed; encoder.writeUint32(RoutePresentationConnection.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(new codec.Interface(presentation$.PresentationConnectionPtr), val.connectionPtr); encoder.encodeStruct(codec.InterfaceRequest, val.connectionRequest); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaRouteProvider_CreateRoute_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_CreateRoute_Params.prototype.initDefaults_ = function() { this.mediaSource = null; this.sinkId = null; this.originalPresentationId = null; this.origin = null; this.tabId = 0; this.incognito = false; this.timeout = null; }; MediaRouteProvider_CreateRoute_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_CreateRoute_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 56} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateRoute_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateRoute_Params.sinkId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateRoute_Params.originalPresentationId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateRoute_Params.origin err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, origin$.Origin, false); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateRoute_Params.timeout err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 40, time$.TimeDelta, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_CreateRoute_Params.encodedSize = codec.kStructHeaderSize + 48; MediaRouteProvider_CreateRoute_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_CreateRoute_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaSource = decoder.decodeStruct(codec.String); val.sinkId = decoder.decodeStruct(codec.String); val.originalPresentationId = decoder.decodeStruct(codec.String); val.origin = decoder.decodeStructPointer(origin$.Origin); val.tabId = decoder.decodeStruct(codec.Int32); packed = decoder.readUint8(); val.incognito = (packed >> 0) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); val.timeout = decoder.decodeStructPointer(time$.TimeDelta); return val; }; MediaRouteProvider_CreateRoute_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_CreateRoute_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaSource); encoder.encodeStruct(codec.String, val.sinkId); encoder.encodeStruct(codec.String, val.originalPresentationId); encoder.encodeStructPointer(origin$.Origin, val.origin); encoder.encodeStruct(codec.Int32, val.tabId); packed = 0; packed |= (val.incognito & 1) << 0 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStructPointer(time$.TimeDelta, val.timeout); }; function MediaRouteProvider_CreateRoute_ResponseParams(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_CreateRoute_ResponseParams.prototype.initDefaults_ = function() { this.route = null; this.connection = null; this.errorText = null; this.resultCode = 0; }; MediaRouteProvider_CreateRoute_ResponseParams.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_CreateRoute_ResponseParams.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 40} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateRoute_ResponseParams.route err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, MediaRoute, true); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateRoute_ResponseParams.connection err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, RoutePresentationConnection, true); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateRoute_ResponseParams.errorText err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, true) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateRoute_ResponseParams.resultCode err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 24, RouteRequestResultCode); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_CreateRoute_ResponseParams.encodedSize = codec.kStructHeaderSize + 32; MediaRouteProvider_CreateRoute_ResponseParams.decode = function(decoder) { var packed; var val = new MediaRouteProvider_CreateRoute_ResponseParams(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.route = decoder.decodeStructPointer(MediaRoute); val.connection = decoder.decodeStructPointer(RoutePresentationConnection); val.errorText = decoder.decodeStruct(codec.NullableString); val.resultCode = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaRouteProvider_CreateRoute_ResponseParams.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_CreateRoute_ResponseParams.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(MediaRoute, val.route); encoder.encodeStructPointer(RoutePresentationConnection, val.connection); encoder.encodeStruct(codec.NullableString, val.errorText); encoder.encodeStruct(codec.Int32, val.resultCode); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaRouteProvider_JoinRoute_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_JoinRoute_Params.prototype.initDefaults_ = function() { this.mediaSource = null; this.presentationId = null; this.origin = null; this.tabId = 0; this.incognito = false; this.timeout = null; }; MediaRouteProvider_JoinRoute_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_JoinRoute_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 48} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_JoinRoute_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_JoinRoute_Params.presentationId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_JoinRoute_Params.origin err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, origin$.Origin, false); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_JoinRoute_Params.timeout err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 32, time$.TimeDelta, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_JoinRoute_Params.encodedSize = codec.kStructHeaderSize + 40; MediaRouteProvider_JoinRoute_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_JoinRoute_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaSource = decoder.decodeStruct(codec.String); val.presentationId = decoder.decodeStruct(codec.String); val.origin = decoder.decodeStructPointer(origin$.Origin); val.tabId = decoder.decodeStruct(codec.Int32); packed = decoder.readUint8(); val.incognito = (packed >> 0) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); val.timeout = decoder.decodeStructPointer(time$.TimeDelta); return val; }; MediaRouteProvider_JoinRoute_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_JoinRoute_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaSource); encoder.encodeStruct(codec.String, val.presentationId); encoder.encodeStructPointer(origin$.Origin, val.origin); encoder.encodeStruct(codec.Int32, val.tabId); packed = 0; packed |= (val.incognito & 1) << 0 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStructPointer(time$.TimeDelta, val.timeout); }; function MediaRouteProvider_JoinRoute_ResponseParams(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_JoinRoute_ResponseParams.prototype.initDefaults_ = function() { this.route = null; this.connection = null; this.errorText = null; this.resultCode = 0; }; MediaRouteProvider_JoinRoute_ResponseParams.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_JoinRoute_ResponseParams.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 40} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_JoinRoute_ResponseParams.route err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, MediaRoute, true); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_JoinRoute_ResponseParams.connection err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, RoutePresentationConnection, true); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_JoinRoute_ResponseParams.errorText err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, true) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_JoinRoute_ResponseParams.resultCode err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 24, RouteRequestResultCode); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_JoinRoute_ResponseParams.encodedSize = codec.kStructHeaderSize + 32; MediaRouteProvider_JoinRoute_ResponseParams.decode = function(decoder) { var packed; var val = new MediaRouteProvider_JoinRoute_ResponseParams(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.route = decoder.decodeStructPointer(MediaRoute); val.connection = decoder.decodeStructPointer(RoutePresentationConnection); val.errorText = decoder.decodeStruct(codec.NullableString); val.resultCode = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaRouteProvider_JoinRoute_ResponseParams.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_JoinRoute_ResponseParams.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(MediaRoute, val.route); encoder.encodeStructPointer(RoutePresentationConnection, val.connection); encoder.encodeStruct(codec.NullableString, val.errorText); encoder.encodeStruct(codec.Int32, val.resultCode); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaRouteProvider_ConnectRouteByRouteId_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_ConnectRouteByRouteId_Params.prototype.initDefaults_ = function() { this.mediaSource = null; this.routeId = null; this.presentationId = null; this.origin = null; this.tabId = 0; this.incognito = false; this.timeout = null; }; MediaRouteProvider_ConnectRouteByRouteId_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_ConnectRouteByRouteId_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 56} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ConnectRouteByRouteId_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ConnectRouteByRouteId_Params.routeId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ConnectRouteByRouteId_Params.presentationId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ConnectRouteByRouteId_Params.origin err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, origin$.Origin, false); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ConnectRouteByRouteId_Params.timeout err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 40, time$.TimeDelta, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_ConnectRouteByRouteId_Params.encodedSize = codec.kStructHeaderSize + 48; MediaRouteProvider_ConnectRouteByRouteId_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_ConnectRouteByRouteId_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaSource = decoder.decodeStruct(codec.String); val.routeId = decoder.decodeStruct(codec.String); val.presentationId = decoder.decodeStruct(codec.String); val.origin = decoder.decodeStructPointer(origin$.Origin); val.tabId = decoder.decodeStruct(codec.Int32); packed = decoder.readUint8(); val.incognito = (packed >> 0) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); val.timeout = decoder.decodeStructPointer(time$.TimeDelta); return val; }; MediaRouteProvider_ConnectRouteByRouteId_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_ConnectRouteByRouteId_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaSource); encoder.encodeStruct(codec.String, val.routeId); encoder.encodeStruct(codec.String, val.presentationId); encoder.encodeStructPointer(origin$.Origin, val.origin); encoder.encodeStruct(codec.Int32, val.tabId); packed = 0; packed |= (val.incognito & 1) << 0 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStructPointer(time$.TimeDelta, val.timeout); }; function MediaRouteProvider_ConnectRouteByRouteId_ResponseParams(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.prototype.initDefaults_ = function() { this.route = null; this.connection = null; this.errorText = null; this.resultCode = 0; }; MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 40} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.route err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, MediaRoute, true); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.connection err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, RoutePresentationConnection, true); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.errorText err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, true) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.resultCode err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 24, RouteRequestResultCode); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.encodedSize = codec.kStructHeaderSize + 32; MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.decode = function(decoder) { var packed; var val = new MediaRouteProvider_ConnectRouteByRouteId_ResponseParams(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.route = decoder.decodeStructPointer(MediaRoute); val.connection = decoder.decodeStructPointer(RoutePresentationConnection); val.errorText = decoder.decodeStruct(codec.NullableString); val.resultCode = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(MediaRoute, val.route); encoder.encodeStructPointer(RoutePresentationConnection, val.connection); encoder.encodeStruct(codec.NullableString, val.errorText); encoder.encodeStruct(codec.Int32, val.resultCode); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaRouteProvider_TerminateRoute_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_TerminateRoute_Params.prototype.initDefaults_ = function() { this.routeId = null; }; MediaRouteProvider_TerminateRoute_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_TerminateRoute_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_TerminateRoute_Params.routeId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_TerminateRoute_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_TerminateRoute_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_TerminateRoute_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.routeId = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_TerminateRoute_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_TerminateRoute_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.routeId); }; function MediaRouteProvider_TerminateRoute_ResponseParams(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_TerminateRoute_ResponseParams.prototype.initDefaults_ = function() { this.errorText = null; this.resultCode = 0; }; MediaRouteProvider_TerminateRoute_ResponseParams.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_TerminateRoute_ResponseParams.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_TerminateRoute_ResponseParams.errorText err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, true) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_TerminateRoute_ResponseParams.resultCode err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, RouteRequestResultCode); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_TerminateRoute_ResponseParams.encodedSize = codec.kStructHeaderSize + 16; MediaRouteProvider_TerminateRoute_ResponseParams.decode = function(decoder) { var packed; var val = new MediaRouteProvider_TerminateRoute_ResponseParams(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.errorText = decoder.decodeStruct(codec.NullableString); val.resultCode = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaRouteProvider_TerminateRoute_ResponseParams.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_TerminateRoute_ResponseParams.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.NullableString, val.errorText); encoder.encodeStruct(codec.Int32, val.resultCode); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaRouteProvider_SendRouteMessage_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_SendRouteMessage_Params.prototype.initDefaults_ = function() { this.mediaRouteId = null; this.message = null; }; MediaRouteProvider_SendRouteMessage_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_SendRouteMessage_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_SendRouteMessage_Params.mediaRouteId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_SendRouteMessage_Params.message err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_SendRouteMessage_Params.encodedSize = codec.kStructHeaderSize + 16; MediaRouteProvider_SendRouteMessage_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_SendRouteMessage_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaRouteId = decoder.decodeStruct(codec.String); val.message = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_SendRouteMessage_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_SendRouteMessage_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaRouteId); encoder.encodeStruct(codec.String, val.message); }; function MediaRouteProvider_SendRouteBinaryMessage_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_SendRouteBinaryMessage_Params.prototype.initDefaults_ = function() { this.mediaRouteId = null; this.data = null; }; MediaRouteProvider_SendRouteBinaryMessage_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_SendRouteBinaryMessage_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_SendRouteBinaryMessage_Params.mediaRouteId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_SendRouteBinaryMessage_Params.data err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 1, codec.Uint8, false, [0], 0); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_SendRouteBinaryMessage_Params.encodedSize = codec.kStructHeaderSize + 16; MediaRouteProvider_SendRouteBinaryMessage_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_SendRouteBinaryMessage_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaRouteId = decoder.decodeStruct(codec.String); val.data = decoder.decodeArrayPointer(codec.Uint8); return val; }; MediaRouteProvider_SendRouteBinaryMessage_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_SendRouteBinaryMessage_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaRouteId); encoder.encodeArrayPointer(codec.Uint8, val.data); }; function MediaRouteProvider_StartObservingMediaSinks_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_StartObservingMediaSinks_Params.prototype.initDefaults_ = function() { this.mediaSource = null; }; MediaRouteProvider_StartObservingMediaSinks_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_StartObservingMediaSinks_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_StartObservingMediaSinks_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_StartObservingMediaSinks_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_StartObservingMediaSinks_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_StartObservingMediaSinks_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaSource = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_StartObservingMediaSinks_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_StartObservingMediaSinks_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaSource); }; function MediaRouteProvider_StopObservingMediaSinks_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_StopObservingMediaSinks_Params.prototype.initDefaults_ = function() { this.mediaSource = null; }; MediaRouteProvider_StopObservingMediaSinks_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_StopObservingMediaSinks_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_StopObservingMediaSinks_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_StopObservingMediaSinks_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_StopObservingMediaSinks_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_StopObservingMediaSinks_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaSource = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_StopObservingMediaSinks_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_StopObservingMediaSinks_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaSource); }; function MediaRouteProvider_StartObservingMediaRoutes_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_StartObservingMediaRoutes_Params.prototype.initDefaults_ = function() { this.mediaSource = null; }; MediaRouteProvider_StartObservingMediaRoutes_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_StartObservingMediaRoutes_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_StartObservingMediaRoutes_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_StartObservingMediaRoutes_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_StartObservingMediaRoutes_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_StartObservingMediaRoutes_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaSource = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_StartObservingMediaRoutes_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_StartObservingMediaRoutes_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaSource); }; function MediaRouteProvider_StopObservingMediaRoutes_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_StopObservingMediaRoutes_Params.prototype.initDefaults_ = function() { this.mediaSource = null; }; MediaRouteProvider_StopObservingMediaRoutes_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_StopObservingMediaRoutes_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_StopObservingMediaRoutes_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_StopObservingMediaRoutes_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_StopObservingMediaRoutes_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_StopObservingMediaRoutes_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaSource = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_StopObservingMediaRoutes_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_StopObservingMediaRoutes_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaSource); }; function MediaRouteProvider_StartListeningForRouteMessages_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_StartListeningForRouteMessages_Params.prototype.initDefaults_ = function() { this.routeId = null; }; MediaRouteProvider_StartListeningForRouteMessages_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_StartListeningForRouteMessages_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_StartListeningForRouteMessages_Params.routeId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_StartListeningForRouteMessages_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_StartListeningForRouteMessages_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_StartListeningForRouteMessages_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.routeId = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_StartListeningForRouteMessages_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_StartListeningForRouteMessages_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.routeId); }; function MediaRouteProvider_StopListeningForRouteMessages_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_StopListeningForRouteMessages_Params.prototype.initDefaults_ = function() { this.routeId = null; }; MediaRouteProvider_StopListeningForRouteMessages_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_StopListeningForRouteMessages_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_StopListeningForRouteMessages_Params.routeId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_StopListeningForRouteMessages_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_StopListeningForRouteMessages_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_StopListeningForRouteMessages_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.routeId = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_StopListeningForRouteMessages_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_StopListeningForRouteMessages_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.routeId); }; function MediaRouteProvider_DetachRoute_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_DetachRoute_Params.prototype.initDefaults_ = function() { this.routeId = null; }; MediaRouteProvider_DetachRoute_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_DetachRoute_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_DetachRoute_Params.routeId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_DetachRoute_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_DetachRoute_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_DetachRoute_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.routeId = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_DetachRoute_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_DetachRoute_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.routeId); }; function MediaRouteProvider_EnableMdnsDiscovery_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_EnableMdnsDiscovery_Params.prototype.initDefaults_ = function() { }; MediaRouteProvider_EnableMdnsDiscovery_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_EnableMdnsDiscovery_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 8} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_EnableMdnsDiscovery_Params.encodedSize = codec.kStructHeaderSize + 0; MediaRouteProvider_EnableMdnsDiscovery_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_EnableMdnsDiscovery_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); return val; }; MediaRouteProvider_EnableMdnsDiscovery_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_EnableMdnsDiscovery_Params.encodedSize); encoder.writeUint32(0); }; function MediaRouteProvider_UpdateMediaSinks_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_UpdateMediaSinks_Params.prototype.initDefaults_ = function() { this.mediaSource = null; }; MediaRouteProvider_UpdateMediaSinks_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_UpdateMediaSinks_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_UpdateMediaSinks_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_UpdateMediaSinks_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_UpdateMediaSinks_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_UpdateMediaSinks_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.mediaSource = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_UpdateMediaSinks_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_UpdateMediaSinks_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.mediaSource); }; function MediaRouteProvider_SearchSinks_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_SearchSinks_Params.prototype.initDefaults_ = function() { this.sinkId = null; this.mediaSource = null; this.searchCriteria = null; }; MediaRouteProvider_SearchSinks_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_SearchSinks_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 32} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_SearchSinks_Params.sinkId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_SearchSinks_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_SearchSinks_Params.searchCriteria err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, SinkSearchCriteria, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_SearchSinks_Params.encodedSize = codec.kStructHeaderSize + 24; MediaRouteProvider_SearchSinks_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_SearchSinks_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.sinkId = decoder.decodeStruct(codec.String); val.mediaSource = decoder.decodeStruct(codec.String); val.searchCriteria = decoder.decodeStructPointer(SinkSearchCriteria); return val; }; MediaRouteProvider_SearchSinks_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_SearchSinks_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.sinkId); encoder.encodeStruct(codec.String, val.mediaSource); encoder.encodeStructPointer(SinkSearchCriteria, val.searchCriteria); }; function MediaRouteProvider_SearchSinks_ResponseParams(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_SearchSinks_ResponseParams.prototype.initDefaults_ = function() { this.sinkId = null; }; MediaRouteProvider_SearchSinks_ResponseParams.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_SearchSinks_ResponseParams.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_SearchSinks_ResponseParams.sinkId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_SearchSinks_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_SearchSinks_ResponseParams.decode = function(decoder) { var packed; var val = new MediaRouteProvider_SearchSinks_ResponseParams(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.sinkId = decoder.decodeStruct(codec.String); return val; }; MediaRouteProvider_SearchSinks_ResponseParams.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_SearchSinks_ResponseParams.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.sinkId); }; function MediaRouteProvider_ProvideSinks_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_ProvideSinks_Params.prototype.initDefaults_ = function() { this.providerName = null; this.sinks = null; }; MediaRouteProvider_ProvideSinks_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_ProvideSinks_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ProvideSinks_Params.providerName err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_ProvideSinks_Params.sinks err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.PointerTo(MediaSink), false, [0], 0); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_ProvideSinks_Params.encodedSize = codec.kStructHeaderSize + 16; MediaRouteProvider_ProvideSinks_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_ProvideSinks_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.providerName = decoder.decodeStruct(codec.String); val.sinks = decoder.decodeArrayPointer(new codec.PointerTo(MediaSink)); return val; }; MediaRouteProvider_ProvideSinks_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_ProvideSinks_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.providerName); encoder.encodeArrayPointer(new codec.PointerTo(MediaSink), val.sinks); }; function MediaRouteProvider_CreateMediaRouteController_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_CreateMediaRouteController_Params.prototype.initDefaults_ = function() { this.routeId = null; this.mediaController = new bindings.InterfaceRequest(); this.observer = new media_status$.MediaStatusObserverPtr(); }; MediaRouteProvider_CreateMediaRouteController_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_CreateMediaRouteController_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 32} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateMediaRouteController_Params.routeId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateMediaRouteController_Params.mediaController err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouteProvider_CreateMediaRouteController_Params.observer err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 12, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_CreateMediaRouteController_Params.encodedSize = codec.kStructHeaderSize + 24; MediaRouteProvider_CreateMediaRouteController_Params.decode = function(decoder) { var packed; var val = new MediaRouteProvider_CreateMediaRouteController_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.routeId = decoder.decodeStruct(codec.String); val.mediaController = decoder.decodeStruct(codec.InterfaceRequest); val.observer = decoder.decodeStruct(new codec.Interface(media_status$.MediaStatusObserverPtr)); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaRouteProvider_CreateMediaRouteController_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_CreateMediaRouteController_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.routeId); encoder.encodeStruct(codec.InterfaceRequest, val.mediaController); encoder.encodeStruct(new codec.Interface(media_status$.MediaStatusObserverPtr), val.observer); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaRouteProvider_CreateMediaRouteController_ResponseParams(values) { this.initDefaults_(); this.initFields_(values); } MediaRouteProvider_CreateMediaRouteController_ResponseParams.prototype.initDefaults_ = function() { this.success = false; }; MediaRouteProvider_CreateMediaRouteController_ResponseParams.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouteProvider_CreateMediaRouteController_ResponseParams.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouteProvider_CreateMediaRouteController_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; MediaRouteProvider_CreateMediaRouteController_ResponseParams.decode = function(decoder) { var packed; var val = new MediaRouteProvider_CreateMediaRouteController_ResponseParams(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); packed = decoder.readUint8(); val.success = (packed >> 0) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaRouteProvider_CreateMediaRouteController_ResponseParams.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouteProvider_CreateMediaRouteController_ResponseParams.encodedSize); encoder.writeUint32(0); packed = 0; packed |= (val.success & 1) << 0 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaRouter_RegisterMediaRouteProvider_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_RegisterMediaRouteProvider_Params.prototype.initDefaults_ = function() { this.providerId = 0; this.mediaRouterProvider = new MediaRouteProviderPtr(); }; MediaRouter_RegisterMediaRouteProvider_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_RegisterMediaRouteProvider_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_RegisterMediaRouteProvider_Params.providerId err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MediaRouteProvider.Id); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_RegisterMediaRouteProvider_Params.mediaRouterProvider err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 4, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_RegisterMediaRouteProvider_Params.encodedSize = codec.kStructHeaderSize + 16; MediaRouter_RegisterMediaRouteProvider_Params.decode = function(decoder) { var packed; var val = new MediaRouter_RegisterMediaRouteProvider_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.providerId = decoder.decodeStruct(codec.Int32); val.mediaRouterProvider = decoder.decodeStruct(new codec.Interface(MediaRouteProviderPtr)); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaRouter_RegisterMediaRouteProvider_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_RegisterMediaRouteProvider_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.providerId); encoder.encodeStruct(new codec.Interface(MediaRouteProviderPtr), val.mediaRouterProvider); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaRouter_RegisterMediaRouteProvider_ResponseParams(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_RegisterMediaRouteProvider_ResponseParams.prototype.initDefaults_ = function() { this.instanceId = null; this.config = null; }; MediaRouter_RegisterMediaRouteProvider_ResponseParams.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_RegisterMediaRouteProvider_ResponseParams.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_RegisterMediaRouteProvider_ResponseParams.instanceId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouter_RegisterMediaRouteProvider_ResponseParams.config err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, MediaRouteProviderConfig, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_RegisterMediaRouteProvider_ResponseParams.encodedSize = codec.kStructHeaderSize + 16; MediaRouter_RegisterMediaRouteProvider_ResponseParams.decode = function(decoder) { var packed; var val = new MediaRouter_RegisterMediaRouteProvider_ResponseParams(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.instanceId = decoder.decodeStruct(codec.String); val.config = decoder.decodeStructPointer(MediaRouteProviderConfig); return val; }; MediaRouter_RegisterMediaRouteProvider_ResponseParams.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_RegisterMediaRouteProvider_ResponseParams.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.instanceId); encoder.encodeStructPointer(MediaRouteProviderConfig, val.config); }; function MediaRouter_OnSinksReceived_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_OnSinksReceived_Params.prototype.initDefaults_ = function() { this.providerId = 0; this.mediaSource = null; this.sinks = null; this.origins = null; }; MediaRouter_OnSinksReceived_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_OnSinksReceived_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 40} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnSinksReceived_Params.providerId err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MediaRouteProvider.Id); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnSinksReceived_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnSinksReceived_Params.sinks err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 8, new codec.PointerTo(MediaSink), false, [0], 0); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnSinksReceived_Params.origins err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 24, 8, new codec.PointerTo(origin$.Origin), false, [0], 0); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_OnSinksReceived_Params.encodedSize = codec.kStructHeaderSize + 32; MediaRouter_OnSinksReceived_Params.decode = function(decoder) { var packed; var val = new MediaRouter_OnSinksReceived_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.providerId = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); val.mediaSource = decoder.decodeStruct(codec.String); val.sinks = decoder.decodeArrayPointer(new codec.PointerTo(MediaSink)); val.origins = decoder.decodeArrayPointer(new codec.PointerTo(origin$.Origin)); return val; }; MediaRouter_OnSinksReceived_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_OnSinksReceived_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.providerId); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStruct(codec.String, val.mediaSource); encoder.encodeArrayPointer(new codec.PointerTo(MediaSink), val.sinks); encoder.encodeArrayPointer(new codec.PointerTo(origin$.Origin), val.origins); }; function MediaRouter_OnIssue_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_OnIssue_Params.prototype.initDefaults_ = function() { this.issue = null; }; MediaRouter_OnIssue_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_OnIssue_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnIssue_Params.issue err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, Issue, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_OnIssue_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouter_OnIssue_Params.decode = function(decoder) { var packed; var val = new MediaRouter_OnIssue_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.issue = decoder.decodeStructPointer(Issue); return val; }; MediaRouter_OnIssue_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_OnIssue_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(Issue, val.issue); }; function MediaRouter_OnRoutesUpdated_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_OnRoutesUpdated_Params.prototype.initDefaults_ = function() { this.providerId = 0; this.routes = null; this.mediaSource = null; this.joinableRouteIds = null; }; MediaRouter_OnRoutesUpdated_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_OnRoutesUpdated_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 40} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnRoutesUpdated_Params.providerId err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MediaRouteProvider.Id); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnRoutesUpdated_Params.routes err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.PointerTo(MediaRoute), false, [0], 0); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnRoutesUpdated_Params.mediaSource err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnRoutesUpdated_Params.joinableRouteIds err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 24, 8, codec.String, false, [0, 0], 0); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_OnRoutesUpdated_Params.encodedSize = codec.kStructHeaderSize + 32; MediaRouter_OnRoutesUpdated_Params.decode = function(decoder) { var packed; var val = new MediaRouter_OnRoutesUpdated_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.providerId = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); val.routes = decoder.decodeArrayPointer(new codec.PointerTo(MediaRoute)); val.mediaSource = decoder.decodeStruct(codec.String); val.joinableRouteIds = decoder.decodeArrayPointer(codec.String); return val; }; MediaRouter_OnRoutesUpdated_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_OnRoutesUpdated_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.providerId); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeArrayPointer(new codec.PointerTo(MediaRoute), val.routes); encoder.encodeStruct(codec.String, val.mediaSource); encoder.encodeArrayPointer(codec.String, val.joinableRouteIds); }; function MediaRouter_OnSinkAvailabilityUpdated_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_OnSinkAvailabilityUpdated_Params.prototype.initDefaults_ = function() { this.providerId = 0; this.availability = 0; }; MediaRouter_OnSinkAvailabilityUpdated_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_OnSinkAvailabilityUpdated_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnSinkAvailabilityUpdated_Params.providerId err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MediaRouteProvider.Id); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnSinkAvailabilityUpdated_Params.availability err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 4, MediaRouter.SinkAvailability); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_OnSinkAvailabilityUpdated_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouter_OnSinkAvailabilityUpdated_Params.decode = function(decoder) { var packed; var val = new MediaRouter_OnSinkAvailabilityUpdated_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.providerId = decoder.decodeStruct(codec.Int32); val.availability = decoder.decodeStruct(codec.Int32); return val; }; MediaRouter_OnSinkAvailabilityUpdated_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_OnSinkAvailabilityUpdated_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.providerId); encoder.encodeStruct(codec.Int32, val.availability); }; function MediaRouter_OnPresentationConnectionStateChanged_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_OnPresentationConnectionStateChanged_Params.prototype.initDefaults_ = function() { this.routeId = null; this.state = 0; }; MediaRouter_OnPresentationConnectionStateChanged_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_OnPresentationConnectionStateChanged_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnPresentationConnectionStateChanged_Params.routeId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnPresentationConnectionStateChanged_Params.state err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, MediaRouter.PresentationConnectionState); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_OnPresentationConnectionStateChanged_Params.encodedSize = codec.kStructHeaderSize + 16; MediaRouter_OnPresentationConnectionStateChanged_Params.decode = function(decoder) { var packed; var val = new MediaRouter_OnPresentationConnectionStateChanged_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.routeId = decoder.decodeStruct(codec.String); val.state = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaRouter_OnPresentationConnectionStateChanged_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_OnPresentationConnectionStateChanged_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.routeId); encoder.encodeStruct(codec.Int32, val.state); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaRouter_OnPresentationConnectionClosed_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_OnPresentationConnectionClosed_Params.prototype.initDefaults_ = function() { this.routeId = null; this.reason = 0; this.message = null; }; MediaRouter_OnPresentationConnectionClosed_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_OnPresentationConnectionClosed_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 32} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnPresentationConnectionClosed_Params.routeId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnPresentationConnectionClosed_Params.reason err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, MediaRouter.PresentationConnectionCloseReason); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnPresentationConnectionClosed_Params.message err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_OnPresentationConnectionClosed_Params.encodedSize = codec.kStructHeaderSize + 24; MediaRouter_OnPresentationConnectionClosed_Params.decode = function(decoder) { var packed; var val = new MediaRouter_OnPresentationConnectionClosed_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.routeId = decoder.decodeStruct(codec.String); val.reason = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); val.message = decoder.decodeStruct(codec.String); return val; }; MediaRouter_OnPresentationConnectionClosed_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_OnPresentationConnectionClosed_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.routeId); encoder.encodeStruct(codec.Int32, val.reason); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStruct(codec.String, val.message); }; function MediaRouter_OnRouteMessagesReceived_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_OnRouteMessagesReceived_Params.prototype.initDefaults_ = function() { this.routeId = null; this.messages = null; }; MediaRouter_OnRouteMessagesReceived_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_OnRouteMessagesReceived_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnRouteMessagesReceived_Params.routeId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnRouteMessagesReceived_Params.messages err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.PointerTo(RouteMessage), false, [0], 0); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_OnRouteMessagesReceived_Params.encodedSize = codec.kStructHeaderSize + 16; MediaRouter_OnRouteMessagesReceived_Params.decode = function(decoder) { var packed; var val = new MediaRouter_OnRouteMessagesReceived_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.routeId = decoder.decodeStruct(codec.String); val.messages = decoder.decodeArrayPointer(new codec.PointerTo(RouteMessage)); return val; }; MediaRouter_OnRouteMessagesReceived_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_OnRouteMessagesReceived_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.routeId); encoder.encodeArrayPointer(new codec.PointerTo(RouteMessage), val.messages); }; function MediaRouter_OnMediaRemoterCreated_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_OnMediaRemoterCreated_Params.prototype.initDefaults_ = function() { this.tabId = 0; this.remoter = new mirror_service_remoting$.MirrorServiceRemoterPtr(); this.remotingSource = new bindings.InterfaceRequest(); }; MediaRouter_OnMediaRemoterCreated_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_OnMediaRemoterCreated_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnMediaRemoterCreated_Params.remoter err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 4, false); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_OnMediaRemoterCreated_Params.remotingSource err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 12, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_OnMediaRemoterCreated_Params.encodedSize = codec.kStructHeaderSize + 16; MediaRouter_OnMediaRemoterCreated_Params.decode = function(decoder) { var packed; var val = new MediaRouter_OnMediaRemoterCreated_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.tabId = decoder.decodeStruct(codec.Int32); val.remoter = decoder.decodeStruct(new codec.Interface(mirror_service_remoting$.MirrorServiceRemoterPtr)); val.remotingSource = decoder.decodeStruct(codec.InterfaceRequest); return val; }; MediaRouter_OnMediaRemoterCreated_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_OnMediaRemoterCreated_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.tabId); encoder.encodeStruct(new codec.Interface(mirror_service_remoting$.MirrorServiceRemoterPtr), val.remoter); encoder.encodeStruct(codec.InterfaceRequest, val.remotingSource); }; function MediaRouter_GetMediaSinkServiceStatus_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_GetMediaSinkServiceStatus_Params.prototype.initDefaults_ = function() { }; MediaRouter_GetMediaSinkServiceStatus_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_GetMediaSinkServiceStatus_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 8} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_GetMediaSinkServiceStatus_Params.encodedSize = codec.kStructHeaderSize + 0; MediaRouter_GetMediaSinkServiceStatus_Params.decode = function(decoder) { var packed; var val = new MediaRouter_GetMediaSinkServiceStatus_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); return val; }; MediaRouter_GetMediaSinkServiceStatus_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_GetMediaSinkServiceStatus_Params.encodedSize); encoder.writeUint32(0); }; function MediaRouter_GetMediaSinkServiceStatus_ResponseParams(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_GetMediaSinkServiceStatus_ResponseParams.prototype.initDefaults_ = function() { this.status = null; }; MediaRouter_GetMediaSinkServiceStatus_ResponseParams.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_GetMediaSinkServiceStatus_ResponseParams.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_GetMediaSinkServiceStatus_ResponseParams.status err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_GetMediaSinkServiceStatus_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; MediaRouter_GetMediaSinkServiceStatus_ResponseParams.decode = function(decoder) { var packed; var val = new MediaRouter_GetMediaSinkServiceStatus_ResponseParams(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.status = decoder.decodeStruct(codec.String); return val; }; MediaRouter_GetMediaSinkServiceStatus_ResponseParams.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_GetMediaSinkServiceStatus_ResponseParams.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.status); }; function MediaRouter_GetMirroringServiceHostForTab_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_GetMirroringServiceHostForTab_Params.prototype.initDefaults_ = function() { this.targetTabId = 0; this.request = new bindings.InterfaceRequest(); }; MediaRouter_GetMirroringServiceHostForTab_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_GetMirroringServiceHostForTab_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_GetMirroringServiceHostForTab_Params.request err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 4, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_GetMirroringServiceHostForTab_Params.encodedSize = codec.kStructHeaderSize + 8; MediaRouter_GetMirroringServiceHostForTab_Params.decode = function(decoder) { var packed; var val = new MediaRouter_GetMirroringServiceHostForTab_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.targetTabId = decoder.decodeStruct(codec.Int32); val.request = decoder.decodeStruct(codec.InterfaceRequest); return val; }; MediaRouter_GetMirroringServiceHostForTab_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_GetMirroringServiceHostForTab_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.targetTabId); encoder.encodeStruct(codec.InterfaceRequest, val.request); }; function MediaRouter_GetMirroringServiceHostForDesktop_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_GetMirroringServiceHostForDesktop_Params.prototype.initDefaults_ = function() { this.initiatorTabId = 0; this.request = new bindings.InterfaceRequest(); this.desktopStreamId = null; }; MediaRouter_GetMirroringServiceHostForDesktop_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_GetMirroringServiceHostForDesktop_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_GetMirroringServiceHostForDesktop_Params.desktopStreamId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouter_GetMirroringServiceHostForDesktop_Params.request err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 4, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_GetMirroringServiceHostForDesktop_Params.encodedSize = codec.kStructHeaderSize + 16; MediaRouter_GetMirroringServiceHostForDesktop_Params.decode = function(decoder) { var packed; var val = new MediaRouter_GetMirroringServiceHostForDesktop_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.initiatorTabId = decoder.decodeStruct(codec.Int32); val.request = decoder.decodeStruct(codec.InterfaceRequest); val.desktopStreamId = decoder.decodeStruct(codec.String); return val; }; MediaRouter_GetMirroringServiceHostForDesktop_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_GetMirroringServiceHostForDesktop_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.initiatorTabId); encoder.encodeStruct(codec.InterfaceRequest, val.request); encoder.encodeStruct(codec.String, val.desktopStreamId); }; function MediaRouter_GetMirroringServiceHostForOffscreenTab_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.prototype.initDefaults_ = function() { this.presentationUrl = null; this.presentationId = null; this.request = new bindings.InterfaceRequest(); }; MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 32} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.presentationUrl err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, url$.Url, false); if (err !== validator.validationError.NONE) return err; // validate MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.presentationId err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.request err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 16, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.encodedSize = codec.kStructHeaderSize + 24; MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.decode = function(decoder) { var packed; var val = new MediaRouter_GetMirroringServiceHostForOffscreenTab_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.presentationUrl = decoder.decodeStructPointer(url$.Url); val.presentationId = decoder.decodeStruct(codec.String); val.request = decoder.decodeStruct(codec.InterfaceRequest); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(url$.Url, val.presentationUrl); encoder.encodeStruct(codec.String, val.presentationId); encoder.encodeStruct(codec.InterfaceRequest, val.request); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaSinkExtraData(value) { this.initDefault_(); this.initValue_(value); } MediaSinkExtraData.Tags = { dialMediaSink: 0, castMediaSink: 1, }; MediaSinkExtraData.prototype.initDefault_ = function() { this.$data = null; this.$tag = undefined; } MediaSinkExtraData.prototype.initValue_ = function(value) { if (value == undefined) { return; } var keys = Object.keys(value); if (keys.length == 0) { return; } if (keys.length > 1) { throw new TypeError("You may set only one member on a union."); } var fields = [ "dialMediaSink", "castMediaSink", ]; if (fields.indexOf(keys[0]) < 0) { throw new ReferenceError(keys[0] + " is not a MediaSinkExtraData member."); } this[keys[0]] = value[keys[0]]; } Object.defineProperty(MediaSinkExtraData.prototype, "dialMediaSink", { get: function() { if (this.$tag != MediaSinkExtraData.Tags.dialMediaSink) { throw new ReferenceError( "MediaSinkExtraData.dialMediaSink is not currently set."); } return this.$data; }, set: function(value) { this.$tag = MediaSinkExtraData.Tags.dialMediaSink; this.$data = value; } }); Object.defineProperty(MediaSinkExtraData.prototype, "castMediaSink", { get: function() { if (this.$tag != MediaSinkExtraData.Tags.castMediaSink) { throw new ReferenceError( "MediaSinkExtraData.castMediaSink is not currently set."); } return this.$data; }, set: function(value) { this.$tag = MediaSinkExtraData.Tags.castMediaSink; this.$data = value; } }); MediaSinkExtraData.encode = function(encoder, val) { if (val == null) { encoder.writeUint64(0); encoder.writeUint64(0); return; } if (val.$tag == undefined) { throw new TypeError("Cannot encode unions with an unknown member set."); } encoder.writeUint32(16); encoder.writeUint32(val.$tag); switch (val.$tag) { case MediaSinkExtraData.Tags.dialMediaSink: encoder.encodeStructPointer(DialMediaSink, val.dialMediaSink); break; case MediaSinkExtraData.Tags.castMediaSink: encoder.encodeStructPointer(CastMediaSink, val.castMediaSink); break; } encoder.align(); }; MediaSinkExtraData.decode = function(decoder) { var size = decoder.readUint32(); if (size == 0) { decoder.readUint32(); decoder.readUint64(); return null; } var result = new MediaSinkExtraData(); var tag = decoder.readUint32(); switch (tag) { case MediaSinkExtraData.Tags.dialMediaSink: result.dialMediaSink = decoder.decodeStructPointer(DialMediaSink); break; case MediaSinkExtraData.Tags.castMediaSink: result.castMediaSink = decoder.decodeStructPointer(CastMediaSink); break; } decoder.align(); return result; }; MediaSinkExtraData.validate = function(messageValidator, offset) { var size = messageValidator.decodeUnionSize(offset); if (size != 16) { return validator.validationError.INVALID_UNION_SIZE; } var tag = messageValidator.decodeUnionTag(offset); var data_offset = offset + 8; var err; switch (tag) { case MediaSinkExtraData.Tags.dialMediaSink: // validate MediaSinkExtraData.dialMediaSink err = messageValidator.validateStructPointer(data_offset, DialMediaSink, false); if (err !== validator.validationError.NONE) return err; break; case MediaSinkExtraData.Tags.castMediaSink: // validate MediaSinkExtraData.castMediaSink err = messageValidator.validateStructPointer(data_offset, CastMediaSink, false); if (err !== validator.validationError.NONE) return err; break; } return validator.validationError.NONE; }; MediaSinkExtraData.encodedSize = 16; var kMediaRouteProvider_CreateRoute_Name = 782952299; var kMediaRouteProvider_JoinRoute_Name = 1199893741; var kMediaRouteProvider_ConnectRouteByRouteId_Name = 1468369604; var kMediaRouteProvider_TerminateRoute_Name = 2076219515; var kMediaRouteProvider_SendRouteMessage_Name = 1226427911; var kMediaRouteProvider_SendRouteBinaryMessage_Name = 956272035; var kMediaRouteProvider_StartObservingMediaSinks_Name = 995039470; var kMediaRouteProvider_StopObservingMediaSinks_Name = 1717033259; var kMediaRouteProvider_StartObservingMediaRoutes_Name = 1710076587; var kMediaRouteProvider_StopObservingMediaRoutes_Name = 1371994592; var kMediaRouteProvider_StartListeningForRouteMessages_Name = 1166293216; var kMediaRouteProvider_StopListeningForRouteMessages_Name = 1140615138; var kMediaRouteProvider_DetachRoute_Name = 1236519714; var kMediaRouteProvider_EnableMdnsDiscovery_Name = 250587548; var kMediaRouteProvider_UpdateMediaSinks_Name = 582169440; var kMediaRouteProvider_SearchSinks_Name = 1268276099; var kMediaRouteProvider_ProvideSinks_Name = 1223794936; var kMediaRouteProvider_CreateMediaRouteController_Name = 2095323133; function MediaRouteProviderPtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(MediaRouteProvider, handleOrPtrInfo); } function MediaRouteProviderAssociatedPtr(associatedInterfacePtrInfo) { this.ptr = new associatedBindings.AssociatedInterfacePtrController( MediaRouteProvider, associatedInterfacePtrInfo); } MediaRouteProviderAssociatedPtr.prototype = Object.create(MediaRouteProviderPtr.prototype); MediaRouteProviderAssociatedPtr.prototype.constructor = MediaRouteProviderAssociatedPtr; function MediaRouteProviderProxy(receiver) { this.receiver_ = receiver; } MediaRouteProviderPtr.prototype.createRoute = function() { return MediaRouteProviderProxy.prototype.createRoute .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.createRoute = function(mediaSource, sinkId, originalPresentationId, origin, tabId, timeout, incognito) { var params_ = new MediaRouteProvider_CreateRoute_Params(); params_.mediaSource = mediaSource; params_.sinkId = sinkId; params_.originalPresentationId = originalPresentationId; params_.origin = origin; params_.tabId = tabId; params_.timeout = timeout; params_.incognito = incognito; return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kMediaRouteProvider_CreateRoute_Name, codec.align(MediaRouteProvider_CreateRoute_Params.encodedSize), codec.kMessageExpectsResponse, 0); builder.encodeStruct(MediaRouteProvider_CreateRoute_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); var responseParams = reader.decodeStruct(MediaRouteProvider_CreateRoute_ResponseParams); resolve(responseParams); }).catch(function(result) { reject(Error("Connection error: " + result)); }); }.bind(this)); }; MediaRouteProviderPtr.prototype.joinRoute = function() { return MediaRouteProviderProxy.prototype.joinRoute .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.joinRoute = function(mediaSource, presentationId, origin, tabId, timeout, incognito) { var params_ = new MediaRouteProvider_JoinRoute_Params(); params_.mediaSource = mediaSource; params_.presentationId = presentationId; params_.origin = origin; params_.tabId = tabId; params_.timeout = timeout; params_.incognito = incognito; return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kMediaRouteProvider_JoinRoute_Name, codec.align(MediaRouteProvider_JoinRoute_Params.encodedSize), codec.kMessageExpectsResponse, 0); builder.encodeStruct(MediaRouteProvider_JoinRoute_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); var responseParams = reader.decodeStruct(MediaRouteProvider_JoinRoute_ResponseParams); resolve(responseParams); }).catch(function(result) { reject(Error("Connection error: " + result)); }); }.bind(this)); }; MediaRouteProviderPtr.prototype.connectRouteByRouteId = function() { return MediaRouteProviderProxy.prototype.connectRouteByRouteId .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.connectRouteByRouteId = function(mediaSource, routeId, presentationId, origin, tabId, timeout, incognito) { var params_ = new MediaRouteProvider_ConnectRouteByRouteId_Params(); params_.mediaSource = mediaSource; params_.routeId = routeId; params_.presentationId = presentationId; params_.origin = origin; params_.tabId = tabId; params_.timeout = timeout; params_.incognito = incognito; return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kMediaRouteProvider_ConnectRouteByRouteId_Name, codec.align(MediaRouteProvider_ConnectRouteByRouteId_Params.encodedSize), codec.kMessageExpectsResponse, 0); builder.encodeStruct(MediaRouteProvider_ConnectRouteByRouteId_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); var responseParams = reader.decodeStruct(MediaRouteProvider_ConnectRouteByRouteId_ResponseParams); resolve(responseParams); }).catch(function(result) { reject(Error("Connection error: " + result)); }); }.bind(this)); }; MediaRouteProviderPtr.prototype.terminateRoute = function() { return MediaRouteProviderProxy.prototype.terminateRoute .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.terminateRoute = function(routeId) { var params_ = new MediaRouteProvider_TerminateRoute_Params(); params_.routeId = routeId; return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kMediaRouteProvider_TerminateRoute_Name, codec.align(MediaRouteProvider_TerminateRoute_Params.encodedSize), codec.kMessageExpectsResponse, 0); builder.encodeStruct(MediaRouteProvider_TerminateRoute_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); var responseParams = reader.decodeStruct(MediaRouteProvider_TerminateRoute_ResponseParams); resolve(responseParams); }).catch(function(result) { reject(Error("Connection error: " + result)); }); }.bind(this)); }; MediaRouteProviderPtr.prototype.sendRouteMessage = function() { return MediaRouteProviderProxy.prototype.sendRouteMessage .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.sendRouteMessage = function(mediaRouteId, message) { var params_ = new MediaRouteProvider_SendRouteMessage_Params(); params_.mediaRouteId = mediaRouteId; params_.message = message; var builder = new codec.MessageV0Builder( kMediaRouteProvider_SendRouteMessage_Name, codec.align(MediaRouteProvider_SendRouteMessage_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_SendRouteMessage_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.sendRouteBinaryMessage = function() { return MediaRouteProviderProxy.prototype.sendRouteBinaryMessage .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.sendRouteBinaryMessage = function(mediaRouteId, data) { var params_ = new MediaRouteProvider_SendRouteBinaryMessage_Params(); params_.mediaRouteId = mediaRouteId; params_.data = data; var builder = new codec.MessageV0Builder( kMediaRouteProvider_SendRouteBinaryMessage_Name, codec.align(MediaRouteProvider_SendRouteBinaryMessage_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_SendRouteBinaryMessage_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.startObservingMediaSinks = function() { return MediaRouteProviderProxy.prototype.startObservingMediaSinks .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.startObservingMediaSinks = function(mediaSource) { var params_ = new MediaRouteProvider_StartObservingMediaSinks_Params(); params_.mediaSource = mediaSource; var builder = new codec.MessageV0Builder( kMediaRouteProvider_StartObservingMediaSinks_Name, codec.align(MediaRouteProvider_StartObservingMediaSinks_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_StartObservingMediaSinks_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.stopObservingMediaSinks = function() { return MediaRouteProviderProxy.prototype.stopObservingMediaSinks .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.stopObservingMediaSinks = function(mediaSource) { var params_ = new MediaRouteProvider_StopObservingMediaSinks_Params(); params_.mediaSource = mediaSource; var builder = new codec.MessageV0Builder( kMediaRouteProvider_StopObservingMediaSinks_Name, codec.align(MediaRouteProvider_StopObservingMediaSinks_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_StopObservingMediaSinks_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.startObservingMediaRoutes = function() { return MediaRouteProviderProxy.prototype.startObservingMediaRoutes .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.startObservingMediaRoutes = function(mediaSource) { var params_ = new MediaRouteProvider_StartObservingMediaRoutes_Params(); params_.mediaSource = mediaSource; var builder = new codec.MessageV0Builder( kMediaRouteProvider_StartObservingMediaRoutes_Name, codec.align(MediaRouteProvider_StartObservingMediaRoutes_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_StartObservingMediaRoutes_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.stopObservingMediaRoutes = function() { return MediaRouteProviderProxy.prototype.stopObservingMediaRoutes .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.stopObservingMediaRoutes = function(mediaSource) { var params_ = new MediaRouteProvider_StopObservingMediaRoutes_Params(); params_.mediaSource = mediaSource; var builder = new codec.MessageV0Builder( kMediaRouteProvider_StopObservingMediaRoutes_Name, codec.align(MediaRouteProvider_StopObservingMediaRoutes_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_StopObservingMediaRoutes_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.startListeningForRouteMessages = function() { return MediaRouteProviderProxy.prototype.startListeningForRouteMessages .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.startListeningForRouteMessages = function(routeId) { var params_ = new MediaRouteProvider_StartListeningForRouteMessages_Params(); params_.routeId = routeId; var builder = new codec.MessageV0Builder( kMediaRouteProvider_StartListeningForRouteMessages_Name, codec.align(MediaRouteProvider_StartListeningForRouteMessages_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_StartListeningForRouteMessages_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.stopListeningForRouteMessages = function() { return MediaRouteProviderProxy.prototype.stopListeningForRouteMessages .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.stopListeningForRouteMessages = function(routeId) { var params_ = new MediaRouteProvider_StopListeningForRouteMessages_Params(); params_.routeId = routeId; var builder = new codec.MessageV0Builder( kMediaRouteProvider_StopListeningForRouteMessages_Name, codec.align(MediaRouteProvider_StopListeningForRouteMessages_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_StopListeningForRouteMessages_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.detachRoute = function() { return MediaRouteProviderProxy.prototype.detachRoute .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.detachRoute = function(routeId) { var params_ = new MediaRouteProvider_DetachRoute_Params(); params_.routeId = routeId; var builder = new codec.MessageV0Builder( kMediaRouteProvider_DetachRoute_Name, codec.align(MediaRouteProvider_DetachRoute_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_DetachRoute_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.enableMdnsDiscovery = function() { return MediaRouteProviderProxy.prototype.enableMdnsDiscovery .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.enableMdnsDiscovery = function() { var params_ = new MediaRouteProvider_EnableMdnsDiscovery_Params(); var builder = new codec.MessageV0Builder( kMediaRouteProvider_EnableMdnsDiscovery_Name, codec.align(MediaRouteProvider_EnableMdnsDiscovery_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_EnableMdnsDiscovery_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.updateMediaSinks = function() { return MediaRouteProviderProxy.prototype.updateMediaSinks .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.updateMediaSinks = function(mediaSource) { var params_ = new MediaRouteProvider_UpdateMediaSinks_Params(); params_.mediaSource = mediaSource; var builder = new codec.MessageV0Builder( kMediaRouteProvider_UpdateMediaSinks_Name, codec.align(MediaRouteProvider_UpdateMediaSinks_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_UpdateMediaSinks_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.searchSinks = function() { return MediaRouteProviderProxy.prototype.searchSinks .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.searchSinks = function(sinkId, mediaSource, searchCriteria) { var params_ = new MediaRouteProvider_SearchSinks_Params(); params_.sinkId = sinkId; params_.mediaSource = mediaSource; params_.searchCriteria = searchCriteria; return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kMediaRouteProvider_SearchSinks_Name, codec.align(MediaRouteProvider_SearchSinks_Params.encodedSize), codec.kMessageExpectsResponse, 0); builder.encodeStruct(MediaRouteProvider_SearchSinks_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); var responseParams = reader.decodeStruct(MediaRouteProvider_SearchSinks_ResponseParams); resolve(responseParams); }).catch(function(result) { reject(Error("Connection error: " + result)); }); }.bind(this)); }; MediaRouteProviderPtr.prototype.provideSinks = function() { return MediaRouteProviderProxy.prototype.provideSinks .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.provideSinks = function(providerName, sinks) { var params_ = new MediaRouteProvider_ProvideSinks_Params(); params_.providerName = providerName; params_.sinks = sinks; var builder = new codec.MessageV0Builder( kMediaRouteProvider_ProvideSinks_Name, codec.align(MediaRouteProvider_ProvideSinks_Params.encodedSize)); builder.encodeStruct(MediaRouteProvider_ProvideSinks_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouteProviderPtr.prototype.createMediaRouteController = function() { return MediaRouteProviderProxy.prototype.createMediaRouteController .apply(this.ptr.getProxy(), arguments); }; MediaRouteProviderProxy.prototype.createMediaRouteController = function(routeId, mediaController, observer) { var params_ = new MediaRouteProvider_CreateMediaRouteController_Params(); params_.routeId = routeId; params_.mediaController = mediaController; params_.observer = observer; return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kMediaRouteProvider_CreateMediaRouteController_Name, codec.align(MediaRouteProvider_CreateMediaRouteController_Params.encodedSize), codec.kMessageExpectsResponse, 0); builder.encodeStruct(MediaRouteProvider_CreateMediaRouteController_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); var responseParams = reader.decodeStruct(MediaRouteProvider_CreateMediaRouteController_ResponseParams); resolve(responseParams); }).catch(function(result) { reject(Error("Connection error: " + result)); }); }.bind(this)); }; function MediaRouteProviderStub(delegate) { this.delegate_ = delegate; } MediaRouteProviderStub.prototype.createRoute = function(mediaSource, sinkId, originalPresentationId, origin, tabId, timeout, incognito) { return this.delegate_ && this.delegate_.createRoute && this.delegate_.createRoute(mediaSource, sinkId, originalPresentationId, origin, tabId, timeout, incognito); } MediaRouteProviderStub.prototype.joinRoute = function(mediaSource, presentationId, origin, tabId, timeout, incognito) { return this.delegate_ && this.delegate_.joinRoute && this.delegate_.joinRoute(mediaSource, presentationId, origin, tabId, timeout, incognito); } MediaRouteProviderStub.prototype.connectRouteByRouteId = function(mediaSource, routeId, presentationId, origin, tabId, timeout, incognito) { return this.delegate_ && this.delegate_.connectRouteByRouteId && this.delegate_.connectRouteByRouteId(mediaSource, routeId, presentationId, origin, tabId, timeout, incognito); } MediaRouteProviderStub.prototype.terminateRoute = function(routeId) { return this.delegate_ && this.delegate_.terminateRoute && this.delegate_.terminateRoute(routeId); } MediaRouteProviderStub.prototype.sendRouteMessage = function(mediaRouteId, message) { return this.delegate_ && this.delegate_.sendRouteMessage && this.delegate_.sendRouteMessage(mediaRouteId, message); } MediaRouteProviderStub.prototype.sendRouteBinaryMessage = function(mediaRouteId, data) { return this.delegate_ && this.delegate_.sendRouteBinaryMessage && this.delegate_.sendRouteBinaryMessage(mediaRouteId, data); } MediaRouteProviderStub.prototype.startObservingMediaSinks = function(mediaSource) { return this.delegate_ && this.delegate_.startObservingMediaSinks && this.delegate_.startObservingMediaSinks(mediaSource); } MediaRouteProviderStub.prototype.stopObservingMediaSinks = function(mediaSource) { return this.delegate_ && this.delegate_.stopObservingMediaSinks && this.delegate_.stopObservingMediaSinks(mediaSource); } MediaRouteProviderStub.prototype.startObservingMediaRoutes = function(mediaSource) { return this.delegate_ && this.delegate_.startObservingMediaRoutes && this.delegate_.startObservingMediaRoutes(mediaSource); } MediaRouteProviderStub.prototype.stopObservingMediaRoutes = function(mediaSource) { return this.delegate_ && this.delegate_.stopObservingMediaRoutes && this.delegate_.stopObservingMediaRoutes(mediaSource); } MediaRouteProviderStub.prototype.startListeningForRouteMessages = function(routeId) { return this.delegate_ && this.delegate_.startListeningForRouteMessages && this.delegate_.startListeningForRouteMessages(routeId); } MediaRouteProviderStub.prototype.stopListeningForRouteMessages = function(routeId) { return this.delegate_ && this.delegate_.stopListeningForRouteMessages && this.delegate_.stopListeningForRouteMessages(routeId); } MediaRouteProviderStub.prototype.detachRoute = function(routeId) { return this.delegate_ && this.delegate_.detachRoute && this.delegate_.detachRoute(routeId); } MediaRouteProviderStub.prototype.enableMdnsDiscovery = function() { return this.delegate_ && this.delegate_.enableMdnsDiscovery && this.delegate_.enableMdnsDiscovery(); } MediaRouteProviderStub.prototype.updateMediaSinks = function(mediaSource) { return this.delegate_ && this.delegate_.updateMediaSinks && this.delegate_.updateMediaSinks(mediaSource); } MediaRouteProviderStub.prototype.searchSinks = function(sinkId, mediaSource, searchCriteria) { return this.delegate_ && this.delegate_.searchSinks && this.delegate_.searchSinks(sinkId, mediaSource, searchCriteria); } MediaRouteProviderStub.prototype.provideSinks = function(providerName, sinks) { return this.delegate_ && this.delegate_.provideSinks && this.delegate_.provideSinks(providerName, sinks); } MediaRouteProviderStub.prototype.createMediaRouteController = function(routeId, mediaController, observer) { return this.delegate_ && this.delegate_.createMediaRouteController && this.delegate_.createMediaRouteController(routeId, mediaController, observer); } MediaRouteProviderStub.prototype.accept = function(message) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kMediaRouteProvider_SendRouteMessage_Name: var params = reader.decodeStruct(MediaRouteProvider_SendRouteMessage_Params); this.sendRouteMessage(params.mediaRouteId, params.message); return true; case kMediaRouteProvider_SendRouteBinaryMessage_Name: var params = reader.decodeStruct(MediaRouteProvider_SendRouteBinaryMessage_Params); this.sendRouteBinaryMessage(params.mediaRouteId, params.data); return true; case kMediaRouteProvider_StartObservingMediaSinks_Name: var params = reader.decodeStruct(MediaRouteProvider_StartObservingMediaSinks_Params); this.startObservingMediaSinks(params.mediaSource); return true; case kMediaRouteProvider_StopObservingMediaSinks_Name: var params = reader.decodeStruct(MediaRouteProvider_StopObservingMediaSinks_Params); this.stopObservingMediaSinks(params.mediaSource); return true; case kMediaRouteProvider_StartObservingMediaRoutes_Name: var params = reader.decodeStruct(MediaRouteProvider_StartObservingMediaRoutes_Params); this.startObservingMediaRoutes(params.mediaSource); return true; case kMediaRouteProvider_StopObservingMediaRoutes_Name: var params = reader.decodeStruct(MediaRouteProvider_StopObservingMediaRoutes_Params); this.stopObservingMediaRoutes(params.mediaSource); return true; case kMediaRouteProvider_StartListeningForRouteMessages_Name: var params = reader.decodeStruct(MediaRouteProvider_StartListeningForRouteMessages_Params); this.startListeningForRouteMessages(params.routeId); return true; case kMediaRouteProvider_StopListeningForRouteMessages_Name: var params = reader.decodeStruct(MediaRouteProvider_StopListeningForRouteMessages_Params); this.stopListeningForRouteMessages(params.routeId); return true; case kMediaRouteProvider_DetachRoute_Name: var params = reader.decodeStruct(MediaRouteProvider_DetachRoute_Params); this.detachRoute(params.routeId); return true; case kMediaRouteProvider_EnableMdnsDiscovery_Name: var params = reader.decodeStruct(MediaRouteProvider_EnableMdnsDiscovery_Params); this.enableMdnsDiscovery(); return true; case kMediaRouteProvider_UpdateMediaSinks_Name: var params = reader.decodeStruct(MediaRouteProvider_UpdateMediaSinks_Params); this.updateMediaSinks(params.mediaSource); return true; case kMediaRouteProvider_ProvideSinks_Name: var params = reader.decodeStruct(MediaRouteProvider_ProvideSinks_Params); this.provideSinks(params.providerName, params.sinks); return true; default: return false; } }; MediaRouteProviderStub.prototype.acceptWithResponder = function(message, responder) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kMediaRouteProvider_CreateRoute_Name: var params = reader.decodeStruct(MediaRouteProvider_CreateRoute_Params); this.createRoute(params.mediaSource, params.sinkId, params.originalPresentationId, params.origin, params.tabId, params.timeout, params.incognito).then(function(response) { var responseParams = new MediaRouteProvider_CreateRoute_ResponseParams(); responseParams.route = response.route; responseParams.connection = response.connection; responseParams.errorText = response.errorText; responseParams.resultCode = response.resultCode; var builder = new codec.MessageV1Builder( kMediaRouteProvider_CreateRoute_Name, codec.align(MediaRouteProvider_CreateRoute_ResponseParams.encodedSize), codec.kMessageIsResponse, reader.requestID); builder.encodeStruct(MediaRouteProvider_CreateRoute_ResponseParams, responseParams); var message = builder.finish(); responder.accept(message); }); return true; case kMediaRouteProvider_JoinRoute_Name: var params = reader.decodeStruct(MediaRouteProvider_JoinRoute_Params); this.joinRoute(params.mediaSource, params.presentationId, params.origin, params.tabId, params.timeout, params.incognito).then(function(response) { var responseParams = new MediaRouteProvider_JoinRoute_ResponseParams(); responseParams.route = response.route; responseParams.connection = response.connection; responseParams.errorText = response.errorText; responseParams.resultCode = response.resultCode; var builder = new codec.MessageV1Builder( kMediaRouteProvider_JoinRoute_Name, codec.align(MediaRouteProvider_JoinRoute_ResponseParams.encodedSize), codec.kMessageIsResponse, reader.requestID); builder.encodeStruct(MediaRouteProvider_JoinRoute_ResponseParams, responseParams); var message = builder.finish(); responder.accept(message); }); return true; case kMediaRouteProvider_ConnectRouteByRouteId_Name: var params = reader.decodeStruct(MediaRouteProvider_ConnectRouteByRouteId_Params); this.connectRouteByRouteId(params.mediaSource, params.routeId, params.presentationId, params.origin, params.tabId, params.timeout, params.incognito).then(function(response) { var responseParams = new MediaRouteProvider_ConnectRouteByRouteId_ResponseParams(); responseParams.route = response.route; responseParams.connection = response.connection; responseParams.errorText = response.errorText; responseParams.resultCode = response.resultCode; var builder = new codec.MessageV1Builder( kMediaRouteProvider_ConnectRouteByRouteId_Name, codec.align(MediaRouteProvider_ConnectRouteByRouteId_ResponseParams.encodedSize), codec.kMessageIsResponse, reader.requestID); builder.encodeStruct(MediaRouteProvider_ConnectRouteByRouteId_ResponseParams, responseParams); var message = builder.finish(); responder.accept(message); }); return true; case kMediaRouteProvider_TerminateRoute_Name: var params = reader.decodeStruct(MediaRouteProvider_TerminateRoute_Params); this.terminateRoute(params.routeId).then(function(response) { var responseParams = new MediaRouteProvider_TerminateRoute_ResponseParams(); responseParams.errorText = response.errorText; responseParams.resultCode = response.resultCode; var builder = new codec.MessageV1Builder( kMediaRouteProvider_TerminateRoute_Name, codec.align(MediaRouteProvider_TerminateRoute_ResponseParams.encodedSize), codec.kMessageIsResponse, reader.requestID); builder.encodeStruct(MediaRouteProvider_TerminateRoute_ResponseParams, responseParams); var message = builder.finish(); responder.accept(message); }); return true; case kMediaRouteProvider_SearchSinks_Name: var params = reader.decodeStruct(MediaRouteProvider_SearchSinks_Params); this.searchSinks(params.sinkId, params.mediaSource, params.searchCriteria).then(function(response) { var responseParams = new MediaRouteProvider_SearchSinks_ResponseParams(); responseParams.sinkId = response.sinkId; var builder = new codec.MessageV1Builder( kMediaRouteProvider_SearchSinks_Name, codec.align(MediaRouteProvider_SearchSinks_ResponseParams.encodedSize), codec.kMessageIsResponse, reader.requestID); builder.encodeStruct(MediaRouteProvider_SearchSinks_ResponseParams, responseParams); var message = builder.finish(); responder.accept(message); }); return true; case kMediaRouteProvider_CreateMediaRouteController_Name: var params = reader.decodeStruct(MediaRouteProvider_CreateMediaRouteController_Params); this.createMediaRouteController(params.routeId, params.mediaController, params.observer).then(function(response) { var responseParams = new MediaRouteProvider_CreateMediaRouteController_ResponseParams(); responseParams.success = response.success; var builder = new codec.MessageV1Builder( kMediaRouteProvider_CreateMediaRouteController_Name, codec.align(MediaRouteProvider_CreateMediaRouteController_ResponseParams.encodedSize), codec.kMessageIsResponse, reader.requestID); builder.encodeStruct(MediaRouteProvider_CreateMediaRouteController_ResponseParams, responseParams); var message = builder.finish(); responder.accept(message); }); return true; default: return false; } }; function validateMediaRouteProviderRequest(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kMediaRouteProvider_CreateRoute_Name: if (message.expectsResponse()) paramsClass = MediaRouteProvider_CreateRoute_Params; break; case kMediaRouteProvider_JoinRoute_Name: if (message.expectsResponse()) paramsClass = MediaRouteProvider_JoinRoute_Params; break; case kMediaRouteProvider_ConnectRouteByRouteId_Name: if (message.expectsResponse()) paramsClass = MediaRouteProvider_ConnectRouteByRouteId_Params; break; case kMediaRouteProvider_TerminateRoute_Name: if (message.expectsResponse()) paramsClass = MediaRouteProvider_TerminateRoute_Params; break; case kMediaRouteProvider_SendRouteMessage_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_SendRouteMessage_Params; break; case kMediaRouteProvider_SendRouteBinaryMessage_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_SendRouteBinaryMessage_Params; break; case kMediaRouteProvider_StartObservingMediaSinks_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_StartObservingMediaSinks_Params; break; case kMediaRouteProvider_StopObservingMediaSinks_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_StopObservingMediaSinks_Params; break; case kMediaRouteProvider_StartObservingMediaRoutes_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_StartObservingMediaRoutes_Params; break; case kMediaRouteProvider_StopObservingMediaRoutes_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_StopObservingMediaRoutes_Params; break; case kMediaRouteProvider_StartListeningForRouteMessages_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_StartListeningForRouteMessages_Params; break; case kMediaRouteProvider_StopListeningForRouteMessages_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_StopListeningForRouteMessages_Params; break; case kMediaRouteProvider_DetachRoute_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_DetachRoute_Params; break; case kMediaRouteProvider_EnableMdnsDiscovery_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_EnableMdnsDiscovery_Params; break; case kMediaRouteProvider_UpdateMediaSinks_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_UpdateMediaSinks_Params; break; case kMediaRouteProvider_SearchSinks_Name: if (message.expectsResponse()) paramsClass = MediaRouteProvider_SearchSinks_Params; break; case kMediaRouteProvider_ProvideSinks_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouteProvider_ProvideSinks_Params; break; case kMediaRouteProvider_CreateMediaRouteController_Name: if (message.expectsResponse()) paramsClass = MediaRouteProvider_CreateMediaRouteController_Params; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } function validateMediaRouteProviderResponse(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kMediaRouteProvider_CreateRoute_Name: if (message.isResponse()) paramsClass = MediaRouteProvider_CreateRoute_ResponseParams; break; case kMediaRouteProvider_JoinRoute_Name: if (message.isResponse()) paramsClass = MediaRouteProvider_JoinRoute_ResponseParams; break; case kMediaRouteProvider_ConnectRouteByRouteId_Name: if (message.isResponse()) paramsClass = MediaRouteProvider_ConnectRouteByRouteId_ResponseParams; break; case kMediaRouteProvider_TerminateRoute_Name: if (message.isResponse()) paramsClass = MediaRouteProvider_TerminateRoute_ResponseParams; break; case kMediaRouteProvider_SearchSinks_Name: if (message.isResponse()) paramsClass = MediaRouteProvider_SearchSinks_ResponseParams; break; case kMediaRouteProvider_CreateMediaRouteController_Name: if (message.isResponse()) paramsClass = MediaRouteProvider_CreateMediaRouteController_ResponseParams; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } var MediaRouteProvider = { name: 'media_router.mojom.MediaRouteProvider', kVersion: 0, ptrClass: MediaRouteProviderPtr, proxyClass: MediaRouteProviderProxy, stubClass: MediaRouteProviderStub, validateRequest: validateMediaRouteProviderRequest, validateResponse: validateMediaRouteProviderResponse, }; MediaRouteProvider.Id = {}; MediaRouteProvider.Id.EXTENSION = 0; MediaRouteProvider.Id.WIRED_DISPLAY = MediaRouteProvider.Id.EXTENSION + 1; MediaRouteProvider.Id.CAST = MediaRouteProvider.Id.WIRED_DISPLAY + 1; MediaRouteProvider.Id.DIAL = MediaRouteProvider.Id.CAST + 1; MediaRouteProvider.Id.MIN_VALUE = 0, MediaRouteProvider.Id.MAX_VALUE = 3, MediaRouteProvider.Id.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: case 3: return true; } return false; }; MediaRouteProvider.Id.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; MediaRouteProviderStub.prototype.validator = validateMediaRouteProviderRequest; MediaRouteProviderProxy.prototype.validator = validateMediaRouteProviderResponse; var kMediaRouter_RegisterMediaRouteProvider_Name = 2036946104; var kMediaRouter_OnSinksReceived_Name = 827271420; var kMediaRouter_OnIssue_Name = 827236525; var kMediaRouter_OnRoutesUpdated_Name = 989999349; var kMediaRouter_OnSinkAvailabilityUpdated_Name = 1720352158; var kMediaRouter_OnPresentationConnectionStateChanged_Name = 1747620880; var kMediaRouter_OnPresentationConnectionClosed_Name = 709584692; var kMediaRouter_OnRouteMessagesReceived_Name = 1177779868; var kMediaRouter_OnMediaRemoterCreated_Name = 1751579002; var kMediaRouter_GetMediaSinkServiceStatus_Name = 1602614509; var kMediaRouter_GetMirroringServiceHostForTab_Name = 857719955; var kMediaRouter_GetMirroringServiceHostForDesktop_Name = 357633840; var kMediaRouter_GetMirroringServiceHostForOffscreenTab_Name = 1659123763; function MediaRouterPtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(MediaRouter, handleOrPtrInfo); } function MediaRouterAssociatedPtr(associatedInterfacePtrInfo) { this.ptr = new associatedBindings.AssociatedInterfacePtrController( MediaRouter, associatedInterfacePtrInfo); } MediaRouterAssociatedPtr.prototype = Object.create(MediaRouterPtr.prototype); MediaRouterAssociatedPtr.prototype.constructor = MediaRouterAssociatedPtr; function MediaRouterProxy(receiver) { this.receiver_ = receiver; } MediaRouterPtr.prototype.registerMediaRouteProvider = function() { return MediaRouterProxy.prototype.registerMediaRouteProvider .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.registerMediaRouteProvider = function(providerId, mediaRouterProvider) { var params_ = new MediaRouter_RegisterMediaRouteProvider_Params(); params_.providerId = providerId; params_.mediaRouterProvider = mediaRouterProvider; return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kMediaRouter_RegisterMediaRouteProvider_Name, codec.align(MediaRouter_RegisterMediaRouteProvider_Params.encodedSize), codec.kMessageExpectsResponse, 0); builder.encodeStruct(MediaRouter_RegisterMediaRouteProvider_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); var responseParams = reader.decodeStruct(MediaRouter_RegisterMediaRouteProvider_ResponseParams); resolve(responseParams); }).catch(function(result) { reject(Error("Connection error: " + result)); }); }.bind(this)); }; MediaRouterPtr.prototype.onSinksReceived = function() { return MediaRouterProxy.prototype.onSinksReceived .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.onSinksReceived = function(providerId, mediaSource, sinks, origins) { var params_ = new MediaRouter_OnSinksReceived_Params(); params_.providerId = providerId; params_.mediaSource = mediaSource; params_.sinks = sinks; params_.origins = origins; var builder = new codec.MessageV0Builder( kMediaRouter_OnSinksReceived_Name, codec.align(MediaRouter_OnSinksReceived_Params.encodedSize)); builder.encodeStruct(MediaRouter_OnSinksReceived_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouterPtr.prototype.onIssue = function() { return MediaRouterProxy.prototype.onIssue .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.onIssue = function(issue) { var params_ = new MediaRouter_OnIssue_Params(); params_.issue = issue; var builder = new codec.MessageV0Builder( kMediaRouter_OnIssue_Name, codec.align(MediaRouter_OnIssue_Params.encodedSize)); builder.encodeStruct(MediaRouter_OnIssue_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouterPtr.prototype.onRoutesUpdated = function() { return MediaRouterProxy.prototype.onRoutesUpdated .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.onRoutesUpdated = function(providerId, routes, mediaSource, joinableRouteIds) { var params_ = new MediaRouter_OnRoutesUpdated_Params(); params_.providerId = providerId; params_.routes = routes; params_.mediaSource = mediaSource; params_.joinableRouteIds = joinableRouteIds; var builder = new codec.MessageV0Builder( kMediaRouter_OnRoutesUpdated_Name, codec.align(MediaRouter_OnRoutesUpdated_Params.encodedSize)); builder.encodeStruct(MediaRouter_OnRoutesUpdated_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouterPtr.prototype.onSinkAvailabilityUpdated = function() { return MediaRouterProxy.prototype.onSinkAvailabilityUpdated .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.onSinkAvailabilityUpdated = function(providerId, availability) { var params_ = new MediaRouter_OnSinkAvailabilityUpdated_Params(); params_.providerId = providerId; params_.availability = availability; var builder = new codec.MessageV0Builder( kMediaRouter_OnSinkAvailabilityUpdated_Name, codec.align(MediaRouter_OnSinkAvailabilityUpdated_Params.encodedSize)); builder.encodeStruct(MediaRouter_OnSinkAvailabilityUpdated_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouterPtr.prototype.onPresentationConnectionStateChanged = function() { return MediaRouterProxy.prototype.onPresentationConnectionStateChanged .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.onPresentationConnectionStateChanged = function(routeId, state) { var params_ = new MediaRouter_OnPresentationConnectionStateChanged_Params(); params_.routeId = routeId; params_.state = state; var builder = new codec.MessageV0Builder( kMediaRouter_OnPresentationConnectionStateChanged_Name, codec.align(MediaRouter_OnPresentationConnectionStateChanged_Params.encodedSize)); builder.encodeStruct(MediaRouter_OnPresentationConnectionStateChanged_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouterPtr.prototype.onPresentationConnectionClosed = function() { return MediaRouterProxy.prototype.onPresentationConnectionClosed .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.onPresentationConnectionClosed = function(routeId, reason, message) { var params_ = new MediaRouter_OnPresentationConnectionClosed_Params(); params_.routeId = routeId; params_.reason = reason; params_.message = message; var builder = new codec.MessageV0Builder( kMediaRouter_OnPresentationConnectionClosed_Name, codec.align(MediaRouter_OnPresentationConnectionClosed_Params.encodedSize)); builder.encodeStruct(MediaRouter_OnPresentationConnectionClosed_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouterPtr.prototype.onRouteMessagesReceived = function() { return MediaRouterProxy.prototype.onRouteMessagesReceived .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.onRouteMessagesReceived = function(routeId, messages) { var params_ = new MediaRouter_OnRouteMessagesReceived_Params(); params_.routeId = routeId; params_.messages = messages; var builder = new codec.MessageV0Builder( kMediaRouter_OnRouteMessagesReceived_Name, codec.align(MediaRouter_OnRouteMessagesReceived_Params.encodedSize)); builder.encodeStruct(MediaRouter_OnRouteMessagesReceived_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouterPtr.prototype.onMediaRemoterCreated = function() { return MediaRouterProxy.prototype.onMediaRemoterCreated .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.onMediaRemoterCreated = function(tabId, remoter, remotingSource) { var params_ = new MediaRouter_OnMediaRemoterCreated_Params(); params_.tabId = tabId; params_.remoter = remoter; params_.remotingSource = remotingSource; var builder = new codec.MessageV0Builder( kMediaRouter_OnMediaRemoterCreated_Name, codec.align(MediaRouter_OnMediaRemoterCreated_Params.encodedSize)); builder.encodeStruct(MediaRouter_OnMediaRemoterCreated_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouterPtr.prototype.getMediaSinkServiceStatus = function() { return MediaRouterProxy.prototype.getMediaSinkServiceStatus .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.getMediaSinkServiceStatus = function() { var params_ = new MediaRouter_GetMediaSinkServiceStatus_Params(); return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kMediaRouter_GetMediaSinkServiceStatus_Name, codec.align(MediaRouter_GetMediaSinkServiceStatus_Params.encodedSize), codec.kMessageExpectsResponse, 0); builder.encodeStruct(MediaRouter_GetMediaSinkServiceStatus_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); var responseParams = reader.decodeStruct(MediaRouter_GetMediaSinkServiceStatus_ResponseParams); resolve(responseParams); }).catch(function(result) { reject(Error("Connection error: " + result)); }); }.bind(this)); }; MediaRouterPtr.prototype.getMirroringServiceHostForTab = function() { return MediaRouterProxy.prototype.getMirroringServiceHostForTab .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.getMirroringServiceHostForTab = function(targetTabId, request) { var params_ = new MediaRouter_GetMirroringServiceHostForTab_Params(); params_.targetTabId = targetTabId; params_.request = request; var builder = new codec.MessageV0Builder( kMediaRouter_GetMirroringServiceHostForTab_Name, codec.align(MediaRouter_GetMirroringServiceHostForTab_Params.encodedSize)); builder.encodeStruct(MediaRouter_GetMirroringServiceHostForTab_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouterPtr.prototype.getMirroringServiceHostForDesktop = function() { return MediaRouterProxy.prototype.getMirroringServiceHostForDesktop .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.getMirroringServiceHostForDesktop = function(initiatorTabId, desktopStreamId, request) { var params_ = new MediaRouter_GetMirroringServiceHostForDesktop_Params(); params_.initiatorTabId = initiatorTabId; params_.desktopStreamId = desktopStreamId; params_.request = request; var builder = new codec.MessageV0Builder( kMediaRouter_GetMirroringServiceHostForDesktop_Name, codec.align(MediaRouter_GetMirroringServiceHostForDesktop_Params.encodedSize)); builder.encodeStruct(MediaRouter_GetMirroringServiceHostForDesktop_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MediaRouterPtr.prototype.getMirroringServiceHostForOffscreenTab = function() { return MediaRouterProxy.prototype.getMirroringServiceHostForOffscreenTab .apply(this.ptr.getProxy(), arguments); }; MediaRouterProxy.prototype.getMirroringServiceHostForOffscreenTab = function(presentationUrl, presentationId, request) { var params_ = new MediaRouter_GetMirroringServiceHostForOffscreenTab_Params(); params_.presentationUrl = presentationUrl; params_.presentationId = presentationId; params_.request = request; var builder = new codec.MessageV0Builder( kMediaRouter_GetMirroringServiceHostForOffscreenTab_Name, codec.align(MediaRouter_GetMirroringServiceHostForOffscreenTab_Params.encodedSize)); builder.encodeStruct(MediaRouter_GetMirroringServiceHostForOffscreenTab_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; function MediaRouterStub(delegate) { this.delegate_ = delegate; } MediaRouterStub.prototype.registerMediaRouteProvider = function(providerId, mediaRouterProvider) { return this.delegate_ && this.delegate_.registerMediaRouteProvider && this.delegate_.registerMediaRouteProvider(providerId, mediaRouterProvider); } MediaRouterStub.prototype.onSinksReceived = function(providerId, mediaSource, sinks, origins) { return this.delegate_ && this.delegate_.onSinksReceived && this.delegate_.onSinksReceived(providerId, mediaSource, sinks, origins); } MediaRouterStub.prototype.onIssue = function(issue) { return this.delegate_ && this.delegate_.onIssue && this.delegate_.onIssue(issue); } MediaRouterStub.prototype.onRoutesUpdated = function(providerId, routes, mediaSource, joinableRouteIds) { return this.delegate_ && this.delegate_.onRoutesUpdated && this.delegate_.onRoutesUpdated(providerId, routes, mediaSource, joinableRouteIds); } MediaRouterStub.prototype.onSinkAvailabilityUpdated = function(providerId, availability) { return this.delegate_ && this.delegate_.onSinkAvailabilityUpdated && this.delegate_.onSinkAvailabilityUpdated(providerId, availability); } MediaRouterStub.prototype.onPresentationConnectionStateChanged = function(routeId, state) { return this.delegate_ && this.delegate_.onPresentationConnectionStateChanged && this.delegate_.onPresentationConnectionStateChanged(routeId, state); } MediaRouterStub.prototype.onPresentationConnectionClosed = function(routeId, reason, message) { return this.delegate_ && this.delegate_.onPresentationConnectionClosed && this.delegate_.onPresentationConnectionClosed(routeId, reason, message); } MediaRouterStub.prototype.onRouteMessagesReceived = function(routeId, messages) { return this.delegate_ && this.delegate_.onRouteMessagesReceived && this.delegate_.onRouteMessagesReceived(routeId, messages); } MediaRouterStub.prototype.onMediaRemoterCreated = function(tabId, remoter, remotingSource) { return this.delegate_ && this.delegate_.onMediaRemoterCreated && this.delegate_.onMediaRemoterCreated(tabId, remoter, remotingSource); } MediaRouterStub.prototype.getMediaSinkServiceStatus = function() { return this.delegate_ && this.delegate_.getMediaSinkServiceStatus && this.delegate_.getMediaSinkServiceStatus(); } MediaRouterStub.prototype.getMirroringServiceHostForTab = function(targetTabId, request) { return this.delegate_ && this.delegate_.getMirroringServiceHostForTab && this.delegate_.getMirroringServiceHostForTab(targetTabId, request); } MediaRouterStub.prototype.getMirroringServiceHostForDesktop = function(initiatorTabId, desktopStreamId, request) { return this.delegate_ && this.delegate_.getMirroringServiceHostForDesktop && this.delegate_.getMirroringServiceHostForDesktop(initiatorTabId, desktopStreamId, request); } MediaRouterStub.prototype.getMirroringServiceHostForOffscreenTab = function(presentationUrl, presentationId, request) { return this.delegate_ && this.delegate_.getMirroringServiceHostForOffscreenTab && this.delegate_.getMirroringServiceHostForOffscreenTab(presentationUrl, presentationId, request); } MediaRouterStub.prototype.accept = function(message) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kMediaRouter_OnSinksReceived_Name: var params = reader.decodeStruct(MediaRouter_OnSinksReceived_Params); this.onSinksReceived(params.providerId, params.mediaSource, params.sinks, params.origins); return true; case kMediaRouter_OnIssue_Name: var params = reader.decodeStruct(MediaRouter_OnIssue_Params); this.onIssue(params.issue); return true; case kMediaRouter_OnRoutesUpdated_Name: var params = reader.decodeStruct(MediaRouter_OnRoutesUpdated_Params); this.onRoutesUpdated(params.providerId, params.routes, params.mediaSource, params.joinableRouteIds); return true; case kMediaRouter_OnSinkAvailabilityUpdated_Name: var params = reader.decodeStruct(MediaRouter_OnSinkAvailabilityUpdated_Params); this.onSinkAvailabilityUpdated(params.providerId, params.availability); return true; case kMediaRouter_OnPresentationConnectionStateChanged_Name: var params = reader.decodeStruct(MediaRouter_OnPresentationConnectionStateChanged_Params); this.onPresentationConnectionStateChanged(params.routeId, params.state); return true; case kMediaRouter_OnPresentationConnectionClosed_Name: var params = reader.decodeStruct(MediaRouter_OnPresentationConnectionClosed_Params); this.onPresentationConnectionClosed(params.routeId, params.reason, params.message); return true; case kMediaRouter_OnRouteMessagesReceived_Name: var params = reader.decodeStruct(MediaRouter_OnRouteMessagesReceived_Params); this.onRouteMessagesReceived(params.routeId, params.messages); return true; case kMediaRouter_OnMediaRemoterCreated_Name: var params = reader.decodeStruct(MediaRouter_OnMediaRemoterCreated_Params); this.onMediaRemoterCreated(params.tabId, params.remoter, params.remotingSource); return true; case kMediaRouter_GetMirroringServiceHostForTab_Name: var params = reader.decodeStruct(MediaRouter_GetMirroringServiceHostForTab_Params); this.getMirroringServiceHostForTab(params.targetTabId, params.request); return true; case kMediaRouter_GetMirroringServiceHostForDesktop_Name: var params = reader.decodeStruct(MediaRouter_GetMirroringServiceHostForDesktop_Params); this.getMirroringServiceHostForDesktop(params.initiatorTabId, params.desktopStreamId, params.request); return true; case kMediaRouter_GetMirroringServiceHostForOffscreenTab_Name: var params = reader.decodeStruct(MediaRouter_GetMirroringServiceHostForOffscreenTab_Params); this.getMirroringServiceHostForOffscreenTab(params.presentationUrl, params.presentationId, params.request); return true; default: return false; } }; MediaRouterStub.prototype.acceptWithResponder = function(message, responder) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kMediaRouter_RegisterMediaRouteProvider_Name: var params = reader.decodeStruct(MediaRouter_RegisterMediaRouteProvider_Params); this.registerMediaRouteProvider(params.providerId, params.mediaRouterProvider).then(function(response) { var responseParams = new MediaRouter_RegisterMediaRouteProvider_ResponseParams(); responseParams.instanceId = response.instanceId; responseParams.config = response.config; var builder = new codec.MessageV1Builder( kMediaRouter_RegisterMediaRouteProvider_Name, codec.align(MediaRouter_RegisterMediaRouteProvider_ResponseParams.encodedSize), codec.kMessageIsResponse, reader.requestID); builder.encodeStruct(MediaRouter_RegisterMediaRouteProvider_ResponseParams, responseParams); var message = builder.finish(); responder.accept(message); }); return true; case kMediaRouter_GetMediaSinkServiceStatus_Name: var params = reader.decodeStruct(MediaRouter_GetMediaSinkServiceStatus_Params); this.getMediaSinkServiceStatus().then(function(response) { var responseParams = new MediaRouter_GetMediaSinkServiceStatus_ResponseParams(); responseParams.status = response.status; var builder = new codec.MessageV1Builder( kMediaRouter_GetMediaSinkServiceStatus_Name, codec.align(MediaRouter_GetMediaSinkServiceStatus_ResponseParams.encodedSize), codec.kMessageIsResponse, reader.requestID); builder.encodeStruct(MediaRouter_GetMediaSinkServiceStatus_ResponseParams, responseParams); var message = builder.finish(); responder.accept(message); }); return true; default: return false; } }; function validateMediaRouterRequest(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kMediaRouter_RegisterMediaRouteProvider_Name: if (message.expectsResponse()) paramsClass = MediaRouter_RegisterMediaRouteProvider_Params; break; case kMediaRouter_OnSinksReceived_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_OnSinksReceived_Params; break; case kMediaRouter_OnIssue_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_OnIssue_Params; break; case kMediaRouter_OnRoutesUpdated_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_OnRoutesUpdated_Params; break; case kMediaRouter_OnSinkAvailabilityUpdated_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_OnSinkAvailabilityUpdated_Params; break; case kMediaRouter_OnPresentationConnectionStateChanged_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_OnPresentationConnectionStateChanged_Params; break; case kMediaRouter_OnPresentationConnectionClosed_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_OnPresentationConnectionClosed_Params; break; case kMediaRouter_OnRouteMessagesReceived_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_OnRouteMessagesReceived_Params; break; case kMediaRouter_OnMediaRemoterCreated_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_OnMediaRemoterCreated_Params; break; case kMediaRouter_GetMediaSinkServiceStatus_Name: if (message.expectsResponse()) paramsClass = MediaRouter_GetMediaSinkServiceStatus_Params; break; case kMediaRouter_GetMirroringServiceHostForTab_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_GetMirroringServiceHostForTab_Params; break; case kMediaRouter_GetMirroringServiceHostForDesktop_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_GetMirroringServiceHostForDesktop_Params; break; case kMediaRouter_GetMirroringServiceHostForOffscreenTab_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaRouter_GetMirroringServiceHostForOffscreenTab_Params; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } function validateMediaRouterResponse(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kMediaRouter_RegisterMediaRouteProvider_Name: if (message.isResponse()) paramsClass = MediaRouter_RegisterMediaRouteProvider_ResponseParams; break; case kMediaRouter_GetMediaSinkServiceStatus_Name: if (message.isResponse()) paramsClass = MediaRouter_GetMediaSinkServiceStatus_ResponseParams; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } var MediaRouter = { name: 'media_router.mojom.MediaRouter', kVersion: 0, ptrClass: MediaRouterPtr, proxyClass: MediaRouterProxy, stubClass: MediaRouterStub, validateRequest: validateMediaRouterRequest, validateResponse: validateMediaRouterResponse, }; MediaRouter.SinkAvailability = {}; MediaRouter.SinkAvailability.UNAVAILABLE = 0; MediaRouter.SinkAvailability.PER_SOURCE = MediaRouter.SinkAvailability.UNAVAILABLE + 1; MediaRouter.SinkAvailability.AVAILABLE = MediaRouter.SinkAvailability.PER_SOURCE + 1; MediaRouter.SinkAvailability.MIN_VALUE = 0, MediaRouter.SinkAvailability.MAX_VALUE = 2, MediaRouter.SinkAvailability.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: return true; } return false; }; MediaRouter.SinkAvailability.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; MediaRouter.PresentationConnectionState = {}; MediaRouter.PresentationConnectionState.CONNECTING = 0; MediaRouter.PresentationConnectionState.CONNECTED = MediaRouter.PresentationConnectionState.CONNECTING + 1; MediaRouter.PresentationConnectionState.CLOSED = MediaRouter.PresentationConnectionState.CONNECTED + 1; MediaRouter.PresentationConnectionState.TERMINATED = MediaRouter.PresentationConnectionState.CLOSED + 1; MediaRouter.PresentationConnectionState.MIN_VALUE = 0, MediaRouter.PresentationConnectionState.MAX_VALUE = 3, MediaRouter.PresentationConnectionState.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: case 3: return true; } return false; }; MediaRouter.PresentationConnectionState.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; MediaRouter.PresentationConnectionCloseReason = {}; MediaRouter.PresentationConnectionCloseReason.CONNECTION_ERROR = 0; MediaRouter.PresentationConnectionCloseReason.CLOSED = MediaRouter.PresentationConnectionCloseReason.CONNECTION_ERROR + 1; MediaRouter.PresentationConnectionCloseReason.WENT_AWAY = MediaRouter.PresentationConnectionCloseReason.CLOSED + 1; MediaRouter.PresentationConnectionCloseReason.MIN_VALUE = 0, MediaRouter.PresentationConnectionCloseReason.MAX_VALUE = 2, MediaRouter.PresentationConnectionCloseReason.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: return true; } return false; }; MediaRouter.PresentationConnectionCloseReason.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; MediaRouterStub.prototype.validator = validateMediaRouterRequest; MediaRouterProxy.prototype.validator = validateMediaRouterResponse; exports.SinkIconType = SinkIconType; exports.RouteControllerType = RouteControllerType; exports.RouteRequestResultCode = RouteRequestResultCode; exports.MediaSink = MediaSink; exports.DialMediaSink = DialMediaSink; exports.CastMediaSink = CastMediaSink; exports.MediaRoute = MediaRoute; exports.Issue = Issue; exports.RouteMessage = RouteMessage; exports.SinkSearchCriteria = SinkSearchCriteria; exports.MediaRouteProviderConfig = MediaRouteProviderConfig; exports.RoutePresentationConnection = RoutePresentationConnection; exports.MediaSinkExtraData = MediaSinkExtraData; exports.MediaRouteProvider = MediaRouteProvider; exports.MediaRouteProviderPtr = MediaRouteProviderPtr; exports.MediaRouteProviderAssociatedPtr = MediaRouteProviderAssociatedPtr; exports.MediaRouter = MediaRouter; exports.MediaRouterPtr = MediaRouterPtr; exports.MediaRouterAssociatedPtr = MediaRouterAssociatedPtr; })();// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; if ((typeof mojo === 'undefined') || !mojo.bindingsLibraryInitialized) { loadScript('mojo_bindings'); } mojo.config.autoLoadMojomDeps = false; loadScript('chrome/common/media_router/mojo/media_controller.mojom'); loadScript('chrome/common/media_router/mojo/media_router.mojom'); loadScript('chrome/common/media_router/mojo/media_status.mojom'); loadScript('components/mirroring/mojom/cast_message_channel.mojom'); loadScript('components/mirroring/mojom/mirroring_service_host.mojom'); loadScript('components/mirroring/mojom/session_observer.mojom'); loadScript('components/mirroring/mojom/session_parameters.mojom'); loadScript('extensions/common/mojo/keep_alive.mojom'); loadScript('media/mojo/interfaces/mirror_service_remoting.mojom'); loadScript('media/mojo/interfaces/remoting_common.mojom'); loadScript('mojo/public/mojom/base/time.mojom'); loadScript('mojo/public/mojom/base/unguessable_token.mojom'); loadScript('net/interfaces/ip_address.mojom'); loadScript('net/interfaces/ip_endpoint.mojom'); loadScript('url/mojom/origin.mojom'); loadScript('url/mojom/url.mojom'); // The following adapter classes preserve backward compatibility for the media // router component extension. // TODO(crbug.com/787128): Remove these adapters. function assignFields(object, fields) { for(var field in fields) { if (object.hasOwnProperty(field)) object[field] = fields[field]; } } /** * Adapter for mediaRouter.mojom.DialMediaSink. * @constructor */ function DialMediaSinkAdapter(fields) { this.ip_address = null; this.model_name = null; this.app_url = null; assignFields(this, fields); } DialMediaSinkAdapter.fromNewVersion = function(other) { return new DialMediaSinkAdapter({ 'ip_address': IPAddressAdapter.fromNewVersion(other.ipAddress), 'model_name': other.modelName, 'app_url': other.appUrl, }); }; DialMediaSinkAdapter.prototype.toNewVersion = function() { return new mediaRouter.mojom.DialMediaSink({ 'ipAddress' : this.ip_address.toNewVersion(), 'modelName' : this.model_name, 'appUrl' : this.app_url, }); }; /** * Adapter for mediaRouter.mojom.CastMediaSink. * @constructor */ function CastMediaSinkAdapter(fields) { this.ip_endpoint = null; this.model_name = null; this.capabilities = 0; this.cast_channel_id = 0; assignFields(this, fields); } CastMediaSinkAdapter.fromNewVersion = function(other) { return new CastMediaSinkAdapter({ 'ip_endpoint': IPEndpointAdapter.fromNewVersion(other.ipEndpoint), 'model_name': other.modelName, 'capabilities': other.capabilities, 'cast_channel_id': other.castChannelId, }); }; CastMediaSinkAdapter.prototype.toNewVersion = function() { return new mediaRouter.mojom.CastMediaSink({ 'ipEndpoint': this.ip_endpoint.toNewVersion(), 'modelName': this.model_name, 'capabilities': this.capabilities, 'castChannelId': this.cast_channel_id, }); }; /** * Adapter for mediaRouter.mojom.HangoutsMediaStatusExtraData. * @constructor */ function HangoutsMediaStatusExtraDataAdapter(fields) { this.local_present = false; assignFields(this, fields); } HangoutsMediaStatusExtraDataAdapter.prototype.toNewVersion = function() { return new mediaRouter.mojom.HangoutsMediaStatusExtraData({ 'localPresent': this.local_present, }); }; /** * Adapter for net.interfaces.IPAddress. * @constructor */ function IPAddressAdapter(fields) { this.address_bytes = null; assignFields(this, fields); } IPAddressAdapter.fromNewVersion = function(other) { return new IPAddressAdapter({ 'address_bytes': other.addressBytes, }); }; IPAddressAdapter.prototype.toNewVersion = function() { return new net.interfaces.IPAddress({ 'addressBytes': this.address_bytes, }); }; /** * Adapter for net.interfaces.IPEndpoint. * @constructor */ function IPEndpointAdapter(fields) { this.address = null; this.port = 0; assignFields(this, fields); } IPEndpointAdapter.fromNewVersion = function(other) { return new IPEndpointAdapter({ 'address': IPAddressAdapter.fromNewVersion(other.address), 'port': other.port, }); }; IPEndpointAdapter.prototype.toNewVersion = function() { return new net.interfaces.IPEndpoint({ 'address': this.address.toNewVersion(), 'port': this.port, }); }; /** * Adapter for mediaRouter.mojom.MediaStatus. * @constructor */ function MediaStatusAdapter(fields) { this.title = null; this.can_play_pause = false; this.can_mute = false; this.can_set_volume = false; this.can_seek = false; this.is_muted = false; this.play_state = 0; this.volume = 0; this.duration = null; this.current_time = null; this.hangouts_extra_data = null; assignFields(this, fields); } MediaStatusAdapter.PlayState = mediaRouter.mojom.MediaStatus.PlayState; MediaStatusAdapter.prototype.toNewVersion = function() { return new mediaRouter.mojom.MediaStatus({ 'title': this.title, 'canPlayPause': this.can_play_pause, 'canMute': this.can_mute, 'canSetVolume': this.can_set_volume, 'canSeek': this.can_seek, 'isMuted': this.is_muted, 'playState': this.play_state, 'volume': this.volume, 'duration': this.duration, 'currentTime': this.current_time, 'hangoutsExtraData': this.hangouts_extra_data && this.hangouts_extra_data.toNewVersion(), }); }; /** * Adapter for media.mojom.RemotingSinkMetadata. * @constructor */ function RemotingSinkMetadataAdapter(fields) { this.features = null; this.audio_capabilities = null; this.video_capabilities = null; this.friendly_name = null; assignFields(this, fields); } RemotingSinkMetadataAdapter.fromNewVersion = function(other) { return new RemotingSinkMetadataAdapter({ 'features': other.features, 'audio_capabilities': other.audioCapabilities, 'video_capabilities': other.videoCapabilities, 'friendly_name': other.friendlyName, }); }; RemotingSinkMetadataAdapter.prototype.toNewVersion = function() { return new media.mojom.RemotingSinkMetadata({ 'features': this.features, 'audioCapabilities': this.audio_capabilities, 'videoCapabilities': this.video_capabilities, 'friendlyName': this.friendly_name, }); }; /** * Adapter for mediaRouter.mojom.MediaSink. * @constructor */ function MediaSinkAdapter(fields) { this.sink_id = null; this.name = null; this.description = null; this.domain = null; this.icon_type = 0; this.extra_data = null; assignFields(this, fields); } MediaSinkAdapter.fromNewVersion = function(other) { return new MediaSinkAdapter({ 'sink_id': other.sinkId, 'name': other.name, 'description': other.description, 'domain': other.domain, 'icon_type': other.iconType, 'extra_data': other.extraData && MediaSinkExtraDataAdapter.fromNewVersion(other.extraData), }); }; MediaSinkAdapter.prototype.toNewVersion = function() { return new mediaRouter.mojom.MediaSink({ 'sinkId': this.sink_id, 'name': this.name, 'description': this.description, 'domain': this.domain, 'iconType': this.icon_type, 'extraData': this.extra_data && this.extra_data.toNewVersion(), }); }; /** * Adapter for mediaRouter.mojom.MediaSinkExtraData. * @constructor */ function MediaSinkExtraDataAdapter(value) { this.$data = null; this.$tag = undefined; if (value == undefined) { return; } var keys = Object.keys(value); if (keys.length == 0) { return; } if (keys.length > 1) { throw new TypeError('You may set only one member on a union.'); } var fields = [ 'dial_media_sink', 'cast_media_sink', ]; if (fields.indexOf(keys[0]) < 0) { throw new ReferenceError(keys[0] + ' is not a MediaSinkExtraDataAdapter member.'); } this[keys[0]] = value[keys[0]]; } MediaSinkExtraDataAdapter.Tags = { dial_media_sink: 0, cast_media_sink: 1, }; Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'dial_media_sink', { get: function() { if (this.$tag != MediaSinkExtraDataAdapter.Tags.dial_media_sink) { throw new ReferenceError( 'MediaSinkExtraDataAdapter.dial_media_sink is not currently set.'); } return this.$data; }, set: function(value) { this.$tag = MediaSinkExtraDataAdapter.Tags.dial_media_sink; this.$data = value; } }); Object.defineProperty(MediaSinkExtraDataAdapter.prototype, 'cast_media_sink', { get: function() { if (this.$tag != MediaSinkExtraDataAdapter.Tags.cast_media_sink) { throw new ReferenceError( 'MediaSinkExtraDataAdapter.cast_media_sink is not currently set.'); } return this.$data; }, set: function(value) { this.$tag = MediaSinkExtraDataAdapter.Tags.cast_media_sink; this.$data = value; } }); MediaSinkExtraDataAdapter.fromNewVersion = function(other) { if (other.$tag == mediaRouter.mojom.MediaSinkExtraData.Tags.dialMediaSink) { return new MediaSinkExtraDataAdapter({ 'dial_media_sink': DialMediaSinkAdapter.fromNewVersion(other.dialMediaSink), }); } else { return new MediaSinkExtraDataAdapter({ 'cast_media_sink': CastMediaSinkAdapter.fromNewVersion(other.castMediaSink), }); } }; MediaSinkExtraDataAdapter.prototype.toNewVersion = function() { if (this.$tag == MediaSinkExtraDataAdapter.Tags.dial_media_sink) { return new mediaRouter.mojom.MediaSinkExtraData({ 'dialMediaSink': this.dial_media_sink.toNewVersion(), }); } else { return new mediaRouter.mojom.MediaSinkExtraData({ 'castMediaSink': this.cast_media_sink.toNewVersion(), }); } }; /** * Adapter for media.mojom.MirrorServiceRemoterPtr. * @constructor */ function MirrorServiceRemoterPtrAdapter(handleOrPtrInfo) { this.ptr = new mojo.InterfacePtrController(MirrorServiceRemoterAdapter, handleOrPtrInfo); } MirrorServiceRemoterPtrAdapter.prototype = Object.create(media.mojom.MirrorServiceRemoterPtr.prototype); MirrorServiceRemoterPtrAdapter.prototype.constructor = MirrorServiceRemoterPtrAdapter; MirrorServiceRemoterPtrAdapter.prototype.startDataStreams = function() { return MirrorServiceRemoterProxy.prototype.startDataStreams .apply(this.ptr.getProxy(), arguments).then(function(response) { return Promise.resolve({ 'audio_stream_id': response.audioStreamId, 'video_stream_id': response.videoStreamId, }); }); }; /** * Adapter for media.mojom.MirrorServiceRemoter.stubclass. * @constructor */ function MirrorServiceRemoterStubAdapter(delegate) { this.delegate_ = delegate; } MirrorServiceRemoterStubAdapter.prototype = Object.create( media.mojom.MirrorServiceRemoter.stubClass.prototype); MirrorServiceRemoterStubAdapter.prototype.constructor = MirrorServiceRemoterStubAdapter; MirrorServiceRemoterStubAdapter.prototype.startDataStreams = function(hasAudio, hasVideo) { return this.delegate_ && this.delegate_.startDataStreams && this.delegate_.startDataStreams(hasAudio, hasVideo).then( function(response) { return { 'audioStreamId': response.audio_stream_id, 'videoStreamId': response.video_stream_id, }; }); }; /** * Adapter for media.mojom.MirrorServiceRemoter. */ var MirrorServiceRemoterAdapter = { name: 'media.mojom.MirrorServiceRemoter', kVersion: 0, ptrClass: MirrorServiceRemoterPtrAdapter, proxyClass: media.mojom.MirrorServiceRemoter.proxyClass, stubClass: MirrorServiceRemoterStubAdapter, validateRequest: media.mojom.MirrorServiceRemoter.validateRequest, validateResponse: media.mojom.MirrorServiceRemoter.validateResponse, }; /** * Adapter for media.mojom.MirrorServiceRemotingSourcePtr. * @constructor */ function MirrorServiceRemotingSourcePtrAdapter(handleOrPtrInfo) { this.ptr = new mojo.InterfacePtrController(MirrorServiceRemotingSourceAdapter, handleOrPtrInfo); } MirrorServiceRemotingSourcePtrAdapter.prototype = Object.create(media.mojom.MirrorServiceRemotingSourcePtr.prototype); MirrorServiceRemotingSourcePtrAdapter.prototype.constructor = MirrorServiceRemotingSourcePtrAdapter; MirrorServiceRemotingSourcePtrAdapter.prototype.onSinkAvailable = function(metadata) { return this.ptr.getProxy().onSinkAvailable(metadata.toNewVersion()); }; /** * Adapter for media.mojom.MirrorServiceRemotingSource. */ var MirrorServiceRemotingSourceAdapter = { name: 'media.mojom.MirrorServiceRemotingSource', kVersion: 0, ptrClass: MirrorServiceRemotingSourcePtrAdapter, proxyClass: media.mojom.MirrorServiceRemotingSource.proxyClass, stubClass: null, validateRequest: media.mojom.MirrorServiceRemotingSource.validateRequest, validateResponse: null, }; /** * Adapter for mediaRouter.mojom.MediaStatusObserver. * @constructor */ function MediaStatusObserverPtrAdapter(handleOrPtrInfo) { this.ptr = new mojo.InterfacePtrController(MediaStatusObserverAdapter, handleOrPtrInfo); } MediaStatusObserverPtrAdapter.prototype = Object.create(mediaRouter.mojom.MediaStatusObserverPtr.prototype); MediaStatusObserverPtrAdapter.prototype.constructor = MediaStatusObserverPtrAdapter; MediaStatusObserverPtrAdapter.prototype.onMediaStatusUpdated = function(status) { return this.ptr.getProxy().onMediaStatusUpdated(status.toNewVersion()); }; /** * Adapter for mediaRouter.mojom.MediaStatusObserver. */ var MediaStatusObserverAdapter = { name: 'mediaRouter.mojom.MediaStatusObserver', kVersion: 0, ptrClass: MediaStatusObserverPtrAdapter, proxyClass: mediaRouter.mojom.MediaStatusObserver.proxyClass, stubClass: null, validateRequest: mediaRouter.mojom.MediaStatusObserver.validateRequest, validateResponse: null, }; /** * Converts a media sink to a MediaSink Mojo object. * @param {!MediaSink} sink A media sink. * @return {!mediaRouter.mojom.MediaSink} A Mojo MediaSink object. */ function sinkToMojo_(sink) { return new mediaRouter.mojom.MediaSink({ 'name': sink.friendlyName, 'description': sink.description, 'domain': sink.domain, 'sinkId': sink.id, 'iconType': sinkIconTypeToMojo(sink.iconType), 'providerId': mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, }); } /** * Converts a media sink's icon type to a MediaSink.IconType Mojo object. * @param {!MediaSink.IconType} type A media sink's icon type. * @return {!mediaRouter.mojom.MediaSink.IconType} A Mojo MediaSink.IconType * object. */ function sinkIconTypeToMojo(type) { switch (type) { case 'cast': return mediaRouter.mojom.SinkIconType.CAST; case 'cast_audio_group': return mediaRouter.mojom.SinkIconType.CAST_AUDIO_GROUP; case 'cast_audio': return mediaRouter.mojom.SinkIconType.CAST_AUDIO; case 'meeting': return mediaRouter.mojom.SinkIconType.MEETING; case 'hangout': return mediaRouter.mojom.SinkIconType.HANGOUT; case 'education': return mediaRouter.mojom.SinkIconType.EDUCATION; case 'generic': return mediaRouter.mojom.SinkIconType.GENERIC; default: console.error('Unknown sink icon type : ' + type); return mediaRouter.mojom.SinkIconType.GENERIC; } } /** * Returns a Mojo MediaRoute object given a MediaRoute and a * media sink name. * @param {!MediaRoute} route * @return {!mediaRouter.mojom.MediaRoute} */ function routeToMojo_(route) { return new mediaRouter.mojom.MediaRoute({ 'mediaRouteId': route.id, 'mediaSource': route.mediaSource, 'mediaSinkId': route.sinkId, 'description': route.description, 'iconUrl': route.iconUrl, 'isLocal': route.isLocal, 'forDisplay': route.forDisplay, 'isIncognito': route.offTheRecord, 'isLocalPresentation': route.isOffscreenPresentation, 'controllerType': route.controllerType, // Begin newly added properties, followed by the milestone they were // added. The guard should be safe to remove N+2 milestones later. 'presentationId': route.presentationId || '' // M64 }); } /** * Converts a route message to a RouteMessage Mojo object. * @param {!RouteMessage} message * @return {!mediaRouter.mojom.RouteMessage} A Mojo RouteMessage object. */ function messageToMojo_(message) { if ("string" == typeof message.message) { return new mediaRouter.mojom.RouteMessage({ 'type': mediaRouter.mojom.RouteMessage.Type.TEXT, 'message': message.message, }); } else { return new mediaRouter.mojom.RouteMessage({ 'type': mediaRouter.mojom.RouteMessage.Type.BINARY, 'data': message.message, }); } } /** * Converts presentation connection state to Mojo enum value. * @param {!string} state * @return {!mediaRouter.mojom.MediaRouter.PresentationConnectionState} */ function presentationConnectionStateToMojo_(state) { var PresentationConnectionState = mediaRouter.mojom.MediaRouter.PresentationConnectionState; switch (state) { case 'connecting': return PresentationConnectionState.CONNECTING; case 'connected': return PresentationConnectionState.CONNECTED; case 'closed': return PresentationConnectionState.CLOSED; case 'terminated': return PresentationConnectionState.TERMINATED; default: console.error('Unknown presentation connection state: ' + state); return PresentationConnectionState.TERMINATED; } } /** * Converts presentation connection close reason to Mojo enum value. * @param {!string} reason * @return {!mediaRouter.mojom.MediaRouter.PresentationConnectionCloseReason} */ function presentationConnectionCloseReasonToMojo_(reason) { var PresentationConnectionCloseReason = mediaRouter.mojom.MediaRouter.PresentationConnectionCloseReason; switch (reason) { case 'error': return PresentationConnectionCloseReason.CONNECTION_ERROR; case 'closed': return PresentationConnectionCloseReason.CLOSED; case 'went_away': return PresentationConnectionCloseReason.WENT_AWAY; default: console.error('Unknown presentation connection close reason : ' + reason); return PresentationConnectionCloseReason.CONNECTION_ERROR; } } /** * Converts string to Mojo origin. * @param {string|!url.mojom.Origin} origin * @return {!url.mojom.Origin} */ function stringToMojoOrigin_(origin) { if (origin instanceof url.mojom.Origin) { return origin; } var originUrl = new URL(origin); var mojoOrigin = {}; mojoOrigin.scheme = originUrl.protocol.replace(':', ''); mojoOrigin.host = originUrl.hostname; var port = originUrl.port ? Number.parseInt(originUrl.port) : 0; switch (mojoOrigin.scheme) { case 'http': mojoOrigin.port = port || 80; break; case 'https': mojoOrigin.port = port || 443; break; default: throw new Error('Scheme must be http or https'); } mojoOrigin.suborigin = ''; return new url.mojom.Origin(mojoOrigin); } /** * Parses the given route request Error object and converts it to the * corresponding result code. * @param {!Error} error * @return {!mediaRouter.mojom.RouteRequestResultCode} */ function getRouteRequestResultCode_(error) { return error.errorCode ? error.errorCode : mediaRouter.mojom.RouteRequestResultCode.UNKNOWN_ERROR; } /** * Creates and returns a successful route response from given route. * @param {!MediaRoute} route * @return {!Object} */ function toSuccessRouteResponse_(route) { return { route: routeToMojo_(route), resultCode: mediaRouter.mojom.RouteRequestResultCode.OK }; } /** * Creates and returns a error route response from given Error object. * @param {!Error} error * @return {!Object} */ function toErrorRouteResponse_(error) { return { errorText: error.message, resultCode: getRouteRequestResultCode_(error) }; } /** * Creates a new MediaRouter. * Converts a route struct to its Mojo form. * @param {!mediaRouter.mojom.MediaRouterPtr} service * @constructor */ function MediaRouter(service) { /** * The Mojo service proxy. Allows extension code to call methods that reside * in the browser. * @type {!mediaRouter.mojom.MediaRouterPtr} */ this.service_ = service; /** * The provider manager service delegate. Its methods are called by the * browser-resident Mojo service. * @type {!MediaRouter} */ this.mrpm_ = new MediaRouteProvider(this); /** * Handle to a KeepAlive service object, which prevents the extension from * being suspended as long as it remains in scope. * @type {boolean} */ this.keepAlive_ = null; /** * The bindings to bind the service delegate to the Mojo interface. * Object must remain in scope for the lifetime of the connection to * prevent the connection from closing automatically. * @type {!mojo.Binding} */ this.mediaRouteProviderBinding_ = new mojo.Binding( mediaRouter.mojom.MediaRouteProvider, this.mrpm_); } /** * Returns definitions of Mojo core and generated Mojom classes that can be * used directly by the component. * @return {!Object} * TODO(imcheng): We should export these along with MediaRouter. This requires * us to modify the component to handle multiple exports. When that logic is * baked in for a couple of milestones, we should be able to remove this * method. * TODO(imcheng): We should stop exporting mojo bindings classes that the * Media Router extension doesn't directly use, such as * mojo.AssociatedInterfacePtrInfo, mojo.InterfacePtrController and * mojo.interfaceControl. */ MediaRouter.prototype.getMojoExports = function() { return { AssociatedInterfacePtrInfo: mojo.AssociatedInterfacePtrInfo, Binding: mojo.Binding, DialMediaSink: DialMediaSinkAdapter, CastMediaSink: CastMediaSinkAdapter, HangoutsMediaRouteController: mediaRouter.mojom.HangoutsMediaRouteController, HangoutsMediaStatusExtraData: HangoutsMediaStatusExtraDataAdapter, IPAddress: IPAddressAdapter, IPEndpoint: IPEndpointAdapter, InterfacePtrController: mojo.InterfacePtrController, InterfacePtrInfo: mojo.InterfacePtrInfo, InterfaceRequest: mojo.InterfaceRequest, MediaController: mediaRouter.mojom.MediaController, MediaStatus: MediaStatusAdapter, MediaStatusObserverPtr: mediaRouter.mojom.MediaStatusObserverPtr, MirroringCastMessage: mirroring.mojom.CastMessage, MirroringCastMessageChannel: mirroring.mojom.CastMessageChannel, MirroringCastMessageChannelPtr: mirroring.mojom.CastMessageChannelPtr, MirroringServiceHostPtr: mirroring.mojom.MirroringServiceHostPtr, MirroringSessionError: mirroring.mojom.SessionError, MirroringSessionObserver: mirroring.mojom.SessionObserver, MirroringSessionObserverPtr: mirroring.mojom.SessionObserverPtr, MirroringSessionParameters: mirroring.mojom.SessionParameters, MirroringSessionType: mirroring.mojom.SessionType, MirroringRemotingNamespace: mirroring.mojom.kRemotingNamespace, MirroringWebRtcNamespace: mirroring.mojom.kWebRtcNamespace, MirrorServiceRemoter: MirrorServiceRemoterAdapter, MirrorServiceRemoterPtr: MirrorServiceRemoterPtrAdapter, MirrorServiceRemotingSourcePtr: MirrorServiceRemotingSourcePtrAdapter, RemotingStopReason: media.mojom.RemotingStopReason, RemotingStartFailReason: media.mojom.RemotingStartFailReason, RemotingSinkFeature: media.mojom.RemotingSinkFeature, RemotingSinkAudioCapability: media.mojom.RemotingSinkAudioCapability, RemotingSinkVideoCapability: media.mojom.RemotingSinkVideoCapability, RemotingSinkMetadata: RemotingSinkMetadataAdapter, RouteControllerType: mediaRouter.mojom.RouteControllerType, Origin: url.mojom.Origin, Sink: MediaSinkAdapter, SinkExtraData: MediaSinkExtraDataAdapter, TimeDelta: mojoBase.mojom.TimeDelta, Url: url.mojom.Url, interfaceControl: mojo.interfaceControl, makeRequest: mojo.makeRequest, }; }; /** * Registers the Media Router Provider Manager with the Media Router. * @return {!Promise} Instance ID and config for the Media Router. */ MediaRouter.prototype.start = function() { return this.service_.registerMediaRouteProvider( mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, this.mediaRouteProviderBinding_.createInterfacePtrAndBind()).then( function(response) { return { 'instance_id': response.instanceId, 'config': { 'enable_dial_discovery': response.config.enableDialDiscovery, 'enable_cast_discovery': response.config.enableCastDiscovery, 'enable_dial_sink_query': response.config.enableDialSinkQuery, 'enable_cast_sink_query': response.config.enableCastSinkQuery, 'use_views_dialog': response.config.useViewsDialog, 'use_mirroring_service': response.config.useMirroringService, } }; }); } /** * Sets the service delegate methods. * @param {Object} handlers */ MediaRouter.prototype.setHandlers = function(handlers) { this.mrpm_.setHandlers(handlers); } /** * The keep alive status. * @return {boolean} */ MediaRouter.prototype.getKeepAlive = function() { return this.keepAlive_ != null; }; /** * Called by the provider manager when a sink list for a given source is * updated. * @param {!string} sourceUrn * @param {!Array} sinks * @param {!Array} origins */ MediaRouter.prototype.onSinksReceived = function(sourceUrn, sinks, origins) { // |origins| is a string array if the Media Router component extension version // is 59 or older. Without the stringToMojoOrigin_() conversion, clients using // those extension versions would see a crash shown in // https://crbug.com/787427. this.service_.onSinksReceived( mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, sourceUrn, sinks.map(sinkToMojo_), origins.map(stringToMojoOrigin_)); }; /** * Called by the provider manager when a sink is found to notify the MR of the * sink's ID. The actual sink will be returned through the normal sink list * update process, so this helps the MR identify the search result in the * list. * @param {string} pseudoSinkId ID of the pseudo sink that started the * search. * @param {string} sinkId ID of the newly-found sink. */ MediaRouter.prototype.onSearchSinkIdReceived = function( pseudoSinkId, sinkId) { this.service_.onSearchSinkIdReceived(pseudoSinkId, sinkId); }; /** * Called by the provider manager to keep the extension from suspending * if it enters a state where suspension is undesirable (e.g. there is an * active MediaRoute.) * If keepAlive is true, the extension is kept alive. * If keepAlive is false, the extension is allowed to suspend. * @param {boolean} keepAlive */ MediaRouter.prototype.setKeepAlive = function(keepAlive) { if (keepAlive === false && this.keepAlive_) { this.keepAlive_.ptr.reset(); this.keepAlive_ = null; } else if (keepAlive === true && !this.keepAlive_) { this.keepAlive_ = new extensions.KeepAlivePtr; Mojo.bindInterface(extensions.KeepAlive.name, mojo.makeRequest(this.keepAlive_).handle); } }; /** * Called by the provider manager to send an issue from a media route * provider to the Media Router, to show the user. * @param {!Object} issue The issue object. */ MediaRouter.prototype.onIssue = function(issue) { function issueSeverityToMojo_(severity) { switch (severity) { case 'fatal': return mediaRouter.mojom.Issue.Severity.FATAL; case 'warning': return mediaRouter.mojom.Issue.Severity.WARNING; case 'notification': return mediaRouter.mojom.Issue.Severity.NOTIFICATION; default: console.error('Unknown issue severity: ' + severity); return mediaRouter.mojom.Issue.Severity.NOTIFICATION; } } function issueActionToMojo_(action) { switch (action) { case 'dismiss': return mediaRouter.mojom.Issue.ActionType.DISMISS; case 'learn_more': return mediaRouter.mojom.Issue.ActionType.LEARN_MORE; default: console.error('Unknown issue action type : ' + action); return mediaRouter.mojom.Issue.ActionType.OK; } } var secondaryActions = (issue.secondaryActions || []).map(issueActionToMojo_); this.service_.onIssue(new mediaRouter.mojom.Issue({ 'routeId': issue.routeId || '', 'severity': issueSeverityToMojo_(issue.severity), 'title': issue.title, 'message': issue.message || '', 'defaultAction': issueActionToMojo_(issue.defaultAction), 'secondaryActions': secondaryActions, 'helpPageId': issue.helpPageId, 'isBlocking': issue.isBlocking, 'sinkId': issue.sinkId || '' })); }; /** * Called by the provider manager when the set of active routes * has been updated. * @param {!Array} routes The active set of media routes. * @param {string=} sourceUrn The sourceUrn associated with this route * query. * @param {Array=} joinableRouteIds The active set of joinable * media routes. */ MediaRouter.prototype.onRoutesUpdated = function( routes, sourceUrn = '', joinableRouteIds = []) { this.service_.onRoutesUpdated( mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, routes.map(routeToMojo_), sourceUrn, joinableRouteIds); }; /** * Called by the provider manager when sink availability has been updated. * @param {!mediaRouter.mojom.MediaRouter.SinkAvailability} availability * The new sink availability. */ MediaRouter.prototype.onSinkAvailabilityUpdated = function(availability) { this.service_.onSinkAvailabilityUpdated( mediaRouter.mojom.MediaRouteProvider.Id.EXTENSION, availability); }; /** * Called by the provider manager when the state of a presentation connected * to a route has changed. * @param {string} routeId * @param {string} state */ MediaRouter.prototype.onPresentationConnectionStateChanged = function(routeId, state) { this.service_.onPresentationConnectionStateChanged( routeId, presentationConnectionStateToMojo_(state)); }; /** * Called by the provider manager when the state of a presentation connected * to a route has closed. * @param {string} routeId * @param {string} reason * @param {string} message */ MediaRouter.prototype.onPresentationConnectionClosed = function(routeId, reason, message) { this.service_.onPresentationConnectionClosed( routeId, presentationConnectionCloseReasonToMojo_(reason), message); }; /** * @param {string} routeId * @param {!Array} mesages */ MediaRouter.prototype.onRouteMessagesReceived = function(routeId, messages) { this.service_.onRouteMessagesReceived( routeId, messages.map(messageToMojo_)); }; /** * @param {number} tabId * @param {!media.mojom.MirrorServiceRemoterPtr} remoter * @param {!mojo.InterfaceRequest} remotingSource */ MediaRouter.prototype.onMediaRemoterCreated = function(tabId, remoter, remotingSource) { this.service_.onMediaRemoterCreated( tabId, new media.mojom.MirrorServiceRemoterPtr(remoter.ptr.passInterface()), remotingSource); } /** * Returns current status of media sink service in JSON format. * @return {!Promise} */ MediaRouter.prototype.getMediaSinkServiceStatus = function() { return this.service_.getMediaSinkServiceStatus(); } /** * @param {int32} target_tab_id * @param {!mojo.InterfaceRequest} request */ MediaRouter.prototype.getMirroringServiceHostForTab = function( target_tab_id, request) { this.service_.getMirroringServiceHostForTab(target_tab_id, request); } /** * @param {int32} initiator_tab_id * @param {!string} desktop_stream_id * @param {!mojo.InterfaceRequest} request */ MediaRouter.prototype.getMirroringServiceHostForDesktop = function( initiator_tab_id, desktop_stream_id, request) { this.service_.getMirroringServiceHostForDesktop(initiator_tab_id, desktop_stream_id, request); } /** * @param {!url.mojom.Url} presentation_url * @param {!string} presentation_id * @param {!mojo.InterfaceRequest} request */ MediaRouter.prototype.getMirroringServiceHostForOffscreenTab = function( presentation_url, presentation_id, request) { this.service_.getMirroringServiceHostForOffscreenTab(presentation_url, presentation_id, request); } /** * Object containing callbacks set by the provider manager. * * @constructor * @struct */ function MediaRouterHandlers() { /** * @type {function(!string, !string, !string, !string, !number)} */ this.createRoute = null; /** * @type {function(!string, !string, !string, !number)} */ this.joinRoute = null; /** * @type {function(string): Promise} */ this.terminateRoute = null; /** * @type {function(string)} */ this.startObservingMediaSinks = null; /** * @type {function(string)} */ this.stopObservingMediaSinks = null; /** * @type {function(string, string): Promise} */ this.sendRouteMessage = null; /** * @type {function(string, Uint8Array): Promise} */ this.sendRouteBinaryMessage = null; /** * @type {function(string)} */ this.startListeningForRouteMessages = null; /** * @type {function(string)} */ this.stopListeningForRouteMessages = null; /** * @type {function(string)} */ this.detachRoute = null; /** * @type {function()} */ this.startObservingMediaRoutes = null; /** * @type {function()} */ this.stopObservingMediaRoutes = null; /** * @type {function()} */ this.connectRouteByRouteId = null; /** * @type {function()} */ this.enableMdnsDiscovery = null; /** * @type {function()} */ this.updateMediaSinks = null; /** * @type {function(string, string, !SinkSearchCriteria): string} */ this.searchSinks = null; /** * @type {function()} */ this.provideSinks = null; /** * @type {function(string, !mojo.InterfaceRequest, * !mediaRouter.mojom.MediaStatusObserverPtr): !Promise} */ this.createMediaRouteController = null; }; /** * Routes calls from Media Router to the provider manager extension. * Registered with the MediaRouter stub. * @param {!MediaRouter} MediaRouter proxy to call into the * Media Router mojo interface. * @constructor */ function MediaRouteProvider(mediaRouter) { /** * Object containing JS callbacks into Provider Manager code. * @type {!MediaRouterHandlers} */ this.handlers_ = new MediaRouterHandlers(); /** * Proxy class to the browser's Media Router Mojo service. * @type {!MediaRouter} */ this.mediaRouter_ = mediaRouter; } /* * Sets the callback handler used to invoke methods in the provider manager. * * @param {!MediaRouterHandlers} handlers */ MediaRouteProvider.prototype.setHandlers = function(handlers) { this.handlers_ = handlers; var requiredHandlers = [ 'stopObservingMediaRoutes', 'startObservingMediaRoutes', 'sendRouteMessage', 'sendRouteBinaryMessage', 'startListeningForRouteMessages', 'stopListeningForRouteMessages', 'detachRoute', 'terminateRoute', 'joinRoute', 'createRoute', 'stopObservingMediaSinks', 'startObservingMediaRoutes', 'connectRouteByRouteId', 'enableMdnsDiscovery', 'updateMediaSinks', 'searchSinks', 'provideSinks', 'createMediaRouteController', 'onBeforeInvokeHandler' ]; requiredHandlers.forEach(function(nextHandler) { if (handlers[nextHandler] === undefined) { console.error(nextHandler + ' handler not registered.'); } }); } /** * Starts querying for sinks capable of displaying the media source * designated by |sourceUrn|. Results are returned by calling * OnSinksReceived. * @param {!string} sourceUrn */ MediaRouteProvider.prototype.startObservingMediaSinks = function(sourceUrn) { this.handlers_.onBeforeInvokeHandler(); this.handlers_.startObservingMediaSinks(sourceUrn); }; /** * Stops querying for sinks capable of displaying |sourceUrn|. * @param {!string} sourceUrn */ MediaRouteProvider.prototype.stopObservingMediaSinks = function(sourceUrn) { this.handlers_.onBeforeInvokeHandler(); this.handlers_.stopObservingMediaSinks(sourceUrn); }; /** * Requests that |sinkId| render the media referenced by |sourceUrn|. If the * request is from the Presentation API, then origin and tabId will * be populated. * @param {!string} sourceUrn Media source to render. * @param {!string} sinkId Media sink ID. * @param {!string} presentationId Presentation ID from the site * requesting presentation. TODO(mfoltz): Remove. * @param {!url.mojom.Origin} origin Origin of site requesting presentation. * @param {!number} tabId ID of tab requesting presentation. * @param {!mojo_base.mojom.TimeDelta} timeout If positive, the timeout * duration for the request. Otherwise, the default duration will be used. * @param {!boolean} incognito If true, the route is being requested by * an incognito profile. * @return {!Promise.} A Promise resolving to an object describing * the newly created media route, or rejecting with an error message on * failure. */ MediaRouteProvider.prototype.createRoute = function(sourceUrn, sinkId, presentationId, origin, tabId, timeout, incognito) { this.handlers_.onBeforeInvokeHandler(); return this.handlers_.createRoute( sourceUrn, sinkId, presentationId, origin, tabId, Math.floor(timeout.microseconds / 1000), incognito) .then(function(route) { return toSuccessRouteResponse_(route); }, function(err) { return toErrorRouteResponse_(err); }); }; /** * Handles a request via the Presentation API to join an existing route given * by |sourceUrn| and |presentationId|. |origin| and |tabId| are used for * validating same-origin/tab scope. * @param {!string} sourceUrn Media source to render. * @param {!string} presentationId Presentation ID to join. * @param {!url.mojom.Origin} origin Origin of site requesting join. * @param {!number} tabId ID of tab requesting join. * @param {!mojo_base.mojom.TimeDelta} timeout If positive, the timeout * duration for the request. Otherwise, the default duration will be used. * @param {!boolean} incognito If true, the route is being requested by * an incognito profile. * @return {!Promise.} A Promise resolving to an object describing * the newly created media route, or rejecting with an error message on * failure. */ MediaRouteProvider.prototype.joinRoute = function(sourceUrn, presentationId, origin, tabId, timeout, incognito) { this.handlers_.onBeforeInvokeHandler(); return this.handlers_.joinRoute( sourceUrn, presentationId, origin, tabId, Math.floor(timeout.microseconds / 1000), incognito) .then(function(route) { return toSuccessRouteResponse_(route); }, function(err) { return toErrorRouteResponse_(err); }); }; /** * Handles a request via the Presentation API to join an existing route given * by |sourceUrn| and |routeId|. |origin| and |tabId| are used for * validating same-origin/tab scope. * @param {!string} sourceUrn Media source to render. * @param {!string} routeId Route ID to join. * @param {!string} presentationId Presentation ID to join. * @param {!url.mojom.Origin} origin Origin of site requesting join. * @param {!number} tabId ID of tab requesting join. * @param {!mojo_base.mojom.TimeDelta} timeout If positive, the timeout * duration for the request. Otherwise, the default duration will be used. * @param {!boolean} incognito If true, the route is being requested by * an incognito profile. * @return {!Promise.} A Promise resolving to an object describing * the newly created media route, or rejecting with an error message on * failure. */ MediaRouteProvider.prototype.connectRouteByRouteId = function(sourceUrn, routeId, presentationId, origin, tabId, timeout, incognito) { this.handlers_.onBeforeInvokeHandler(); return this.handlers_.connectRouteByRouteId( sourceUrn, routeId, presentationId, origin, tabId, Math.floor(timeout.microseconds / 1000), incognito) .then(function(route) { return toSuccessRouteResponse_(route); }, function(err) { return toErrorRouteResponse_(err); }); }; /** * Terminates the route specified by |routeId|. * @param {!string} routeId * @return {!Promise} A Promise resolving to an object describing * the result of the terminate operation, or rejecting with an error * message and code if the operation failed. */ MediaRouteProvider.prototype.terminateRoute = function(routeId) { this.handlers_.onBeforeInvokeHandler(); return this.handlers_.terminateRoute(routeId).then( () => ({resultCode: mediaRouter.mojom.RouteRequestResultCode.OK}), (err) => toErrorRouteResponse_(err)); }; /** * Posts a message to the route designated by |routeId|. * @param {!string} routeId * @param {!string} message */ MediaRouteProvider.prototype.sendRouteMessage = function( routeId, message) { this.handlers_.onBeforeInvokeHandler(); this.handlers_.sendRouteMessage(routeId, message); }; /** * Sends a binary message to the route designated by |routeId|. * @param {!string} routeId * @param {!Array} data */ MediaRouteProvider.prototype.sendRouteBinaryMessage = function( routeId, data) { this.handlers_.onBeforeInvokeHandler(); this.handlers_.sendRouteBinaryMessage(routeId, new Uint8Array(data)); }; /** * Listen for messages from a route. * @param {!string} routeId */ MediaRouteProvider.prototype.startListeningForRouteMessages = function( routeId) { this.handlers_.onBeforeInvokeHandler(); this.handlers_.startListeningForRouteMessages(routeId); }; /** * @param {!string} routeId */ MediaRouteProvider.prototype.stopListeningForRouteMessages = function( routeId) { this.handlers_.onBeforeInvokeHandler(); this.handlers_.stopListeningForRouteMessages(routeId); }; /** * Indicates that the presentation connection that was connected to |routeId| * is no longer connected to it. * @param {!string} routeId */ MediaRouteProvider.prototype.detachRoute = function( routeId) { this.handlers_.detachRoute(routeId); }; /** * Requests that the provider manager start sending information about active * media routes to the Media Router. * @param {!string} sourceUrn */ MediaRouteProvider.prototype.startObservingMediaRoutes = function(sourceUrn) { this.handlers_.onBeforeInvokeHandler(); this.handlers_.startObservingMediaRoutes(sourceUrn); }; /** * Requests that the provider manager stop sending information about active * media routes to the Media Router. * @param {!string} sourceUrn */ MediaRouteProvider.prototype.stopObservingMediaRoutes = function(sourceUrn) { this.handlers_.onBeforeInvokeHandler(); this.handlers_.stopObservingMediaRoutes(sourceUrn); }; /** * Enables mDNS device discovery. */ MediaRouteProvider.prototype.enableMdnsDiscovery = function() { this.handlers_.onBeforeInvokeHandler(); this.handlers_.enableMdnsDiscovery(); }; /** * Requests that the provider manager update media sinks. * @param {!string} sourceUrn */ MediaRouteProvider.prototype.updateMediaSinks = function(sourceUrn) { this.handlers_.onBeforeInvokeHandler(); this.handlers_.updateMediaSinks(sourceUrn); }; /** * Requests that the provider manager search its providers for a sink matching * |searchCriteria| that is compatible with |sourceUrn|. If a sink is found * that can be used immediately for route creation, its ID is returned. * Otherwise the empty string is returned. * * @param {string} sinkId Sink ID of the pseudo sink generating the request. * @param {string} sourceUrn Media source to be used with the sink. * @param {!SinkSearchCriteria} searchCriteria Search criteria for the route * providers. * @return {!Promise.} A Promise resolving to either the * sink ID of the sink found by the search that can be used for route * creation, or the empty string if no route can be immediately created. */ MediaRouteProvider.prototype.searchSinks = function( sinkId, sourceUrn, searchCriteria) { this.handlers_.onBeforeInvokeHandler(); return this.handlers_.searchSinks(sinkId, sourceUrn, searchCriteria).then( sinkId => { return { 'sinkId': sinkId }; }, () => { return { 'sinkId': '' }; }); }; /** * Notifies the provider manager that MediaRouter has discovered a list of * sinks. * @param {string} providerName * @param {!Array} sinks */ MediaRouteProvider.prototype.provideSinks = function(providerName, sinks) { this.handlers_.onBeforeInvokeHandler(); this.handlers_.provideSinks(providerName, sinks.map(MediaSinkAdapter.fromNewVersion)); }; /** * Creates a controller for the given route and binds the given * InterfaceRequest to it, and registers an observer for media status updates * for the route. * @param {string} routeId * @param {!mojo.InterfaceRequest} controllerRequest * @param {!mediaRouter.mojom.MediaStatusObserverPtr} observer * @return {!Promise} Resolves to true if a controller * is created. Resolves to false if a controller cannot be created, or if * the controller is already bound. */ MediaRouteProvider.prototype.createMediaRouteController = function( routeId, controllerRequest, observer) { this.handlers_.onBeforeInvokeHandler(); return this.handlers_.createMediaRouteController( routeId, controllerRequest, new MediaStatusObserverPtrAdapter(observer.ptr.passInterface())).then( () => ({success: true}), e => ({success: false})); }; var ptr = new mediaRouter.mojom.MediaRouterPtr; Mojo.bindInterface(mediaRouter.mojom.MediaRouter.name, mojo.makeRequest(ptr).handle); exports.$set('returnValue', new MediaRouter(ptr)); // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'chrome/common/media_router/mojo/media_status.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('mediaRouter.mojom'); var time$ = mojo.internal.exposeNamespace('mojoBase.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'mojo/public/mojom/base/time.mojom', '../../../../mojo/public/mojom/base/time.mojom.js'); } function MediaStatus(values) { this.initDefaults_(); this.initFields_(values); } MediaStatus.PlayState = {}; MediaStatus.PlayState.PLAYING = 0; MediaStatus.PlayState.PAUSED = MediaStatus.PlayState.PLAYING + 1; MediaStatus.PlayState.BUFFERING = MediaStatus.PlayState.PAUSED + 1; MediaStatus.PlayState.MIN_VALUE = 0, MediaStatus.PlayState.MAX_VALUE = 2, MediaStatus.PlayState.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: return true; } return false; }; MediaStatus.PlayState.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; MediaStatus.prototype.initDefaults_ = function() { this.title = null; this.canPlayPause = false; this.canMute = false; this.canSetVolume = false; this.canSeek = false; this.isMuted = false; this.playState = 0; this.volume = 0; this.duration = null; this.currentTime = null; this.hangoutsExtraData = null; }; MediaStatus.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaStatus.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 56} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaStatus.title err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate MediaStatus.playState err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 12, MediaStatus.PlayState); if (err !== validator.validationError.NONE) return err; // validate MediaStatus.duration err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, time$.TimeDelta, false); if (err !== validator.validationError.NONE) return err; // validate MediaStatus.currentTime err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 32, time$.TimeDelta, false); if (err !== validator.validationError.NONE) return err; // validate MediaStatus.hangoutsExtraData err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 40, HangoutsMediaStatusExtraData, true); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaStatus.encodedSize = codec.kStructHeaderSize + 48; MediaStatus.decode = function(decoder) { var packed; var val = new MediaStatus(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.title = decoder.decodeStruct(codec.String); packed = decoder.readUint8(); val.canPlayPause = (packed >> 0) & 1 ? true : false; val.canMute = (packed >> 1) & 1 ? true : false; val.canSetVolume = (packed >> 2) & 1 ? true : false; val.canSeek = (packed >> 3) & 1 ? true : false; val.isMuted = (packed >> 4) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); val.playState = decoder.decodeStruct(codec.Int32); val.volume = decoder.decodeStruct(codec.Float); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); val.duration = decoder.decodeStructPointer(time$.TimeDelta); val.currentTime = decoder.decodeStructPointer(time$.TimeDelta); val.hangoutsExtraData = decoder.decodeStructPointer(HangoutsMediaStatusExtraData); return val; }; MediaStatus.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaStatus.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.title); packed = 0; packed |= (val.canPlayPause & 1) << 0 packed |= (val.canMute & 1) << 1 packed |= (val.canSetVolume & 1) << 2 packed |= (val.canSeek & 1) << 3 packed |= (val.isMuted & 1) << 4 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStruct(codec.Int32, val.playState); encoder.encodeStruct(codec.Float, val.volume); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStructPointer(time$.TimeDelta, val.duration); encoder.encodeStructPointer(time$.TimeDelta, val.currentTime); encoder.encodeStructPointer(HangoutsMediaStatusExtraData, val.hangoutsExtraData); }; function HangoutsMediaStatusExtraData(values) { this.initDefaults_(); this.initFields_(values); } HangoutsMediaStatusExtraData.prototype.initDefaults_ = function() { this.localPresent = false; }; HangoutsMediaStatusExtraData.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; HangoutsMediaStatusExtraData.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; HangoutsMediaStatusExtraData.encodedSize = codec.kStructHeaderSize + 8; HangoutsMediaStatusExtraData.decode = function(decoder) { var packed; var val = new HangoutsMediaStatusExtraData(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); packed = decoder.readUint8(); val.localPresent = (packed >> 0) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; HangoutsMediaStatusExtraData.encode = function(encoder, val) { var packed; encoder.writeUint32(HangoutsMediaStatusExtraData.encodedSize); encoder.writeUint32(0); packed = 0; packed |= (val.localPresent & 1) << 0 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MediaStatusObserver_OnMediaStatusUpdated_Params(values) { this.initDefaults_(); this.initFields_(values); } MediaStatusObserver_OnMediaStatusUpdated_Params.prototype.initDefaults_ = function() { this.status = null; }; MediaStatusObserver_OnMediaStatusUpdated_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MediaStatusObserver_OnMediaStatusUpdated_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MediaStatusObserver_OnMediaStatusUpdated_Params.status err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, MediaStatus, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MediaStatusObserver_OnMediaStatusUpdated_Params.encodedSize = codec.kStructHeaderSize + 8; MediaStatusObserver_OnMediaStatusUpdated_Params.decode = function(decoder) { var packed; var val = new MediaStatusObserver_OnMediaStatusUpdated_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.status = decoder.decodeStructPointer(MediaStatus); return val; }; MediaStatusObserver_OnMediaStatusUpdated_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MediaStatusObserver_OnMediaStatusUpdated_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(MediaStatus, val.status); }; var kMediaStatusObserver_OnMediaStatusUpdated_Name = 1251989421; function MediaStatusObserverPtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(MediaStatusObserver, handleOrPtrInfo); } function MediaStatusObserverAssociatedPtr(associatedInterfacePtrInfo) { this.ptr = new associatedBindings.AssociatedInterfacePtrController( MediaStatusObserver, associatedInterfacePtrInfo); } MediaStatusObserverAssociatedPtr.prototype = Object.create(MediaStatusObserverPtr.prototype); MediaStatusObserverAssociatedPtr.prototype.constructor = MediaStatusObserverAssociatedPtr; function MediaStatusObserverProxy(receiver) { this.receiver_ = receiver; } MediaStatusObserverPtr.prototype.onMediaStatusUpdated = function() { return MediaStatusObserverProxy.prototype.onMediaStatusUpdated .apply(this.ptr.getProxy(), arguments); }; MediaStatusObserverProxy.prototype.onMediaStatusUpdated = function(status) { var params_ = new MediaStatusObserver_OnMediaStatusUpdated_Params(); params_.status = status; var builder = new codec.MessageV0Builder( kMediaStatusObserver_OnMediaStatusUpdated_Name, codec.align(MediaStatusObserver_OnMediaStatusUpdated_Params.encodedSize)); builder.encodeStruct(MediaStatusObserver_OnMediaStatusUpdated_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; function MediaStatusObserverStub(delegate) { this.delegate_ = delegate; } MediaStatusObserverStub.prototype.onMediaStatusUpdated = function(status) { return this.delegate_ && this.delegate_.onMediaStatusUpdated && this.delegate_.onMediaStatusUpdated(status); } MediaStatusObserverStub.prototype.accept = function(message) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kMediaStatusObserver_OnMediaStatusUpdated_Name: var params = reader.decodeStruct(MediaStatusObserver_OnMediaStatusUpdated_Params); this.onMediaStatusUpdated(params.status); return true; default: return false; } }; MediaStatusObserverStub.prototype.acceptWithResponder = function(message, responder) { var reader = new codec.MessageReader(message); switch (reader.messageName) { default: return false; } }; function validateMediaStatusObserverRequest(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kMediaStatusObserver_OnMediaStatusUpdated_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MediaStatusObserver_OnMediaStatusUpdated_Params; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } function validateMediaStatusObserverResponse(messageValidator) { return validator.validationError.NONE; } var MediaStatusObserver = { name: 'media_router.mojom.MediaStatusObserver', kVersion: 0, ptrClass: MediaStatusObserverPtr, proxyClass: MediaStatusObserverProxy, stubClass: MediaStatusObserverStub, validateRequest: validateMediaStatusObserverRequest, validateResponse: null, }; MediaStatusObserverStub.prototype.validator = validateMediaStatusObserverRequest; MediaStatusObserverProxy.prototype.validator = null; exports.MediaStatus = MediaStatus; exports.HangoutsMediaStatusExtraData = HangoutsMediaStatusExtraData; exports.MediaStatusObserver = MediaStatusObserver; exports.MediaStatusObserverPtr = MediaStatusObserverPtr; exports.MediaStatusObserverAssociatedPtr = MediaStatusObserverAssociatedPtr; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'components/mirroring/mojom/mirroring_service_host.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('mirroring.mojom'); var cast_message_channel$ = mojo.internal.exposeNamespace('mirroring.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'components/mirroring/mojom/cast_message_channel.mojom', 'cast_message_channel.mojom.js'); } var session_observer$ = mojo.internal.exposeNamespace('mirroring.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'components/mirroring/mojom/session_observer.mojom', 'session_observer.mojom.js'); } var session_parameters$ = mojo.internal.exposeNamespace('mirroring.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'components/mirroring/mojom/session_parameters.mojom', 'session_parameters.mojom.js'); } function MirroringServiceHost_Start_Params(values) { this.initDefaults_(); this.initFields_(values); } MirroringServiceHost_Start_Params.prototype.initDefaults_ = function() { this.params = null; this.observer = new session_observer$.SessionObserverPtr(); this.outboundChannel = new cast_message_channel$.CastMessageChannelPtr(); this.inboundChannel = new bindings.InterfaceRequest(); }; MirroringServiceHost_Start_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirroringServiceHost_Start_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 40} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MirroringServiceHost_Start_Params.params err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, session_parameters$.SessionParameters, false); if (err !== validator.validationError.NONE) return err; // validate MirroringServiceHost_Start_Params.observer err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 8, false); if (err !== validator.validationError.NONE) return err; // validate MirroringServiceHost_Start_Params.outboundChannel err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 16, false); if (err !== validator.validationError.NONE) return err; // validate MirroringServiceHost_Start_Params.inboundChannel err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 24, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirroringServiceHost_Start_Params.encodedSize = codec.kStructHeaderSize + 32; MirroringServiceHost_Start_Params.decode = function(decoder) { var packed; var val = new MirroringServiceHost_Start_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.params = decoder.decodeStructPointer(session_parameters$.SessionParameters); val.observer = decoder.decodeStruct(new codec.Interface(session_observer$.SessionObserverPtr)); val.outboundChannel = decoder.decodeStruct(new codec.Interface(cast_message_channel$.CastMessageChannelPtr)); val.inboundChannel = decoder.decodeStruct(codec.InterfaceRequest); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MirroringServiceHost_Start_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MirroringServiceHost_Start_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(session_parameters$.SessionParameters, val.params); encoder.encodeStruct(new codec.Interface(session_observer$.SessionObserverPtr), val.observer); encoder.encodeStruct(new codec.Interface(cast_message_channel$.CastMessageChannelPtr), val.outboundChannel); encoder.encodeStruct(codec.InterfaceRequest, val.inboundChannel); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; var kMirroringServiceHost_Start_Name = 534521278; function MirroringServiceHostPtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(MirroringServiceHost, handleOrPtrInfo); } function MirroringServiceHostAssociatedPtr(associatedInterfacePtrInfo) { this.ptr = new associatedBindings.AssociatedInterfacePtrController( MirroringServiceHost, associatedInterfacePtrInfo); } MirroringServiceHostAssociatedPtr.prototype = Object.create(MirroringServiceHostPtr.prototype); MirroringServiceHostAssociatedPtr.prototype.constructor = MirroringServiceHostAssociatedPtr; function MirroringServiceHostProxy(receiver) { this.receiver_ = receiver; } MirroringServiceHostPtr.prototype.start = function() { return MirroringServiceHostProxy.prototype.start .apply(this.ptr.getProxy(), arguments); }; MirroringServiceHostProxy.prototype.start = function(params, observer, outboundChannel, inboundChannel) { var params_ = new MirroringServiceHost_Start_Params(); params_.params = params; params_.observer = observer; params_.outboundChannel = outboundChannel; params_.inboundChannel = inboundChannel; var builder = new codec.MessageV0Builder( kMirroringServiceHost_Start_Name, codec.align(MirroringServiceHost_Start_Params.encodedSize)); builder.encodeStruct(MirroringServiceHost_Start_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; function MirroringServiceHostStub(delegate) { this.delegate_ = delegate; } MirroringServiceHostStub.prototype.start = function(params, observer, outboundChannel, inboundChannel) { return this.delegate_ && this.delegate_.start && this.delegate_.start(params, observer, outboundChannel, inboundChannel); } MirroringServiceHostStub.prototype.accept = function(message) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kMirroringServiceHost_Start_Name: var params = reader.decodeStruct(MirroringServiceHost_Start_Params); this.start(params.params, params.observer, params.outboundChannel, params.inboundChannel); return true; default: return false; } }; MirroringServiceHostStub.prototype.acceptWithResponder = function(message, responder) { var reader = new codec.MessageReader(message); switch (reader.messageName) { default: return false; } }; function validateMirroringServiceHostRequest(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kMirroringServiceHost_Start_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MirroringServiceHost_Start_Params; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } function validateMirroringServiceHostResponse(messageValidator) { return validator.validationError.NONE; } var MirroringServiceHost = { name: 'mirroring.mojom.MirroringServiceHost', kVersion: 0, ptrClass: MirroringServiceHostPtr, proxyClass: MirroringServiceHostProxy, stubClass: MirroringServiceHostStub, validateRequest: validateMirroringServiceHostRequest, validateResponse: null, }; MirroringServiceHostStub.prototype.validator = validateMirroringServiceHostRequest; MirroringServiceHostProxy.prototype.validator = null; exports.MirroringServiceHost = MirroringServiceHost; exports.MirroringServiceHostPtr = MirroringServiceHostPtr; exports.MirroringServiceHostAssociatedPtr = MirroringServiceHostAssociatedPtr; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'components/mirroring/mojom/cast_message_channel.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('mirroring.mojom'); var kRemotingNamespace = "urn:x-cast:com.google.cast.remoting"; var kWebRtcNamespace = "urn:x-cast:com.google.cast.webrtc"; function CastMessage(values) { this.initDefaults_(); this.initFields_(values); } CastMessage.prototype.initDefaults_ = function() { this.messageNamespace = null; this.jsonFormatData = null; }; CastMessage.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; CastMessage.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate CastMessage.messageNamespace err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate CastMessage.jsonFormatData err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; CastMessage.encodedSize = codec.kStructHeaderSize + 16; CastMessage.decode = function(decoder) { var packed; var val = new CastMessage(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.messageNamespace = decoder.decodeStruct(codec.String); val.jsonFormatData = decoder.decodeStruct(codec.String); return val; }; CastMessage.encode = function(encoder, val) { var packed; encoder.writeUint32(CastMessage.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.messageNamespace); encoder.encodeStruct(codec.String, val.jsonFormatData); }; function CastMessageChannel_Send_Params(values) { this.initDefaults_(); this.initFields_(values); } CastMessageChannel_Send_Params.prototype.initDefaults_ = function() { this.message = null; }; CastMessageChannel_Send_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; CastMessageChannel_Send_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate CastMessageChannel_Send_Params.message err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, CastMessage, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; CastMessageChannel_Send_Params.encodedSize = codec.kStructHeaderSize + 8; CastMessageChannel_Send_Params.decode = function(decoder) { var packed; var val = new CastMessageChannel_Send_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.message = decoder.decodeStructPointer(CastMessage); return val; }; CastMessageChannel_Send_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(CastMessageChannel_Send_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(CastMessage, val.message); }; var kCastMessageChannel_Send_Name = 774299308; function CastMessageChannelPtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(CastMessageChannel, handleOrPtrInfo); } function CastMessageChannelAssociatedPtr(associatedInterfacePtrInfo) { this.ptr = new associatedBindings.AssociatedInterfacePtrController( CastMessageChannel, associatedInterfacePtrInfo); } CastMessageChannelAssociatedPtr.prototype = Object.create(CastMessageChannelPtr.prototype); CastMessageChannelAssociatedPtr.prototype.constructor = CastMessageChannelAssociatedPtr; function CastMessageChannelProxy(receiver) { this.receiver_ = receiver; } CastMessageChannelPtr.prototype.send = function() { return CastMessageChannelProxy.prototype.send .apply(this.ptr.getProxy(), arguments); }; CastMessageChannelProxy.prototype.send = function(message) { var params_ = new CastMessageChannel_Send_Params(); params_.message = message; var builder = new codec.MessageV0Builder( kCastMessageChannel_Send_Name, codec.align(CastMessageChannel_Send_Params.encodedSize)); builder.encodeStruct(CastMessageChannel_Send_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; function CastMessageChannelStub(delegate) { this.delegate_ = delegate; } CastMessageChannelStub.prototype.send = function(message) { return this.delegate_ && this.delegate_.send && this.delegate_.send(message); } CastMessageChannelStub.prototype.accept = function(message) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kCastMessageChannel_Send_Name: var params = reader.decodeStruct(CastMessageChannel_Send_Params); this.send(params.message); return true; default: return false; } }; CastMessageChannelStub.prototype.acceptWithResponder = function(message, responder) { var reader = new codec.MessageReader(message); switch (reader.messageName) { default: return false; } }; function validateCastMessageChannelRequest(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kCastMessageChannel_Send_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = CastMessageChannel_Send_Params; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } function validateCastMessageChannelResponse(messageValidator) { return validator.validationError.NONE; } var CastMessageChannel = { name: 'mirroring.mojom.CastMessageChannel', kVersion: 0, ptrClass: CastMessageChannelPtr, proxyClass: CastMessageChannelProxy, stubClass: CastMessageChannelStub, validateRequest: validateCastMessageChannelRequest, validateResponse: null, }; CastMessageChannelStub.prototype.validator = validateCastMessageChannelRequest; CastMessageChannelProxy.prototype.validator = null; exports.kRemotingNamespace = kRemotingNamespace; exports.kWebRtcNamespace = kWebRtcNamespace; exports.CastMessage = CastMessage; exports.CastMessageChannel = CastMessageChannel; exports.CastMessageChannelPtr = CastMessageChannelPtr; exports.CastMessageChannelAssociatedPtr = CastMessageChannelAssociatedPtr; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'components/mirroring/mojom/session_observer.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('mirroring.mojom'); var SessionError = {}; SessionError.ANSWER_TIME_OUT = 0; SessionError.ANSWER_NOT_OK = SessionError.ANSWER_TIME_OUT + 1; SessionError.ANSWER_MISMATCHED_CAST_MODE = SessionError.ANSWER_NOT_OK + 1; SessionError.ANSWER_MISMATCHED_SSRC_LENGTH = SessionError.ANSWER_MISMATCHED_CAST_MODE + 1; SessionError.ANSWER_SELECT_MULTIPLE_AUDIO = SessionError.ANSWER_MISMATCHED_SSRC_LENGTH + 1; SessionError.ANSWER_SELECT_MULTIPLE_VIDEO = SessionError.ANSWER_SELECT_MULTIPLE_AUDIO + 1; SessionError.ANSWER_SELECT_INVALID_INDEX = SessionError.ANSWER_SELECT_MULTIPLE_VIDEO + 1; SessionError.ANSWER_NO_AUDIO_OR_VIDEO = SessionError.ANSWER_SELECT_INVALID_INDEX + 1; SessionError.AUDIO_CAPTURE_ERROR = SessionError.ANSWER_NO_AUDIO_OR_VIDEO + 1; SessionError.VIDEO_CAPTURE_ERROR = SessionError.AUDIO_CAPTURE_ERROR + 1; SessionError.RTP_STREAM_ERROR = SessionError.VIDEO_CAPTURE_ERROR + 1; SessionError.ENCODING_ERROR = SessionError.RTP_STREAM_ERROR + 1; SessionError.CAST_TRANSPORT_ERROR = SessionError.ENCODING_ERROR + 1; SessionError.MIN_VALUE = 0, SessionError.MAX_VALUE = 12, SessionError.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: return true; } return false; }; SessionError.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; function SessionObserver_OnError_Params(values) { this.initDefaults_(); this.initFields_(values); } SessionObserver_OnError_Params.prototype.initDefaults_ = function() { this.error = 0; }; SessionObserver_OnError_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; SessionObserver_OnError_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate SessionObserver_OnError_Params.error err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, SessionError); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; SessionObserver_OnError_Params.encodedSize = codec.kStructHeaderSize + 8; SessionObserver_OnError_Params.decode = function(decoder) { var packed; var val = new SessionObserver_OnError_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.error = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; SessionObserver_OnError_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(SessionObserver_OnError_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.error); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function SessionObserver_DidStart_Params(values) { this.initDefaults_(); this.initFields_(values); } SessionObserver_DidStart_Params.prototype.initDefaults_ = function() { }; SessionObserver_DidStart_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; SessionObserver_DidStart_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 8} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; SessionObserver_DidStart_Params.encodedSize = codec.kStructHeaderSize + 0; SessionObserver_DidStart_Params.decode = function(decoder) { var packed; var val = new SessionObserver_DidStart_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); return val; }; SessionObserver_DidStart_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(SessionObserver_DidStart_Params.encodedSize); encoder.writeUint32(0); }; function SessionObserver_DidStop_Params(values) { this.initDefaults_(); this.initFields_(values); } SessionObserver_DidStop_Params.prototype.initDefaults_ = function() { }; SessionObserver_DidStop_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; SessionObserver_DidStop_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 8} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; SessionObserver_DidStop_Params.encodedSize = codec.kStructHeaderSize + 0; SessionObserver_DidStop_Params.decode = function(decoder) { var packed; var val = new SessionObserver_DidStop_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); return val; }; SessionObserver_DidStop_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(SessionObserver_DidStop_Params.encodedSize); encoder.writeUint32(0); }; var kSessionObserver_OnError_Name = 1763532480; var kSessionObserver_DidStart_Name = 2054941130; var kSessionObserver_DidStop_Name = 699678780; function SessionObserverPtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(SessionObserver, handleOrPtrInfo); } function SessionObserverAssociatedPtr(associatedInterfacePtrInfo) { this.ptr = new associatedBindings.AssociatedInterfacePtrController( SessionObserver, associatedInterfacePtrInfo); } SessionObserverAssociatedPtr.prototype = Object.create(SessionObserverPtr.prototype); SessionObserverAssociatedPtr.prototype.constructor = SessionObserverAssociatedPtr; function SessionObserverProxy(receiver) { this.receiver_ = receiver; } SessionObserverPtr.prototype.onError = function() { return SessionObserverProxy.prototype.onError .apply(this.ptr.getProxy(), arguments); }; SessionObserverProxy.prototype.onError = function(error) { var params_ = new SessionObserver_OnError_Params(); params_.error = error; var builder = new codec.MessageV0Builder( kSessionObserver_OnError_Name, codec.align(SessionObserver_OnError_Params.encodedSize)); builder.encodeStruct(SessionObserver_OnError_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; SessionObserverPtr.prototype.didStart = function() { return SessionObserverProxy.prototype.didStart .apply(this.ptr.getProxy(), arguments); }; SessionObserverProxy.prototype.didStart = function() { var params_ = new SessionObserver_DidStart_Params(); var builder = new codec.MessageV0Builder( kSessionObserver_DidStart_Name, codec.align(SessionObserver_DidStart_Params.encodedSize)); builder.encodeStruct(SessionObserver_DidStart_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; SessionObserverPtr.prototype.didStop = function() { return SessionObserverProxy.prototype.didStop .apply(this.ptr.getProxy(), arguments); }; SessionObserverProxy.prototype.didStop = function() { var params_ = new SessionObserver_DidStop_Params(); var builder = new codec.MessageV0Builder( kSessionObserver_DidStop_Name, codec.align(SessionObserver_DidStop_Params.encodedSize)); builder.encodeStruct(SessionObserver_DidStop_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; function SessionObserverStub(delegate) { this.delegate_ = delegate; } SessionObserverStub.prototype.onError = function(error) { return this.delegate_ && this.delegate_.onError && this.delegate_.onError(error); } SessionObserverStub.prototype.didStart = function() { return this.delegate_ && this.delegate_.didStart && this.delegate_.didStart(); } SessionObserverStub.prototype.didStop = function() { return this.delegate_ && this.delegate_.didStop && this.delegate_.didStop(); } SessionObserverStub.prototype.accept = function(message) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kSessionObserver_OnError_Name: var params = reader.decodeStruct(SessionObserver_OnError_Params); this.onError(params.error); return true; case kSessionObserver_DidStart_Name: var params = reader.decodeStruct(SessionObserver_DidStart_Params); this.didStart(); return true; case kSessionObserver_DidStop_Name: var params = reader.decodeStruct(SessionObserver_DidStop_Params); this.didStop(); return true; default: return false; } }; SessionObserverStub.prototype.acceptWithResponder = function(message, responder) { var reader = new codec.MessageReader(message); switch (reader.messageName) { default: return false; } }; function validateSessionObserverRequest(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kSessionObserver_OnError_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = SessionObserver_OnError_Params; break; case kSessionObserver_DidStart_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = SessionObserver_DidStart_Params; break; case kSessionObserver_DidStop_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = SessionObserver_DidStop_Params; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } function validateSessionObserverResponse(messageValidator) { return validator.validationError.NONE; } var SessionObserver = { name: 'mirroring.mojom.SessionObserver', kVersion: 0, ptrClass: SessionObserverPtr, proxyClass: SessionObserverProxy, stubClass: SessionObserverStub, validateRequest: validateSessionObserverRequest, validateResponse: null, }; SessionObserverStub.prototype.validator = validateSessionObserverRequest; SessionObserverProxy.prototype.validator = null; exports.SessionError = SessionError; exports.SessionObserver = SessionObserver; exports.SessionObserverPtr = SessionObserverPtr; exports.SessionObserverAssociatedPtr = SessionObserverAssociatedPtr; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'components/mirroring/mojom/session_parameters.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('mirroring.mojom'); var ip_address$ = mojo.internal.exposeNamespace('network.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'services/network/public/mojom/ip_address.mojom', '../../../services/network/public/mojom/ip_address.mojom.js'); } var SessionType = {}; SessionType.AUDIO_ONLY = 0; SessionType.VIDEO_ONLY = SessionType.AUDIO_ONLY + 1; SessionType.AUDIO_AND_VIDEO = SessionType.VIDEO_ONLY + 1; SessionType.MIN_VALUE = 0, SessionType.MAX_VALUE = 2, SessionType.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: return true; } return false; }; SessionType.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; function SessionParameters(values) { this.initDefaults_(); this.initFields_(values); } SessionParameters.prototype.initDefaults_ = function() { this.type = 0; this.receiverAddress = null; this.receiverModelName = null; }; SessionParameters.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; SessionParameters.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 32} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate SessionParameters.type err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, SessionType); if (err !== validator.validationError.NONE) return err; // validate SessionParameters.receiverAddress err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, ip_address$.IPAddress, false); if (err !== validator.validationError.NONE) return err; // validate SessionParameters.receiverModelName err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; SessionParameters.encodedSize = codec.kStructHeaderSize + 24; SessionParameters.decode = function(decoder) { var packed; var val = new SessionParameters(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.type = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); val.receiverAddress = decoder.decodeStructPointer(ip_address$.IPAddress); val.receiverModelName = decoder.decodeStruct(codec.String); return val; }; SessionParameters.encode = function(encoder, val) { var packed; encoder.writeUint32(SessionParameters.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.type); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStructPointer(ip_address$.IPAddress, val.receiverAddress); encoder.encodeStruct(codec.String, val.receiverModelName); }; exports.SessionType = SessionType; exports.SessionParameters = SessionParameters; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'mojo/public/mojom/base/time.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('mojoBase.mojom'); function Time(values) { this.initDefaults_(); this.initFields_(values); } Time.prototype.initDefaults_ = function() { this.internalValue = 0; }; Time.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; Time.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; Time.encodedSize = codec.kStructHeaderSize + 8; Time.decode = function(decoder) { var packed; var val = new Time(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.internalValue = decoder.decodeStruct(codec.Int64); return val; }; Time.encode = function(encoder, val) { var packed; encoder.writeUint32(Time.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int64, val.internalValue); }; function TimeDelta(values) { this.initDefaults_(); this.initFields_(values); } TimeDelta.prototype.initDefaults_ = function() { this.microseconds = 0; }; TimeDelta.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; TimeDelta.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; TimeDelta.encodedSize = codec.kStructHeaderSize + 8; TimeDelta.decode = function(decoder) { var packed; var val = new TimeDelta(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.microseconds = decoder.decodeStruct(codec.Int64); return val; }; TimeDelta.encode = function(encoder, val) { var packed; encoder.writeUint32(TimeDelta.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int64, val.microseconds); }; function TimeTicks(values) { this.initDefaults_(); this.initFields_(values); } TimeTicks.prototype.initDefaults_ = function() { this.internalValue = 0; }; TimeTicks.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; TimeTicks.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; TimeTicks.encodedSize = codec.kStructHeaderSize + 8; TimeTicks.decode = function(decoder) { var packed; var val = new TimeTicks(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.internalValue = decoder.decodeStruct(codec.Int64); return val; }; TimeTicks.encode = function(encoder, val) { var packed; encoder.writeUint32(TimeTicks.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int64, val.internalValue); }; exports.Time = Time; exports.TimeDelta = TimeDelta; exports.TimeTicks = TimeTicks; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'mojo/public/mojom/base/unguessable_token.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('mojoBase.mojom'); function UnguessableToken(values) { this.initDefaults_(); this.initFields_(values); } UnguessableToken.prototype.initDefaults_ = function() { this.high = 0; this.low = 0; }; UnguessableToken.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; UnguessableToken.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; UnguessableToken.encodedSize = codec.kStructHeaderSize + 16; UnguessableToken.decode = function(decoder) { var packed; var val = new UnguessableToken(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.high = decoder.decodeStruct(codec.Uint64); val.low = decoder.decodeStruct(codec.Uint64); return val; }; UnguessableToken.encode = function(encoder, val) { var packed; encoder.writeUint32(UnguessableToken.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Uint64, val.high); encoder.encodeStruct(codec.Uint64, val.low); }; exports.UnguessableToken = UnguessableToken; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'services/network/public/mojom/ip_address.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('network.mojom'); function IPAddress(values) { this.initDefaults_(); this.initFields_(values); } IPAddress.prototype.initDefaults_ = function() { this.addressBytes = null; }; IPAddress.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; IPAddress.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate IPAddress.addressBytes err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 1, codec.Uint8, false, [0], 0); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; IPAddress.encodedSize = codec.kStructHeaderSize + 8; IPAddress.decode = function(decoder) { var packed; var val = new IPAddress(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.addressBytes = decoder.decodeArrayPointer(codec.Uint8); return val; }; IPAddress.encode = function(encoder, val) { var packed; encoder.writeUint32(IPAddress.encodedSize); encoder.writeUint32(0); encoder.encodeArrayPointer(codec.Uint8, val.addressBytes); }; exports.IPAddress = IPAddress; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'services/network/public/mojom/ip_endpoint.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('network.mojom'); var ip_address$ = mojo.internal.exposeNamespace('network.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'services/network/public/mojom/ip_address.mojom', 'ip_address.mojom.js'); } function IPEndPoint(values) { this.initDefaults_(); this.initFields_(values); } IPEndPoint.prototype.initDefaults_ = function() { this.address = null; this.port = 0; }; IPEndPoint.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; IPEndPoint.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 24} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate IPEndPoint.address err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, ip_address$.IPAddress, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; IPEndPoint.encodedSize = codec.kStructHeaderSize + 16; IPEndPoint.decode = function(decoder) { var packed; var val = new IPEndPoint(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.address = decoder.decodeStructPointer(ip_address$.IPAddress); val.port = decoder.decodeStruct(codec.Uint16); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; IPEndPoint.encode = function(encoder, val) { var packed; encoder.writeUint32(IPEndPoint.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(ip_address$.IPAddress, val.address); encoder.encodeStruct(codec.Uint16, val.port); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; exports.IPEndPoint = IPEndPoint; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'url/mojom/origin.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('url.mojom'); var unguessable_token$ = mojo.internal.exposeNamespace('mojoBase.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'mojo/public/mojom/base/unguessable_token.mojom', '../../mojo/public/mojom/base/unguessable_token.mojom.js'); } function Origin(values) { this.initDefaults_(); this.initFields_(values); } Origin.prototype.initDefaults_ = function() { this.scheme = null; this.host = null; this.port = 0; this.nonceIfOpaque = null; }; Origin.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; Origin.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 40} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate Origin.scheme err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; // validate Origin.host err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) if (err !== validator.validationError.NONE) return err; // validate Origin.nonceIfOpaque err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, unguessable_token$.UnguessableToken, true); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; Origin.encodedSize = codec.kStructHeaderSize + 32; Origin.decode = function(decoder) { var packed; var val = new Origin(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.scheme = decoder.decodeStruct(codec.String); val.host = decoder.decodeStruct(codec.String); val.port = decoder.decodeStruct(codec.Uint16); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); val.nonceIfOpaque = decoder.decodeStructPointer(unguessable_token$.UnguessableToken); return val; }; Origin.encode = function(encoder, val) { var packed; encoder.writeUint32(Origin.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.scheme); encoder.encodeStruct(codec.String, val.host); encoder.encodeStruct(codec.Uint16, val.port); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.encodeStructPointer(unguessable_token$.UnguessableToken, val.nonceIfOpaque); }; exports.Origin = Origin; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'url/mojom/url.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('url.mojom'); function Url(values) { this.initDefaults_(); this.initFields_(values); } Url.prototype.initDefaults_ = function() { this.url = null; }; Url.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; Url.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate Url.url err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; Url.encodedSize = codec.kStructHeaderSize + 8; Url.decode = function(decoder) { var packed; var val = new Url(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.url = decoder.decodeStruct(codec.String); return val; }; Url.encode = function(encoder, val) { var packed; encoder.writeUint32(Url.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.String, val.url); }; exports.Url = Url; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'media/mojo/interfaces/mirror_service_remoting.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('media.mojom'); var remoting_common$ = mojo.internal.exposeNamespace('media.mojom'); if (mojo.config.autoLoadMojomDeps) { mojo.internal.loadMojomIfNecessary( 'media/mojo/interfaces/remoting_common.mojom', 'remoting_common.mojom.js'); } function MirrorServiceRemoter_Start_Params(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemoter_Start_Params.prototype.initDefaults_ = function() { }; MirrorServiceRemoter_Start_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemoter_Start_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 8} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemoter_Start_Params.encodedSize = codec.kStructHeaderSize + 0; MirrorServiceRemoter_Start_Params.decode = function(decoder) { var packed; var val = new MirrorServiceRemoter_Start_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); return val; }; MirrorServiceRemoter_Start_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemoter_Start_Params.encodedSize); encoder.writeUint32(0); }; function MirrorServiceRemoter_StartDataStreams_Params(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemoter_StartDataStreams_Params.prototype.initDefaults_ = function() { this.hasAudio = false; this.hasVideo = false; }; MirrorServiceRemoter_StartDataStreams_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemoter_StartDataStreams_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemoter_StartDataStreams_Params.encodedSize = codec.kStructHeaderSize + 8; MirrorServiceRemoter_StartDataStreams_Params.decode = function(decoder) { var packed; var val = new MirrorServiceRemoter_StartDataStreams_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); packed = decoder.readUint8(); val.hasAudio = (packed >> 0) & 1 ? true : false; val.hasVideo = (packed >> 1) & 1 ? true : false; decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MirrorServiceRemoter_StartDataStreams_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemoter_StartDataStreams_Params.encodedSize); encoder.writeUint32(0); packed = 0; packed |= (val.hasAudio & 1) << 0 packed |= (val.hasVideo & 1) << 1 encoder.writeUint8(packed); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MirrorServiceRemoter_StartDataStreams_ResponseParams(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemoter_StartDataStreams_ResponseParams.prototype.initDefaults_ = function() { this.audioStreamId = 0; this.videoStreamId = 0; }; MirrorServiceRemoter_StartDataStreams_ResponseParams.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemoter_StartDataStreams_ResponseParams.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemoter_StartDataStreams_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; MirrorServiceRemoter_StartDataStreams_ResponseParams.decode = function(decoder) { var packed; var val = new MirrorServiceRemoter_StartDataStreams_ResponseParams(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.audioStreamId = decoder.decodeStruct(codec.Int32); val.videoStreamId = decoder.decodeStruct(codec.Int32); return val; }; MirrorServiceRemoter_StartDataStreams_ResponseParams.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemoter_StartDataStreams_ResponseParams.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.audioStreamId); encoder.encodeStruct(codec.Int32, val.videoStreamId); }; function MirrorServiceRemoter_Stop_Params(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemoter_Stop_Params.prototype.initDefaults_ = function() { this.reason = 0; }; MirrorServiceRemoter_Stop_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemoter_Stop_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MirrorServiceRemoter_Stop_Params.reason err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, remoting_common$.RemotingStopReason); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemoter_Stop_Params.encodedSize = codec.kStructHeaderSize + 8; MirrorServiceRemoter_Stop_Params.decode = function(decoder) { var packed; var val = new MirrorServiceRemoter_Stop_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.reason = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MirrorServiceRemoter_Stop_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemoter_Stop_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.reason); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MirrorServiceRemoter_SendMessageToSink_Params(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemoter_SendMessageToSink_Params.prototype.initDefaults_ = function() { this.message = null; }; MirrorServiceRemoter_SendMessageToSink_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemoter_SendMessageToSink_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MirrorServiceRemoter_SendMessageToSink_Params.message err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 1, codec.Uint8, false, [0], 0); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemoter_SendMessageToSink_Params.encodedSize = codec.kStructHeaderSize + 8; MirrorServiceRemoter_SendMessageToSink_Params.decode = function(decoder) { var packed; var val = new MirrorServiceRemoter_SendMessageToSink_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.message = decoder.decodeArrayPointer(codec.Uint8); return val; }; MirrorServiceRemoter_SendMessageToSink_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemoter_SendMessageToSink_Params.encodedSize); encoder.writeUint32(0); encoder.encodeArrayPointer(codec.Uint8, val.message); }; function MirrorServiceRemoter_EstimateTransmissionCapacity_Params(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemoter_EstimateTransmissionCapacity_Params.prototype.initDefaults_ = function() { }; MirrorServiceRemoter_EstimateTransmissionCapacity_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemoter_EstimateTransmissionCapacity_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 8} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemoter_EstimateTransmissionCapacity_Params.encodedSize = codec.kStructHeaderSize + 0; MirrorServiceRemoter_EstimateTransmissionCapacity_Params.decode = function(decoder) { var packed; var val = new MirrorServiceRemoter_EstimateTransmissionCapacity_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); return val; }; MirrorServiceRemoter_EstimateTransmissionCapacity_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemoter_EstimateTransmissionCapacity_Params.encodedSize); encoder.writeUint32(0); }; function MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.prototype.initDefaults_ = function() { this.rate = 0; }; MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.decode = function(decoder) { var packed; var val = new MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.rate = decoder.decodeStruct(codec.Double); return val; }; MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Double, val.rate); }; function MirrorServiceRemotingSource_OnSinkAvailable_Params(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemotingSource_OnSinkAvailable_Params.prototype.initDefaults_ = function() { this.metadata = null; }; MirrorServiceRemotingSource_OnSinkAvailable_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemotingSource_OnSinkAvailable_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MirrorServiceRemotingSource_OnSinkAvailable_Params.metadata err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, remoting_common$.RemotingSinkMetadata, false); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemotingSource_OnSinkAvailable_Params.encodedSize = codec.kStructHeaderSize + 8; MirrorServiceRemotingSource_OnSinkAvailable_Params.decode = function(decoder) { var packed; var val = new MirrorServiceRemotingSource_OnSinkAvailable_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.metadata = decoder.decodeStructPointer(remoting_common$.RemotingSinkMetadata); return val; }; MirrorServiceRemotingSource_OnSinkAvailable_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemotingSource_OnSinkAvailable_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStructPointer(remoting_common$.RemotingSinkMetadata, val.metadata); }; function MirrorServiceRemotingSource_OnMessageFromSink_Params(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemotingSource_OnMessageFromSink_Params.prototype.initDefaults_ = function() { this.message = null; }; MirrorServiceRemotingSource_OnMessageFromSink_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemotingSource_OnMessageFromSink_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MirrorServiceRemotingSource_OnMessageFromSink_Params.message err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 1, codec.Uint8, false, [0], 0); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemotingSource_OnMessageFromSink_Params.encodedSize = codec.kStructHeaderSize + 8; MirrorServiceRemotingSource_OnMessageFromSink_Params.decode = function(decoder) { var packed; var val = new MirrorServiceRemotingSource_OnMessageFromSink_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.message = decoder.decodeArrayPointer(codec.Uint8); return val; }; MirrorServiceRemotingSource_OnMessageFromSink_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemotingSource_OnMessageFromSink_Params.encodedSize); encoder.writeUint32(0); encoder.encodeArrayPointer(codec.Uint8, val.message); }; function MirrorServiceRemotingSource_OnStopped_Params(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemotingSource_OnStopped_Params.prototype.initDefaults_ = function() { this.reason = 0; }; MirrorServiceRemotingSource_OnStopped_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemotingSource_OnStopped_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 16} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate MirrorServiceRemotingSource_OnStopped_Params.reason err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, remoting_common$.RemotingStopReason); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemotingSource_OnStopped_Params.encodedSize = codec.kStructHeaderSize + 8; MirrorServiceRemotingSource_OnStopped_Params.decode = function(decoder) { var packed; var val = new MirrorServiceRemotingSource_OnStopped_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.reason = decoder.decodeStruct(codec.Int32); decoder.skip(1); decoder.skip(1); decoder.skip(1); decoder.skip(1); return val; }; MirrorServiceRemotingSource_OnStopped_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemotingSource_OnStopped_Params.encodedSize); encoder.writeUint32(0); encoder.encodeStruct(codec.Int32, val.reason); encoder.skip(1); encoder.skip(1); encoder.skip(1); encoder.skip(1); }; function MirrorServiceRemotingSource_OnError_Params(values) { this.initDefaults_(); this.initFields_(values); } MirrorServiceRemotingSource_OnError_Params.prototype.initDefaults_ = function() { }; MirrorServiceRemotingSource_OnError_Params.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; MirrorServiceRemotingSource_OnError_Params.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 8} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; MirrorServiceRemotingSource_OnError_Params.encodedSize = codec.kStructHeaderSize + 0; MirrorServiceRemotingSource_OnError_Params.decode = function(decoder) { var packed; var val = new MirrorServiceRemotingSource_OnError_Params(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); return val; }; MirrorServiceRemotingSource_OnError_Params.encode = function(encoder, val) { var packed; encoder.writeUint32(MirrorServiceRemotingSource_OnError_Params.encodedSize); encoder.writeUint32(0); }; var kMirrorServiceRemoter_Start_Name = 864384739; var kMirrorServiceRemoter_StartDataStreams_Name = 1555654096; var kMirrorServiceRemoter_Stop_Name = 622551634; var kMirrorServiceRemoter_SendMessageToSink_Name = 1961057848; var kMirrorServiceRemoter_EstimateTransmissionCapacity_Name = 1419162000; function MirrorServiceRemoterPtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(MirrorServiceRemoter, handleOrPtrInfo); } function MirrorServiceRemoterAssociatedPtr(associatedInterfacePtrInfo) { this.ptr = new associatedBindings.AssociatedInterfacePtrController( MirrorServiceRemoter, associatedInterfacePtrInfo); } MirrorServiceRemoterAssociatedPtr.prototype = Object.create(MirrorServiceRemoterPtr.prototype); MirrorServiceRemoterAssociatedPtr.prototype.constructor = MirrorServiceRemoterAssociatedPtr; function MirrorServiceRemoterProxy(receiver) { this.receiver_ = receiver; } MirrorServiceRemoterPtr.prototype.start = function() { return MirrorServiceRemoterProxy.prototype.start .apply(this.ptr.getProxy(), arguments); }; MirrorServiceRemoterProxy.prototype.start = function() { var params_ = new MirrorServiceRemoter_Start_Params(); var builder = new codec.MessageV0Builder( kMirrorServiceRemoter_Start_Name, codec.align(MirrorServiceRemoter_Start_Params.encodedSize)); builder.encodeStruct(MirrorServiceRemoter_Start_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MirrorServiceRemoterPtr.prototype.startDataStreams = function() { return MirrorServiceRemoterProxy.prototype.startDataStreams .apply(this.ptr.getProxy(), arguments); }; MirrorServiceRemoterProxy.prototype.startDataStreams = function(hasAudio, hasVideo) { var params_ = new MirrorServiceRemoter_StartDataStreams_Params(); params_.hasAudio = hasAudio; params_.hasVideo = hasVideo; return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kMirrorServiceRemoter_StartDataStreams_Name, codec.align(MirrorServiceRemoter_StartDataStreams_Params.encodedSize), codec.kMessageExpectsResponse, 0); builder.encodeStruct(MirrorServiceRemoter_StartDataStreams_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); var responseParams = reader.decodeStruct(MirrorServiceRemoter_StartDataStreams_ResponseParams); resolve(responseParams); }).catch(function(result) { reject(Error("Connection error: " + result)); }); }.bind(this)); }; MirrorServiceRemoterPtr.prototype.stop = function() { return MirrorServiceRemoterProxy.prototype.stop .apply(this.ptr.getProxy(), arguments); }; MirrorServiceRemoterProxy.prototype.stop = function(reason) { var params_ = new MirrorServiceRemoter_Stop_Params(); params_.reason = reason; var builder = new codec.MessageV0Builder( kMirrorServiceRemoter_Stop_Name, codec.align(MirrorServiceRemoter_Stop_Params.encodedSize)); builder.encodeStruct(MirrorServiceRemoter_Stop_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MirrorServiceRemoterPtr.prototype.sendMessageToSink = function() { return MirrorServiceRemoterProxy.prototype.sendMessageToSink .apply(this.ptr.getProxy(), arguments); }; MirrorServiceRemoterProxy.prototype.sendMessageToSink = function(message) { var params_ = new MirrorServiceRemoter_SendMessageToSink_Params(); params_.message = message; var builder = new codec.MessageV0Builder( kMirrorServiceRemoter_SendMessageToSink_Name, codec.align(MirrorServiceRemoter_SendMessageToSink_Params.encodedSize)); builder.encodeStruct(MirrorServiceRemoter_SendMessageToSink_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MirrorServiceRemoterPtr.prototype.estimateTransmissionCapacity = function() { return MirrorServiceRemoterProxy.prototype.estimateTransmissionCapacity .apply(this.ptr.getProxy(), arguments); }; MirrorServiceRemoterProxy.prototype.estimateTransmissionCapacity = function() { var params_ = new MirrorServiceRemoter_EstimateTransmissionCapacity_Params(); return new Promise(function(resolve, reject) { var builder = new codec.MessageV1Builder( kMirrorServiceRemoter_EstimateTransmissionCapacity_Name, codec.align(MirrorServiceRemoter_EstimateTransmissionCapacity_Params.encodedSize), codec.kMessageExpectsResponse, 0); builder.encodeStruct(MirrorServiceRemoter_EstimateTransmissionCapacity_Params, params_); var message = builder.finish(); this.receiver_.acceptAndExpectResponse(message).then(function(message) { var reader = new codec.MessageReader(message); var responseParams = reader.decodeStruct(MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams); resolve(responseParams); }).catch(function(result) { reject(Error("Connection error: " + result)); }); }.bind(this)); }; function MirrorServiceRemoterStub(delegate) { this.delegate_ = delegate; } MirrorServiceRemoterStub.prototype.start = function() { return this.delegate_ && this.delegate_.start && this.delegate_.start(); } MirrorServiceRemoterStub.prototype.startDataStreams = function(hasAudio, hasVideo) { return this.delegate_ && this.delegate_.startDataStreams && this.delegate_.startDataStreams(hasAudio, hasVideo); } MirrorServiceRemoterStub.prototype.stop = function(reason) { return this.delegate_ && this.delegate_.stop && this.delegate_.stop(reason); } MirrorServiceRemoterStub.prototype.sendMessageToSink = function(message) { return this.delegate_ && this.delegate_.sendMessageToSink && this.delegate_.sendMessageToSink(message); } MirrorServiceRemoterStub.prototype.estimateTransmissionCapacity = function() { return this.delegate_ && this.delegate_.estimateTransmissionCapacity && this.delegate_.estimateTransmissionCapacity(); } MirrorServiceRemoterStub.prototype.accept = function(message) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kMirrorServiceRemoter_Start_Name: var params = reader.decodeStruct(MirrorServiceRemoter_Start_Params); this.start(); return true; case kMirrorServiceRemoter_Stop_Name: var params = reader.decodeStruct(MirrorServiceRemoter_Stop_Params); this.stop(params.reason); return true; case kMirrorServiceRemoter_SendMessageToSink_Name: var params = reader.decodeStruct(MirrorServiceRemoter_SendMessageToSink_Params); this.sendMessageToSink(params.message); return true; default: return false; } }; MirrorServiceRemoterStub.prototype.acceptWithResponder = function(message, responder) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kMirrorServiceRemoter_StartDataStreams_Name: var params = reader.decodeStruct(MirrorServiceRemoter_StartDataStreams_Params); this.startDataStreams(params.hasAudio, params.hasVideo).then(function(response) { var responseParams = new MirrorServiceRemoter_StartDataStreams_ResponseParams(); responseParams.audioStreamId = response.audioStreamId; responseParams.videoStreamId = response.videoStreamId; var builder = new codec.MessageV1Builder( kMirrorServiceRemoter_StartDataStreams_Name, codec.align(MirrorServiceRemoter_StartDataStreams_ResponseParams.encodedSize), codec.kMessageIsResponse, reader.requestID); builder.encodeStruct(MirrorServiceRemoter_StartDataStreams_ResponseParams, responseParams); var message = builder.finish(); responder.accept(message); }); return true; case kMirrorServiceRemoter_EstimateTransmissionCapacity_Name: var params = reader.decodeStruct(MirrorServiceRemoter_EstimateTransmissionCapacity_Params); this.estimateTransmissionCapacity().then(function(response) { var responseParams = new MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams(); responseParams.rate = response.rate; var builder = new codec.MessageV1Builder( kMirrorServiceRemoter_EstimateTransmissionCapacity_Name, codec.align(MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams.encodedSize), codec.kMessageIsResponse, reader.requestID); builder.encodeStruct(MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams, responseParams); var message = builder.finish(); responder.accept(message); }); return true; default: return false; } }; function validateMirrorServiceRemoterRequest(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kMirrorServiceRemoter_Start_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MirrorServiceRemoter_Start_Params; break; case kMirrorServiceRemoter_StartDataStreams_Name: if (message.expectsResponse()) paramsClass = MirrorServiceRemoter_StartDataStreams_Params; break; case kMirrorServiceRemoter_Stop_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MirrorServiceRemoter_Stop_Params; break; case kMirrorServiceRemoter_SendMessageToSink_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MirrorServiceRemoter_SendMessageToSink_Params; break; case kMirrorServiceRemoter_EstimateTransmissionCapacity_Name: if (message.expectsResponse()) paramsClass = MirrorServiceRemoter_EstimateTransmissionCapacity_Params; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } function validateMirrorServiceRemoterResponse(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kMirrorServiceRemoter_StartDataStreams_Name: if (message.isResponse()) paramsClass = MirrorServiceRemoter_StartDataStreams_ResponseParams; break; case kMirrorServiceRemoter_EstimateTransmissionCapacity_Name: if (message.isResponse()) paramsClass = MirrorServiceRemoter_EstimateTransmissionCapacity_ResponseParams; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } var MirrorServiceRemoter = { name: 'media.mojom.MirrorServiceRemoter', kVersion: 0, ptrClass: MirrorServiceRemoterPtr, proxyClass: MirrorServiceRemoterProxy, stubClass: MirrorServiceRemoterStub, validateRequest: validateMirrorServiceRemoterRequest, validateResponse: validateMirrorServiceRemoterResponse, }; MirrorServiceRemoterStub.prototype.validator = validateMirrorServiceRemoterRequest; MirrorServiceRemoterProxy.prototype.validator = validateMirrorServiceRemoterResponse; var kMirrorServiceRemotingSource_OnSinkAvailable_Name = 341337265; var kMirrorServiceRemotingSource_OnMessageFromSink_Name = 1727300331; var kMirrorServiceRemotingSource_OnStopped_Name = 826958995; var kMirrorServiceRemotingSource_OnError_Name = 441783253; function MirrorServiceRemotingSourcePtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(MirrorServiceRemotingSource, handleOrPtrInfo); } function MirrorServiceRemotingSourceAssociatedPtr(associatedInterfacePtrInfo) { this.ptr = new associatedBindings.AssociatedInterfacePtrController( MirrorServiceRemotingSource, associatedInterfacePtrInfo); } MirrorServiceRemotingSourceAssociatedPtr.prototype = Object.create(MirrorServiceRemotingSourcePtr.prototype); MirrorServiceRemotingSourceAssociatedPtr.prototype.constructor = MirrorServiceRemotingSourceAssociatedPtr; function MirrorServiceRemotingSourceProxy(receiver) { this.receiver_ = receiver; } MirrorServiceRemotingSourcePtr.prototype.onSinkAvailable = function() { return MirrorServiceRemotingSourceProxy.prototype.onSinkAvailable .apply(this.ptr.getProxy(), arguments); }; MirrorServiceRemotingSourceProxy.prototype.onSinkAvailable = function(metadata) { var params_ = new MirrorServiceRemotingSource_OnSinkAvailable_Params(); params_.metadata = metadata; var builder = new codec.MessageV0Builder( kMirrorServiceRemotingSource_OnSinkAvailable_Name, codec.align(MirrorServiceRemotingSource_OnSinkAvailable_Params.encodedSize)); builder.encodeStruct(MirrorServiceRemotingSource_OnSinkAvailable_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MirrorServiceRemotingSourcePtr.prototype.onMessageFromSink = function() { return MirrorServiceRemotingSourceProxy.prototype.onMessageFromSink .apply(this.ptr.getProxy(), arguments); }; MirrorServiceRemotingSourceProxy.prototype.onMessageFromSink = function(message) { var params_ = new MirrorServiceRemotingSource_OnMessageFromSink_Params(); params_.message = message; var builder = new codec.MessageV0Builder( kMirrorServiceRemotingSource_OnMessageFromSink_Name, codec.align(MirrorServiceRemotingSource_OnMessageFromSink_Params.encodedSize)); builder.encodeStruct(MirrorServiceRemotingSource_OnMessageFromSink_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MirrorServiceRemotingSourcePtr.prototype.onStopped = function() { return MirrorServiceRemotingSourceProxy.prototype.onStopped .apply(this.ptr.getProxy(), arguments); }; MirrorServiceRemotingSourceProxy.prototype.onStopped = function(reason) { var params_ = new MirrorServiceRemotingSource_OnStopped_Params(); params_.reason = reason; var builder = new codec.MessageV0Builder( kMirrorServiceRemotingSource_OnStopped_Name, codec.align(MirrorServiceRemotingSource_OnStopped_Params.encodedSize)); builder.encodeStruct(MirrorServiceRemotingSource_OnStopped_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; MirrorServiceRemotingSourcePtr.prototype.onError = function() { return MirrorServiceRemotingSourceProxy.prototype.onError .apply(this.ptr.getProxy(), arguments); }; MirrorServiceRemotingSourceProxy.prototype.onError = function() { var params_ = new MirrorServiceRemotingSource_OnError_Params(); var builder = new codec.MessageV0Builder( kMirrorServiceRemotingSource_OnError_Name, codec.align(MirrorServiceRemotingSource_OnError_Params.encodedSize)); builder.encodeStruct(MirrorServiceRemotingSource_OnError_Params, params_); var message = builder.finish(); this.receiver_.accept(message); }; function MirrorServiceRemotingSourceStub(delegate) { this.delegate_ = delegate; } MirrorServiceRemotingSourceStub.prototype.onSinkAvailable = function(metadata) { return this.delegate_ && this.delegate_.onSinkAvailable && this.delegate_.onSinkAvailable(metadata); } MirrorServiceRemotingSourceStub.prototype.onMessageFromSink = function(message) { return this.delegate_ && this.delegate_.onMessageFromSink && this.delegate_.onMessageFromSink(message); } MirrorServiceRemotingSourceStub.prototype.onStopped = function(reason) { return this.delegate_ && this.delegate_.onStopped && this.delegate_.onStopped(reason); } MirrorServiceRemotingSourceStub.prototype.onError = function() { return this.delegate_ && this.delegate_.onError && this.delegate_.onError(); } MirrorServiceRemotingSourceStub.prototype.accept = function(message) { var reader = new codec.MessageReader(message); switch (reader.messageName) { case kMirrorServiceRemotingSource_OnSinkAvailable_Name: var params = reader.decodeStruct(MirrorServiceRemotingSource_OnSinkAvailable_Params); this.onSinkAvailable(params.metadata); return true; case kMirrorServiceRemotingSource_OnMessageFromSink_Name: var params = reader.decodeStruct(MirrorServiceRemotingSource_OnMessageFromSink_Params); this.onMessageFromSink(params.message); return true; case kMirrorServiceRemotingSource_OnStopped_Name: var params = reader.decodeStruct(MirrorServiceRemotingSource_OnStopped_Params); this.onStopped(params.reason); return true; case kMirrorServiceRemotingSource_OnError_Name: var params = reader.decodeStruct(MirrorServiceRemotingSource_OnError_Params); this.onError(); return true; default: return false; } }; MirrorServiceRemotingSourceStub.prototype.acceptWithResponder = function(message, responder) { var reader = new codec.MessageReader(message); switch (reader.messageName) { default: return false; } }; function validateMirrorServiceRemotingSourceRequest(messageValidator) { var message = messageValidator.message; var paramsClass = null; switch (message.getName()) { case kMirrorServiceRemotingSource_OnSinkAvailable_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MirrorServiceRemotingSource_OnSinkAvailable_Params; break; case kMirrorServiceRemotingSource_OnMessageFromSink_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MirrorServiceRemotingSource_OnMessageFromSink_Params; break; case kMirrorServiceRemotingSource_OnStopped_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MirrorServiceRemotingSource_OnStopped_Params; break; case kMirrorServiceRemotingSource_OnError_Name: if (!message.expectsResponse() && !message.isResponse()) paramsClass = MirrorServiceRemotingSource_OnError_Params; break; } if (paramsClass === null) return validator.validationError.NONE; return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes()); } function validateMirrorServiceRemotingSourceResponse(messageValidator) { return validator.validationError.NONE; } var MirrorServiceRemotingSource = { name: 'media.mojom.MirrorServiceRemotingSource', kVersion: 0, ptrClass: MirrorServiceRemotingSourcePtr, proxyClass: MirrorServiceRemotingSourceProxy, stubClass: MirrorServiceRemotingSourceStub, validateRequest: validateMirrorServiceRemotingSourceRequest, validateResponse: null, }; MirrorServiceRemotingSourceStub.prototype.validator = validateMirrorServiceRemotingSourceRequest; MirrorServiceRemotingSourceProxy.prototype.validator = null; exports.MirrorServiceRemoter = MirrorServiceRemoter; exports.MirrorServiceRemoterPtr = MirrorServiceRemoterPtr; exports.MirrorServiceRemoterAssociatedPtr = MirrorServiceRemoterAssociatedPtr; exports.MirrorServiceRemotingSource = MirrorServiceRemotingSource; exports.MirrorServiceRemotingSourcePtr = MirrorServiceRemotingSourcePtr; exports.MirrorServiceRemotingSourceAssociatedPtr = MirrorServiceRemotingSourceAssociatedPtr; })();// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; (function() { var mojomId = 'media/mojo/interfaces/remoting_common.mojom'; if (mojo.internal.isMojomLoaded(mojomId)) { console.warn('The following mojom is loaded multiple times: ' + mojomId); return; } mojo.internal.markMojomLoaded(mojomId); var bindings = mojo; var associatedBindings = mojo; var codec = mojo.internal; var validator = mojo.internal; var exports = mojo.internal.exposeNamespace('media.mojom'); var RemotingStopReason = {}; RemotingStopReason.ROUTE_TERMINATED = 0; RemotingStopReason.LOCAL_PLAYBACK = RemotingStopReason.ROUTE_TERMINATED + 1; RemotingStopReason.SOURCE_GONE = RemotingStopReason.LOCAL_PLAYBACK + 1; RemotingStopReason.MESSAGE_SEND_FAILED = RemotingStopReason.SOURCE_GONE + 1; RemotingStopReason.DATA_SEND_FAILED = RemotingStopReason.MESSAGE_SEND_FAILED + 1; RemotingStopReason.UNEXPECTED_FAILURE = RemotingStopReason.DATA_SEND_FAILED + 1; RemotingStopReason.SERVICE_GONE = RemotingStopReason.UNEXPECTED_FAILURE + 1; RemotingStopReason.USER_DISABLED = RemotingStopReason.SERVICE_GONE + 1; RemotingStopReason.MIN_VALUE = 0, RemotingStopReason.MAX_VALUE = 7, RemotingStopReason.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: return true; } return false; }; RemotingStopReason.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; var RemotingStartFailReason = {}; RemotingStartFailReason.CANNOT_START_MULTIPLE = 0; RemotingStartFailReason.ROUTE_TERMINATED = RemotingStartFailReason.CANNOT_START_MULTIPLE + 1; RemotingStartFailReason.SERVICE_NOT_CONNECTED = RemotingStartFailReason.ROUTE_TERMINATED + 1; RemotingStartFailReason.MIN_VALUE = 0, RemotingStartFailReason.MAX_VALUE = 2, RemotingStartFailReason.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: return true; } return false; }; RemotingStartFailReason.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; var RemotingSinkFeature = {}; RemotingSinkFeature.RENDERING = 0; RemotingSinkFeature.CONTENT_DECRYPTION = RemotingSinkFeature.RENDERING + 1; RemotingSinkFeature.MIN_VALUE = 0, RemotingSinkFeature.MAX_VALUE = 1, RemotingSinkFeature.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: return true; } return false; }; RemotingSinkFeature.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; var RemotingSinkAudioCapability = {}; RemotingSinkAudioCapability.CODEC_BASELINE_SET = 0; RemotingSinkAudioCapability.CODEC_AAC = RemotingSinkAudioCapability.CODEC_BASELINE_SET + 1; RemotingSinkAudioCapability.CODEC_OPUS = RemotingSinkAudioCapability.CODEC_AAC + 1; RemotingSinkAudioCapability.MIN_VALUE = 0, RemotingSinkAudioCapability.MAX_VALUE = 2, RemotingSinkAudioCapability.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: return true; } return false; }; RemotingSinkAudioCapability.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; var RemotingSinkVideoCapability = {}; RemotingSinkVideoCapability.SUPPORT_4K = 0; RemotingSinkVideoCapability.CODEC_BASELINE_SET = RemotingSinkVideoCapability.SUPPORT_4K + 1; RemotingSinkVideoCapability.CODEC_H264 = RemotingSinkVideoCapability.CODEC_BASELINE_SET + 1; RemotingSinkVideoCapability.CODEC_VP8 = RemotingSinkVideoCapability.CODEC_H264 + 1; RemotingSinkVideoCapability.CODEC_VP9 = RemotingSinkVideoCapability.CODEC_VP8 + 1; RemotingSinkVideoCapability.CODEC_HEVC = RemotingSinkVideoCapability.CODEC_VP9 + 1; RemotingSinkVideoCapability.MIN_VALUE = 0, RemotingSinkVideoCapability.MAX_VALUE = 5, RemotingSinkVideoCapability.isKnownEnumValue = function(value) { switch (value) { case 0: case 1: case 2: case 3: case 4: case 5: return true; } return false; }; RemotingSinkVideoCapability.validate = function(enumValue) { var isExtensible = false; if (isExtensible || this.isKnownEnumValue(enumValue)) return validator.validationError.NONE; return validator.validationError.UNKNOWN_ENUM_VALUE; }; function RemotingSinkMetadata(values) { this.initDefaults_(); this.initFields_(values); } RemotingSinkMetadata.prototype.initDefaults_ = function() { this.features = null; this.audioCapabilities = null; this.videoCapabilities = null; this.friendlyName = null; }; RemotingSinkMetadata.prototype.initFields_ = function(fields) { for(var field in fields) { if (this.hasOwnProperty(field)) this[field] = fields[field]; } }; RemotingSinkMetadata.validate = function(messageValidator, offset) { var err; err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); if (err !== validator.validationError.NONE) return err; var kVersionSizes = [ {version: 0, numBytes: 40} ]; err = messageValidator.validateStructVersion(offset, kVersionSizes); if (err !== validator.validationError.NONE) return err; // validate RemotingSinkMetadata.features err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 4, new codec.Enum(RemotingSinkFeature), false, [0], 0); if (err !== validator.validationError.NONE) return err; // validate RemotingSinkMetadata.audioCapabilities err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 4, new codec.Enum(RemotingSinkAudioCapability), false, [0], 0); if (err !== validator.validationError.NONE) return err; // validate RemotingSinkMetadata.videoCapabilities err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 16, 4, new codec.Enum(RemotingSinkVideoCapability), false, [0], 0); if (err !== validator.validationError.NONE) return err; // validate RemotingSinkMetadata.friendlyName err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) if (err !== validator.validationError.NONE) return err; return validator.validationError.NONE; }; RemotingSinkMetadata.encodedSize = codec.kStructHeaderSize + 32; RemotingSinkMetadata.decode = function(decoder) { var packed; var val = new RemotingSinkMetadata(); var numberOfBytes = decoder.readUint32(); var version = decoder.readUint32(); val.features = decoder.decodeArrayPointer(new codec.Enum(RemotingSinkFeature)); val.audioCapabilities = decoder.decodeArrayPointer(new codec.Enum(RemotingSinkAudioCapability)); val.videoCapabilities = decoder.decodeArrayPointer(new codec.Enum(RemotingSinkVideoCapability)); val.friendlyName = decoder.decodeStruct(codec.String); return val; }; RemotingSinkMetadata.encode = function(encoder, val) { var packed; encoder.writeUint32(RemotingSinkMetadata.encodedSize); encoder.writeUint32(0); encoder.encodeArrayPointer(new codec.Enum(RemotingSinkFeature), val.features); encoder.encodeArrayPointer(new codec.Enum(RemotingSinkAudioCapability), val.audioCapabilities); encoder.encodeArrayPointer(new codec.Enum(RemotingSinkVideoCapability), val.videoCapabilities); encoder.encodeStruct(codec.String, val.friendlyName); }; exports.RemotingStopReason = RemotingStopReason; exports.RemotingStartFailReason = RemotingStartFailReason; exports.RemotingSinkFeature = RemotingSinkFeature; exports.RemotingSinkAudioCapability = RemotingSinkAudioCapability; exports.RemotingSinkVideoCapability = RemotingSinkVideoCapability; exports.RemotingSinkMetadata = RemotingSinkMetadata; })();PNG  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@(y PLTEjXZWnր_pCʃ6ƴqך8Uρ'L1ŖeӝdD0V,o~#iy4lՂA]Eۊf[)S^u5ƈ&${ٟBɯcӌކa3Byxz?Ƚ(;Ǖ7+èRxT%|fԿ.:zߔvؓ<`җrFPߩ+ܵtׅ܋h!z|-/*b= s@tRNS冽IDATxփv@Y%kֶm׶m۶mթ(a q./py qggn87_~]3eg-oʞCU霪Jjƒ¥:S2:pdVoMSRPEZZ`W땵JtT-[jꚚT-,WO!f,@<\wD>̊DYlon z`K aQlc$n(6mh6 ]&Vm;0p#&$ޞٹr6#%}EeW{Xk9 8|3GIcSѓBOgQ_>Ո|Vi_G*uJn8L|u}!fWp9o[[Bx_c{hyMވō&CZe[}d UԇB5  jDsqy@H,fťepE網UC-6\Pg"m[ZnW{W{X >g3bj {UdUx!ExE;}g2;?=Nz]=WyˀYkv_חľ.(Wv,"әN?ů KP1Uf4Nňi]uap]01M!]\%VWWU -*ng`M\ѵQco!TU0T;:  >tL\B ~│)QjnvG`\s&6`rL9̬wf=.EW`5 ޿vKJaAz!I`Y3Rhn/jvva D4xyabbƼKJݮ/29RSRphjoJ`g=o~$,nFuU3 }hU<ܡQCCʼjϤ\E"̕!1!==ȖYDA7o"&*D:;;׳( )rh>HNLH7?ICDEjr2˾+T(ԪTF&saN<yvP) 5E˭7@Va| iEkokϻwȫpz K^P:?(]0pQ$75 f*F@ںi3E-X"$(A c&  pغMQYQS6:1jjlb)(_NҨDYY755a6zBfY6(|1??- X*LNN100y,..~}hAs1>6^sss t| ~NB. y? ? ;n^F&qΝ>($+.Y' _ Qӱ̤D,s煰.;leU<9! asIDxط`M~`>DprQDp~Ɖ%]}dDH/H}8N8VH* ?VN!B;|& }0H)Ipzifq)j3;qY0blL}NED$Ƶk8w,>t]f9 Bh+`sP4xߴ`)).Fp@ .<=% ̌ Dx!EBBieTU *"}hd:׮\es F;PBJZU-:[eRtd$c]+IpwsCzj*}LQ7N ?a2:TIENDB`PNG  IHDR@(NIDATx횃cMXcm۶m۶m۶m&$c{nWu*o?k^N}=(DTGGG#I H"Y ,1 $HNNnGy$i, K pr////oUvv6|g^999S<%bn%{ ڇ[4mU+V =r{-2ѥc'al2DsÆ!40γ3g@uw;fEMQxŋ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@(y hPLTEUUU~~~&&&888 AAA''' )))>>>GGGͅ~///㨨,,,555ZzvvvQQQ _sm1/".---^p 2uuu???r o rrr̵""" OOO'4ihhh QMƻ ~wjdSSSN¢1tRNSx~IDATxڴS{1Luڶm7}ݟ7 De>$eP!KgF $ ,0F3DRbI/vk{RoSГRR ߤ9܀oSy?ds.^KBZw\.K˔g`o?\<$.pv@+ʪfy%9Y`q u ]}/UOSuTM[Z܀ؖNwt@W@Oo @ GhhɩVh{%<{;VX$KJʉF.v (Lfg(<؊4R UBb j"T |Lq&,P3\Lf3m1pIENDB`PNG  IHDR@(4bIDATx؁f@}\%)(Y Di*uf70dĊF3xsW)I.~GPleg}t=M\ Jjp.+Q aD{%XՍy,+(Jh{R BH9Z-"# H2@8Jp^g@L;@ AP~j$s (u pBk2 -#PIo =rXM A%3U:2`@*d=5x@N9@;[@9LCm F\Im6$A!Tf=(n!Ip MT=`ikU/Y [>> APPJtPyp-@jPwX")A@҇TD 'g^m#g@ge&:@x+2;{9D_ҿ.,5Wڂ/0@ՠ9h}s@ X֋=, 8b2l ,B.l->}Oq9,@1AZ K#઒bi|Uk̑, ɩA+==~8 M^V!=|HHR8?$[8>~+Ε=fh40 9N)Wa>t-*~(0> > > >yPbKv$8)u@HI_ns$I OA[a>Ӕ; LȱB C #;t<ЧjakЏ\v$dH FZ`@eAK′C= PZxe4Πm6tyLq!Nt8xnA"\T09;@& ^_16IENDB`PNG  IHDR@(NIDATxp$[g۶mom۶m۶mۈmgֿ9n3=U/ڵk/::: ..U9HĜKU} -- (1+1W֐wb&v/zRiewNKCeUw >p<o"iP /M %C%X!.p)5_ K58p(=W -etw [aҵWA.# EYv T_Ş!1}1tϨ7~@K_8g>N`#^^¾c>^~@S?I& RPVyT^/]L/dOd78؛KD(T8]cH[(闌܇mТN;LW4)Ƶ`v}O9m;i'ڠ㏺ {IsO $C.g[ ӔM06~p ö>)0a5@#E3@a?N@@L~Lx?0EI;IL/?Xr<3@5~yEPZB=AKLO<cd[wCO=Fh|{;Mp݇=ս 9. Ʒb<4?bKւ_7r"EW ^W2<+,uKTnCڦ/BK}(uxȳTJFN}غ 7j$@I; )`6 ꔜ~M@RR*qf!DUvIBB@P PR @% rB fs0y#m[AqPlUUI}'|Gei:c4M oAy7\EY, Q!cr (b,K$\ׅ$ d(LYalFϒ$ }߃vB(+k3B h! !!~@T<5۝o\8i')꺖Ia( o4@ N9 2qmE낪8S u]a6=eY4,K,#q A4 a&Om;lu]ya4N.*躎(h/P$kY{ H<>"{  1?=Q(IENDB`PNG  IHDR@(y VPLTE;6=8}B>>9٪]YګئIEmi޴HC|ЕiڔΑzvԟ<7޵LHDS]Xץkg`v8PLE@QMEAtqykiԞok~ʫ٩Ӝc_?:Ұۮ˷B=ἼSNVQhdUQea̍yvA<ع߷JEfbҚjgפGBąutRNS-q*cIDATxC@Jն_m۶m{f>0WX]f0$31  sqyw1F;|6R?z\M7DN՞+U3 VODzj (+Yh&R:pG~Z+ M W"(j/PJwtjeC> 6nT ,0w?bf` HSO:B[f gg PJ  DV@rF⒄ !#pK_xx"+}@l/WKI.\sQtدUIENDB`PNG  IHDR@(N7IDATx#g?۶m^۶'m۶i93=6֝ٮ:շ~* t#uuu2f|}}}8^fL&13v eJ)5ΦTrOV5v7jǗgxb?js5]+n11Noڻ6(ho&^)o NiU 75{gptj)/㳅lfXO;~(Ľ\)[k/ޓ˯lN~UKV[ϯ>=N"Q sI_c!_]%@IIƏPk0`:>U+ 3 }hG1|8`bt -O|/cbb#CP%M6j ZP#KVN*+] i /z="1gOxv%)*u|O:_y[?ܤk1 NPHr7x0ʩ/l;jbYLu[̫rZrT2!Pc+>1PJ;ˀitkgʀQWtNVo$`]<>eL?ts1Jk&`Yh4%FѦjc+ dĬ0O6WZ\RyHDa8薂7 V*C]O/dؗbʨbra~1F’89N5%Y AP("muL?6FxI9jDyŔ3B9CQs+zq%< (Y&QZiNק?]A81kg3Q> f%!QLWXj'ō^~k%m:(2:)-;7eH:M_p}Iյ 7$ FP.Rx8fl$@{P-RMN*޲wWŪx3 <v9'{Khh\5K]GtRQ\YFG+<#rBc9<|I&S)Tc?1wpg gIENDB`PNG  IHDR@(y PLTEUUU4~;@0P<65g~Wp~=8NiD`ku8VIdَ–&Gl2Q>\n:Xotrϣ̜͡pi舚.Mݏ>94Sˇ$E_wLgB_`xކVoᦴ)IMh7xf}Uo8[t?\#Dy(H1P%F?'Hб&6sV48f^Q[)k_1`%Z,?ag4`+m\/(y3Ps_+,an鱆?P?բ.J ֶRiȨYj[y?)f^,r;ZVn (#eY %u N(X5&`VI ~m0gXYT'!mq,ϯ m/7 HoalٺEPd6BsK-Tcms86VN\9^ynwݟ^N6Uwf5v4BDcy)TR^r(0;Ej ]p,X;ToEpAs?-FSj`eٍT[Liqaa"jˠcVk5(voV[y'8"y>z9+5~Nj`q{K-\^{>y]=W Yv 8FY^;>N^~sԀM>wux0]Pycs` \_ 3Յ{ΆOʰ|q-wj:?&jx<28N00X)n;c۸e`qBRpLf{m-:+idϓGrV펙86Z`SV-K@J,GLp?A\П?(] DK!BI#&0lSW>"!#ك"Q㶊씒^4a,OhОXj Q Gfmn* &#aXj%'w[Y.VóbNN$T8G W^,8ʉɨxf w> q2x LG#y>}֤wKޫsb~`9![ksPz,A]bᝳd.x5k*hc}^L 2\H OǠ }REdT]o}T'bE]tE]~9svIENDB`PNG  IHDRL(TgsRGB IDAThY pT>l$fM"Ly!R:HXeʴբLXZiұiN)L"B:UGl}sG;93s?7 @"@1WO- wJGsBJhk0W"tbUim]խGq3]9_\=!A) sJ~榎g}d3[wL8=dRrʖ*+=u>_yN(?qJ=e.n>rN3䄭AjAk}sw}sB8ɣ]n{؛dj ̜*Y4'_2"7Gӡxt#(\24i*L{a(0E:%/x 8ĭ7,I߲G:keAhXMgݕI$+c{"5Iǁka2>%\Ρ5tjv%7]úrRCZl2&XAXmYvWUj1uǐYaP<o nD_0>AbA$?ȮOkݹS˥G7{KlE4k+,F?Q/ ZZ a(UN"Y9IĠ'KXp@,%\~m^X a518 ,WK ̆jaAJF9]Į%#fcTdع:wJJJZa)]nd,DE@+BYc csynACupv #ɐ$I+5te8)w5|g<~<%3躤RTH' 4/G92̭M祬Zմ EN[ I޸U(90smj߅!ȼ WzEQ2Փ(f}Vr.)[ JphҎ=+~C3e ,R$SbPhV ,~̣,.syGYq;Goͥ[UȼV5L*Ii%t`c|Um\w:ABí٦;:K[^t~%7Ԯ( LKs&M2֡]\sƘ=J`7=ߧ^xc)Y&S聼۪mͨO;gz&ERLWAR}iJ~;L[:G1]NO;c!6I&|gI>v*4~h"}hR+k!FM84;@,JcdL2$rAEd4VL.Va\IS>ʇAlcVi$^H:.iBT+BGl[jP-DE ӵ; 8uAr+80hйo~cn#szˊg`Ҽ8טT:9B=Kri:wח qیH#1z ~2N> 0!X:X1ww#yEg踘"xи{bq)S*܅u1!^{n"_9:?b^5V>5?ɱHH#`o0V*њ2;{,s-/xfTnn͔os}gq?@^Y^E ~ۆ9sXo&>MGyU #Kܲ.٭vD 4KO̫7T8Ds~.%&u:`*qc@`>Bm73ؤIENDB`PNG  IHDRP! k5 ߛ<|KYW|b/F7ߒٚjLtAK]tk?:'jD'ىjMˆФӮ&SWvB}syo/_~ܸ!yb4xl+͓r \ XL7}'q&rÈ'wMaO}YwLٿ@h$~ zTfdE7Lo~`ҾyK;[Edk,.c(WZrt|n/2re{}_ǓZL64XוiQ/^rwt{:fmӡpa Wߍ>5rÆqcL~$&#=/f^aǗO7W((̟g,>ϤuM0@v`,T6]ȱ?_'_~؎| wܱ'6zyl1_~6?`غqC _|A)Ɯg$IVc@]36`8D  nh)uM7_fN؎׸24hz8WvȸC'{4s1ntzF8/e]eH7#$qy!cǒ+?9`-?P r BЕmi9!/\궶jߖ6?&A4sx/5CM+uh4¨ay#mN?XtC-xԫDӍ^}sE8)dvw]'FPshK:@ݴP"~7|4Xn XV~# x;zqa;rt0=idl @-_~Wf\\q]tE zhDsU-opzgK8Pn6* #kK-ߘiMUDu]E|g_[z?erXzmk)?cRM(?aL> øZ_e@gmki+o)iC ^@lo?Aˏf'iM+6몈+ t~h5j@XPC;(_I˵tߖOMi هV4xnZö `VunP7U4JߦI->0j28spIW>+&+(B!cD6W}AIhY0Ysp-^?G7翗KH:,'CQ=)]+Op(BCe;uZpM6 m//vw*mgq]{4:mB!Mŭ]L6oĵq'÷R:SA5~_+֒>-]ˏq(B!&ڔ9'6a66׊kƵ>!49wÌϪ=AAR|1aW='&}j[B;!][XJ-KR Bl 6вjFp55S.W5T@\tT2u 7Q B_Y_ؿ&nA:?.h=u7`fB=!pcLn-ǵ@!؏]u^~rf&6 gkc4 ~=F7Bv~c E=!_ҕt*=ǧ@!Z+J?FJE/UJ!}L<!$LDO7Q55wM z3M|oTA ~L|ԯu S~BQξ若}1F:jܐצ\Ҙ ^w>,Xs Ńwc9s *ɯTMoF%<2%!4oژyjs%DW]P&< O:wLce 50P}X{QWC(Bjd J(BCU`R6;2l|}X77@nO0|eD?{]@̈́!(l&0!4E_\@ cTqp`:hJ.t#@N|ZsẩP CVɠk&FsyX;|E^|ۙY~Ɲ 'scn]@Q yF8bDb Z`M \M?(@T 0T3 jԗkFڕ"X$b@V<1mhi>t.VM 4 vu@aokAjy3  R,G:Q6??< V :-S]/ 1BVqI$ֈkA9<`/<?!tepBr R }#q0eDU 9Bç_Z kzVdzK l0W9Q sׇh# =kZLsʆi`ġ8xZyh~ÙDC >LbNMT̺5ik*NRj Rsb9@EQU+NZ ?y!$8>'$B#X+ׂ3p !pgPWn]@1!Ng:ؙn22HnkS.mVX3!2 k`A{ɡyO|J] E!@_JXv{LBH!ͧaD>!$W(e?XDo k5D&Ƽ{{l=h6ۆ ՚S[[XpZ Boa !X\Rm[ؼ#uk-XJ%C{=q|(7ʡȁ[u]n>!öa/\ wYVl=: ^r3'~џ(B޷I?!lײ%Rds=PĊTzv-As^7Z A21EÐ1|g3[Hu sZE(BPgr:BnVBe/*Ai?X.)ߟ)M6eр(֒S2`eJMڝޣL+' ǡ<^Z |gv(&f Bлm+v+f"<sP[,k"Aل`T1̫5p״O8 nƢ>w }9kC=ЧO{fS]9`ck?k5c-yOI@u7d7*VoE?wBkϜ6!NG[xؘdmEsnPT@ȤV: _z5?k.9kCl ȑ^0Z+hpܷv$h"Edz=L2ekZbMyo9g= ۊi^-Yd9*+g<1מ5 WnQ e 2H`!rU|a+[4#h%<sU(hZ82kYHֲg@02=:j# AUc `Ֆx}9=9ܚvbn:ˌ˯y F|,g=]K"aSro=wp(2YTgde+Vrݕ;_UOuG宓>c$=˗,[ɬ/#2j]"Ѹ4Vxd)䘱#|rH#En}tؿB| NvO$I&7A?:0T+M@~S/+]f/%>В+OI>Jn^ϧ|X<|c#[)ﶯ-p1O '+PDjͨ} ?,d1!d.֕T|ޖ|[ZJjo_sr7l0GƕbD2ٜסf_=0QE?DSXKCẺ'2_3.͏^Y+hO<6%ŸZry!AZwm6CD@Z5DcqPO.Hn+JB` (ϐ|(N*J@8jT(m2|15=S 5-/ }x^ò{T $HOƗl(E\& ˯p|A\yóCX.q,xO?Xm^q0?|C<7yRӺDisR UOĭ-ŶR3*Wj }^DBӧgaN_;`S>Hy 1b~^ξ,\#c3=k5ğ qX( wخ<;9˿S0RKґrkO;B1WWy{ܒޮg_@CF:SQfy  Qõ+'z}([; xk{iU}|v=FQM䯍mL=Q.,\Gc+st;QbI)Gp\Q\(Fڋ8oXVe'x2-˫+SeJvf·?#Pß-^V қ;Jjsa:*ܨv fX;urXF< ,-dz S{zC6veq9ͲR>Yb66-s7%K ͷ侶m( m 66 &4ޅ0dy]|V%R9YVU뽟U0\YEoaڳTK Z0 [Q,BtQ{ck͞Xd7 t31[^Yj4 N!銸[]"*B&[^C֎EϪ>C*;GJ**T Bm}"-Tk7 ZOO{$~S3ޓ#羣9w|B}ҒggԒAR2_dUOz@0͛ZR]wAܾ 6̴LQzvVX&MZrD}VEM}VA\XOn(`ϪAL`W ނKz^ʮwj?>@o}_>pp5OwX\,O@<D# ̀ B2G.͊Ldu=&B#X+9#r"$bJ WP>@U@YmՃDh1/|<yZJZB(/n-o4'%y0Z(׷ət^NzmµZ#?랗TZyVP*׷3ԌuV @G;XP:.V}sQ!- ؘ,:7xĐdv_>zH9eɭ: 09`\;g0{*l_6Ӫ0Nq-kj 3U[ʳj5͟UE Y5S!vCEJk `:R7F =B/Դc&3RA5` #>. ;5gZTי !F+nHZE%ڼyޫǙ'3 kt 'vH |m({ZROVVQb Og#(=9UYcU#$j!OKN+fIP $RKG#/J_?v'$zҹ8J>c|gHj$;8dDx翯K1p7yIon)ŕH>꜑ޥpޱۻ1^ƴx&Ųjsl+5g=l6vYE9DֶyZ\WL,B0 ٤RY XY`#K#/'̂\|@8kaSiu;g+lE(P ȍJZl 2&q=*7 i64C/ ÞUz/`񀄐bzx /u_[KZCH2%E'c;Af,Ht-nS&6AR/s-P,*;r3?]_"(tn_}}6%=MHބC9j{|`Xl-aIՖRT|!7c<갉׀ׂdy8NRyVѠ'hmLFSv20TRoН&e$u_OunFq,5 >{tf>.c ?oMCX\~exDZ uGb}DJ w_Fs4BF,E͇ ׈k5/3dLK\>frzƣۻYi;cm.՝gk3){+ &+O/nrDz Zhsϛ >he7 6ZM8' .F4TYAQ(G! SnxLL _/zؤP ( y׏^κ5fHzs=& FwzS=\ׄk$J<ڞU\h:d#{=I>DºO G6@s^qRu@&7L70+Kmp-4+YrUf&[MN8Ήs#k54T,Rq[ !xbY(qԪejn2BT ƗF|&N'tӶCl)%x/лߊ8OmE7Fm˂l6=j} 9p.fڒgD[g]tLm9kaKH&W멉{mW\;_|l ?@(#g?x}Sվ"TlQcc`_E(T6xRC1A`8cpBPz}ieU@s$WpAԴg;78c8e !B5YEHZY>'yJwNfoaA) W*} Y%)Aj<%}lf! QlDRS ` cKpF {Ω;g785}AZf`VSo~ E<5(p_2_'4B_UFzxO, 6 Vg6wv{i <5EW/?v<A29Nx@t(eFѸԖ?+n,/$/^^Ayto}bm'4#/*P˕4{ j@( ԞBMd;-qEֵDۂeQpCI$nc>|$8C԰M!Q%_(*pXV&j 7a5w?J|n~ ֣aD&.ݍ0.\tGKpjY!2TxӫЃQ8'S[VPsB0f=*JMXP kX C4BBr&=zA>7 2{Pih[[Z^B`h/m(k{,B'uóN-Ga<8 <,M;*)9>!s5[mCI?dkD4YCL/=E,"5SPF˾~V| _wҪ?ѩTDUy Bp%lwT|¦X*sL\[@F,< b=7Tؠ/?y C4E߄`̯C#o۸W=^ܐ=󵁂;iY+GY)Z@CQ?NzsGmܑh,nC\˕̺`c{Yaw8>%3.OAo>  'Zh4Q1Eb-n/z:F_2PK5d q1_ 3!lBnuh#!0\mSasa-X s-Έ'İ6d&Z@64>ЙZP=2ž6<'>5p/UM@>O z:]YOl"‰av5 xr1CAO}A?3̞ek雧 !FX\l6ox "+i!_L,%ջG{Ylۖ_}A؅W\+}t6Hx2K Mk&mIPoǵ'&aL7u/׿rjXtx!5d}E9.!2ŹEcp4CY\&vm?"п^u)&pP:1l1_,Q @0 Q &?,g/$Rk h6(=%a#`yP5C,5A?zkG{\B+1<7F0^,Wgu_3P@~~$~(PP{&hju#)WxXyQa֛#{Z1&ZS=dF|\BHZ ?O@L6'hBԬ{r$~'i Τ8smݧaVDH/gY4Ksc{ #>.!cC1#<-xۤ횽(Pdы77j2hh у:lyXQJo #jwejC~%Y-t/,85K<\`lx.k7<֡6:k[4=LaG3O 86!* X2*\:}DZ GOck'\_ (rL>skP-嘄` e .E:^(nokx-MAC C)+x_9 0?|o!X9VE" 0 .FFd[Sk?, A鼚7y)/c -Ed73؄ aZPiuA\7e)Pqp Fe F⺽6z_})WkJш}PENÎ̺))!O iR)B`^-y`4?{5Jf \f~kgun7ܬOvY>RASgk"źRkd K+VV(IĽ'_Qy|"x65h@nUnh6kOj$ϹնͽVBDYkPTbYm2%Đ ?ln6hhJ,zSjTK,wuxz䛯RO3/^.>yCm+%`iuPǐ,<'rRz|([y A?mp"Tb\WuE*2XnF QfS **/"c_r_?!7,]M3(P |U JVC7I(NWcX2ql!fr\|#@~4s;(P #].Mcc3{ ƷQBvϐAS6T&^6AQ@HQ 嚎`r>v2/Y޶wBҢv`3/8"lԬm*Jq;yl-ay!h³6Yzb"3P_TTBp+5/|nZ@Px6,dOHp1 mJ=W f \;d9Ss-E1k1noѩR`@d?](\I}Q@(<^Pn?>!;=OB_}6W ̕-  <>6 L&7S?)+ĵp pH}0w'>ld6L.P@(<<?,FV5QׯDHmxNBijVQKP p?dcU^I_Opim;Fz:@2=f dߍHL볊@؝ųp~ oybk[wwQ1EW p zSk3jV$$f -yUT8J'%z' /HEN&WP@(b[p 7=bIb !'QUĒI}V1/j`=D.zRԴ,Қ> @8Ov$X}sk uX]/C2Xk1=Ke)XJx_2,_}kJ#rPYy,_z^^Mzdj; j{CDrSBK>'`BAB$>'f\~LYE@ f;|7ss?C;qIR3lp`qB@ڭ>,|X9wE}b@A䴼ΌPe{imS=vtRXn>bmcGzoh7zXق  `_^ݐd4sn.+K+c!7S2A$5&L!( gNN&&,YD:r|ر* Tu9뱶0*G9[进}\n#YZݐ߷%||ќoƪtGjpL L}_wY~u $V{J%ƄUrpX zKa~@ /XrKgzz%G.,Kc:'YءB&S>T/ x軹yc/{ @;- ش۝VTq-taR`84L~w!}R뀳K5fٽDp~qeǪ)coҪb ~_Iy5@`9 ]YYۖ(K')Ggp޹ ӋI . x0݌& $;m&֋+m:>ڦD|*~'5_rzմ YYp@{) ۺmHk-vj.4^cf)v*Ƅ3IO@=YQ j ؝Ӛ}@EUZ%F=ڰwpR LgþU7dsgOeUeNHxOjM㔎W]Tnn⚎Y >w@ 7tbzIZ]f[Zbt:WZdcUJk-1d-@]q\?90 clԾqj -kiM.{7w CndymKSwy؂f(u{7\(stigb0PnodyuX=J>9U=O,s{חM tGRLSUuw^OC $ ^6vV7saV2 m=o 9> rptZ)Md-i@ Q`-e]NjreӽmY\i?}ٱ`cUڞ_\n$ _ӏoJIZ0@ǀl\^L=+k[毩\3~,X)B7rxr.+kvRp߯c!_lc@c@^8lM4Mwn~!i[GvwN' ZO'z_j1?+v*ɼ07rhǪ\_r}nұj]Pٳ]\Ը>/  >g$}؉ŕշb;{w֮݅;S=ӯk']J7VߏU}ƪ 8q5 0(R(mqjc>G1)R/p@ h,<>>󳼼d?ӿV_ -ͿI߄%)BIaTt@ %dӘPp㦦E:>o ?X1#i!b0 N/0j $/D;֗%X!D?5< `X8ESGIՉﲝ|;~zz>V}<},jv LP 0Q L4]#@̥}L-Q}ϱOͧ5wY_wx` *=y?۝DZ7%_,;'}ǫn0ND G:brmM3'5,KV| uOAp渮/I2B Y">h|MNَg<VvK&r]# ɔe#qIU'!vFC M?1a R904ct}ST6> MI@0\tBNeDt^ (4{>{?Q${-o ˾(@@Eplw/.Y"4iD~,ŕ{ө\oNk˫e`32QqRJ 2~A@ AVZ{ Xq<=YimKX:K<+0 0)lP0 e_K[#sRt*Uv|UR_'i97u@ L~-ZpP%W^8p/V9K ( lO\ Ń"sG ,W7٢2 XXnI{%`~ qڭh@]lUm/~j5YZֶِl=Hfmd ʗOBT;FgiwЦJG T?;m?gkg6_ۛcȶ 2>VmAhLف3Go|VΎuL'ON9y[ Jh:˞Jh~y_)WY^ԅ-H_R@~|HM0erp;6" R ږ|#u?)wgW dθ.q=0 (s4Sb@yx] to<~ +)3T`ױ`zPsR@ jݽ={ MN'[;{f#Bo̕43s 04 IK97Q5`5,fAs'>//S*W:n\?p-oǯird{pf tRWjf3Pc{C 9ZGBJP)jVo4K3>+[ C榣pž۩,x-g'^ueZZmfC4j0L' Hk )5l6]߈ N;Yzkk,Қ&|o@+%3@-Hџ-^&ZPy@!Dxzk7ۄ* &MX@x/?WXVZY,?q&:*A+]U@ ŠUme Ov{_E4bU{WA^Yw*_#U-?æBNϺr޹\n,߷ P{iQk#N(z U[{TJ d0L? TǓnQ%Ije$MdKnJp\mWw$ k$ 1HZ7n.jTLM@ {P$J Vl1-b}|}vi:Q-l?~gx`R@ͪ< ˆ4-کg@wuIRDv1"'m9.dQ#BNm?|{/k9 ž g]z5Ke%"Ս,}8+szg+ Fclj}""׌aZ|xh4 kz,@d @rQ f=18)ご%@#UO̢@`ױMJysG@ HwA赣PWo0Y[̑7Qn@ v=M^;jO[T:v }ǝKe v*X//o g&$ >HJ-F,|< "[(OYMlls=cTDP4OW3sDMYqtkXf(33s p\9M\SSLlnZV Mlwg@8 vuA]Cʇp0 pHX<5E9pĀ Hs?P-Hb Xm2T+.բ ~.;ո(+Xu==HZC  ,+OД_&’Hr-FuhYK}r|0<WSU_xGez"_=__̅@ A C0p5:8~^|\(bQn<0UY<b D@@ 65$iEx䪚KPW~/]4KWQs!r8D@ON>  g;d犈MH,_Н[Μ=OoT_@U,[s)Cː^.f9Aj8@ A-ڞQA b% .3! 5%C[sVW&'(q? $pB|AٝZf4_|?˨=~2U|i3)xH3Ξ;߫"^]{hD@AZ|CdVڒ~sv9.'ZlJy'1m)׮ߠ),Jnzqd<ҝ. e] {@  l&Ûk׭HZI'(GS'"R ʴ6mF K"ɐ6 AD( ۔ۍ""&oXKjC #\ FdW]7|xm| \Z6:P.*!A4"AM@"|y 9~?o I3}VZO KyDo]RR ƖuDs= ̂4~AF(x)P3Yk$=:ݻ,,[VX\v[m={k+ ) MM'5dKsɫ*}~4l{?ϟ}71 RPD̂x9јmj iYc^ | 5 C-i;"_ϑo4"\Z@tH"tRژa#ǥ,u?lsR=.0 RS?{y SY4 Dcj02 [!Iua}Űs o @Bq4uF9rP|ljOTXzcOf rUHfm# ;BpUB=^1c `Q* \쥇g@OG=߰y`dZLz)7)jLIl~{eGykFoQ@J %9Ģ dh1g;̢~(Q"1@ > +W St %.hmڲ (T^SjjcMͭ#HeߣD5׍o$=wXv>Y&?`ݯgf]LK[3GeԙWPbsLNtn^} 1Dq\Cp$[zds07.nHC!t kgr%x(/]6oAѠ =<]dفW" sN7`Wb ͺϪ_- KԎ oݛpϿb*mL߼",p]|OY\v#j|^A)y<^2Cj[&<t⎮ >=w|iF%u+!&YT4fa?D_&u Aπ6P.944K5&)9vc=^YvU=^5[H_0$Vko> b]W#:%ƲPdr!E@tGp <n *lvgc /U?36_L~,[ :]PECFrk޷zr:]\qSংN5oǔ+x)@@aAc 8NOA",MMlk퇚")]E sEC#*h߭& Gԝ|t]lJ&Q{d8k۶mۻk۶m۶meTFvetz^FD3[ެ5sBDܼ!",нQvp+3,Y$ٹoW<{j%~oSt\8Oj;.eHv$C%#(ӯ#HΗ-»f|&n8?N=(dIm!Y1 z|xx젛wn6 5v^W_%v75FL5-$ّ I4]lco % ՆPaj :i~ӫj]op‰'N8NɐdIJz35^|B~ } y.m&& L7Ƀ9EL}3\{"Hl>I*ƾd _…\F k*.rZml_R`9$wDL8?NqHv$C @ү?5t:+:N(\p7ﭰs)\|X1^L!Ʈ Lfd(xܶm{'ɌdG2`*ƾBW]F^!udYR,o|Sy.|Q?xN}+*0b(\yzºɊdF#R0n09LH*\ِʽ/\O*BIޗ/sá-3+6@[|9/dE2#Q0D?SOZfy9ĹE/{•:}1Ƌ Y(ـ@nL("cj7t~3nFT!lC:GUe>6Szav &P˃dAkF2"Y(mgnϲmF"1{c4W@Q(@ޗ/D`5ɊdFK&S{Zrdkcߨ\AAQߠ`w"H6$#Ɍ1$-J~eukcwjW|99mw$ɊvXS{16 [JgJҼ`"]Vz2)_+rdB!1j~]k[%'M@p:C ylBga:owU?ɄdCMտLm'&ؕQůOmsv('Zj~lVN{zt=? P .3 *YIa&ɯ3?g1it$ϯWwpBo%ɪ0!!ђx;NK;}oUsuiy.UuϿ2g7D矉3j&=)矁&{)ݯ3<9=/<矁 Spz= 4RJg?$dF-$d̓}(el&Wɼ`]+õV~Lm2N *Jm<0Y7쯶m<*m~ɸZ/L N.ljJ>ߦb.,%d 4k7UvHVCd,FHݤ_{6[2JV,%nx\.ۆ-qj\IPyҖazrU4m6ܯ3&t6oRl8Z&Z'O)u&y=8<ꗫUHmR^]j{i,;hcm]M,k`V &G'rUƞ\Ij?[L&|"`5Lzf&$iv .7 \ 'U[xaH Rf#J>6*th~W|o!cɘes>9>>oݻG0Q<==E-r9űdlc1v'й~xxܟF ȱrl׺g K\/]ڶ}f)LuB`L/l~(}d_gcqXs9e@Zo(B߮= vӳҥi?֓|uA>L~66l3۾}-ǔc\+ J>ZJQ2Ll;Ⱦ[+ c4?_Jy?ť^Qk}?Jvk>L~66l3noL6ndIENDB`PNG  IHDRP! sRGB@IDATx p#}#&ùͻ/ɲd뵵,;rrV٣f6NlvloRw.{-KdI~~zz眜{M7=nh4~yxhv|h9R[_"ʩB ! :h9J5j]J!! B@ٳTsrxlPP6ѣ\fݟjv][[[z(Ϲd?_MRF! 0_~rrsl('}@hȲR@! 8&-oSǗ.R ,ʀeʥ?կ^Ú:Po~u+VB@! ROqSG41>B@! &P+/TXWrptY o֖ox]`s_rdB@!~y[J*wZz B C + OnЏ~yroG)Sַܿfoa[! 0-n`"B@! z7/Szo $Jnom*- :D+ۡ nF(P4!.?J۹++2E$B@! Kѥ/8+B@!]W(Pw"<I뛢فiZǤ^S`v\z3Kg g$ѶMMKa! B(gs#`G"B@! XTo4չO3=\۶ }`42ߡ!B@! 2*nrϜIOB@|_ɿXS4roд#~\9Q,`ej! BH򫯓'G,ݻ{br\! @W_ϝ3dcwhJ wzpՐ6W8Z <)Y dB@sڢɉqU) fQ45wB@! RHL~ yu]Z pDMm{k9X[p?lB@! 2륋_R쌑憪!B@@zzW@y.Ŀw.Ο~;\ P-ɿ)>x ! X]@+W\Z* DAyB@!`)ͯѫʵ2ۃt/>gu7J=gkKڒ $۴/B@A`nvGV]\\By8B@hyz。8U?~&R`o:iDRB@!Z3Tp // RAiM! I\.$ݛ%ӏGIetyJF- ! 0C!r8G6V\R* #)I!lllg_^Cy <!ɥ(hFh; C|2!Cg7#MWwoD{i8sSм4)B@M`*k2R@#`r&'+1?ZN! f8(A<""2@Nn+_ MIuo~[ߡtEO9rB@!`.33^OIo@! Љu8@( #9I!`6^OznX^ r[5O.%\CPu5BA!BB~pB s?aN*O^ X^^e`+ݝiz{=aI&|NٮG! @DuGW ! O cOK 󴺺jJO^IxC`%E! X\b S|xU"B@柆iRQXWR )&+_ C->݆1k^JB@! jHٵN8%0E/! EfEEgi :NBzRܗD@* Krn7EGRݔuxuCB@! $Ԉ&j el6*-5A² w!`8/^K͚ۉ#_e'"  9A!  ,$VD0{J++L/Bf* Gj_yEM]e8Ͽ]XxB@0u@DspTRZFgE ʀ F rL~Fo h=-k'qC ! >kkF]uq&s8“kS6F8Xs#e ī&}B@!p FG"e5tYN !`ɗg2GPDI:tQs?}Syz(2IB@A`c}O;NU夐NIy9!u^6x=_n02GwBԑ]w,Q! q@ ')# Mů,B%M`]3Ϝ2MnIDMW[*YE  K,TqBBggP<,.-m6CJAqҙ|Q`?ʼne +(B@!pPH( (@jZgc}=5FE%&t' ӧ͒ ^yIԭ T$B\¡X()$t"`wWceq~r$@^w=+ PۏT]j:JE`)cB@!C v{(,,"D&./ʪ@AHJҬz W^!g"W= d 8@˧E !  -Uu{<"&@tqS H[*w&޺yD60j S˭j+FnݚαZam^#B"L+?O]#V'lZE0.VLw̌Gz=r{(iqa4"`nAsnJ¢"8u]AZelfWTVK_i@Q\]h:NJE`ū*cB@ DiI)UT&!$aZ_]8Y fe̔h#X.4=9A33I t˧ o>7sJ-Gﻅc^-YIMss?,pq! [@RYDOT ,,cϒm! B@wEEt]woʘ,(,wX0&!p:T!@048iuewxvz¡ݙ@x>Ss+e^L@$6˲^'_jV=ʭ=-峥(J8B*kx[?z}a  Ƅl%t:5 xD%v;乴yr Vp#r0}\_8F6וC89@(@rwu_B@X呓S~f^E›MW+ᕱXMTQQI7CuL4vWRHaXZ^Nӓ2`~n8-Q?'0~!qMRXreB@;Olvúv{$ں9ch^$PH Z&'73X]VA&?BA'b>{WbO<#Rę9<q,~ˁ+ fNN*kUwxun .MwdeB@( aCh+L7ZC .1C@ V* ɚiWL%pxcYrs]ʤny'RL`-9h_D#pi)v'doRc$@ߞ F $'@ -JJ]}C?jar0U>  a}zX\!u ` N{ &/ׯ^Q\0v! 0OD6>VU/`+} }HuB옐l%pG4ATXteB)D.c"p;$^# ?5ބT(2@%*h0߹>PܸJV :d&d6V!QwAy(d5@`XYLFnEUyJ<Gwd7ݣn<|@1O'18x0ArdKdXʹM(fylm1߾uA*&+Wk.$M

!C_(Y80lf[sASGj*m+e1@,-7Ϥ| tq !MNV^7szGXnmzl(=VJo3uQdE. DDzL&s[hzjV sSVLOt)G'o~e_ 3p4RPLR<+ˊ +/ :^7٬omuV80--.c%?(!9nEȼQXTB}V.cgFV"BJIU"NGEԳ]{ԿmuɆ) ZAЊKBEH $U/p(Dw'?`EчLQ}@)4)˲K1#w3l &ﲸ"]c.(5UF?+vvT_zM2@QC.?g3p,8O9&iW>D]Z (-.QU X)zhrbҪCm\`V`&"BX78iksӸ(cN-0 sL(JRFdOF V}<iá"P"MO($ڿDL$3] @cc~]CSj.X؉+D" #? M7RZ7+!c+D@apR#@!`V~_s0GtDWj?P(]Dd#JbW7FuLjd5X؉+1kLSP; ` k)4AcJ;RE6e:U?㇍}~Ks2(2I߅@ N$<9!qDM U*eu58V9sSDe6nݫKE ?ycu{3;րKe&TX`:PIJ s^"lh"B@K+sX[YǭFLWO9]ԃ!RM LWcHkjcv%74jRv K 3D^m=n6;TzeDBp49ihı;n)ϮYerbʘzIo(\fg]luBmBZVV*vóatv3~_B@B {$P~*GC X;ڊ*ʿ}k@- سi@3RH vE@,(ǵnc??7ǑwOx@FBʧX[Jإ),_R3Ե" ԱaO|4!B@5<#^Y5T7`[)a}MJ*,.V2KJ#Mxt]pSp;3M+Kɻ!!X=?+ (x,"G[Įdu.Ϻ2;EFC:/éD 01+&2B^ dbBM]=yc܄knnꥺFzW4̰hJVX51bQ O=BDpbx`yt0b|F+OԩwmLO/Y6ak2Q 'S=htM7 ㇌@~;Y^\bӿS T(b(N:sm+Znj7H[m({ɃG샲]Y^h#;FnۓCWXD˕ZRV6r[.!o*d~JB g,O  h'g"'}@UU5t zM,MJ[B0p3Zkpx&x";#0氅B"[Vt#PlBbD#ZNmKkxD\2"Ialva '2w5(6 T/Tp{<\;J( a `ˍfʩDA0K!`XGzT xҒ"~KE:Hˣ⵫uZ/#˻SVV_6ZB@V;ꄈ$ƁjoT!ctMc(zПd{645SuM CTM5.B+(46hNDR1;]`L"88'FˎBk;_TSQQ19\Nr2B( qzz&v[GhmDʧV rQD&$5#VQcVWgߙ3=(N>1b̃\Aol&V$r&` t?3[ _Д(|%*!<[8[ ƺ3^9ݽP{{m8trsy;H ťtd;y{$J.2aj\ f,n(pB)#_Qk+SPNn_ZޫzD Ǜ{]8] RCR\A^4~FT`-E>0 d/ƋDXNr; BhfN09ɓ~X:Af%zL\zEv&-n-@4r@~x +UR} /=3ӃnVxx߁̚TBo`CjERo%%&O+}k1O9Nv3Y` "B*>-F@=*/&{ 9 e>pbs種M7tgVS0AqPO=^756NͫWhBhbjD<pF:E`4a_BpSeyl>ǯT^QOQu{H e_֖(_Acft+vPBD"Lk >S!`XGz= 5冠 -p7Z^ڿ_~.BEwl_~8~N>C.\?!Aa#SuÛU  . 7x5;*O/pn\ړl/QNe?-!l^J`RgMLE것xe&)-0L(v ZxR V^m-멯qb%שE+[Sݽs;٪ +k]h2kN1'k@@q :vr3/u؞@9U4j*v]]_TS4eKK2L˴6׻|.YS? Kf*"DrX < WB?bhAuvOd2}^Y_b; }&8b%qP{ mS*OPXz_K@{B@' j{'SAYN&זGZ0ā_lT8L+o"cI',O ʟ\.AO=t].7-ϥk8 K0V#`js3&g ~xwE)27n7Ru)LƣG8`5_weDIѐMӌݙGZ\6E)EK/?|委3Fw?PҨZ>!%"XaHT8n爻4[~{딿"3N޹Y^nP1D%]`*"H94.8LcTX5wI 7dIx7EFo?vLZhiqo—;MQh`Y_Lk +  ;Zgw/ٷ> 9mF~Uo?a,@ElD YG ,(JJX0*P2Y>KW0V$Uod@TD?!|oG85B^M!é(X!ns6 7tu ½{wg}o$]Tp8_6('(v󐿄&NONW5DU4_[޷rbԮ=>`j!@8T́E ib|s}Hkh {^ )IjjXQ3,a_ePPt樐SxSEIuϧfN8v LE @.OJ. ܜ O)~[9md=ߓ?$܃&(~^9sVxU SA{bͪE`*2V^2cL|I#2OkKserx[^Z Êa*DFLTOz5Ol$烟hfx*EC! C*t e)}yrԷɮ'B߳uVB<\2݅OYGmi,cQ9_l!dfl ?c/?NqEb\o^G*,oJ 6Ck47֭Ӄ05@Ks#sܯ밲V~d~'k(rS} !;'h&:ijեCLhme|ЯE 9k#/D=^?h7]\]]SK_~FOS 6U `)o,E@6b nze ~ /Q'K 4V!NXD41iz+ (ϭ~ha4}jSE϶D'Mr0J#d}yF>Gȣ f2p/-){_©8*+GE <ĬTF>4;=MM-Ǩ-JK(Jv_xQϫw:oS2bi!: Xy"+ciHpW76BUdv["U[WK.H[ihiKqC>Mk*/D !Eo9ܮi=~=W=,9?r#V sTg'G)/#vā" qx/v존l̐Ŵ/ t<"#:~/-wݣpp{Z(-J<;dPwWPf3w삝>g{iknnnՉSP;$]<%Pt~y4n㿤^crw*w+X>&"cB z}ylYc5:koӹ %/]|AYwJNC3Fc|RPCpTVz,:j9+Z!K{Fcʊr6x .yEkҗFu'MXP&(ҥ8K/?amMN,L}hui N%]rV`\ Q|oUV2t0S`a>?QAbYMMX"A.5EEŦRĒCv&Xa˓(,.KTxexWsD%ssfrJ 7?x{Pl~y؅xme,򜬠q%fc&̣]T]V >' ,d+ 8\^z뫿F> [{RJB %ЗVm~l;?)uXĊVE=O lBm va (Ƚ sjM>{r*{½*¦" 'c;:k]!Vَ,Bp"r=VPk :qY7 q慤8G@J@'CBy~nJx%9 I;s 7E\/\z؈ɀtM|Ow?Dmh'(ShA"'0ɩ+LDᴙ djB:wx^UVI>W<DZ%{,oV8*?߫VWI-U9[}?v(>-0Xi#<wTn +Et2A3kAEQSP10d3֞/|wK<,}G}Ôf;+Ŝv/J5L٭(Xx1Gqo {} 'iMTRI#d;8F\s34/\ŠG;=C)~$-Woܫ\ʽv%𐢸D9 n^ p9HO`yqBM9'^]%lWÁxňNd P_U'd ) ݑJ@e?D'ID3<L+04 cV#&P_ߨT"/r㮔B`h_y䶾idh& hk Ę2}ܝήkqw׾}f؁I(p{Ō Q37,P^bjl½s?W!+  y~r'u?}m,V b| 2h0{܄=^.*W_jtm $D@ a2@yC}~?z]ɿObwz?@z>L-|ՑJ3ci+&>P&{Hn0czy]Hw߬>V3_x D>jSV+׮|txA94#[&e{F(Q^USWG==;S҃΂ 0A߱ jt_gplGp@+|ĩY';LyMvw&t%}I^jU}L Kf7M&0ї@AY=O'o03}AДA Yŗ=&kx&'r~Qbʪ4"KC 'ٷzi"X1p^eG|Bl ܻ(-[O 3HM+PXyQe; 0,^M +l$vMVr%J"WHq8mKEx/x_Om@""OK$yJ_}r 5W?|Nmhj|B@y<JVya`1E͛JZ>6ݼv'tvlT4F/).Qħx޸9UGb޽?ܫvggFLy*UҙshłHu\,ȣs'tO0Od^I@cNMp"se-l.Gu|Rpd)5`iv~fG  OpUn <,V`v~VRj=F4>6QCue7ij?}F1zP| 0+έU 1>y%ý ~<OycLfֺi:.gfvޠ^Nnj[/ur E#plʡv3uV-ǎSGB~xHԱH!ı 0Iw;cƾ3s 9DS.WPm]=u޸+@YlN@V%2>^ϲZ<@-"@f(i*/믪l}WRp?kRݲ'X;JF:%Nt/OJs~HݯaҲw<']ChΫ++"ZI7 3<Ν|v2LV9=wfw%M93} 7{aܑC[3v^z@ @4N*{~ͩ+畱><B s K%ZyN~>{N1S~p冊uz[ 2B6ёVa웖E`#ܫ:Μ@maw>kslyN>M|wV>x]*6iMp9,BPV! 2@-ڿxAS߹O@n/̫Af \?fmi&n2'ᣕFP̔Of5N&t]YI<WO q[JgG"ʥ?Яb \~pV׃U!5}"B@@/jdAE% d |ZO$>\VJ%]]o/X>˞sB%HUhbÃMC܏b0H7|܅KJWg\q|]DYϕ~J8-^Qq1X(Z$9*W! K1*ww; !3L@TeˠՎ׾Beu@ ϑAͮ6ȟ Zr͂I6f +g8u.bl-tU"pt Ţ$QZ[[c,5 !+_ʫKKAMH `6r$8~ͦ4יa#MG'O15LWmK+"Iim+Ř06mCI I^7I"X -ND0OwR[V߸ndpDO"9=}iݕ_B Tq M `>c.\t&4+ǨW/`Œ1`,(/ZD6i|lTߊ36K"Dd{U_I ٟ|Q&L臘s)p>r4CK?GmE۴[5,*t9J_ˢQ*|l模zzԝ$T@4ןD3?{b =t:]<49x-ƴ6IϬ Iu CV^% 8;;C M{a[dS ؕ{'o[nNƍfr yB@oR_Z̫#|[ NҨ ky__7wGԻ^tE(\L߻V(te˸ݪolVG"~1`]5cZz^+| <UVWSII)}./ޤM^ ´{\T&/G]uL:0c0~cNŸA.\R=^>9'*Q&G@ϗʷ|Ŵ],]RQܫ,}2J:s6Bt'J +O)/3?qYeڊnэ?Il [ݹu.\Dn;uY],vEl<~͉鱢)7,#$UKIVr2XΔ9 |Ϟ?ϖ늏GOM@SDUGz5E[ۘSwsS/=)9Eg]9&V"BlJJJ {I_Whc}qnMURo̹ K@'l7;(q8~ 򪻩7V~ϴc|Ɍ'X T+0ج-`_6Um&4¥KJJ@ENgUtUi{+JX[[UV99ʬn^aL6s8 U P0ts0L B+dLk4<]*cFe|pMKz{ ;qK x~{)Eo;Oi?xB+ńt]}v揥`t]mcJQ)1`Μ\0>ڪ4֊x-.POOZMҌ'O$=0!d 2E%H$|^PmgfceMYYeׂuV,/HHȤսpc6Іy.V({EY sJ(GIX S^摊5tg_ܡk}4t˿^#疇JDsDW/%5m O!ebspR{^ٺH))-S{ ÓyUM3^6~U0rJp@AMT=rb' bY/6*VZRN&GE6{1;;XED=tzr[Z1tѪMG~Ĥ 4nv_A`vxZ0i|C!MC󍨶Pɇ|X-0QHT#XrL1}!Z ʪj|-Nx#}R>0,%ZO(+j' F@#O@1Q ~6rZ;Ye,OC<{ş:+% 59`e( \ LH_o/feUb+f[G{YW + oR)H́:o\7BK|?߫8"H' ktq^NzOvxzh`'k~ܶzQr?ltVcHԢ0,~6:*NJ.fg98hmV*s8$P\}Uua%8I~>1 ?Oxa✬tw%A=8x[d\Dc`/{ռqJS|IzxvzHY{"B `o~ܹ vz/}$嗫 ql>wbwiFX- )w9wD 'O)NP f 8L妎O.Vմ? v+# M5^~ ?Ŀp$+ÃAeEQMYf>YcW5Jl e+QvSFJSW%H7b=: %Vay?e,/WDs&o~67O눻oNZZٗEe)DxajkS[|n8]e`)>4ǩ9_%NW---)i 7DO!+"144^e(F\^YQF-u  GX?rLdf1O4Ut@/A@gdu9rX KE%^gJ=Ȕ+yM V.OSOWXA%_F6@4hR`X^x* NCrs_k6 W E;KQ("j"p*Mq- 435E lbFD_LN_b.{?::ֱ 1y*8]#Y T^j'Znҧ&؉! dS/\{Sh+k}ʼnoRt3rP3G@s`agXuTFiIG r立0:%/cїxƬo*jCoD' 6{VXqɚtIt+r"]v@Q:ǙoU╤('[ d-hgŇ?}}9ToNᵃ]c/嗢Eټ०lczD90;}|1ַrGJ$d5=es /Lf{vvspOQXz> r3}ȳΪ(SgZZXȵ&IpN7ּw}f8e ,sLMz(ڃYVk!@B&%[YhQG%miB'IBu dKRfwߦH8TI OI3ɓTUSKgr2=Hի 83(J>H!5D<9K;~X8*8Y6Ck}2L&??rerܺ J}%]`JD`ዋȖ#R>epsRΌ<ٔw!p DOCv| @QvowOC4j#HA!`'&^;#A|3tS.ׯQI<.݀\ laMT*ETw}zXaeq(trbAVVV M-J=N"PٖUIB@d5]nXfR,sAe ꨣϜ M4zIMK/F# #N xqI)&®UvVYesA%.[.8 V TF´0=x8urziyi)*SQf$T~'=>ZZׯBIgןܫCx<PMBY=ĩJUow?PbiHT6IӄeX Nf0)&FxL)8yelkY+RҙP3@9Ad'*Q$ܸ3O!`E/=VIxHaWM+X7 ^9p8e>_:QdE5AGVY_CjQէ#x㭊VsvJFR!?ܫ`$<JQ$ORjH7CōeTTN%ʶX]l=>r>Ʋ3u ujǹ TזKyyyiuV# Tr8?؏>Ξ@3CVՕc?:MJ(8\婍DT!Q0a-*.6Ңܫ8V Ⰸ咿<?e?~taqbn4|/K:S]VEcnrSx@7YQ?][]1eE{Gv%PPLn\rdTBrii1UI;B ,-qPmtI*rJx˵*;r9d.c{ PɫUʉOSN/mO]ME-N us$돩Έ@+12"gU(TL>6wܴ2%Ct%&Rt*~~P+dU>V.ңަ;yk~Gӏ(c)5DPX^(]V~(82 ݜV.7|"D[J4߻E" s]Mvz@Bq',@*S(`{0ohlR "-Z]Y@ O`U5*OA{lY3Zf"~ϧc_(ʫifk}| r% cJ:۝k&|FNP|>ߥ/0 4hUy+M5M@x]HLl &'+",D>|/y Rn,hg? ;CbR@]LjNw2~s316F 8-c& p! qRD=.$r4w+X%W9 env ifzh M=S Q'ub#~ŗiW@pu )|]$PЗ^x 9@]]=߫i X~9۟݌4MlNB!% \sȴ]$ 4I?kka#2n^ekWdE8ROIQ_dB+w'BĂ'.OC+:D++Z~.D?HYڊnY ː" J=;{M#E@2F¥itxP@u EH=!“{X̿-&~~0<Q!yLj꿽[[GS{P?m/-irt67Š?~4QEw5ұV~e mF~XMiQHX69EHjy->H" TVVΫ?({H +'8 픴i-R]˦~P!\ߢ+ۛv$IV)$yw>(œJ*6wX  )|rr*lW!,WB WS%Hgn7p ;&"B [餤#6o(w,2W֮ɷЏJUuZ1űDH/mkZiUfmS2@nn3$ %`hcCyDeo8ti -.sҨPT|^"酅yjk'`NDݏ ! LB X*8y$=J7|uS m#ϣw$(e?&s43=dB=jhl$X \Uګ}K'! 2Ψ"ˌ":AG3@ T^QB$Iz߫Zd@EdEpxRZ< ;wO6}%d-5uTǎ/-6)Vjoos;v)(TRݼy7pmtu2<z7^Ou_; @L,߀.NahLJhsx5^4˅쨽?:}0X"hxټj\DSUSst ܝP0nQok EcGxS$7+m:B Yb;q!x:8+N @ m&X{Pj٘4j_.y/cG{T3t٩' 3G H$K& E8/ց@@۳[<۲tZи iſmD ;F@ֳr=ϑXqqp5O̚]EŔ_0p(yq#40 Mf,E"$ ;tj[ˈ(,ezhG&)Su@J YT?֟s.?zynnn.-ZLiY5RvL?y_8ſ8adJr36{|&pV9c-Zx)UVW)р!*Z5QGaH  ;;;i1Gzzo" "H#>]B!QKK!lU55l䅻ʘLUVYUd9+/k;}Favb.><򬪮l$Ϫ~VuU,gwvtWơV釃Bamė2D[?@@ n)$#Ni|$s$P\ȋ~-b$^0F=4:2:l-,.*tjKq/9 QNNϤ9ȜUEc*<4/s~rzǡd% \i EL<)`0RȓNRir v󢽪fkU]},a~ qdp8DILb vptܜ\r!/W XJ\l u`Kz:9nD9lNlr6;XEWsm6+YRE!v&9f\r.BVF"aD7A%PPP[<$I"gG /?~ "8.'Ë7Yr&1Mv;sO,;0J:n,!`ZgP"P^a 7&fE;RoO$0 EE%|khL"c>wyoD+;|j˼h X\nM@:é KJbUc4?Gvj/9?E*yqGF 9\Qjre?+cH   JxztAzy'~H3sHTϊQjBH"(|v:YaZ%Tk.k),(\TmC]蟱\dLL͏oRv/3.dxfdoG$/2aFA _vIv4ċ~/m~*dw_/{&5 YPqEPQ-:;`* %\Lh&瑡av@IdH%@pPx3٫u08q!T^^kY/ܦ?րHānյajM4̚H 'alTB3LmJ8D@"ّ@ A--U5-Z[Y g6/:Fլ)+ӸPD:H} `Lfo g4bޢU  q5|Qs,acx)D8jiNdڢ3NKS|9|Z[SeMmLab2r̐NSO 5$ԠQVG05hŢPal B@l/YJ'B Ѧ#,˔._NaY[bUVUه)TqprxS$xa!)  5ۤqf. 1oP~HS}{'A'kןM^0k pRE@̙}3b҄y6nZ"!(f!Do  }G&7)ōD?7?1:f@@Y}}pY}=»z\{14| @ȮuMUVWibO߻Ba^vR&KhV鯛U]EVǛBttd}yuܐ/u Hkp:8'!C/󘄠!3@J ε$yn59D>]vҎkNjX h՚&E3QdŎ^P;;2w?%BUAaǿ8 )'oxvӐwt_'@`1Ycc@ˋr)*T" F% *ZٮK_q8cD";5uP X hߞ݈` ʻ8ś2PæGx9S>qx-hv#"Lp=% H fsW"R^'b7&zHe*$0"Q_,XT>:H8sdQ֪RŚ j>=BY HT7eJ~OY)dт~& 2 t[.A4!0"޲1@I`^M-]vD7OP`E kar:w"բh;n,C"gKEeeRQn!V\RB#)D_ГzDYg((*]b1cEuhg  ,#qEM^?6XX sI Pɯ5SIC+*uU2xr#O&3DbW\FVCp8^A!Qe#|X %~B?!h  z{/-/HD&VIEըYTQ/&Unw> Hq$ 3r:^d&YXKwоKOP+d/gB!7p+M?{ zA H`I:*/v~~y<@###Z虚 6C^tBx f %PM$TL3<8  `%arY)K)Do.Zl&Yn=|s;k!vzGgDE&Q*; J$|n^.o\=vj.*3.Gv=z9o6jnj`0/<+ P?,׬ߠ 51:w/9hDw7 /42VoBEgd:&a%ݢhsXG;FGfyCta.7{yZ|dY+:UyeլpaC &Ųw.,'%/wv>l= o(7?O((2@V m3/!XQ7I~߳J9 hd5]N &hy⴩KszA@ D*6/;1U~т1 XɘإS(nTNh$J@Zyo X  Ng@eu5<Ύv:_id,@fO QsP04ʒx'TEgt j*v螺zLX Q[_CN-bQ8ab%vIZlHDBۿF'ȘIFêZ1ED;eoT.B[e!]rm{>v`;C?{rGŬ_YU*;NqO$ ,[CUN{ܝáKfTus+'  0G^abA0sHI@NưqmL߇H39hu: xQMNGB~ /@_u0v[,V vf'~-&׫Tj;; \T\R|>q݆YG;ސuoJm)qb\H8D HeҚB: NGEݒKյn*; 4lcf.K>zε~F#`zx 4OǏ#Y~(Ave4OmiŚ5kQ(A,vZQ 6PH b $0a<嘑́e~AvaUM I#Hy3brFli#`j TS[OMGihi?qF/"V7*ɟq Nx?tYT9X#Oja,Zi~S_(- :zjdG`簍` _ d zxBGYT@@  5ךALڬ#2$E熎ţ(0$SJhx37:Bv}=e1ZyJX rrrNG56 )Z2G@@@ dbhݱ1G's b!h~YkX N~^օe`~1 9!):Gt,E "dw8) %gnqC~, o@v -)\.*Ԯ9L$ s\#b !@@ dt-Z4;NQъ0VFL@]ݹ䉔1G$}(| f%P^QA k=y98@Eܐ9RXTD2gZ[O ߁XVd,MR7AB : L <6S6=N/]23. TTVi21t=2GD sx!OlTVZFǑ1%!!5Gٟ 0K i[%j~bXO ALO/<`z2GDkNhL W8IRm+kJc9too7;մK5SRZ ]NnrQS[EӈD"4U€HvB/@ K@%nJ_ovNEOK+$sȡIr+%{*`1Ϧ067y'dAR,[NP7k;L#0Ú 6 =*H&h连dV܁ ](5ҲELJ'v2 **hM,dkU@` <   `LETYeg ! sEԟes Eynm? -ǏRG((ZZjomÚiA2G `r.@@ Dw{˜մ HV} 74мF tѷJv줪YKe3eН#E  &PR\57MAF@s(Ú@-;kݢM5t%qz8Ŵ|*M;t @`GA@ xCp:c2;2d.q3$4Et֪+k:w>(}3{h&MڹD%{΁@щA ot೤2gdHΥ,a2Zf-/~PH䁣ȡ(77֮s@  H"\   zEZCpzQctDRv 0ʪj:k*}{vўD س{Y,VZs Ä>@Z @V@@@oEFks':Lqt԰Emx2顷#q itdAjDUkְ&;6@:4@@t999$B FGN ;2d.ɜxH NR1P@`1GA@ k {B?k8U9)REݜBJKK)/P0(RQdq䅿j%Nv>\.75,h BcQw Q8@K-8B7E// &H/ܼ<##s! sH95p/LFjѼ D_ve~_[Ov, P<=ċLQ؏j>rht8Ё:@D   fumIf(ʡ gk?*h PH6u[s(:L ם@m}=ϛO6lքE$@rdS"'k8H^Ϧ/ v}jE*r列݋Vzх;es0==ք7Ι@tEԜ D D9xZg[w?؜F1*,*KW^aGOC 0kn0ujٶ djy?$ϵчr=6`"Lw>|G&rW>Rss3ug5d3'?P$sJV8[1H88 ,[Nݳ dvz6ں:p  $ A@I1%YGrlt6{.}O5 OF(;]B4"^W9;MS]ۿ?}h],t_l\-ԇ@yy9&+4>=LM)ϡ++SS!j,'0Kw۸TVT>jO_] J>$Bz}N'!7;'m}EɬҐeGRtnh! (иۜ4qv)"̍sㇻA@ B KݵME>rq_/_X?RY+ DS -i:::hjjk&8Υ2AETԐF:xz?DU:b@ ǞCm፮  4nE8峘_q!Vhg(;vcjXAN/[N:<%%@ozzziᄑo>=V2MH$2hyz%[wl=FYK$o^CcgowuC!C``=1j.(y|acÓNb^и]-C|bQ.b/XVv-S0Ul UV+:tȟMGA@ iyƿ}_b?@S`_Ew'kS344}>x}HelB< B_RQQ=St KcǸb'T}$:X֓]foy;.9}ShѢ{newRVPccc矟}^BV-Gw]?ª:}IH4]ٷwc$@@%%_GRf+N8#{U3\v~.ޤ?keE-]4Yӧ>irSJr+}he ʭw^t'W]S.oyr)Kѹw(/; 89j`vv0MB(V׍ij Ft@@%Hjvk9nze./OO,,O"4>fY n3UU]qq@җLlvz}KFi `.k[T^ܮcӿ"a -I5a2. bYYIMEKniQ|zgT7]mݮi w@BӋ/RkK+|}ݺ@wŗPNNn3[l vN@ wŕחWV[f*FGf7_cЏDI  i%NX|qgOțXn`Zw*:kʫ<1Uh 488n#oq_|ʝ߲@;ߡ+.\HO>dL ?x~WN'MW}$&Lz_\O2@`fV"52H-RKF `K1K@@ R ";.*yzfH@ۢX.'ӿ֭doi9N/wdoN//.Z:m{nZrA%\BmLcDL?gYr%.YVR*@YGbUj/i萰e Ԭ>T @ DA@@`F in瘡r}̱SnYnxګ_QQ-{et_CcwpIhKO>d]'W^}r? ϞI;ͥs+i!Z#Q'k@ qضq!ɪ@@0 !yjd}vZV{.YP(H&@;a3; ;~zL8{78Wy%L_WǩrssqO jk O/)+-ƾ\ @lp2-ZO_di 3plڴɾyK[h'@!z  0N G:N?Fg!ߦ_<S "bO¾:w_gbf75?UD+驧>9bUUw;})x?|]J1 .IU's psll2ioyO">h@&8GA@@U| =6^rr'~W::#nr^"dʖ1NGY) tj?eF/8N;ꫭ=6Ajjk|޹8 xܱ0*EW^}uH:DRtnT,bO?C@@jޒ  `tQPvQ2 8-丸U#,9eC6Qhuk_׷MZuqI1~tEJg?&o׭[GC^p2?ST @*x`E$*5K/\.w:?oϥF\ݾ-K-I%|䎮Zpzw^pJQw}S.%귵,8ݫ~\yUuxT҉:Q$ɤA@RF(2{s2߹Β)[L++IɍOZ\J>H哖Ghd_jw'6*$Lib迩S<\%^B+W5kľ{jɈ/|KѹP<$IG @@RA@Uh\B xnz5r@R0I@hesC%LjxO\0۝:1vIsG<4E">\.}k^㋱ϩ:jDVE=   ,mI$v   :(-yXuCE)a>)|x%v۷vAW~E###ϩ:qǝIB?UQ@*JOB1{';  L5.މ~M9.g+مFigO:6̰s=40५?t5l''цJK𷿾Owǚ~$ YcqIR~ >=Se&E֙EN7~_ 7md'+)e?w^/-^GG֦{qM/O9h^F)Fy  0=PόP_d?_Ȧ\]0_KzlvWX 4&ٱ/me>VL# PGna "c蒎=JA&B_n+;**i;H?6wQ}}}' 9P<F@iSHi_c"r,ym/7KgO&Cvͭ6ƝKێO$(~PڼJ k!>¤(xkF#G}ce/>D!شʜJeݨ @N~\#pwۚwX] } z  qwl ӫp:65i- * ^Л>8ы9{-Z8vS}rr`?Qd?6r꫅s$ە7x© mxbԹJ<Jj=O۠\ 5Q @ RU~Rݬcx/--59'ѹKd/& j^-]t~]SS`ɗYc{c\W*3 @0ݬ5#`qZ4@Aa;>z ^j%;\[D7:R iE MiyݣU67쥡ϮkYB2S䵚x̔7CM#wT!jSrrsA$|cR"<ϩ>9#sG̥T׏@@]Y8 GTeZyBOU}fӦ;>n-ocXc=0 />gN)dX  qPxE`E$g%?}s&:_Ѓ; /tq\HH6zt~ڛn L~-mL<6mLY.y0Sl@(  } Oihs7];cǎӟ4-ΙJkcP9@vP,rԋn:#sXscap8oy?[3=fvݦۗ^w-P!EuI{wF)r0)JXQ23OH   ]J[o9>7:$@GX|;C7 )P4&RL 6mz ]U"_TyJl6WKճ&{M[K>6*x'[A-#~Bm/_#r @`2 RiyS+xm<@ ZCuBm/l~%_;ޕnף=T?ΦZ*g#5eM\NaWdUxbΤV 0G}S675)HpMDCbnB2w@@ l/^Ty:c'^ʧ>i)7346oKop/ܔf Gl;@@F^ n51OY5.\,[yWBM.}ήy?|1{sƛ?v~ؿ~՘Lnl[Jv! =}l' yP*X$3)Rq?y^H_\^H8F"o Ŕkc I"gm,E{DA2~2vaQӝFG2hr #lNJ~3ɮؼoJ5٪~iؼ?{@Gxe(/5dNp9ĉu7|vCE % 4.^BO)۲\wӭxq+EUGj㛿X-\㭟Pw]Ňq=ɿƷ   .=' ]>ZjCĤ:w0 nmqPPo(~$=G7#t:iu*TeCwp  q˂vx:J[VSBAFi$U(;uNI]k~_UچJRPu$ 劇r]ZSGJBw@@2T>/#AGz***%Szr@@@7r˒HR#\HMQ{oK?9 _ds|{co6st0;F hkUccfGb;].⹠05 t@~\rpڠU#UT6m0W(ŲietJ>ڦب}'fS'E2;i@@ Ztp޴ H˖SQQ1v7@@  Q%@zX\@YxԚv2̉7  EQ @ <)da>Y7 -H)s{I2dN @@H4G  '0^vK5BL/yϱ_6 t@@ Q$J A@LI᫮H8o( Kk.UBkѼ h{ @@2|d  i!p퍷E͕+CtDHHZh HM*GZE   U ȪDg@@REoס?TI- s#*ށTUoz hŪ]͋zTYЁ:@D  $pW}޿z8G j9:g~ms. @`AGA@#es}ȥj&Gӯva˜ʿEoݥ}k    @(@@nt#/WՈ֮FX&27VSeudjQ>6r@@@Lp&|   '()EvVxJ(Y\EKQQq1#dk',9>v}*@@@% i"$NΏD"?`W+~:tccf;.beXn]L}t@@RF)C@@B]+xsΊ*^}QN籇E*󺟆ņn6|A?A@@ U*Ҩ@@$R@d,] p P?@OwBcctҲq;*[,.?ÿ)  )"@@sظU!"|(,;'jx_RZE;?|NS@@'A@@  H#|T   `>7t`$8G /ށ{(ɮ=%TZZNEEŸ=Xv=tA@@CpG  &'pm pXaa@7 zMeT)U-V;~zTA24%/kgN~A!V{BR~LѾ/@N_P3ۯ. GԏrY `e eah1,-ݗ}qSn^>fOlGEj @@@ @cd8G.bwv@]DT?S$#!+@ah# Gbjâe{}wNn^r KNO rd?rH,N ?>cn5   Hnؗ>l]}w+8l#@^ m4@@>h߾}{qj- XPU8Viâ*,(Jw|(jU0Ê%Xhf~k8A][=T7Ƕ?( Z5o}/[wQu琲z^w0@H g9qJR\\ܔ$A|ȗ()) o_C?2Ɛb>29]u{MIRM{q#>u-G>IENDB`PNG  IHDR szzgAMA a;IDATX c`#=aY d`b4#,E܆_rd 0_HK+飔;Qm٤lKTax(OObddxq #{ >tr31%LDDmq X8w##k&VL/i6=xң B>XzX!'2Դ4tBsB>$V,<O9,GF-n>#& "`SSB=&d``WL=SGM!y&X7IENDB`PNG  IHDR }JbsRGB IDATX W=Q~/qB68HsrXب`g%h%l.v"6 6b'""VUlKsfu |ͼy޾5f]/$Ht1bْs Jʐwu?FҮU OՏ?Ed}VJlT ~Uchϒ'UM!$H~xz3M@NZv}%sp. rͼrk;Qf=P+ cFYݓJ&gRހs Iȕa 8TxDZ@܁0I~ Uj+$9޽08v]Adgɚ[(uCiP%EAI9mVS I*y9ڶ(˞Ŋڣ \ϸzOV$p/OG9'uJ6'qsnO^O@PRաxIGI7sNǍt܄aɹa7ƺmZyU&mNډY]I8&NWZ3Jx0bXi (,}k oSΖMCm||<8Ja;NE9>+E龀8FB۱DlrCǀ[,mvq%ݮ>kZW|!UہTq{>1 |I/PR W|#@x8cPXH[A6$ԡqsqwPTIENDB`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+`bB b&!$o{͖{ݙB#1&I39s̙3gfkF,Gі!d',ݚ㙨x4YfbQ5\alt(LS3: x`=U4leWo 0cplF[V4lGwJٖ$V@x1ɕ3n?O)DVTR=ƶ5@U\*mvd~q~ I֖t[7͖ lQa̰w[z75kF#6= #AnbTmu3Hv2NY3⇒5F8OhRw)k:{LBG8y5:xIԒFw[g9'1Pxp߬,'' VxŎUTXpuIw>-ى:R|%jB:Xy.bG#xv-}'~ +hƝq+yK T+;9 \?*ޚM厃ԤWbžJX|5 9;,)>f!`[HH?k a 轚nRv*Pz^:URzeB+7J Oz~m,*ZU tRtߠ.3ЇoV*~zy11]J^d&2='4\A1"#{{FzUvQ7IENDB`PNG  IHDRRl9IDATx00%wnkǠ  `0 `0 pw} mx9'צ{MYkb2蓠ĨoO*Š8S!Fvη:T|)t>Nć@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**9i pHYs   cHRMz%u0`:o_FPLTE  !!!"""###$$$%%%&&&'''((()))***+++,,,---...///000111222333444555666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~?1tRNS@fbIDATxK Й]RQA7[X(KJI:+IF&]MAQ32 }LQ%7i#ɚ{VS Ą J=tIENDB`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  IHDRr ߔcsCl0`MIDATx^QgPw3Weo! /0|,"S~zW0a6ɾL^)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  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``w8csCl0`MIDATxShHo3ƞֶm۶m۶=l}e1o kM)RJ)RJK2\\,!Uޗ>Ϧyϟو>A#8N7sRW}NS%F%u3Q*}Iog, 9$ց/Q4r(Y0WOu]z.uɸu+] 4@4@4@zf&h&h&hLf-GWn@yu-ô_ tp2w|/૽&@fw$c=.@ &9it>5.9]qvq0c9!#Ol.f AB6e ’ 9̤^_g&,۪,Mks(tpA3f;q $P;O(u& $b D1 )11 0BpH~Ŀ_&{+5/vEg\57|H~|{|нxnE>fUAz"6|+vu --;ejѬ,W?_]ا)f.3M:VܢYo,Bda0kHk:MZ 6ur;BFz;1$-xcfgRZŠ^|؎qlyqŅx0v ^-CN0x-V,uYeb>xuX ^\0}5J,^ V[K@Z10Y#eGPMQԙ:0?^o?|*d:hX;Α+|*Is؏/'&s4吞F7 J0D7U7-qS&m.P7ÜazA.G5( CȲqp$_,T(4wW! \PfO2Z\eh;0e|-zDBdOi&--R N߆x‘:`1\㴶蕆9|7"%=qR_>&mPj0}W0Ԯ u_e}V$J}3 9瞫 lu?Y731ǂe<6mct+wk)D0dL#?-AWpz0 tImwd:*Q5nT%u^ xS)!IIMkrGNMG8cg؇7I}ҧuN0DTm@U* c|V;q˙s+tVV_c6me녱nR#^HgZ  +#c|Jra ƆMiuOxyZ(1F$`֚}o5 &XEg?f !QCҍ2|HyIlʶYN~cMCVc4ҋXhQҽ,1^.#Gq{z^KTweQ(+>urdw}ۇOD@7 Lg:[I=Ho͒0 >E&g,,x7A찬H e^ibl"ݥ¿#7cc} RJYR -sFOMg"sT azơͧAAb?]ݹnmpw{)N⾗{`taxޙuSGz{KLvGzٞj2# H! R>D*jLJYR?|<`1WM 0>q6 .BkH`C|zk uXJNzz+Ɖ-B2}AFk 2e\,2J] UgK7%e[vi."Mnׯ ;'M 0 {ϮVAx]\ -,çV?2p~hRG!}D$vHFTqE0LŎ| F ܭs7vdxKםmP7/w?bIZPOF" /½wH' ެ`UAw̡"@\[A(B8~H]Y3۳w\%/ˆ͒E4Eui.j׊aPr0+ݳogu fMVmzh-UAl-6S֧}[gq:~mi>o;|Ӡ"XOQSV%٫PU__/!s];W_wU > `W5}ޗ4F"ʨ}"{B`q!C]/tá> 4ʣMQEo{Uy7>(#J>qXЗ 0M0fgt3?nŸ˫7mtFLUa6;T]V҅6lt٨&90c^7g3"hI[xؘv$Utm8qWXĨ@8Æ7ܙӝIo0$ְO}kPmq^%>=1mL > O/jO|`/+ۀ>U 힤K:$vMG2ވ;cdoB ?_=yOO+řWGNߌy6$d*ҍ $p:ý2<3dtze5ƀM<H{BP `ҋ,O{äˈRaOBҶ.ܣ8{lokh vtHدeam 06uU,_ ,>GEw5Z?-z̬k`{ml|q}@f[J|L_)St˳>şFڷ^hJ~:um AsddY%!_$6u~~gm{Q퟿dB\D;za] e$8(9EI }?Q1F_=ic׷ڀwiO.{@/ޑsT߽,~ 0C~?7A-lUG/& ¬Dͨ Zȏ?nc/ CkQ ]fUF+ 2ˏhΪߧ52hXi=jI?u-o :H7}W}7~-6p ǘu hʠSᘾ7]@hkzڼ??7bޑ*z;iN 7iAJC=CvbLo,R9TeVUXdUނ0OzE/q(YȁB5!M?{N0|sސkC!_j/ތ= O j5'y%N{UA~Z hIs>%S/(xkXfޙCQ@Hwv>X'|҇A?ۿׇn>}G K >(?2R5! ?2\B|q}}S2MPB(xh3Upt%+a~XGzU6C[=_ Mtў);ӆ=~'7>I ,kJKYQ sAi5Խ>ā.oe[v\W$flLN&tx7۾ p<>1{]'י;6eYx*D ߞvh(ҹPZXY (19}G"ph]n㔨n>Yof`VK[0XmvB2)Ll&MewBJ!"tsR4}Q,*G:Lx[툂դ8[wjE4 j,a. PPʤE,uZxtK#rO#p FrKN)\S"۩ :vBi2V 89*aUg9!3pР˓D_q+wcqøGHIA%y8$&5rk=MwKKmٛ+=d ΋> kR@-`V&ֹ(&IN+֦;i')!$#rjz8) ):h>E ƍ~Zߔ6E-Cpyl>x^F3E8oiQٮI͕FCcQc Pj@oik ⤟fK#5i׈ik=']!*AuL4%lzܑC^YbvG~-%˅/ɣMVu*J$0묓Q`(Xƒ{WEr+*ӌb{`%jjx4i4a/:Dn2˩b<-vܻ'kŜ(kl\<.0/,VS$"k{9qY9s6$Jcnq0%,RYW%N!;š'L|T$'8'd R˙I%5Ha(@i0$La+ͮEG9eD<[@5$ 7{N|x?t7Nv{=l1@O;ZenOsϲ ͎O:Dā_ ZŵWjJQJ"y(]m5B0suȟ>ɴN]APIӃnM-w4U3J{wa!%zQtܤ:`.ybedX8 ^d)CsOyZ2^F Ukq 0T̋sh4ބcܯ: 5C_۞*]JLr4c\xNoi\;iJyN;f DM|-ߚUf@6اi\/}=/nlnz#4io+.&nokaFHڗҥLY4MBa6GS?,ӗ'Y^ qI$R=vnrh*뉖o_]rq]0b5('u9 fȡxӳVi| pW6ɞ5DM tzyI+`EwO7J') 4{fqڽZ"XIԌA-Hy I 12ݫ¹YY$-sQ x(դa!ALf"~O#( =P? ,w+9 וP|xP77~'HЗv))R+5}~Xsh H ku֪`.:- "+pҐCE /5e.Rm HU&hEmɢh9"WSt{ɴǻ@Gm[ [ R$saG \? \Ug_!gݤ4H@XV-%]0K>C1emɼN3]DW7)ω%Sm<|K3vٱ8#_N*0$ 'j2dh<$-I`/`"0i݀ێE/|.u虛!;ªi{I'.]!00:pd 魟vAf;Y9MN ts wlOca?qZeɕӑs }ۡryţ5/5zWj s(,Xw-`i?+ruodֵvvyڅ>L#=DxJ.zkAgIv_&<,@baHwӫ)]L!$P.-?b vyZlFnҞ$-hsyjqPYHcyr wn 䁣kfC՞a1e>xj#pRRUNkg0FxWMB~4IsJal"XE^%\1ܲ]{+ws' ( Ȼ$V4ծ҂㒝boPn7HEx /=kv2{rڦ 0Ϊڹ(0$<ظ60H T/+~8GLsb.E!w$HjM'H LE=]P!$f䷥[D"q]*A3ls<' t.8ݹvJҎ:j}<˔Ť{uL<2dlȼ LHII\SX9's0&x9ڜhZ_ R{B=8gjZUBZ9&gqCz [JqJP23c!6\Ѩʋԁr䩹yFk)-ݦ&a0FZ+zP4JW޾0"`ҘaT"K!VzYFmdJ&h;18t{ԕ(3E#R؞z=bLd_HoQIh7v 'jlHX\r] hY8~0u;.1B7ֵǧ7(ٙO 6袰bYx Ը07}GO(ޣWKf } `7@/&MDXmw~(f L,Y']GTOS9zXH{/?%. ʠ[ۚ|g-5NbK@Sv^'6vwࢭ<6-Tt'i'tw/+9,(1, vm":[]m`,ۊ1 !+HqU$hXo3ڨ.Q!:@ Nr'cL_%B f^1\-%k鈞. M1U2ӎdX*W"?g1Ne靍wrt<oϵHlC8&t*Ss %3$\e_TI\!J;2}mrm20]4·([xUZͻ/mejyL^4ky,T.sIlNGD;%aIW ЂtI4k>?KZD7Hy|Htz|9\97XPڡ{VکFk< pB/4 ZdE H@H[z+ڗg<%YG}ZAtWXƪhܾ D韒%,فԺ̸-ET&+Z&+ޏAOpg, { JZ۝җoWqZpiˆW'zT`pWn_á" q<1:30s4y@l^CB]\X-i.t\3v\rZT&잮(:z/ps >N"+")\$Iwv_OX7)􆾫yiB)0u$MWħiF: E`o0'PF"<*,sY){0ȴ҉.Hf !+᮶A5Mwht$sFp@C`$TyqO@>y+ȦX{ROَctm'iEu|NLqq-iLEWi#F2@ŠPb`}Liq3"MVsteF2q_S +Ipt׫랟JKS'Mp2xusgR$R\%d/9.u,cq|ܡIfc@$rZ5R e;Cކ䑬(MMǙA*sppZ헺prv를û M#&HNj!Dwԛpo+kǥ0&]1%1Qv_k찃2BȂn\ vr_G= .F3138Vm&ȣDMSpY #$.ٙVfpmy郥Hӵcȍ,i˻\FMH0 \p([nbjb&F@\hF~h*C={X?ؓPA.jTN_!*"LRb-bqcG꠯NuﬦP|-v` ifpO Alz`A峽&ipLZ85v8?tIӱYa +"B:+Iq;oBZ𧕳i/QEy}[LH`l";#}!VYkݡ}=@@ׇp` sy]'D9;ĕz<Ȏ6x=Gta$c6_k0:iBZmƛvyz8NCm[=,KA<Ʃ7_bIܬ쑘=KI:4uԝ'Ix0嫠 |J ,:GzLxX$DUsy`$#~qԉ~BQlz{gG|NkCuHH[#FuZtXQHz3-vqƌ]eD屈Uٟy.7{Chc%͝8f3i A@yM5;'0gڼ&rUґʸ_UQB{^C6kBP !Gj@!opLJ5lz*7,>eƋbq{v8Op5j=iZ3XBqRJGtӜrY Y)%V{ V;Nk1ɜ|PP% ؇ذ4}aVET0$2l1"WrK)c6+ Խ! ۣ/mMY 8iz#A c%q7( 'uoZfJr_pJ1iTpY=nٙl_ݮaVoϴ"c">G:nȗ^BY0gݏ]hƠo*y;r47+g[WCh^JA>[zjԋkv21S <:,Rrjǘ Fyg$%&j-RVGV/:$|ge;Uqػv W+'swY$x9oh 2ՙ'7k`@X}p/fTc`@v{.@,4>X$PGՎZDS%x7c@wa/u un2Pj b{w/-cc #ħucޏ9'Sduώ P!#5%F%#E$1(^៚p$[;TECG5+I99ǽ4,ݯ!Q.;}Bpj26CHm<|E:,/Ax0CRꏂ42%2EuQ86;?q?[3rnYGM]5=儝DHh)oONՄmgk앳`l٤yA& #@3 @`M&hq~aG9]+}mOL dMHxlTt~逓PUvhz pԿy` bs)q;n^M'-chk!MdL@`1"F&="nLoRNpNɖˠ֡}8лc+uM5Sy{Tσz-ǘ =H=`|@m8CpAaG!1;]c\ԘAx/cu6 PoVA9=݅OoܛcmønV`=,^úEƒIpd( DI$ 5l+trQzŭ 5,]řLC).vIT$(Iz~Z8/10w3E=Eթn3'9^&l2- W +~OHog#?CbTJLv"FXwC<5ϕgdծz>R]t$9^聯^M@F{KC=#ر>͢PH);^Y]+푝!t=0f⃉fc>Os3~tZr,hYB RnP#V Gbbxc,ɺhI}CE??OۘM۽wj* ׃uCz8!A*}$SbIϫ[0D7[Z|2G+jGuSɒFT펥eW J~Mj=ٕޡ#)).鬅5Zap␊@SnsD :t_εc@㕟OȗY_< -{}]]VB:'3ϫS|zkDZANJ9j~h̛jV2.,]g[pĉMqG#<8Rܛڋ#HT+v*%QJ(c1xt$yT՝t_[1)u:;s]HddqAn\ՂmsiK;ݣx,U=ɠ:t~ JSШm#Up2;Z٣-fsxzrY5A&IXAbd 52/7mwNږ;8Nps  $cL)52Y=Y_qm2?VgD\^>2WԙE2xӝDzO7TjFƮڿg&K ]kK~[UÑM_?0:w Q]@R P ="t<,U!dXmͽoWVQuǦ.z$|ӌEH<8nw+-Vvl`cqoyK˭_=O_9,L_Hp{|td56z]yW?qo8H=ZoeFLShYg.{rt"% qI0>zw!AOA7^}tF.5w|q/-%;"ñrn89T3v#nνHrOoumGjU=NGtHq§^Mj.½ͅCpyeV/$#|/$PABHݘdLɖDXe!ͮR,𻙘W. IQeʒJ),,`=V82!e%:oI6PAϞD 'I2hh-!cWce- H"q}8y%TWB[cz 'XJLRsh^:f~'Բ8-wGk,&摼T7|cvl G>C/C-&^}oΡ}ީ0Ӧ>,~~qke~oW} ӽ%pzu2nU.=az=^?)cvs<_v}bO%WJaUH߼{[yjyv-ݱeGa֮e~ߊ t/ao_^;i"x+kUKG6HNr?zمoe~b/$Fm 巉z;H7P~l\s[ t%r+`vsud0 ; Ev[{= A] FRzg5[ ;NXCxC9b6Sm, bلiEˠM]~PQY=O[nՆ:(} 4KY}T07T7>&|T/͔fv㥔-CA+2}AAs>h_)(uz;S_>EqZktpa? ;Z~^~<l0'HMaz2ۑt&('$6?mrK ? kaA9Kf%U!Gude eI˸7n$ܵ`@䍒MMq-A|v2B® +tEn =81ҁݪWЇ[2] G{m;;ʛxӟ5.C<΀yN)n{n˜Mrk*1ׅ8R[ri',_U/~cj@hr4nv7|] ޅmU?#w?v}wy'iU}ۗJ1AH,]͝LPޙ㿱5a|n=;0ċ:c`L~bLS Nx'~k&~m7^&6|6X2 ,|wϺw˧mjWlg}qo9ev(j%4PoXoi9}GXo+}$:=7쳕6 N~k7UzaG;|:o|vLFR=sQ_;KgW s.3yO!i3V*h{tv;Y>Ԓ钫]-HEӉ;u|ʂW}j{ZJ9n>ro*Xޙ֭ti9|{Rw8\KU,A1- }?vce@5v*&IjM]etwRB+w=a\32{hϢU)Ro19m>c0EarƄA=WHA"hX <)N\j=% 7<,ZB r\DZnoh큳y#~ctp~bY#f%m=6 #~_] DQh 5nk8(t/GW^lv0_+[Uлv jW%哿C"MKQ fM6|zԺ ;X$[OqLIDPT{`/#_pѐ8GВP/Yu{^2>ݴ8gi}xH'+Bry0ƽ>W.(\nMe /_'v!͂]qgPUz"ćer<}}`~~us}k%k+M| Fr^O>} KjX{aLqj,hB&2WSYZϣ>1;hG3,ѿSXrF"3 j ",Y5xn5:'LO+M^.|x;Fg~>SW}w}T?*_'Z$%uFk~:ǟqxm"¹}s(j) G Jg(M[Wh">?UIssS !^9p8phZEn ^{8Tc,<5o\Z5.ںLsdbEXo}1i ޒǯȝPP5ԄKs(zlڀ׬E29TEaWЯMU^ x*8<n30#D"!v H|:M%cP67EhЉ£ e"^5Øz@8ҕXԞd0&xбyX3Ma% >#ϢdBhf0x;Fdsfun2-d L:ju;iD(B9lpy7$u x6l3^(me YBImrB7-U*G*n1̗1*Ԟl n w(%Ed?c\d y:Y jF-}6cq}~֩"~iz{5sEϓ8Q{}=;#ڼ4qC# |E'݊NU<3=@4dN=U V=>3&ׁ_3'c E;IH MSe21NL"36y .vޮ&ͷ}3 U  jN}Ok,bdd Mxl-?64+ȟG3K1O_|E}}R8%?ZOy~)Ke^KoV1>Rct?k._Qlӟ??E;?|3J?>"]C*fĻ(D!`7}RA_XS}PIO ZWtgJR_K5M9LG?_ۡſc!zsv tTu5?`fsf׉҄2>T"Jxw-{cCv}=97g9c_m[v Gl 6KJ+/19"'9bBGaNײ}%"2Zp'tq'YpD+a('ɱcb v L(NWbpW -D%&'][OxpY2|l}yuո? `*)q) (n2L`̌lT=~'S9Pl'pHF J5?Do3yy˒|&9'r}Xhz|Lqdr . eWvf" 8+Ԥe+j.O ^tHf\tp V{T?u[꣦'1AƈZiw54K.g՞:DBv4nI*Gڭ  ZgZF lj;DuCĕ;[8ĐśKPF.jC[<^[TCfy'ráb.o'k+Cy^t`u]JRȝyJ@DPWlesJh'6hNhB4NnHoRGe `է[⍼6\<79~d݊u߁XԾ " |x0]UKh%#>?-z1uY {bS;x ]­ ຺AZK._ ks-Gz#q( Cns4 e ^/ gQp3i[ζrMk!8:xݼlڣHB>*XE"嬢/>JWmL"סyR!g`c^ȓoVgSrA2(t5YZ@Re`5[{-yBbz;7)%labq~D\@VwYߥ)0U2fK˦__r_DO9ٟd_[AL}}RyEܳ~6>|OX =r:cV=?qR鸞VT)5(raKOw21 e|! } {݆hI$2')[&E O-M󄐆,ڜ~@~S959Y1l:/1Lՠr4gIB& |#0o=$N2؅'W@6uMx/Af؜#+3("QM lN7 njšqldMGbjJLzG M#H尦غ*]O ׊synkh-'rcnQkPy5J"լh׈X؏Ar2`W^vW+a10,o|-僌Ry?+t۟{aK/p~1nvŋ`x򔼝"7V<3hy5]a âu AAɐGa KD{܀ѸFF-cq:҄%r ! '#'GˏSF,JXCh~)/4%aBp  _p@O]n>q$3|: K ^YhxǺр8sBwadhM;g`Fj I *exZKd3 7Y'fe3ײs;g#4x{7Bwaך Ptlǎ{$7vbvؙR#6OJ1USf?7@l(񙶓WT6DZ+Kqs,HjlDoXkaz LZQnقb"qv6u{ײ4>Ӌ Z7Pe3f0:#ZU\J^VNAvާCjX]W͗'M7RI/H9{AC)|y圔Juzs3{lZ P/6Lrx4 YΨ|:t`~A~JGyirn.f`>33sӹI :SIQ$EC9}'pD |Ut]þ)|iNh޽Pv ݿwVATLG OqK,UpbeA-A1~H6=R[['+C?FGmW (n-Pn39eSԙ5ts?2`^ Gvk/n`q*hlк,4/:q#G/[ [{}{; wi)3\8Dꤾ< hF ]OY"o =kC4{t@NSvḪT[OǦȥ;k#C$az{AW.;N27xZK%Zo8yLM(<=eRJ=}aHmϲhǀbz!iIRhSȮ3udpo |tce{aNv^Kx!Dt{\/+{ )H2 C,J&k9v!}9;:\RLB}Rhj[ +:i3c LvmU.'\\\R?LF9&ט3׍!FQHQڐ##5^;|T+$y+б$  ޽2 9m-є}*qEEmLعSV[uG:j Bb ʖ撓9Y)n,D;\"ra>2b@[۠} Ēq|n>ݤZ #):yq7Nh(;)V0:06Bڲ}Z&uWHLʹ]^z_=pt C O%rF.)z`W(3v!!Gwfa^cJc|;$}m97;IݛvBȜoo-ȋͷȈؠ5-oW<$/(|Ȅ .@c]ΦD0ܯT+ϿX91ՈjޏR>xU2e8Xw1b x|hC^08.u-=0Okr2ceN_-[QxXp'W48ϸ.F&-_4y@0_jSdy*>Ύ>HyC>aq&\\lޙP5\CCUc5x)[9B|$4᫐y.Bv q[,0+ k :B5,wSgIϒY~^!agUl> nw{K Vol/PNzE(ea;;O b6=k$c ]Pqwto}pvГCڨSƒߦ6M[y,d<}r"pbr9PKŧ'd=!‡mSz$HUF0^+,5k v g" v]/j!m.-0CdChɟt3iVl4WG#m^}[Kpb8aH+_XF b xN%K5L?כk-@OcVo9bq ¿wBۧvc!qz+i*_ڝioRkw?5}XvPgSo4o_Wѥ~vvm߂>0f?~֨F"?~/5=1fz{s_Zeʧc-x/Y|cFb1~.oXCCz+hSwJW<tI!c8Xǹn'_~n}QoCf wl6Eɓ.q9s/IK:/_~EQ(RU -8e^?R@=5(n߰,ţ}!`׮[6(}J*ra 0F('@Hjx!ؗ-2j۳N6Ѻqj`܇d,x@&*>XqKK): ZsՋkWtv^eܶFn$V7 :و4(n)}ы 6kɔ.F5Z]k7M׸@ͯDQpICX8_u WOϗz 1Dœ\+v"e^9xv|6}S:jHzuފ>3|tۺ2H'>*5 <26&rl60@shĉKXkqdZ+M!vDyFP5pt!*y~m/1<u6BP^?t:}ڢ#V!`nIn8R@$!I-|gA*7ͻ=8C2TNrz*f1;vևbҳ u/\Kf}\&]E޲ɺ㾞^] RNԜ 0~@Z)5Jpb paCy1GHySF=(dE\;%qR pjT Ҟu|ڧF4P)I+=uc(he&`t|#ۢ)Bc/<$.jáok`U[cЊ,>GF<$̋"9;GMFVEtkW].QkQHXǡx<7 <;t5r? `=x Bb O0 xHp7xPC}Gŷ?e{ |sZ2GkEWe(tp[$/"f{!WP`gI:)M&18ۙFͦ^;X\$SS綷dj`e^`E^ M{nVDM[VMv:\y8 ]&ȸ*vhvyKĪ~%ܬ(^54qqZ;TbיRlUJT{(`6M_[MeZV U4_g>~ʠB=*v S$H/悮;bz[fvadGl+8F^ lz oB áOfL (/}@H{' e[XkS'!VFԕoB۝TR`"%"Z]J}_ oPRի>g:k_J;Z13l\5E:jBuF7Ů9W}%dU]6X.nG!f4ia 6iljIK!_MLtDULLms4V<%3: {$Y;-5]L 86)Q(n1p-elTT:W|֋Num{oA'4!Cji oo+CWTU{eH֕aW])ޭ-Z[dͲZe1e5VE,faYъnb0rg\z/o[v궸p#uBY0R0+*Zn!7Vhl`l k jZ+dځX~?.bZt˒t3&S#s?`:Vg׿`~uXw<GSRPto@|dNܪGƝ^-zk 45zpG pJ׀A|)B:K*Zzw*Bi0t67ۺ[+VZxzv_/?IluJLf": w3Pe. (pz971BNYbxsfB1t\N P|K+ybNmG3''[ZY'U@NBI Ӎ1ڢ{BɊñ'>g۲*hxidXPU" bH`P;hHpi*glkx8Wp˟H)^S3_R'׵tV)2(>`.pF> 7˝8%\Z9 ̙;}/8T| hPF`KIPOˁzI:М+ Sz™8Ь@NӅp-akrX LfQaYOʯ(Jk 4WR8A #7P2\=: b^`8Y F*LUT_ S#ok `JW)J~}"u6Y6\V?RC*-+Ul [k=sV܉0>C?H5?Af 9(`?=qr>`?/%O%2R搉_~L_dٗ:2:"Uc ;3P)"o ɢ8ރ4?}*L7~驁c{5 x'pOO8A?NQrOP܃~"60HZr wx3Oc*iq?#RJ?nĖ8!rQEn3~8#U[:SG >p(O[C< 4gM4|s"+]q-|6>u%hd;= [!(/ C^b#j9!>,9g-軼9rZOh\ o* >i6cA@n2*g2HXr RfJ,:y'\ۛ8%4)L:ӇI\2u껙XB,aJOp=o/ƥ *l9v|v6D-e-Ֆۦ7`4&-R<qh` @f 32gG?mig}]=2% NVr\*.u EЌ_8pgf|Ir(02QBv"`hIC'#A ,ź`AU@nK~&fwh.[~m_܀{gߌZ=c*T1sC1[VTY*P`_(l2m.O">J1 aPI;E-e(S, a(yQ8~gN7<3Wj»w! 5oY ~JߕMO sv2|& Xo]3#ȭp 2XSsȾYEs?I}7;Medr$ TF_B?E:7DmnT;"@Bh[,-@O aba?pν (w&$>vo=Iu˙)ƛr^&$Q=Pfm~|#^?ڟڟv,@' Ih薢Ŷv<.2lYYP6yJ@W瘕kUm/u[B7!>P8@{2#;r ɶ^QfXB_`^\_= sRd+F@\M೔tl{-K Ind?'KI_Ee{{JgTLc&xF3/'?f)&r'бg`B9Fq}NYNsJb oC8t{Dfg:@)Au.LգI˃gkz/<^<λ7h W^ o ͫY$\RdV1(*>4%\2ї od,Hrm *M- VZXPrqQLI /qq׋VߘOEYk[ ň3XE=TGϣOyϑ ~?ʇT8k隿=>)pkVGAv􆨂%}؄Z aU(24+kPxg}}8^p2] X'kCzpLvP7s_}}]oh%r?ڇpx fv~Ż2$}7ֱ‚F鍩 r|/\m~]wkV*5ް;(ݕAN/a8eFT {WßN7UN H-'=3i|R<`fs>L70}d:M%ދO-bgp_iF/L͗EC:V/!Ӭ/wݧtWYMl~>yw?,ytÅ yY(ʼnVl,#W񳠑uP+"D!o]%tp^r˽>*=d4uE5mi 3plc56ᬥ,8 Y)]Qܚ2:mqBhNSPvDq^TEUYHzer4X,HA.Y#e7޳o <3'|d,X=#.á*25i .L af!/vc~7] ÿF>=@_K~/H=6a`wnz٧ I N(I7qMww"0ZؓK@0']OҔ=u҅y &.Dҁp=:#艰aFaS``06|0 `Õ3K<}x|   Ğ}_7L੯5jP:Ԃy[|  ֍},?m\N~e [_z}cL X^yg}xnqʞV#|0ˮ+< ZkSZ{fB+@ݟ$LT5 ɧfRLރw Įz.حHzbGT?Sn= {8o`gtb|=!g lguN7?3‹1#V ad F[80xS`2ޠpT˅{Bd"5D0SbkdWMt'T|O֪q*=UDzá7"ah !Tk~;9;+C"}K+<3h}x6kSws}<g['+dDo9rפ]dֶ*ܝ( N׹9VbI&4GFrƑ,|@o[T߁L <xrF&,VEd'/av{28`873iOqp~BM߳8Fbho7zݍ!7}89r=KBA~l:#ƿ"^Pg:/bgƳt [f Ě @ ԮSCZCbT5Ͱ@| ƥsB0{-tNO}$1!H- ӽsByQvIahzk =t+?|FNsDU ì]\=?(ݺ;?9?ϢU#(zΒ-7eof`.MG󸵢C"+Jj5zcgll%rJ3<0lC+X:8Jflj)V]IYُ~czg.5,0'/iuy>|'KFa? ?Ξ Xn+YO^Lƒn&qc_9nָ6o˗qM|_9aïv+]5QͿr߁vV=i ˵?wvv6??`.W*wx՞OD2%XOxĻKs?cX܋ړ oȌimLGL-./o:^dOwk{{px>\C*  z ?x VoJ yѐ%>,Ϛ2C'v8Qk2)Tsʶ#Oi4{k lFk^gjv퀟^Ñy#-#yw9 l?K? O/w_p {vM;]$Q}9v;b s>dW|wO3+X/<0.# v$ÛimsNh{0$I N,B!ϻk> /X'qOgN32!яi13?geLo] xӭCw\_{~5][|t)N9uBm:j20+ʞWNe!Xs5iσEK\6>Ewa`9X*u5 acu [zˏJF$QMo>]{raZrH"E>id5bb:wq >_3I:r3>Xgܓ';z 5+l(3h<@NzxS4s`Y'j8=˖{c;#cxAc@]ʤQgg}I^LJ(`+ШT j|,p55dσ&+^L=3A7"?Alo<ɐ49)on[ 9!‘AHhxVC!BZ4M۶Z%)4c5z Kw:RF;/ҦXmk2qg&bsYeэrx'[ \U-s4XHc? &H-=i 1ZQwVnazhm%b\ڕ0XH@Ek szMY^wEC6KjStX7e]sncUPXWroPANCFw[f;MjXlL1| m*Bjڼnh[$U3K17i Wn xα4G+O4WkXm+En=&!jV-KnR}>뵪 3|XZFo9q5UߤF9h=6J1~i`֗j}$muw:ZQh~s9-bKLSc p a^C-JL'e%Q hhf[fϻ[ID5ªӠXFXGKU#!I[~ήuu_+f^ۅ,"q !Q**ޜ  &gMZVI B_cc$X}SM0@}w-75j4 ׯU1ZEW7tVo־&R``jr;:MRɶ;<J+GsEx02 PV[L)b6Pԣ}4U?겂68X&Vm,ھ^,ͫJ-VR5bZ`TXٛLc0k>UHņm4ݞ> QC֐U+;l%cRw+{-&)`U/*Lx`G{-n6S͟ &39a]v5"L[{'yUU5`|#rEﳼ'`T =STџiRntҾTT'Ǿ\ҤJhdF(׷{wD}ZVI8 x"ZI%ZZ Wʮq˄ 39cw+vXb LRiAwjJjR76 K&N4׺k:rzl!*W-%\ph[M*P&JW زϪd96rс(Ql Wl7' ^;vkL'ݱjA lؚPtuY ]c=eb7b̊eׇ>4ѢRW@ۋ~w" uo<j4_&s\rDiQa(B@4Er.Qt⛍eh{ Fom 4vnwd6VV/dz)n]7X|=6י|uJs$),Q}b!Z%mr]ϭNGӛVv(9J~ӗJXU.ʕ 7Ẳ "`@4V+Zi^*+}Ui&9]|qP+Ҳ6CQzK˽T7dƃ=9X<dd\Re9 uǁ ]CVlH<`=`bJFdPDhQQSUzͪ5W;$v,Lh&aXV[0\џ1YVk6ɑ,۫g/Zpܵ@snݠV [̖ l;XEUWe_]c[vgB8*4Ѐ2%f(Uۣc{[Uv (, B_*M|ej䘥AcavQոEظaL`hQk1q1:`4yc^r3sۻKxzFiw#jn03"m_k Pɶ8gAeQ~Xv;}Zk`:7Е0h$Gt:t凋}83P TWҶF>c1f(fm1ƉbbpjĜ}aOESdu1Q7R0.4Ir6NׁaŪ^eF4Ay1hE0T4:j60ɇTXUkz @}T&5[cʋLm:%}M8z[Z!XF 5F%dJE3ڪ#zmWj@T&B'XiGsqU1׸,JVbSP+7%\vdMk4ڛ@>R`]? !&-v%:a.^̊2_ұCR7`-oNi *R&DiT#WC5JC%u h$K|t>NX *Ȉ\w{&A8hwOUuzwXƲi/u2թ r$4:E/'.o:i/hܙj5,nۃ 0_K1MdkmYxTT-eXmezq7E-g3<0 k,_߁Lr[^TmqM8FZ#ݗ*j71<.xĕ78v5IXBR=#Ls\͎,;!-Ff3v܃g!!#в~y6izӹyxʞ&artV Ba01O~^ )>3󤔝&f4xyL]as՜C~gTm #X,gYf̆~(.Q_O֤h0$@WWFwu/S,Oqy4lvE |JQ9|jIe]0:E&#g@91G,yj\Y4Wõ pvkӵ9dq dnEQQCTߪ((nԠǜlqd;o;NYq,[YOYG 7$}vz%=FmǪWUQL > X])7lqmK5#𩋶x-vku*XukE%=:o*_BV]uq:6R|B/u]3/{%ڞv5JnP Ll2GCrHws߇eHIܸٱ|5k7V. VDQr %<S9kaMyl?W.Kewݰ==}hOH_ȯu}U홳 6վv,PFCwvtίqr3駰ۭǶ &p?{OAAs HѳN/%"DOCV?iIaA+OR S̓c;2@7Yw7R\ gEv /n X[ `i(ak2>7>xk6x 7|!'fqI5jz{ʗjf-vc5Ť,ݨC{Zr=͢V&y#Zb@ۭŤhԨ8$?(;8)’nP0;J\tUw ھD@0#:UUf`iK*w3#|NrvkHA [{fdNPĦA>HfY8@szrX؈'趯CSGIU}KMD^/-Mq.F }G-KNL4wʐE`ǂK8MH)'V> Bo.uJGZ2^bHI$iS7 Hz|r61" (t78,RJV2?vΐ:¾9GTz a@(~j+(,Yok2%T5BT" l"B?Wo+9pd)=2}*r"YsxZ<% 3~AbKX-* Qr.g vi͡r-BG# )~IG%vɎpp@-<bG%. '8w<;%A3g&Brv{_?\m>6(=v9D"1/|,,ג#!QpҊTH8 x,rrC9/x7␐N$p?-r=Y&rrʑBZj]<\-Ir/1Ϫ0hhӷ\~iPR@ܝB^?jd-ᱟLu)˚ԇ؜ &#Kp5Re$}d5"VZvVzϜZtҙNPƱ`߿03rٛ[KQG2<Mxlnh 7'w+&kp(oTӧ9i շ_A'vRsO,~SC(r*GT_^-e((~_f30p堡h%\ 9 ,M>;a"UHyZms%o(hh\hTY vF:WG͘}웲p42v2`M=%zotO31 ԬӍ'C VOuYOU2hK+70;MuWunǍM\-fwruJ3q_鶴QKovO(uPim W.D,+4iBw'Xf+]o_e+W/V0Oq[@Z}366U5sj߭D5|z˚:ij^= n4՗cMVפѾ#nlnpTI+/y^Mh9s_[i/ZZnW@6SOQIA] @Un0+)<`:zX@4E/iOEH@Rq ^HrE+.gFC.eS|8Ns%|N.%3^dpQD*=4QBl_4$\"l2w@{.EHyn3 5Q!H,.s.>]_ASM&t΅@w QåX[2a( DIC ,V$p1ݕ` 3<-ŚƦ!ʥ5 LDaਬ@BM16mԔ}cwI{hP#NXewOy-%Ns*wGB\J Q}ՓwB5 |t 5c.BpTl>gܓf&ކ8ɨ!tF񚺎A32q*kH8c(+&/i&\cm,)ɐqJʘ(jJ;caNOLBlTyM=c`FHMg`o$zX\WmU3{K0W(_Zʷ7]OjfpFQ9ps{O f  sPtiY -bTbb-Guk5Ų~`jNJ*3'et<2 {QqEeOAPNG  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  IHDR@@`UcsCl0`MIDATx^kpU@sr;B\$$@*XiXX"8tढ़*Qkۿ࠶b BwEp[H9'ifɚ='0g޽]u/?s}OL? or;p)^yI0z8źp/`۵6a >u?/CřDPYQno#ֹD2vyE6e#'$ZoW!fQ L=sCNa> \nE-:/WҌQX$033 J!8HI3{a72t`n( kP f;F/`vG)pki`/9|?n\ "Y+i <3O3D'`# tn7meMw U2ނV6 fycr3[J,e`zMoYLV&΀ rm. W|&d hbX ˕jKمRY |,K `L˫TTɑMWZ8p2 c E|XdƧ l)E6?؂,`b* #\,@@3hjTMՌ5}-e*~k%@lŪQUrUzu_/d[ʮl!Vm6W 7R%2A`pt}WBQHX,hۮ|ip !,F 2fj}pq=1pBNSh@9&9O6YyJQJG<,t-$ҰR^|y8GICNh|K H_vJt#,l! FxvJt!`&Dt8r @&[HnlywͬPi΅Dn8:/BLQ)*S*߼ L\l mM v7#Bޕ5BEIUG4yU{Y/'pⱑBr%` r6\:IО[iL_r=G^9x@![qRutQrƻL\T*USwf["Gw3JS8'e!ZUkJU~ƪ"Kצѥn40W1bH TdYHAAgѽw0Bxhg^TL_hȲٽsN|YVVR |Sr8{XJR9'4eV nB~S4%*A LpUGsN|xYV_-za]W=5I) s:;wt @g)Q 8ı[A=r|x4Te(8*yB[#܆vpr{|ق .p Xe{ҋT JA*l h4eA BoTJok)v4^>xBJ4Qտaݡ-m_v>~q_?GvB㔯,ȫX3yg%T MRj5p/NV&DSl %)MP*Q.\e*xk 4RJ<*|MLPҔɯ|_#k~0{#i..nrWJOJSҔ*_?JR¹O ;kDtͣ]+=D,âIENDB`PNG  IHDR@@`UcsCl0`MIDATx^Q@FeIȀPMEA O-x6}.Leύy|x@oĈqgA{ 1c! /-B"b1q Y`u B%+bI0fFB2frcP(b<<\D:J=<<r=5|u%_S!W;5ϩ  NM_NuMLyIENDB`PNG  IHDR@@`UcsCl0`MIDATx^=K#QNތ/F#ɺA [,)Y_-+a]A?ZY[m/"kgc{3NFb3ȝp<H) @gFl}7r~ !fd6] ! :" c Y\9 #$yn ;:[(AB@w H@1HE#<e" q'AtG,0V9 @5L (p $@绀9^(a4:ou_ 7 @4:o*!pHL4 y,`% bFPB""oD>1@o| "7?nw,vl ۶|doD:oEHNЄ2hB/4$?͘] KqO%7&4xy:>;XDS U̢[ n1@1 qh`:oeM(1ʉqI3^N5ӹ8t>AĸMHx;-O) m tIENDB`PNG  IHDR@@`UcsCl0`MIDATx^͘mUgޛ!$-X-`/ R PF LmWWK`-E`A,TDQ:st8 Nw{.Os>}sv<ŃH@a53gP^W[uVq!o(d7jxW!qxy]U]L*3uǿw:NL3exT|r?uߙTP֞ ;@=NL}e xB&gJ"e|tܯx7@ i}MAJ٫GZH d tr&C@ @ @ @ @ @ @ @ @P@P %P8O h}&蔀XAӀiXAF@VsjZ4.9jv"XbԨP"8.%*Ԩ[T!GLHc+a(S'r+14SnejĮrY^DԩRɤ@a% Iy} fu@f  ^ BzK*N gGY#Ft^0 A \lLR8dSݧUwcg6E 8en?NH-vh6Z <̮VPv{\%t_kM̭SߚM hh* Z(";PsG 4x~MHjz!$9pV 7;`C1iΚĄ&)/yv~ے>JQϰF;X7"H"x XKytq &S9E(> kGgP)4x;I]NDԨP8ɣʯe9S?v=chҠ,!Qyp$p':ذb -MwxvwktǡkH*F<CdOCЁWѱϫ9(R%$w'h=ޟ)FL@EځF+N*E.spΕ/Rh+8 aK2/ 4l\5M/֊H:oZ>WIENDB`PNG  IHDR@@iqcsCl0`M 4IDATx^[}lVW[BS*Z1AK"$$ؒjĎ!  I# ! FeP *J%Ӝ֛޼7'r99<<}y'(l?]$ ј= ALd2<~a_gsGj3Nã0nڵɛ7ov޽]?xxxx@{c^0>B!Bx}0{Lb7Ç q}< R 't\A;PF`#ZGqS@?|z3#s$͈c> q2, '$rKe X1?<1K`OI@;0}Oƣk'$d^To޼;wt8kEy0W;kJ]x衾)f=H8o.]i#GL=ʃcr]+BؓI$$IBwfyy}m@V=(xvCY!zݶt6[՝lZ'O}Wq|J隣8} )JeḸOAYt$ Hy4> GT_J: Oh{NW@@I>53Bh"e)L3Z׶P(.\l'Uz6mRju)HooP2*xIjW_f~?in93H`ذaҲw^>8 HBE,j9g_"H, ]رCV|Ne+^|ˊN,׏k׮f+++P[l[,sN'tC3 Yf#minnܾ}[qW< Y(|qcNB@]]6^IY^,F+: +Wt%@KON:FUUAN8ĊL5wh;sh!GUܹs`&WLpŊ#)f Y ,YY];w+ "{ |aƪkʕ+]gϞQC?VݻwR"H4hgo7ku(l***r%Iqü@' /xrv=gK2;++($ÒBW3N 0׵;$,@89?jH<|jnI"q]ٕf;KwLώ| 5f,5;$Q+:$DKʌ&슟h(Y!ÅS'~nJ)N1{s8T$*C@$TqlOpٕطlIkA=m "MaLEGc+la%up$Tפy%a'T)PBIIDRD^ɂJFtGմ`+{ ~fNzv#jZOk;[]XL*ѫpj聙~`n;?wL@Qv}D5 t./&Y+>T@Q1aU[G2A{1:&"{X@T(4ff"OfvwA9OvS0dS Z)zVXrPP "8@e٦٦.yH+|a]2T>sxݘHV%ɏ/)V>o:K1&pJ-`k_)QRT\]e:)JÀH{}X&mJGu [߾GxWٹgF' : ڌFDl^&Cb֘uN߷ȯdtqLI5_d-]1(A !3J nOYkp/fl|) <'44 SD-Gkڜ|Èj+O@iGn<OT#H\4 +$ROsʐv1b]8>ծwSNvl RPRE˝`xpEڜf_X#  6=hM,ZyKq!xmt.Z} \!jpY >ˠ\cqaCq7Cފ]kpvccp8 : c,,C4h(V|9^/_)[0(41 GqǺ݀)hЅbo5p $ɨU٭X݀,1,Ur8jmaO._@P6-k-RۡO#0 QaW՗?Qa ((k{JǏO@^0h J7X*?PR)IENDB`PNG  IHDR@@`UcsCl0`M@IDATx^TWϹ3˲%PjڠZM)EDŨMcVcKBB"B@465ؔhզj",eؚA ڄ$twgg_$Lv/{{~3 %KU7%  E51F#ۂT>S5Ϸm3h GU[?cTeBH|E*T}7,S@Ck Ʈ[5Z1Ӱ#~'s+,kwb3fm8n QA4Po|0 n0պf/)DQS |643V{p=dN:唃!i6:H xcL[Mv[Nbg*)t>$sFU@nVF<NO &72;ѣ" %}6 {54EQlh)%Sz׀Zw9YkUT]>ڃWOrjGmsY̛ m{T0|嘤$[oPC6'{+NR7kJ; ST=7BzýJXda0<˕VW U fTLDoo)*^nrLTe޾gu8d V4v%*24&­@!@TLn1OsNS2@fq3Z -s@cYMNA!fjA*kxȑ-s1I>H(P}WᠳRdһMØ֎X?-3jvOU4P7fԨuNF٣Q`! U3M?<2JFmm]sڋIHUAݘ~#5u0& *@ Owa39fjQ/ ٭[Iw.(El~b Tא-Xn3𠽺AVFI/ƬVdYIrP&azf=V&ƨ8[2yC=ibls]%u6~m (GmU.8n$3PSnم}M~a,mb9ku<ԀeO,oU(W1ePq]υ6.cHs N_6K)u{lUSO׶@92RL}RF$^JZbh?D䈢LH ]u$4Td~7I!הbD4Bg!&w.( .R.w|I?ylNIENDB`PNG  IHDR@@`UcsCl0`M/IDATx^}gu98YE؆2F7Xp4 Lة | k^d:QQsjli#8* W0.9p{E8{~/u z"Q2AQb k!r Q=>_. YzNAɽcr:/ 7|٘ӆAk5dB3*6W-s5qW1/0 dJoxAfUhf>T*O0 d gbH'D "5-FE+]k]!lwyfif\:owRGuom6i+DĺA@ĩoR 6Vp%ih:fuPJ .HgeS P(K|| '>-DQ \cf뻆> xG[:Oi2J d=g.̿_bȰ[`[,s5dB%}0}V horj2 (k.i?t@r[;o+lAY sBw駇V |Š~NKJ}2j}L ytqT"*, а>!@$6VJݠ$x6U^ 2. sz)crUgvZr7E<  t3wڣ]78 m-ϺSdD7opވ2o Q2kk'|\79!E)PM`҄ []X~uJ2(^VUZsQ&2h0=M[]8F=Ɉ DIƼ`!G\(~~mmE5 *;jݘ Ga Eﰟ R;v=`jRaGQl_k ?恨GZvqﵧHZCڒM?gaIUՕG^r_? *PUhCgFM휶_;)΄S>N۸V*@bRh^4]]eJh:cKǨxZI@,ׁ85'x\3 t3E4(v;'qi[@~\Q}Z5C@[⦡yCΓ9(-@WL>euF5YYb x7>j GO.ԩ/ݩ-qi.I) PsoBG&j& IH7!}ubpu=cP,IENDB`PNG  IHDR@@`UcsCl0`MIDATx^kWﳷaŠ[VKTӆvA[nj( ZkS_5!ƘTIl$ o- A757ʂ\2?83q 'Dx~9y8|RtďbyOA9ʮBa"D"Dm~4y+  NDZ)|s#\"y!=\xSUmb0% D$iF @xp@.j6kRIIk#)Rd,yX]b,a4c9C JyIzp0ɟ U 訤SO$*@Z% Gic/JCB1s҃5I_);t!u V~1f,12$ai>Hoc{T;L#EԀN"A6Jxc/'m^3øfn`^;# !Ш7p'{H; _tݖ9]N3!Ec;J z*isщ'f2_="=jYUR/3; n]Κ'JGaɘBPi5MooKF3i1@3z e14ЮKLyNU; c+ڦ骤׿I+v`q?$*PZ/]pAd.^I׏'PM؂%T~N:lk%]>8|tKҰ^$<B(kckxZ@au{X&,e1, IIe.HڳXBX`3ya&djR vJ:s2L頝Vd`)_~OiGK7oMN&Kiq"5_5_ź_Kg.#Q撧DؤWYɚe%n@E&>O th% pkTL6+zSa[gO$-)#l4~d)S.覓t)Vb2^w $ !I)F,|'EPsaH:i /˔o"EF:O|\z2U,#N$it7 l$"$ VvH:]1+iک#d>\ly3,B]_DQ`|$Ϭ@M5(QkP=~7WްGۑWb4 KN܇; wtOX?^g#^o`Kt]U?98ѫIENDB`PNG  IHDR@@`UcsCl0`MUIDATx^_OiVX ?&-AaC GoֽMz<1bVwP3=PO;s2!'y~̼s&֧~/T׀> +< w0/ۗG?#߯K~1KŃAT@8xJpCx<%xOxKxbx <pw"ll?<>fCm;0ZX)uP:(5;6k>,{\ƲԒ2VzpX {?}>9,s 䑓}|}[Xrz:6J3HaN 򑀼U_,~uj5 +਄D_BqH@J>,:*),n0q^q$#I1go/`; @j6ޜTMm:h(@*]%7+}*. ]:<pBa) g!I;=i>>E|y.? 7z0$rm%e@OBbJTC0q?[Q Q= cF BX+ƏX}#ۦclHZx `,~{( / ,EKi_WB[¶%D$Y76xAq_:\@ bގHB[%skvtP>T_^ԟ7?l5:}0aѬE {Nj6'^ ΅ $aiBiLx`1!#_ܦ;c^c].<O''! Gwx||8apw8h||'N \YrDZ*)k~_\bhp~uFm/1(a=ъ7qØIENDB`PNG  IHDR@@`UcsCl0`MIDATx^ٻoUeY|Yvm+KDbPHHD(nґ*e7(E@J4q$ IlCj3Gc>r2srymGs9Y>N#8 QQ5TqxRL)FX~s@eÇƀA|µM(_!Sh4K[BF{e<1uζRM8OCa\/!ڄx9C !&,)@uFb@4h2O#@nƑϗ!*7wK}ޗ9wOs ouU_P8N?wa6&]%) 7lt(yL\?'` : FM~^kγ">}?&+Rc$r3!88IKt,^[]I1OJ%S&i2N3<-ܜP?Ma 2&)J_1w?SKx PG Wh-cv7'÷## 3.m+8 l Ą;^/_251K[P3 LyEL (`^/*~J 4X#T`Sr7!yc 5NZ =xizBI RŎ5@/ޢIE 2C8rѷK Ȓ#@dj {@[zR9n79V"Ujzߣ9.3F "]$ħ=2>!/3 =RcL2[@ӄQxnQZ3BH$dQ'̔54R0،RoC>_#:E{IENDB`PNG  IHDR@@`UcsCl0`MIDATx^OKbQn?WMYX)%6Zͬi5ML+׽@ i{8nj|Co{3 >`B`SL)L{=v:s߇xD]'#*@oOT^c` ] r^&Xy` 'yp @0%@LBޔ`0!rޜ WjG}Y'K8@D=c:Y"aQR(Q:lMv{ӤN)8&,E, `-ؠ-lF K,RH 1MCG$9*B$WO7C(Ǒƀ1` ƀ1`_#>HBdO(0{kxߜ = v7,7{\}yVӇ$0GQ|C9fHY)iTY: reIi9>Eh] 1yN&s`7QK߇f*"o E9o [9o ļ}0xy&F#B:@ȐD5X<!o i|%'D?@eլIENDB`PNG  IHDR@@`UcsCl0`MIDATx^MoU=db';-qj4IEP6HH "6l+D+|nUb^T$+M[5͛fp|S sѵ'Ds& `=9 y Q@(C1ft*n ! tRNK1= OAwncc8*q^ ԀG`2K{}2 ţHz505V3G G -\ST`R07Р*Gw_b SR@|ɼ|2aS Ą߾<53э!hB1rAyi=Z7!.(n7o'KBTG~kI ysu|;p~{ovv*i1@ _6%?tG&q^_9,++#{0OtH}3,H2M֌6SzwOdJ@<73Tc?v,Qn_,t,Sxx„p/.z?\*,LMVen`o«Cۇ>)=teW9_/&|\>1uR$ Wp>)qƖL o1+!=:dCBHs,Ӻr(nd <<*w_t1\#kR!@֎g) X8ݎIB-%@VKC,.:rTK\M*ei2g9GΈY "GKyYR?55Bk r6Ӕe27i2Y\?RCc L?Yrt>ĊIENDB`PNG  IHDR@@iqcsCl0`M IDATx^[}LT)32"b T]-KYݏVݦJMvuUiMMhHmq7Q0.d5Y?¢Dc4l"ongrdy#Iړ}wι_j b1BLz،0R>|؁o2WQP000' 3%fӵ3>}###mpttghh mѽ˗/ϖd!”6چ?~ \k xs&]DL >FW- 5"AST[wr'220 *X4/*>'g${ZJ=:$ %_9!eu "HcANml4= r2B6ȖB)`"V?uF$h Ҳ"ōsRo~-V{P_A$ 20j/X@Wd腕', WYBmtB!ACee-s$ \ ټB@ZOoVھ@Z=8W-N{Ɇԭ ۀC|$ 2D?~z<_sH0QbzWnߞ%HCmGVnjp M HI*?O:4& >|x3/$H@4( ,]ٷo懀D~S}Tb<τ%7|ދ8Ì 56= @s=zT;VGٞ =ͣj$ۚ`nZ`ӹjժw H2HuB $Ipo VGԁ7. kw"֓!V`= `= Oʒ!'! Xd>LhlAE m6y>K #@dfflڴI<|p8**jr7E+>~>IDeNo=۶mRarh]^Ccv% U0HIN2AG-[SBhRL2P{r!$xv>RZKƍ;v(Ne}M{5OMM;vڵm/rbxv7QNt" _S~L X$9sF]C, gfNeKSyq…Bev}'O[Xdggˍʑt&`~Lx,"`մ*HT&g\}AW^$޾}[\~C^Јuʕ+744rØtvIFF! 7o$I-7+˗{v|:o_ȹsNogYqXr IIcc<!960EBB! 0o21r|0nܸ/=Kc9Hf%$F1RLĆ`ijj"_Tw3luWycijgJe<Rgܞl5}5;yt99lRe˖mDJ"*,}n{w!VؘU34b།apH!n]{ N>JZǹ$ZM@(̢xiw2b:n䙓#oN$X:ބ>O\PD/FlCxABcҥK\`F-~嶚Wƃo&0Iq3\l/g(%8D?xt4-l1f?ESO|pH_fZl[0?r/ް`'f|'x*/,^cDJxYF Wy:+[f$ {d<0Q&[.U "@j$? !<R/IENDB`PNG  IHDR@@`UcsCl0`MIDATx^͘]h\E 4V1^ *ЪP(6*j+"*("*5B( MJJj"BբV"Es=0v؅p3sW~J_$x$  Xp biYEb\@",>D LFA6\Fp|($@@ >x*$' H\|" Ps*$y Z $ E SJ *H  *H  *H ?+Y$»%UWA_ ~$UWA_ ~$UWAs^@{%Fƒ>9Y8-Hg#xC0q[%ǬkEM*n"s4-dUӄ(RJ l =, DȲh!KHD25v>;b7 S熍.3BтjSIFЦO>!7!/߳ %,fe*jC Fp sM0tn[)QBBc 7$f{N G:N,nhg8@;&kB-˸bG4w*$ߍ#o(H2eYj# \ ( @DE4SC.#붓"@8}q|p#)S4Oc>Wrpn|FW*8 ;⊧'45s|Dq|Y)ᯙe<dߔvр7x)o3^Ə#4QY2E q:^郊* sq6A=]_xu<@pAnpq3/ntozFW5驗{n$@L: J̾掝}sa) (15^c@ag ɚxU'ЪP @&o/ޑ"DMX#P3- $b\(C[_[w/HIENDB`PNG  IHDR@@`UcsCl0`M[IDATxױN"QV[Yz#XآbLԇ) >%X0(|$@u903Θv`p,/m XJ/¼ C0Da?!ލ B!+t 11jbL?Qh@PO[E8֛\_ìB UImj."Ig#,gZXRy.y,@7XCuDazT!Ęm;+t5? Ѹl'8 }O3)66 WJ߇mic#? {U|C-Η={5eEp:ou FD|yBTZ7ǤR$&@M@, /&9&+r)C6qx(`GI 6yR,ՉVa|HϔƜHS s㸖pGcП6nqH=ڀR 2 E`#KǚMNMѦ3nBğ-ݖI(O.39 1썻Mݣ{:A;k|T`C%)t;ΗvC{slyMxrwpZf Y:~߸'I1s:>skUZtifYdܥaÝtpթ[fowwjZ=X~e1[]@< I15N3i+7=іd/X@rj,۰@ʤ$&0'ƞ6w)⌻)^R%Ūl%xeP qOSsEN-BB!KB %. WRmf\  =vj]Zm,=-{wfI$NZCV4Ǝn$-#NёPGdHx2Dg?izbw sdbϭz*U %438Lqg@sp~ Re%yET( ^OzG2V<Ï%=с!͋,R"ղ|Ȝs"$^ڰrdX߶X^m}0gN|\"cIENDB`PNG  IHDR@@`UcsCl0`MIDATx^{pT޻]!<" "i vCSe:V T )#vZP_V( J #nv=_3sf!܌o=|sX`R#D^>( u`S+T.nI+,Mn]#2ᔻGuN!D] VO:BQ(hl]彯BҴ A# ^Kt.`LJ<1|U yש##ڃaR&o}0wP(\7:/޹{X#p~SM &Ws?}U:Eţ}ko>Ne(}~o|顅!̊q nhl"v;{3w pPXQͅÍZ=ƬTE|\ԠxTOhw݄g"GܲV,.72X,0'џ>pOj2 /(+K_k, @ێYaOWO~bNoS1jvʂLҏ CgkvXѐDϽXaVQK zzvd\ij=9#K n^F%_VT॑AXe6l* A'/hbXVH4 h٧R}e5)DBXe }:7Lh/pu47 rߴ 6luE釛8vahS:""M&}An?JBp.Izr>B^~aPB2 Q >yR!8! ڄAX \ HB _X2S2!ς-PEӆV*Y%"'XzAч -APSH_od*Zy>Crp!iE8nIkX Q+ 4}uKyoKHy(߉`ﰜMsw0"V@Wqݓ>c`.H TMكPA[ Xm81+:˭}FdWɣ$Վ`(IF=k$MHI(hu<Y2Uzt"Pne U!a3E,ಂblz)?]! xTQY@.,a:c[F1S]&VQ@޽?jQGW&c˳fT0 ʝP vռiD[\ (Dw| Io>齡lZPjc43&zLݼ"iN" ɒ!MWΪ]WL0Hr2 D(@m+׌=$^aIṳ?ppK<9?)͌#h@:(2j+/_N-G4h3GʙYЩIDh|̲_shV5 UJ6ڼTS-j6u11t e< *Knqکe"-{3NŃ&639OFhy&TtwD*J%<d.ŅտeR#^..* A"Ѐ(ﬖAV1Á q\lj0&qM8v9Y\vO0mցj6["j1HE׳imBmZDGMHMHMHMHzM]2xU5X˥OB΍EÓ/^_<)IЍ#́95g)DRpʹs"a}18Ĥd\Dr!#%nE 1˨YaMӰeGL&[LÆde@?e$6ʦDf7Un 4ըiZQ6$IK_LW$1'XbIENDB`PNG  IHDR226@:IDATx^NQ2Jf Sb|Tl ,o 4XhZݱ &@p)/15qazM'/y ?H>&ɍDD$E@@F8q tyzA 9"<p(9%-L2 oIY C $ At';ID4]2A v!.䥽:.+Ǝh < 5g$ )1J O!Av!Y MшpIKpT !F}km]I5Q__h( +!9O1qD=E3q-iwfkG(:,: ?ox8H,vzӎ1,HeEM'fԩ3D}3B#ҤA* Uj4h #T䱠oAT )H 0R1F@Y 9 Lg#,^3J$>uaA4l]·Vh/5aG434o{y4Ϥ&fB??NS%ԄL17UۑQԄ Ì0b;ܙa5 a'; Z `@]2I.c=4᝱_m JCIENDB`PNG  IHDR226@:IDATx^[hU3{ EXRS55 Z V0``B(^W/4KҒX>*"Zں;gݏ}7=g{<\-=C;SE2KhV ίE Dc@%f[H$u8ק3^x:;oҖPЦ'ox¡46TЦ2ҼcWj<thvїF$52ķFӺZ#"ʲw-ME+X5Zq8$q8&)('{w*P!qӸiUo ˑ+Dd'HԐQjLS`LP.M.)СK@DxPKshXOˆK.ĤIjʓD$dAP^!&%!.!1XH5.+%3hkmh5e-KK$y6i OI,rZX+I\$8Lgjז]jݔ`V$D > c}ۮ$oI\^Z81ۥLmH;$dQdXv=`թ-ĮFHDJm!gZ|XnϞ=|% ɓSWS#Ŕk=O|='q*!` 6G" ߠ5yQ:GExV%G<&` _d~G-XKzN8$/o2qxήw^̩R߿\PP 9bUD>ПL׮]#,@>ܹˀwjnnV26HuttDwRbyw\-7*nEDec΄1x, /$TRReddСCق{^@ 4^kgjo*,b=gE :N:{,ݺu^JO|tRO~ѣGwmmm !\$rA軓l0d&ba@ KۼR||^[)xe` oN#za bH^^FCCC OT[[K^WɼBdIq{KH"m۶h=Qyfңhbbjxs>QHaGf D"<3gΐ15$3f9;,’,yP"RiDEN[ڵTTT`XL,E(rκ2tz}B˒5!%6S`Rq:`<55z{{8;[.K}dHm8F$er|C$sBXIb{·}Td֭Jdzސ8ݴFRd4 o L!զ\⭈7I=IVjm߾l U ݪB)~owTUU)jo8?VECriÇm)..f Pʪ~0.p raŋU6ZA t!`;v6tJdoâHփBn+ԧ;IԲzۮe=+ZBs,y<y]`.-+% Y,ӗ]"Z _RKCP[VYIu\zV,p| B (jZVvYE$VU5Pn\R>R"c6x.vBY,( ĎYtI6lC둃2]Nl)֠r]ܗfpx{Ee\ Q)d \KBd-$΃ϥcXEaA?S_n/`IENDB`PNG  IHDR226@:IDATx^핱 @ E JzZz@,k\1!I\'ˇ1 ÈC>@IJEҬ\Pm{TW:"fO .Dád!:ƋBɮ:&!4@ B*!t o(Im:sHLۚ5gvstW$xLjƬ׿F szG+ka7k‘0IENDB`PNG  IHDR226@:IDATx^m\W߹sw1ټTֶAH FDQԨXXV), b*HTT|*Ii%VcJYJ[ll^nc۽G\p`~Xs[l%*-TRJI]oA?C*i_is'M[-x۫ZӀfR {lYk,cv9Ho5k)=l45Mھ;reja\#<9EiJJ2,wah+B!"-]ur[]Xʴ٣.1u*i >w>F!:D@ >;|Kyu Di`O;2>w3pzZ" ='\#0k<刳J%tu,8k?e/azR D-xNw<_=FG10H/rZ%k]7k=kv@Nf>?߆_WJM-vm g>NO?]T"F1D6|Ɨ O/TRB ޴"[7>Q'*V[ >Ȍydt\7==;^JcrYBh]5kneY XfJH]Cڧ *$9mma94{XP* |{iSaqE [>KDq.&3T(kR1}}um.LDI3zmo4fDuduMz4"qKZY}6x V휲aiw1DmcH+1gԘQ)M@ѾIe').;&ГC$T$4uDJ.: J]T(Cl$R*P$=R1 )) $ D 2j sqIENDB`PNG  IHDR226@:IDATx^]Te;KV^H)D E \EXX`E!QAa?E$Ja.Bi%*JA,l7;{~찡'{Gd@@#qB$(}(*6&R5/SqT"`\ɪ ׼ܣxڊ>H,ӆjTn-jRmr2 ENa"TSD7I"p8$'$Aza2K(BO82&SmrEh *H"Ihζ| P(ġI2Tڽg54l!xV8ljrhKf8 f0ɂ+orHH]ogg,8B"3e[ xjO`OҼaFdfh`0j~&qPOBT1[$8ظ'!HdÅo2Y@¼. aaZ~aIč>XxBY; BP$3P@TsǍkB_^C6,OD"fAfudKEQoQԷ_x}cFu峲n3Fh x1eCNG7^{vӲ/ c>Om6q-1wTQG꼒kpMoRD|1$tV"BDu$.D%fB"8ga%_>w)IENDB`PNG  IHDR226@:IDATx=@ x)XRh7& +hwvcͬ +|(mvp(8ӍZ ~zb)Q&[{q/ۇ&cXZv&Xd"ncߢrg(q|⿃H H $&5?/9WNLKгXRs瓤RE-m~HXIENDB`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@:IDATx^AkAwd7MM" I7mlU[^z1z"" ؃'R`zJA ccXABaf   IΑ@/j B`a$!Il,4!.:5|;CKq&YVF!}@+L'$ #GtBC,Rd 0HOJƔdvjN=)"@·Jm!F-s2")̝s^^(Zjl'JiE;QɽUJ56/"!+^1,ظddOd=v'b퓇roD@0WHoԗ7sg80} &I?a>\ïW∯9a/7>.IQ_̻[kq)f8~jJ 4^1AZ#d*!cT&(2+ bTS8A@doH9BPN>x (/gX_ND$6Tgdp踙jX )݄[  %OAIENDB`PNG  IHDR226@:IDATx^NA" b-B(6/WO> <Z=`6쬉]&3 3 ","^ 6Bc\\#oG$1iOaL2$㹗>)}D f,&,""#}DI>&"&&<族A@Ԅ xz7g'= x#L0@hO! 2G93Yz/O~~rg5Z0>KP$ )*c׏`-Y,D!GT j2?B"_H , (beTHeYeuq  $"5Cr46 dCE,M" 4g-VYM"&B 1&( g ƭ0!/-2X"G-o# o^x[x-l2̫[8C40$;w|͇ORZ09B/sXQH핞/Vف"|WB S{$P!_)Q} ?77PbLS8 Lz1[XF!$rXHz}!!fԄ)`Ԅ٥bd\bmK>"-ZHfѼo߷M"",Pi6 TPd&1YY&=" "2XI""3a1wA 1.@"< ?=<IENDB`PNG  IHDR226@:IDATx^kpwIݲU Ҳƶ`ŋ(a^,0Ao!8^vy/S Tc,KI41+ˋI>BHIyI{$%l2ƒNqD#Bx=Ea! Nj rv 4Bl,1FRĠHE!A珵8#&T$Vo1(XdI'Cr8+wh2N92{AjA%^}buFzM~j:e /Ma[&ֺo/Zu,t~ i؈Z[b?;] EM|'$A~U.m%a"}wd%Ml'^4,_‹_6/OY0G|cZuW:]A%5 c;mh24Oy!*C CTj2I1̜8dd18I^k18B0F81F6pM<%3Z}zJV)c1Ĉ0*mbO VRxwUDaIG s_{N6bpd"r2 Ѥ8LpscWaC4iP(U8̰ݑnG%= FlPVutRIU6%C3H t"?8x_<05IENDB`PNG  IHDR22?dIDATx^ݙmHgǧxR1|stlsƂ ɾKi [ؚ1@1C'1hSږ542ͷ떛xd!%aE Dzhw V\ jAL8ᛚ֌6777@D+ccc{ ʡX. ݻwNLL7?۷/ މ4N> 9ʦMt.#gn|?aX;N @lٲ%_xw7]Z*` # J9 y<رDOMO? ~, ђ>@ 0pTZ:i}2mft~ݸ0Xl`?=X_[ϩS 0aؽ;w( a}# ┧:99ܘǏp`2L3.f}0}#"a%1홝ȹtDoo`'r 糲}faȁHX8?QĆ-a@\.Ro$AbYɬg7<`0H@{vaߠ6 #ǟFs`0%=GxVgHT8ʬZJ0T)T`̪}#5HcZDq,7+gϞ'zw ܿr$;FBcUC kuuU*bXW٩9gzgzXww)x>d,',r8M E. RG^ѣG֬ ?~|#??UU}*n@bb"uN< rt]* 544(x׋k;::ڱuwJuv+ +%G ph$''L)t.GDKfJJJdRRCZ@򦰼$2 t:(tM:{,q֎]~}4{C @Ú~53sV5k(ǃܢRtt[~gXX% p>"f&{N3$77hhh@EEEoTSSC }V% !^ܹΜ9CB5ZmFsyB4J|šg>eKb'wpkr Dkx"VWW' >zzzj:H0 W`aX-Ƿn; XfXlO: 1T7A=1(q\ _ ɴaA$[8Vv^?%sXtu7Xe$JAgY1e.+fPTPuAs3g珇y3}{/.7]mB{~ώu?ё1OzY{Ÿ?`nvg/g8;ѿ Z%gG_k![g3h#`(ёcUh⏢mVd3g^ܠdʧ/X֑OI-I| U4lK~{OA-S6Fvw_w3Lbh֠SI>?[; @#|x`dQys_KNwFmYe:sbp1:j}dd/֟e Z6;ȀKmBT)((((((#ڶ /[(&]g>.߸+E,UtI3n FG]?QX wk~S *_N[k]?QWK(a&'[??ke2_JZȧM݆zq$a>,JmE⏶ȑhG%* NbEOס#df wȕ$o=v[ySXc4OS⾜gEr7"\|TB=*npJuOf8OAc}GG䚎G?vV⟌0穬ϐ7| :?r~vtߥ}2{3- h7x] I%,&5{q$͈y@O‚e?r!FM10hB?$9tLYpni%X?`tWOiX'@,Z?y&]в9yZb%#~9Uqh :t8Qd 0A:8g52"U"j¹@Qy6t >i>"m;Nah'zl# 5D~/5:o ߴG ;KzptWUh eP%_>m]gP;4e1sP/ρba'OHm%,cNn?JDŽa_%+rKIǿ*~'^? 8 z:@}]sz1tM?)1-&A-ӶϵToƿm~d4/=C&7cK s]m!b?1G?i?݄1| ی>\}7M gЖFD -@UG[HL%c C5 FVgmlO oA+;k*+6_F/Ya_MdZAAAAAAҪ^mBm;/J-ƕ\qI\6y63ͧ%U3ݧA] _ P/Qsp&EZMi\w't3Ijo ]ؿ.U%)4.Hq @?oʿ^r_U|;ZA||8~w.hA릋/ZJ`|m(s%M0K>K,ރv+ib;Z&?M[yLKō(4_C9TzsFG@{vob1 RdACەX/GCGqa>+o5k6 ϱ6i2,3)OCu  |$vwߙ>{ag,S`a)&A·٦s8 5mt>bng}$3|?{G9:sjnxQ΃\~ß " tﲟO&hRLu}{5y!:%ypgsG|>gr;x5OMg:KB1tL房[/O6@6 ȗnF;g}!(& _8̨b}ӛ>;A螃OgMP[f'c14!]O~ސmƟc` \c[tD >c;Vl+ : Wheg BF:jg}(4kQ*g6'ocBدW̞ZV1?`_]'J ݁WWȲU==9Koo{ؗg>df`LHdm/[lgxɎEGϘ}/|ĸmTTw^I4GعeMoߟ~v*`]k6z~i[>}Me:|gWbĜ"C鍆g@ͿӲͲ]Ɵ]m??+>oZQ ,.Ǘ8K)szbf >X|3)4jBezk|c3j/E~fm?'2+1_ʘω@ؿ5_qb@6Y7mKfHl,yÏZϜȶD)K2Rkv3 SO+s#Jb-t1b+<6G n #;/VbO|/9f?.:#ţ ->_s4(ٟS(0UnסPu]?1ua! wڏVl/+?3..˰_k vEgS~t]t]6+9gSzV}<ĭ.Y|߲? |&_?t~&Yga%GA2kq3׈?'YwşFW`#s_̙hisq{aiX^N5[ȥRXh?}ʿ&n6V^1vo9_s>55_?9 ȼN8M׺;` |Nܓ,B7ƕ.>&wGn.-&\of$+mh?$((,TX`hKdȾ ]Yk@HȲ.>P >w>4;g>?w'M7?k\ f|?s&ӷ+,t-OyKllJI}syc9CO'\]ߤR%vqG-WWUE_\R__yA5_s{w=D)}د&$W+ti+h#J߆qD<_j :Q}^Ͽ+ 70x]WV=$d֡[P0+݁,\I[jVWUP|wawO~ ?ߧWU W~i8f!K_A]-vG>TJ tFaMZCU|,n^[pQ1O8U{Ցlj*PW2c jAuQIј|_kOIMu/g|Ќ?_|6'l+ô@u&&5oa+Ij (lb"c'd0x ֆ#TL@  5|>xsq-WeO_wG?t [x0YU?$x7oWPȯ7:y5vۢL+'זJeEUG oC_W}W<ű_ߧK 0{_YouH7Tچs<Wr<5c  -_v@Cd;0b55gs uj`Wv`q|ϙ(>= :i/;ϒ:t]`;TOh|u= {??]O>oaM,BG> J݂֠c*NAZY,CZQ!]ZT|#kEӛkۏU-so&OISt3-bɏh>~<% @oZ1|lVǍx6c]9Ǻ`Vh_^kq ;,5jǬ?S~F3kdk^88(((.^8氾_7bqڇ.B9OF_E~`jH0l~I?Ua?(N? Յ!/+7>X%%i÷yy%0Tm/<ߕc4h 1~(^QGv鳡u 5bZDgV+_{?\3߬S*|گ4.9oz?xυQ_^̜Kox8< USPPPv ,0`?nڄNf/Z|Jg[=ixH{3cw" ~DK H86kOwv8o߫Ϲ[̞~~g*9WH@O'ƿw֟F]mnG"Casr"O_AAAlY~rZ`e,tꂸNM3_˒& 3ԭ f?c_%39mOCl˺p۶/+G'_ n`g*Ǎ?*nYd] M]PtI dw-vc^@~}FцV`=֞ 7~a6Kـ-6>8c>"sj -OOGuh&;̞1w cIP= _^Ë2Tvo < _⯵϶_ Ōo8qmA뗮f>E6-|4c}qoEVoC~d#WK;U*ْ[d3O'1A?0h` ].ɘ|_$U,`sLcw;ض-D_NA i?gG>m9v.Vv&Z5Gcp5EB`vq-pO>c7nMF7`pLe їPYUk3a+%,+&jӅ`䏉Jןn5( jtYTe||V*1BHi^<4?wrպ`!?Z|'v3>:GXV|ߣ?J5(" [:\@Ÿ"AU|{B $?A2Eb_o|zA,D^nܤKVS6 G{P~ ;YECv"]_xt vn9c_&NJ *EϿ?&&]|@[j$Jf>7X$1Cu=rԺ~򹖋oWm^6>XՈۭ'3AQϓ/jPwdmi;1|vOѿR;#̶WB\>^/ePsU/iH-Q,fAAAAA_f3{@'VWH|ʛ53){+F ` =i Z2 rd=-r\#"kf_:ߟp ] u\ ˱mOw/c8ڎ1e7@c|?wUv,6`Kߧ2]|9ӗ<E;'Ó>mO{\gLrlX ⣓54Hl߁ H"~7??q,L8gDш$,Os69H"Ŝ\hW⥔;2_>TX ̥; AVY[jdQPPPPP(eb#8vďBGzVΗmWn9˽JubS^koy6 -ihvyڊխ_7\¤fɊ}of_a K^%lc?~%?|$."lc? Dow\n7b[n4h%7&T?er[okBdbq| c{ŧoy>c63!h?77pQF#W"ߌ?cc@~1Ⱥ3߉]m~#o=53ƿ=Ǔ֚glF|n[4ʡ&p?7qfE?q^OeE_DLQMo|2/yoZYH!҉9AAAAAA 񼋟氕D엥y(/gonZ[^ ._@LȳU3|+KCHxS#Qoˤin߬ &w!l$9ѤдE ~4_~}eP>A~'X8F䷁qE$)h%ܢssofSP]YnL̵Z\iY{U`;jZ]b?ڊBйv=hG-._,"@ZrnY-(((((HĎ;SU"~&6Y-o6/Ϫ I#_6 Y=貹N]%<W$bV p9a"~-A~%_ΌZL71|tE$c"M_l6ܪ%1pO7]ͮ?s̄_Jh*E/+̌!W&?OK>cVlX+Ub/cT;QNlMEh%P|ʪڎ4:v 1X4?v]AAAAAAl!)ZU+/I9L[fmy9{::Y9X&ʹoG'96`H~$Ķ-Jw/7oxvH0J-NBm_<ܶ; 67\ \Z>cv^X;]hC6 i?!+boU%Q. YùN- ג` 06tI|Tڏ-3M7;<4&kȖ-_ MoZfCwcʋﭢkK)]qM;T쏮?sakZL;vE,ס(z nQdq/b~pIENDB`PNG  IHDR226@:IDATx= @񩬴׳(譴W3G7k$]y&4k+87#8#?66E F ,FBNTdC0r =cZ1 !$ 0 #cbUqYBadR,//AJMuxԕ׵~ߴ³ Z@GGqđ!Wϫn IENDB`PNG  IHDR226@:IDATx^[hUs&ِ65ِ4iLҤ`4E(XE-M)> $hLGeݤU,酴ݐIpgI23'v]8CO9˜s۬@!ېCdCm6?$'RU^.eGZ_ٱ6R@`[c0VrSʡ(t̎q 5F>h:&E*[H Q &\bqF1}Sb C\AT-mUnQ(ӆ4DYU eNr^ 0.HG2eUaQlXa&ޣb~N)Q90]´l.UnC}XPCF%Хz >vF qt](=fGy(aA}јogSGhx{'FF M0_ Q/]bKcϏ+|-JoN/iu,Sr:(󙽎g/f3V4_+kS|IZS;&Jṭ9)<..wR"UZ/5_n|2ؑwl.4˜|RA4H|Ra[pbhN GPXqfS\b SͿ#⧥Sx-R4Q gϻR,z "_ *4#*?3-(6YȟIENDB`PNG  IHDR226@:IDATx^]H[w'Fv1fj*MN]`;- v`W^aSevcCA֏dqRcγ?2' ܜ8{|y$r$${o{#٘ǐ|8Ph!GyPF @~QM/qG&g?kW&} ȃ#д3sPI cspΟշ8n6 $um,|lV ZgȉH2XCTQB,b?c+FJY8[t0b7{$teUH+j6U%(i$*Gv"]C 2LY`$)IG!$jBx`$OH>xPh)Cu"L6(epcљw6vح:0QfY ~QޟFOE1uD,s r;sKFno&O u_~^OgnAa4F6WV"7c2 ϡJ)vK0+ߓmg0mILzh7Inϝ찆7#j1M^Z xAqRjQ²/~D=]c|swj2KALû<O)^1ɾ*cK=m(OYģ|#bS0Zh{{']gΦ'<`L=~Q&L=+تL'bg^;vjmj7Jc7"VO:%'Q YE(Tf%8/jG#"iFJ ?TI|ȟƭVdC=-7JAăRGQfa'=d7R>_վKJXIaMOnQr/Pb3tbP ֵwS6KZ|(3(uK([){ V<T nˢKpabY U3b_lo>IENDB`PNG  IHDR sIDATx^ԱjP讆8ƈSF@,[ri򛿳?/JDzx:ǀ/]䉻Z.N浓8B]t[D?D+hyF3ȣ@HTABP򗀹\ngo*rUpzH*\&+TZ qOLƁ01`!a3|yHvpf%!ĿHtIENDB`PNG  IHDR sIDATx핱jA@_PD;=APHVT-NN@IaD D76s9n.aa=֝// XK.ABL3"|6Wy6$p< +^V}%K BgVJ8+\ "L{-|R:5:\Ax#`m|ZMy%x )L3%yj:T͞= H Lo|IOb*s;OWs^Ŭ0^e3pI!FG>#(#)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  IHDRqIDATx^A @@ߜmO(Rm-0 "Z~\=t${HCM lJP).!YȆGL7hHV5rǐ;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  IHDR DPLTEXEtRNSX=nf֪ij .[fxFͨP\~0L?7p4ftwGIDATxڬr0D63{xfy}+ŶJ8 V;膆1MgZLt+Qϗ湝 ɲQI!i}az$ - LHj?^,~)jv@R d_vid]j:B?lSQs-;T|r=/?gǨ<;_r/Wonֈ: rHnScB 6۞J҆L IT\`QAY:t>n0"9A^To<a#13GMaewIENDB`PNG  IHDR@@wPLTE_ch`ci`ci_diiii_ch_ch_djUU_dh_cg_ci_cg_dh_dj_fg_cgajj`chaei`di`ciUUU`cjaeh_dh_cj_chchh_ch`dhffpaciajj_ch`ch_ch`di_ch`ppmmm_dh`di_dj`di_ci_dh_ch^dh`dh`ci`dlhhh`eiaehbvv`di`ci_ci_ch`diddd`ej_ci`di_dhffbeiddm_ci_ciadjccqafk`dh`ej`dhddi`eh`ci_dhbgk`hp`ci`eh_di`ciff`dhadhffmaejffsadj`dhccm`flkkkbei_di`di`ej`ch_dh`di_di_di`diadj`cj_ej_dj_ch_di`dh_dh`ci_ch h|tRNSU{ ^:Mv,ֺyǝpΤ@rL oz Dތ2e.X9 b#:T6(N0=k[c3ѷhc ~IDATxS%M ෷m۶>hMU>=}e7NAI &UWċCe pȉEc$/,=L>RIXXKk?^wb;H'-6*i~Xp4R?7DXu\賧8LH`$fNJa;E2?& sEI2 EqcMb1'X!>:MVQ_ZIV,YCU/=B!8봏4.5Y}_vMLU*[92Յ&At 2Mf"OyyAh$JuY8vͅD5C r.TwIu(RHȭy|iy!t +VrBS$Q1^$Y(`Fx#dFcҟS%s,>~;ҁ[7o?p9}w;N|#V>|IENDB`PNG  IHDR@@PLTE̚?TtRNSU^{ :Mvyֺ,p rͤ@LoX 9D2 .eb:T6(cN0=kz[#3ѷeIDATxbJKm۶m۶wS5]ut%|^`; 77Cӽ@;3d(JCK:FdsyjsYI Y:%\*R~knj*ЕXvpE&m:AوVt3(xxQ,HV5"63яk/NCInMj$席Ǩ$mX\USi&i-u@t&-mp 48mY`D?Dh m O[$k,m9QZhQ8BL@* ]% G3-}к8G+4Hn=ܘ ]\ݧt;wVm=:%1O.}_YZ| &5Ԫ$h Σƀz4@.*h=T G(& ?UOMz|HS3$C=¢ʰTX\96[A-6W6IEL+" u05#wI~nVGа1```Gܘ}PtA?ea t-'AS.?uN$Gqc>]t>cmHOoo9[6soIENDB`PNG  IHDRPLTE`dk`di_dh`di`eh_ch`dh`ch_di`flff_ch`dhbii`ej`ch_ci`dibeiajj`ch`cjbfj`ciacj_chaeh`dh`dj`dibvv`di`di_ciadjhhh`dieek_ci_di_ci`dj`dh`ejccm`ehddm_ch_dhadhqqq_ci`ci_di`dh`chbgl_ch`di_ej`dj`ci`ei_dh_dh`di`ci`ci_diiii`diadhchhbek_fi`_ci`diaci`dh`diaeiffmadi_di`di_eickk_dh`dibiimmm`fi_dh`ej`ch`dh_di`ciddo`ch`di`hphhq`dk`ci`cj_ch_dh`dh`jj`ch`ciacj`dh_di`di_di_di_ciammadjbfj`gn`di_di_cjbei_diffp_di_ci_dhaci`diadj`diccqbeicgkagm`ej_dibdj_ciafkff_di`ej_eh`ci`di`ci_di`eibgk_diafk`dhaei`ci_ch՝7tRNSJūX͚( "oIHAgƉR p+γ~j6B 􍛺4˔[huUi1QKd?#\φz'Pn5xХ Eݝէl}޸YF%vNyTD>*0^2eS3r9k7|ZbIDATx6cneff|̏̌wv:ә:Yږy;@Ė,Hp2XyuƩZ]vhwme 5ݥq/nO0D- vcZY_ %J-IBjS0VSO50SהtS T94TA=LZzcniesm]}Z}p 9ZbT@tVΌZYG?Calh#VcP;-.@i!4 4eCd/>1\P曝n!&qG \ӄjۂ,9CJ P' > ~ jnAe6FלFr1hfr~i92SPi>lNBPsT'́R-s,ZPNP駗1Bw^cPLn+WlJh*W/&L/tkgh3V4m zAp?$H@w:(G`+hn[\$ >vz [ȗ ޶FEJzFd_2JG:lFс|=@t*1B^-AAuY+# _5=6!9AFrzA#/ Cu*VaY.?w&|\^| XA5#: vz+x!KadֹNJ< jx8v)_Gcż|'G~5gN{勳kCuPk'?ǕԄpXdib 7X8 8(E"k;hE]"M]l^9= nNH]? Pe#8襮$;!јq(W\ljT&B-rjVhew 5LRV܈K ɘܺLk}o^VLѾ5WoQY9!X HfvM Mx͂LIcyLlI>4| լOq>@#_-FgV5A~?å2 ?*q͕vucl.L+{Kk>{S^{|ݯH^ vIENDB`PNG  IHDRPLTE̛x"ItRNSJūX͚( "oIHAgƉR p+γ~j6B 􍛺4˔[huUi1QKd?#\φz'Pn5xХ Eݝէl}޸YF%vNyTD>*0^2eS3r9k7|ZbIDATx6cneff|̏̌wv:ә:Yږy;@Ė,Hp2XyuƩZ]vhwme 5ݥq/nO0D- vcZY_ %J-IBjS0VSO50SהtS T94TA=LZzcniesm]}Z}p 9ZbT@tVΌZYG?Calh#VcP;-.@i!4 4eCd/>1\P曝n!&qG \ӄjۂ,9CJ P' > ~ jnAe6FלFr1hfr~i92SPi>lNBPsT'́R-s,ZPNP駗1Bw^cPLn+WlJh*W/&L/tkgh3V4m zAp?$H@w:(G`+hn[\$ >vz [ȗ ޶FEJzFd_2JG:lFс|=@t*1B^-AAuY+# _5=6!9AFrzA#/ Cu*VaY.?w&|\^| XA5#: vz+x!KadֹNJ< jx8v)_Gcż|'G~5gN{勳kCuPk'?ǕԄpXdib 7X8 8(E"k;hE]"M]l^9= nNH]? Pe#8襮$;!јq(W\ljT&B-rjVhew 5LRV܈K ɘܺLk}o^VLѾ5WoQY9!X HfvM Mx͂LIcyLlI>4| լOq>@#_-FgV5A~?å2 ?*q͕vucl.L+{Kk>{S^{|ݯH^ vIENDB`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 gIDATx^ ]yHEH#4}Cj$$yffF!6Ɖ7Lql ۀ ωc9߱.i#)&$B $ OՙSo}snۙ:xyߞ?IJU&ukյY]]az.1ݸ }4:[Ik&E\Zq3 (\=pw`竫ZWF^xm%sD\czh,DɑmW8l՛Aձopgzi}>Bp4`k@ob>?׋|0<.*|/%i^&ߨ 7D<0߭šy٠ax>/1?k |[7|> >ox%}LX|^o}^WM,?4%a[a C1vPh~2Q>/k~,nc S}<{5?o<7yz> Zî\y߹ZZӺE'mn8JΔ yWCtq>iNtO7E2'Mk =Kg^zSr.kAV)^^R\+; vڛUv5BXsbx sހ^n|kݺSzệRe{T}_Sx\ 46J?{XTw΅^iUa@F eh^ 7`>͘^g! W0&}H[b>"|>NDz`LBk}D>8W\//=oǸ1Xw|^Jߡg8?rhڮoa>̌(9\ :|BiF=䠄{7I/H; t[}73zYp߶GUWs8H=to߶yVo؏/j{41IV[Pi 6W(ag\YJ~8a(zP|Q+5N3/J蹲5B75>W.\o=@A9VzjOCy4PQǽu %Ut\w)?i|z%a- \52h~>oz .xO٨{rbދL)=Ã>x ,ΰ4Ƭz)cqsOa|ÿ|70.yof5V\>CypS2pœ4:ZYHoo&ʭt +V*\J.) c\c%n#^\<:G^3Z9|vJ\r)quE=ڡv䘫3E}ѥ^)/p )>?:8vW) z >yU 1.׈Ϗ++pCoC.6#C!z їSP|=1Nq{vJp $a']kWjG\zs4|p\:^=Wꅱԕ^Hcz]_Dzƕƨ"ao9P_Oz5SZy3B/` Z`.Z<a7 e[27̿n^. U,ГRz k!6^+o˥A/ϕSvyo\s;bq^Ǽ\z 5A]sHZ#QkU/}1;a sv6$s<뗦Ue^{d.SUη^Xk"ۖn>鉶!jMY59r5FgW2J"Wk,є&15%*eqX Xm֬i;EËL!J^1rh¯w2ך}\3pUF1Ɂ1WwtuѽW0҈kJ|c+^9\.|s*1\BwWWzi*!^ۛ^<7Z" z!6e+]|'y6*zF\ HH۞r+L!Ƥz3? :0GEËr |)m+y~8îHZ{l^zM^pM5>o7Ø 5q8Jov99kf^yFV!laUyT:EC65,?d(G9QKFMLuQR=u gRf۰|u5rQS3NUt%3|kCf`8nOYv|hfwtDY \JFsE z!F_~^oT ү z<⃴\kq1f?_w?CSBą{ŮtC5MjFylVMKCӢ$>>;8\nw.,؊V^{wǴ9y2M.)dta|aXoxhM_my_!6`rJj~ l!\=w7ݝi <W%zu \ p Djjݣ{zٔp ^lɵv4:8~R7p-MFmq/jյZf"![rM6pUo̥ p-o%55?EpbbO7\Q?^l^NCGzkż\h^O9P|ͣٸ3_rT.RpdÈC}% +P}=C>oٻhK6M+M}Xr0FuDKl/"4ׂ,z-)ּ\dZkA}ޔ Su!_#a ~8U>)p-@/p Mxs H캰]kA\*G3RWS lazOAo= ۤKf~azRIX S^wf:GzXz Ss=8ۙϟozC-?L3_h ;^wK/xЁaB/7dVOgLF;v.q-K , ^xa.~;N_F?ͱn䂷FNgB u,g =VIˈiL\svѽVi{Zú^Wiqpqz_Jd뇉q9%ri<+~X^j*6 MItpВW5׊ \Kqu(Y*Rܾ|>4 *ßw DM?tĒ4 W;4gdlSm:ԫ=g#* UwUOQY*RZKR+ 2Ċ5< c7KL+}Cحpp6r35jvܑ0Ɨ|cEZ 4p$ _Rs2<2Ls^{qoے~B_}Ņ9ɳZpniraLqr)CpipY1YrIġ `Lq|-wqe<.lZu^b-[?ՈD] r-jO7+^WKg\+2p)[Е,$6:bԦbrl|׬"rUD@aq*^s#&Q &\}FI ):,:\<> s!7+Mx!\CeU?^"bJ >?zm24D懆yY^~h px0J?o8G sGCk?+>?tGJr^F yC԰tMXo#9?T?FDžrwy}QR97l|s iN+>&+?4^EKQ(@_>A*G;]-4?zq|^/uqzWy0// k.:?Fmly~X\jN0>3gHf[y[О(H>/;G'9ƴa=z/r 7,:=W#O'̵u 9@":Xkun~Z].Wה|Jt۵Dխ<>qArQKVzA][\K3UUl5n+=1!6kBѐkj-S\tWբ, ۞@];"+I1׻g"VI"B"!2 .8OjX/v-Ihh"X]^I_խ6Vzݣh^vnH9E-${AO}=|f:ktY_y-,6bD_Vn-kY\_=:hvwyx0N^uz]a]UE?E3_ 2nSyE]WWI>[<4[=~.: z\j}sa%_z}<<8G\of–yp͞~c?Y^U׵˸5*sŅ= I_$ !bZ8\o$ϭk^X6/2W]=je?aZϼZgyy>bBri$CyTYzՙ~?߰e8 5?tUϣش<|ҼJUJ#3-gޠKbz+=FNz.úu(p!WխKˏuDu+uDg#X.VfPp`b7m5ZU[|kγ4p՜:km6.둁!Y/^X 8H&KF\z^< p'6\0?~t =Y1w+NŹpuLop!vr?v.U&]FZk6/[0jGY N(|J#?mێZw>CCyTB>^^IԸ= />P;ǿ8]'`^6r-9HcPzTMԶQ2j:ƹP[m{6Kq=NZm q"ϟ+!E>\f2axuqz4-NGo%/l^>D Jm8T{ ϣSCuQ$M¯rbp}7Qf.upḽ4|>p-Ï_2zc8^EI7 3kr7yFx~6z\^Qf:}=sݦ1P4W}s 2}8د߸BzCz_B=Q^7=j˧<#2 aPy՝1 k" t_l X}2p2v_i*s4S*L! Dcu7XrQ/pmd\myrׯuM\v8-tr4fLERk7VXp}=Mw=pJA\u%׊zm- m}=otx<:r_c4\mf1?lMc\J9zF>Bϻ 84Zg! o~Bx`j#.e{߀^5d vc~!j:q.U/(?^ct\<UM砶ȸKȣop\/OVMq3CeFfg _E 'z\}CRCL=CsӴBP}"32{r `pZf,oOfKܚ:RrWzk+5fv{`8ܴn|NS.ķjńkzQŸփ8{jGW׫8<9jG7k>R/ε0ll/ZzC/O\=>[#.L7K[KA5yq䇑^\ŷ^nqX MFka ziuz _4[7ZWk6x~W. ߰>?B/wy[o_7Q|ì8߸o8/W8CK7ǡM\<78T5/GG ?ͫn2P`G.ڈ[_C4<ʜ"{PG( ?4ፌҫYXݦQ73Lz@e_Am/uU^7r%'s)jU;-A0Cpɬc)lzyYXɢ- 7| x?._gcJ s[Gt>FPwve'[T`9OE?)~}'6n+Yq-vJ/ + z5I*^D%z\{ 紛Ђ ?ypO g24\^!Gu|ݏ̠iƁuaڂ S잻"]/xˠ\i/ܣK˞S ׅ;s_ p]`~Aׂb |7Q}ޞl=9K z]('2H~hCO ಘxvFfy:*j"ne)Υj" \Z-QA-'Υj,9eKq.Ԉm^Źw Uš><륙rufюX(Tzc:ځpf\UGh|ᥜ o\\ݣ^kUn_K 5mߘ,=?W2|C7/KuyO$Uz#\LL='XgVއ6ZAzz9h6/\/gʟpћ1-!QDm6u6:aK(u};X#02L/ ۘmd`jVkߦ+z~~+zq!bgb-9F ҃͸m2pU za@"*ZZd\PW(l|p%bq5LW,H^Ÿ6r.Kߠ"ZW8'+4?/C >_#E/xwĒk*o 7sPdv}1KseTkJ\,/qC~(&ߨGbzmyp )|:,4~|:oeȣD7gYåwdz8CpV ϣJT+Sq.Uk\/:KiA^zGz ÚLPT[Q|J 5TauRx>4 }G5FB{}z6 \SzIy\cIƵZc(ݒ`*sx<= ^ҹ0؃E:߀IQ\cz2\WUs2>< eyz||׵^ri1CGOpќc^yIq%qQ_ Sv*@/UBmX2pU 5|ġ |^P/b|I`qtq6|uIoZ/(s~(gkzP-}\$Vw}toOeQ˚uDC ٞ-4G[/G_!&Ֆk>pᘶ8W^3Viz`[G7B/q4q99s1͖3..w5|\,Wk>_||y6Mpp.~f5Ou@:@]W\ЪY\e_M!1^Mpi=/j䇲OQҗP0͓5_/U2;"a0`kgk{!j7kwyTŽ˸KMz([o(r@|=ƵC(~(??l nӨH2?WʯG|Ge=/s#u)")u肳>snדX%cMpy՝ѫN^X X`.\z2.]T חxqWW4 9p5 5q sa^W_ӧ?;hK!ҹ<4h. ̋4Ћso|C&y| a|5ejsj `oΊGCo.;DWզFFq.vM!B4\fחȣ'6AC5zB~/Bhk7گx>>D[*ҋE\溍:+B7zrڡʑ~ j /*U+l|9Ƶ7UM~{Bϱ#ՌF WOA:kp.Hz-9H!.W\815qcu1Zv5_ k%=5|iMzp M8\T_SkrV5KŸa.7#Bq k \S^D G%??DMj!|hz^jay~&U'\9\ p_g ~X5H?eaz][ ~Άg|7ם^! laQt!˸k&uBU)mAWCzm Ѩp+5;< Ђ1ti ` Ъ'D@׸*rUp_rCzo|d|j\9z"s!a^Fsx kF\Y||q0-DC CTWj7o;!7C\g ^F6CoK/Yo6FIxJJ\x4wGq{,U"kk8\{?s3K:WU0ѫT׺SFzaobz7(6^t071>~C6?|^%AK~r|?׀A/>K~o-|c9s3v"¨xfqg|~37 B $Pk+TrsBU&o 7 Qkz8/C\/q5 nbPW PH=j _?45*P/y9}=Nzv4r^I"~27\JײpIBs/\k@2Wz(/9\ʼ eX& Tq m.PfBoUC\ 5^e߈EMG&yA[\B;KC ,bk8?_0rqxZ^GG0p¯oWw\#'h^ɣx>mD4]]+j?*|Ğ4.E[)(-+!HD~tt.a 5!#GyACϛ|]}aKs>^|d7s y[.'?7C#dơ@^ o ]}c|vOV$!#Y{|CCepl=BȸFoh,!q(4?,1y9/4zo }?Kmi^'*y7|<|\W[ސl7zrU|yz/k{w1nf^sW.Ov"ZøHZz&mG4zM8Hc+8׹tzIeu4 m価ѫz$^sy; n퇜Kz"Ú hVkP>暢_kɁ5UõfD/9\s5rerA\ 9d(ӫ/D! #Qoz:>+!(GDՁmjUC^C}_OoC1@SkbC7 MP3 x [3V\w Ҹ/fDƸ^ҹ\3w^` z}qp 亞qmtob\38.=!t +="Csj 9]?/_p50jG[2|EmFwj|! r8! a^FN W j!!r_%\&3u ~}PCd\ׅ0/sL-a>YiSڟXq.iz"u,Emv)v1 \\f>YK㚡| lXވUDE q$ jZ_3Ë8|Е>} $rƥyl !?o5z|r+0m9E7kSZjS@l͜+a L!e6q$$]b EW| eڵk(:&T)\`=F5cQ( OԺSY4r{t,oTKBƸrS5pEqQ^]RBaWҹچh׫}*o10/|)C\`y4.>Ҹo&-_\/,oRdWϯoSTK (ʑ:kL.sV2gC/0/^#Ӗ-lI*k5w7ͷgzI広m+^Krq:2A\#b\j^zQK*ל]q@/pmcX߸0rݕEV]Dr]Kz3t){C;<7$P Z^qdj,}]GGѳNA\fBb.c\ LG#GWϷg³`.qa-݌IWzXף8林"b5 ,q*Y/^2kIqDr#ߧipլNE!\c{Kb}@p ] vO4Y,\}XW)Z|B:4Cqa\o&C\G|^^o;L\8+Dyp <r5 >|=|cyY apR!S ^!O0L6/5]hş^ak}Jx're!\r蕉  sŹ¹VBfq3tG3 QzLC:/q8#of0f>e>#TWlшCu+|~z}=03s!f˅Lz ÙơO$;?_2Ź_Ӥr7F<*o^p/b72g %k!?,zGw;HOoc7)C}^u9 qt_I2:Kh_6Ci)2z:s䇞Qpz WZW Cdߕjv=`м\D{^]pYUj%Եupl L`׬];^R1p= ̝<&"R뤭^/oLI^'99F~ik _e wE~&2?@\/j/F\Jx 213[\"J s\9W^fz2O2ŸazM^blz3"bz88y^/p&΅ٟ<ʬ.?\uo %%! EOߊys]fe~՝QJf'9?9fPRy&?3fꛛ+%\#V䪗<q-^Į 0*:c*j>볼NyEeU&\ٚlzx5b*D5Y r.<@Aa*rm{lp-C  zy짫8}oHB^o}^yħ4z}!'4:|Q \5y\.O\1OߘKCvyoOe v\S0xy^ |a8rLꅜE^ Y^Y/Y gِk>cr|7J:Ɨ YSz~gΥjZWJ.;r.?Yg3Eg%6/K~_.*9Wz^pY4:Y}=1:R?t1Kzz-|$zor5ߺm+&jf=2;WG\4[A5-&zε@ >q-n] 1p]ĸ6h!?Jj =1 J֫c#  ôY5HA>a!jGMN4>Ϸ||;HGsg!Z^WOWq|wGM1jUzuT^C//7&q(70Z4z=.󲊹gRKk5q|} wŠ/(q8L !d^^]^>ׯ\k %?[`}~B" sݦs5%gG^r|^.@m֊pPzN5? t|U:/h~XO~&]R]p~!qu2p*kFؿ^8췈NOx'V=m\\*rZO|GίYLZzz r?;f ɇB=%w 0 +>Q^!& zUxWR]~h1/y2/šȾ9+˓^U%g{^- 4lnLQ^zbc.iJV¥^qm7墯 ׺+%! p{hQ\8YRl3gi1|q+קGk.,}~/FŽ|^~lG0络_'`]K7oX&h[.,.བj=ѶlݚYV θz--བ6lZA:\]+> "ŋsw]-vJZA*~aW Dz:o70!v3KF;.~^U.A4e(WbkK>?K([|q oG9.^s{+bsGBhvi(_Zݜ :Йi:skIzan+<&&Uܠzs# ;1yĵ4 GN퐫3 {e.4%좭<ȣap|%q$ą2ߐZg'vUe7DR_U"Cs_Jl>r׫ Ǯe qwه p%bq>Ù;izR^ӄ]NJqx a.5q#t~( ;1`~(2UF1/'o[#$}yl3g]^ AzBCh PqE>3z.zMq/pK9xd*WuZ͕)"\Irs4zQz}҃:@G\3zh?]A=j^C񅹲({8AYV\su?2k\e=yRsC:6G̣}sud'QC}Śpm2ġؾ^ZJq8IQ  ~ؑBqu_Gd6E&*gۙ<ҋ]]:rW/҈*p-g\6I)s4J*gU;iiZ1~=a1@yJ"M!:{aMyJzw\\XTB1,c2EXPzUx<4Lw!$$+ЫP`~fuC eCI'~Yh8MP/ .[]34tݼ~`"ąIY ~qN3wZxm'u/ԫ82hb\/[,z =WvreC2W`L9ZV׌z"׸|z;YsyN7vWYv^ߞˊP?,7<Ӗ!gKx>6 yNp%)ƥ<[ We(zsr }"w6Jz=/ "M?tk7%C8ׇ*ˁo,wo,Oy^to8J˺yeۮ<_]c bdZk!%A2Ҥ6t|"05&2|沄J^YZZ$Kcٸ)ʒujV웱c_!Շ4ׂ}UMg$XV {韰{Y%yZ^Fip$T:^{蟳Ek^T]4\KVK 򫱣?|r!1A% :.m!ܼW|ޞ \gɘs/N eRz}Sڔ^+_~A/71&RGASy^Hz(SͅYX>F4l)aϗKce_%foIe&͵ ^KҪ:@Z`.5գ{uxX/CzTYyTZR̾^D{ԇ#Teb_ ZV̾!Xr^v_7<M~^ei5E8|$/or۟3jA\YCפ5/Z^\SesЫ:ER"p-5a}zbd 5.bEC5ْkm)h?}ȾVk(fۂ}tmx[ir5h1gO-V\/puR]bQXбp}27l")ep->HיLQ =^Ga׬] (Weu_,=H=5 .9He_ǏcŶ \襾,XUϫL CS]BƗks]4kJsm߮wø|}\xmw1U*ۼܴRYY :/cAŰ^91+/؇^ġϾA sz]S%8=Z}ES/Z@gq[pR9epYΆgi&тn܌s-6S.צw )6CTjȥkQߨa>_a޻,VǶ>-I͡n3&Mzŕ̓m¿ ޢƗ\|ws[j娯7σ^~Wa||ÒM~hCo2ϣu}=39?tכf~ J,ZQeVpԵ} z"ASWD dcxO|MRZ=t-20hVBGAmכWU\fA59b(azUF1G5&Ww,k4ݔ&5W[L 884+WOsW..hiRѫ\m8{>mhVǾ\\/W<:NǛRii\9qiJczG5< 5i;=zڬexv|oZ4_T<;* :^er0Ue&#e,jtn+B' 뱔q^ B9DIcٔ^/QczV` 81y.I^buu'wXˏX{#ʇ˜ ,ABZy(nח^^<.}k:,,1|X?H6@/78Z1ǕϬLK!+AK8n 1{G%5Z}M xm~X5HO1{G! \|>< m3u_R\}`X{?<4|xn^Nf?>Xc9Q~].,VDcRsݵ+s!ODz]nCh_! 1by:z#u-&?]+M7J5V󘗑o y=ʥ^ji72}-Vkr՞4}#>#=Ahz7ׄ::Ht12KFS~Þ++4uq1|Wu6pMP?MMz9r.5,l󲋺MG~Xnv6 Q-uߡ|ya-C}=pU ]W@ j1?9p?/eY?A~h\5[og|9fo9~; gs%ǖXz } Q 0yz~1D篴> 'Ə+ׅhJpaW3Fz8)s%|¼ =||%?[wgϕ\k z+<^]GG)7UW8|}o>W֛^#uU`ݦzmL/~㰶.0m78Wwq"wh(b_s)˛EF}z >_?}ϕ^|?.pV&uu՘WWޥJWHz!; \NSw6Wsa6p|U5`'|Ch 20݈V$PWͨ@/ >_g8C&.WW*Wz|?m<Z/K5n+=׼˕o?CPЕo3wzv?{5\ƪ#T>wu>3D \[gԸ:\!>xO8<clRϕ.[<ن冣%+v\3vR/a.\}ez0TB.0 B=46k#1)ֱS3-.yIQr|#>>?c7_#}=!KopP}uݮ+f\7_V䚎{20qiq^mj,>ݿBWm5aOx)3/ Iٚ8\>㙮k8bK{<ӫcm8>݂nтk/{@(J#0Խ|ߵ^Qѥp/3 Wj>/82_wK%2e]8B@ Uc7yނÇ8\㥴=Wr{s_o%.TqxEQ.x-4ƿ|d\/0>i~1opG]Gn%z"kcuB㹑Zbyo_:^?R?l^[-֖'Ǹjè Ṓ镱6뽸zX}^^>9!Tfayp2ϋ C\W-7 }=CHo%>7ژo0dW}QC^C'^Po0?oZvCi/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 szzIDATx^NqFn@; !ٸ{L/2--_D7&j P L`LC0_ʹ3ΐt%3|?1lX" 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ϴ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  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뭷~=8n삳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 $BiIDATH1P BB`bgp0@d0 3cW.7E-SqQCEle8Y'4ND:1UѦހa0 !nZ -s>EdS3h&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щIA:H(zr6+&q?:Q"tm2匵am`7!d yQN]PٌjC#Q^s~IENDB`PNG  IHDR+('csCl0`MIDATx^M0Ѯ=3x!*y\\DuSØM%H:et'8xl}RN mɍ6gYJJAmsjl&ݐ |3X>c7+n捪;~ۮ`=}ǭa+ `g\tw0!6g19lsN{O"g mnTa3U~#Vr Zi(|o*I IENDB`PNG  IHDR+('csCl0`MIDATxcXjfac30NO@`P,dž ~aw,C|A|w,ai;ӡtr,IbԱt迟?;x4ѽѶ]@; @J1x0cC fU~SA3IENDB`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'+csCl0`MHIDATxcAdHc?Hv( ;h-0>-`:!FyTDƤBE-<IENDB`PNG  IHDR'+csCl0`MIIDATxcHdHcX9Y$)r-y|O1a^;-|ODŽ@QhAvZ`|ZjtC$ HIowyIENDB`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!