PNG  IHDRxsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<,tEXtComment File Manager

File Manager

Path: /opt/alt/alt-nodejs22/root/usr/include/node/

Viewing File: v8-callbacks.h

// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef INCLUDE_V8_ISOLATE_CALLBACKS_H_
#define INCLUDE_V8_ISOLATE_CALLBACKS_H_

#include <stddef.h>

#include <functional>
#include <string>

#include "cppgc/common.h"
#include "v8-data.h"          // NOLINT(build/include_directory)
#include "v8-local-handle.h"  // NOLINT(build/include_directory)
#include "v8-promise.h"       // NOLINT(build/include_directory)
#include "v8config.h"         // NOLINT(build/include_directory)

#if defined(V8_OS_WIN)
struct _EXCEPTION_POINTERS;
#endif

namespace v8 {

template <typename T>
class FunctionCallbackInfo;
class Isolate;
class Message;
class Module;
class Object;
class Promise;
class ScriptOrModule;
class String;
class UnboundScript;
class Value;

/**
 * A JIT code event is issued each time code is added, moved or removed.
 *
 * \note removal events are not currently issued.
 */
struct JitCodeEvent {
  enum EventType {
    CODE_ADDED,
    CODE_MOVED,
    CODE_REMOVED,
    CODE_ADD_LINE_POS_INFO,
    CODE_START_LINE_INFO_RECORDING,
    CODE_END_LINE_INFO_RECORDING
  };
  // Definition of the code position type. The "POSITION" type means the place
  // in the source code which are of interest when making stack traces to
  // pin-point the source location of a stack frame as close as possible.
  // The "STATEMENT_POSITION" means the place at the beginning of each
  // statement, and is used to indicate possible break locations.
  enum PositionType { POSITION, STATEMENT_POSITION };

  // There are three different kinds of CodeType, one for JIT code generated
  // by the optimizing compiler, one for byte code generated for the
  // interpreter, and one for code generated from Wasm. For JIT_CODE and
  // WASM_CODE, |code_start| points to the beginning of jitted assembly code,
  // while for BYTE_CODE events, |code_start| points to the first bytecode of
  // the interpreted function.
  enum CodeType { BYTE_CODE, JIT_CODE, WASM_CODE };

  // Type of event.
  EventType type;
  CodeType code_type;
  // Start of the instructions.
  void* code_start;
  // Size of the instructions.
  size_t code_len;
  // Script info for CODE_ADDED event.
  Local<UnboundScript> script;
  // User-defined data for *_LINE_INFO_* event. It's used to hold the source
  // code line information which is returned from the
  // CODE_START_LINE_INFO_RECORDING event. And it's passed to subsequent
  // CODE_ADD_LINE_POS_INFO and CODE_END_LINE_INFO_RECORDING events.
  void* user_data;

  struct name_t {
    // Name of the object associated with the code, note that the string is not
    // zero-terminated.
    const char* str;
    // Number of chars in str.
    size_t len;
  };

  struct line_info_t {
    // PC offset
    size_t offset;
    // Code position
    size_t pos;
    // The position type.
    PositionType position_type;
  };

  struct wasm_source_info_t {
    // Source file name.
    const char* filename;
    // Length of filename.
    size_t filename_size;
    // Line number table, which maps offsets of JITted code to line numbers of
    // source file.
    const line_info_t* line_number_table;
    // Number of entries in the line number table.
    size_t line_number_table_size;
  };

  wasm_source_info_t* wasm_source_info = nullptr;

  union {
    // Only valid for CODE_ADDED.
    struct name_t name;

    // Only valid for CODE_ADD_LINE_POS_INFO
    struct line_info_t line_info;

    // New location of instructions. Only valid for CODE_MOVED.
    void* new_code_start;
  };

  Isolate* isolate;
};

/**
 * Option flags passed to the SetJitCodeEventHandler function.
 */
enum JitCodeEventOptions {
  kJitCodeEventDefault = 0,
  // Generate callbacks for already existent code.
  kJitCodeEventEnumExisting = 1
};

/**
 * Callback function passed to SetJitCodeEventHandler.
 *
 * \param event code add, move or removal event.
 */
using JitCodeEventHandler = void (*)(const JitCodeEvent* event);

// --- Garbage Collection Callbacks ---

/**
 * Applications can register callback functions which will be called before and
 * after certain garbage collection operations.  Allocations are not allowed in
 * the callback functions, you therefore cannot manipulate objects (set or
 * delete properties for example) since it is possible such operations will
 * result in the allocation of objects.
 * TODO(v8:12612): Deprecate kGCTypeMinorMarkSweep after updating blink.
 */
enum GCType {
  kGCTypeScavenge = 1 << 0,
  kGCTypeMinorMarkSweep = 1 << 1,
  kGCTypeMinorMarkCompact V8_DEPRECATE_SOON(
      "Use kGCTypeMinorMarkSweep instead of kGCTypeMinorMarkCompact.") =
      kGCTypeMinorMarkSweep,
  kGCTypeMarkSweepCompact = 1 << 2,
  kGCTypeIncrementalMarking = 1 << 3,
  kGCTypeProcessWeakCallbacks = 1 << 4,
  kGCTypeAll = kGCTypeScavenge | kGCTypeMinorMarkSweep |
               kGCTypeMarkSweepCompact | kGCTypeIncrementalMarking |
               kGCTypeProcessWeakCallbacks
};

/**
 * GCCallbackFlags is used to notify additional information about the GC
 * callback.
 *   - kGCCallbackFlagConstructRetainedObjectInfos: The GC callback is for
 *     constructing retained object infos.
 *   - kGCCallbackFlagForced: The GC callback is for a forced GC for testing.
 *   - kGCCallbackFlagSynchronousPhantomCallbackProcessing: The GC callback
 *     is called synchronously without getting posted to an idle task.
 *   - kGCCallbackFlagCollectAllAvailableGarbage: The GC callback is called
 *     in a phase where V8 is trying to collect all available garbage
 *     (e.g., handling a low memory notification).
 *   - kGCCallbackScheduleIdleGarbageCollection: The GC callback is called to
 *     trigger an idle garbage collection.
 */
enum GCCallbackFlags {
  kNoGCCallbackFlags = 0,
  kGCCallbackFlagConstructRetainedObjectInfos = 1 << 1,
  kGCCallbackFlagForced = 1 << 2,
  kGCCallbackFlagSynchronousPhantomCallbackProcessing = 1 << 3,
  kGCCallbackFlagCollectAllAvailableGarbage = 1 << 4,
  kGCCallbackFlagCollectAllExternalMemory = 1 << 5,
  kGCCallbackScheduleIdleGarbageCollection = 1 << 6,
};

using GCCallback = void (*)(GCType type, GCCallbackFlags flags);

using InterruptCallback = void (*)(Isolate* isolate, void* data);

/**
 * This callback is invoked when the heap size is close to the heap limit and
 * V8 is likely to abort with out-of-memory error.
 * The callback can extend the heap limit by returning a value that is greater
 * than the current_heap_limit. The initial heap limit is the limit that was
 * set after heap setup.
 */
using NearHeapLimitCallback = size_t (*)(void* data, size_t current_heap_limit,
                                         size_t initial_heap_limit);

/**
 * Callback function passed to SetUnhandledExceptionCallback.
 */
#if defined(V8_OS_WIN)
using UnhandledExceptionCallback =
    int (*)(_EXCEPTION_POINTERS* exception_pointers);
#endif

// --- Counters Callbacks ---

using CounterLookupCallback = int* (*)(const char* name);

using CreateHistogramCallback = void* (*)(const char* name, int min, int max,
                                          size_t buckets);

using AddHistogramSampleCallback = void (*)(void* histogram, int sample);

// --- Exceptions ---

using FatalErrorCallback = void (*)(const char* location, const char* message);

struct OOMDetails {
  bool is_heap_oom = false;
  const char* detail = nullptr;
};

using OOMErrorCallback = void (*)(const char* location,
                                  const OOMDetails& details);

using MessageCallback = void (*)(Local<Message> message, Local<Value> data);

// --- Tracing ---

enum LogEventStatus : int { kStart = 0, kEnd = 1, kStamp = 2 };
using LogEventCallback = void (*)(const char* name,
                                  int /* LogEventStatus */ status);

// --- Crashkeys Callback ---
enum class CrashKeyId {
  kIsolateAddress,
  kReadonlySpaceFirstPageAddress,
  kMapSpaceFirstPageAddress V8_ENUM_DEPRECATE_SOON("Map space got removed"),
  kOldSpaceFirstPageAddress,
  kCodeRangeBaseAddress,
  kCodeSpaceFirstPageAddress,
  kDumpType,
  kSnapshotChecksumCalculated,
  kSnapshotChecksumExpected,
};

using AddCrashKeyCallback = void (*)(CrashKeyId id, const std::string& value);

// --- Enter/Leave Script Callback ---
using BeforeCallEnteredCallback = void (*)(Isolate*);
using CallCompletedCallback = void (*)(Isolate*);

// --- AllowCodeGenerationFromStrings callbacks ---

/**
 * Callback to check if code generation from strings is allowed. See
 * Context::AllowCodeGenerationFromStrings.
 */
using AllowCodeGenerationFromStringsCallback = bool (*)(Local<Context> context,
                                                        Local<String> source);

struct ModifyCodeGenerationFromStringsResult {
  // If true, proceed with the codegen algorithm. Otherwise, block it.
  bool codegen_allowed = false;
  // Overwrite the original source with this string, if present.
  // Use the original source if empty.
  // This field is considered only if codegen_allowed is true.
  MaybeLocal<String> modified_source;
};

/**
 * Access type specification.
 */
enum AccessType {
  ACCESS_GET,
  ACCESS_SET,
  ACCESS_HAS,
  ACCESS_DELETE,
  ACCESS_KEYS
};

// --- Failed Access Check Callback ---

using FailedAccessCheckCallback = void (*)(Local<Object> target,
                                           AccessType type, Local<Value> data);

/**
 * Callback to check if codegen is allowed from a source object, and convert
 * the source to string if necessary. See: ModifyCodeGenerationFromStrings.
 */
using ModifyCodeGenerationFromStringsCallback =
    ModifyCodeGenerationFromStringsResult (*)(Local<Context> context,
                                              Local<Value> source);
using ModifyCodeGenerationFromStringsCallback2 =
    ModifyCodeGenerationFromStringsResult (*)(Local<Context> context,
                                              Local<Value> source,
                                              bool is_code_like);

// --- WebAssembly compilation callbacks ---
using ExtensionCallback = bool (*)(const FunctionCallbackInfo<Value>&);

using AllowWasmCodeGenerationCallback = bool (*)(Local<Context> context,
                                                 Local<String> source);

// --- Callback for APIs defined on v8-supported objects, but implemented
// by the embedder. Example: WebAssembly.{compile|instantiate}Streaming ---
using ApiImplementationCallback = void (*)(const FunctionCallbackInfo<Value>&);

// --- Callback for WebAssembly.compileStreaming ---
using WasmStreamingCallback = void (*)(const FunctionCallbackInfo<Value>&);

enum class WasmAsyncSuccess { kSuccess, kFail };

// --- Callback called when async WebAssembly operations finish ---
using WasmAsyncResolvePromiseCallback = void (*)(
    Isolate* isolate, Local<Context> context, Local<Promise::Resolver> resolver,
    Local<Value> result, WasmAsyncSuccess success);

// --- Callback for loading source map file for Wasm profiling support
using WasmLoadSourceMapCallback = Local<String> (*)(Isolate* isolate,
                                                    const char* name);

// --- Callback for checking if WebAssembly imported strings are enabled ---
using WasmImportedStringsEnabledCallback = bool (*)(Local<Context> context);

// --- Callback for checking if the SharedArrayBuffer constructor is enabled ---
using SharedArrayBufferConstructorEnabledCallback =
    bool (*)(Local<Context> context);

// --- Callback for checking if the compile hints magic comments are enabled ---
using JavaScriptCompileHintsMagicEnabledCallback =
    bool (*)(Local<Context> context);

// --- Callback for checking if WebAssembly JSPI is enabled ---
using WasmJSPIEnabledCallback = bool (*)(Local<Context> context);

/**
 * HostImportModuleDynamicallyCallback is called when we
 * require the embedder to load a module. This is used as part of the dynamic
 * import syntax.
 *
 * The referrer contains metadata about the script/module that calls
 * import.
 *
 * The specifier is the name of the module that should be imported.
 *
 * The import_attributes are import attributes for this request in the form:
 * [key1, value1, key2, value2, ...] where the keys and values are of type
 * v8::String. Note, unlike the FixedArray passed to ResolveModuleCallback and
 * returned from ModuleRequest::GetImportAssertions(), this array does not
 * contain the source Locations of the attributes.
 *
 * The embedder must compile, instantiate, evaluate the Module, and
 * obtain its namespace object.
 *
 * The Promise returned from this function is forwarded to userland
 * JavaScript. The embedder must resolve this promise with the module
 * namespace object. In case of an exception, the embedder must reject
 * this promise with the exception. If the promise creation itself
 * fails (e.g. due to stack overflow), the embedder must propagate
 * that exception by returning an empty MaybeLocal.
 */
using HostImportModuleDynamicallyCallback = MaybeLocal<Promise> (*)(
    Local<Context> context, Local<Data> host_defined_options,
    Local<Value> resource_name, Local<String> specifier,
    Local<FixedArray> import_attributes);

/**
 * Callback for requesting a compile hint for a function from the embedder. The
 * first parameter is the position of the function in source code and the second
 * parameter is embedder data to be passed back.
 */
using CompileHintCallback = bool (*)(int, void*);

/**
 * HostInitializeImportMetaObjectCallback is called the first time import.meta
 * is accessed for a module. Subsequent access will reuse the same value.
 *
 * The method combines two implementation-defined abstract operations into one:
 * HostGetImportMetaProperties and HostFinalizeImportMeta.
 *
 * The embedder should use v8::Object::CreateDataProperty to add properties on
 * the meta object.
 */
using HostInitializeImportMetaObjectCallback = void (*)(Local<Context> context,
                                                        Local<Module> module,
                                                        Local<Object> meta);

/**
 * HostCreateShadowRealmContextCallback is called each time a ShadowRealm is
 * being constructed in the initiator_context.
 *
 * The method combines Context creation and implementation defined abstract
 * operation HostInitializeShadowRealm into one.
 *
 * The embedder should use v8::Context::New or v8::Context:NewFromSnapshot to
 * create a new context. If the creation fails, the embedder must propagate
 * that exception by returning an empty MaybeLocal.
 */
using HostCreateShadowRealmContextCallback =
    MaybeLocal<Context> (*)(Local<Context> initiator_context);

/**
 * PrepareStackTraceCallback is called when the stack property of an error is
 * first accessed. The return value will be used as the stack value. If this
 * callback is registed, the |Error.prepareStackTrace| API will be disabled.
 * |sites| is an array of call sites, specified in
 * https://v8.dev/docs/stack-trace-api
 */
using PrepareStackTraceCallback = MaybeLocal<Value> (*)(Local<Context> context,
                                                        Local<Value> error,
                                                        Local<Array> sites);

#if defined(V8_OS_WIN)
/**
 * Callback to selectively enable ETW tracing based on the document URL.
 * Implemented by the embedder, it should never call back into V8.
 *
 * Windows allows passing additional data to the ETW EnableCallback:
 * https://learn.microsoft.com/en-us/windows/win32/api/evntprov/nc-evntprov-penablecallback
 *
 * This data can be configured in a WPR (Windows Performance Recorder)
 * profile, adding a CustomFilter to an EventProvider like the following:
 *
 * <EventProvider Id=".." Name="57277741-3638-4A4B-BDBA-0AC6E45DA56C" Level="5">
 *   <CustomFilter Type="0x80000000" Value="AQABAAAAAAA..." />
 * </EventProvider>
 *
 * Where:
 * - Name="57277741-3638-4A4B-BDBA-0AC6E45DA56C" is the GUID of the V8
 *     ETW provider, (see src/libplatform/etw/etw-provider-win.h),
 * - Type="0x80000000" is EVENT_FILTER_TYPE_SCHEMATIZED,
 * - Value="AQABAAAAAA..." is a base64-encoded byte array that is
 *     base64-decoded by Windows and passed to the ETW enable callback in
 *     the 'PEVENT_FILTER_DESCRIPTOR FilterData' argument; see:
 * https://learn.microsoft.com/en-us/windows/win32/api/evntprov/ns-evntprov-event_filter_descriptor.
 *
 * This array contains a struct EVENT_FILTER_HEADER followed by a
 * variable length payload, and as payload we pass a string in JSON format,
 * with a list of regular expressions that should match the document URL
 * in order to enable ETW tracing:
 *   {
 *     "version": "1.0",
 *     "filtered_urls": [
 *         "https:\/\/.*\.chromium\.org\/.*", "https://v8.dev/";, "..."
 *     ]
 *  }
 */
using FilterETWSessionByURLCallback =
    bool (*)(Local<Context> context, const std::string& etw_filter_payload);
#endif  // V8_OS_WIN

}  // namespace v8

#endif  // INCLUDE_V8_ISOLATE_CALLBACKS_H_
b IDATxytVսϓ22 A@IR :hCiZ[v*E:WũZA ^dQeQ @ !jZ'>gsV仿$|?g)&x-EIENT ;@xT.i%-X}SvS5.r/UHz^_$-W"w)Ɗ/@Z &IoX P$K}JzX:;` &, ŋui,e6mX ԵrKb1ԗ)DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA݀!I*]R;I2$eZ#ORZSrr6mteffu*((Pu'v{DIߔ4^pIm'77WEEE;vƎ4-$]'RI{\I&G :IHJ DWBB=\WR޽m o$K(V9ABB.}jѢv`^?IOȅ} ڶmG}T#FJ`56$-ھ}FI&v;0(h;Б38CӧOWf!;A i:F_m9s&|q%=#wZprrrla A &P\\СC[A#! {olF} `E2}MK/vV)i{4BffV\|ۭX`b@kɶ@%i$K z5zhmX[IXZ` 'b%$r5M4º/l ԃߖxhʔ)[@=} K6IM}^5k㏷݆z ΗÿO:gdGBmyT/@+Vɶ纽z񕏵l.y޴it뭷zV0[Y^>Wsqs}\/@$(T7f.InݺiR$푔n.~?H))\ZRW'Mo~v Ov6oԃxz! S,&xm/yɞԟ?'uaSѽb,8GלKboi&3t7Y,)JJ c[nzӳdE&KsZLӄ I?@&%ӟ۶mSMMњ0iؐSZ,|J+N ~,0A0!5%Q-YQQa3}$_vVrf9f?S8`zDADADADADADADADADAdqP,تmMmg1V?rSI꒟]u|l RCyEf٢9 jURbztѰ!m5~tGj2DhG*{H9)꒟ר3:(+3\?/;TUݭʴ~S6lڧUJ*i$d(#=Yݺd{,p|3B))q:vN0Y.jkק6;SɶVzHJJЀ-utѹսk>QUU\޲~]fFnK?&ߡ5b=z9)^|u_k-[y%ZNU6 7Mi:]ۦtk[n X(e6Bb."8cۭ|~teuuw|ήI-5"~Uk;ZicEmN/:]M> cQ^uiƞ??Ңpc#TUU3UakNwA`:Y_V-8.KKfRitv޲* 9S6ֿj,ՃNOMߤ]z^fOh|<>@Å5 _/Iu?{SY4hK/2]4%it5q]GGe2%iR| W&f*^]??vq[LgE_3f}Fxu~}qd-ږFxu~I N>\;͗O֊:̗WJ@BhW=y|GgwܷH_NY?)Tdi'?խwhlmQi !SUUsw4kӺe4rfxu-[nHtMFj}H_u~w>)oV}(T'ebʒv3_[+vn@Ȭ\S}ot}w=kHFnxg S 0eޢm~l}uqZfFoZuuEg `zt~? b;t%>WTkķh[2eG8LIWx,^\thrl^Ϊ{=dž<}qV@ ⠨Wy^LF_>0UkDuʫuCs$)Iv:IK;6ֲ4{^6եm+l3>݆uM 9u?>Zc }g~qhKwڭeFMM~pМuqǿz6Tb@8@Y|jx](^]gf}M"tG -w.@vOqh~/HII`S[l.6nØXL9vUcOoB\xoǤ'T&IǍQw_wpv[kmO{w~>#=P1Pɞa-we:iǏlHo׈꒟f9SzH?+shk%Fs:qVhqY`jvO'ρ?PyX3lх]˾uV{ݞ]1,MzYNW~̈́ joYn}ȚF߾׮mS]F z+EDxm/d{F{-W-4wY듏:??_gPf ^3ecg ҵs8R2מz@TANGj)}CNi/R~}c:5{!ZHӋӾ6}T]G]7W6^n 9*,YqOZj:P?Q DFL|?-^.Ɵ7}fFh׶xe2Pscz1&5\cn[=Vn[ĶE鎀uˌd3GII k;lNmشOuuRVfBE]ۣeӶu :X-[(er4~LHi6:Ѻ@ԅrST0trk%$Č0ez" *z"T/X9|8.C5Feg}CQ%͞ˣJvL/?j^h&9xF`њZ(&yF&Iݻfg#W;3^{Wo^4'vV[[K';+mӍִ]AC@W?1^{එyh +^]fm~iԵ]AB@WTk̏t uR?l.OIHiYyԶ]Aˀ7c:q}ힽaf6Z~қm(+sK4{^6}T*UUu]n.:kx{:2 _m=sAߤU@?Z-Vކеz왍Nэ{|5 pڶn b p-@sPg]0G7fy-M{GCF'%{4`=$-Ge\ eU:m+Zt'WjO!OAF@ik&t݆ϥ_ e}=]"Wz_.͜E3leWFih|t-wZۍ-uw=6YN{6|} |*={Ѽn.S.z1zjۻTH]흾 DuDvmvK.`V]yY~sI@t?/ϓ. m&["+P?MzovVЫG3-GRR[(!!\_,^%?v@ҵő m`Y)tem8GMx.))A]Y i`ViW`?^~!S#^+ѽGZj?Vģ0.))A꨷lzL*]OXrY`DBBLOj{-MH'ii-ϰ ok7^ )쭡b]UXSְmռY|5*cֽk0B7镹%ڽP#8nȎq}mJr23_>lE5$iwui+ H~F`IjƵ@q \ @#qG0".0" l`„.0! ,AQHN6qzkKJ#o;`Xv2>,tێJJ7Z/*A .@fفjMzkg @TvZH3Zxu6Ra'%O?/dQ5xYkU]Rֽkق@DaS^RSּ5|BeHNN͘p HvcYcC5:y #`οb;z2.!kr}gUWkyZn=f Pvsn3p~;4p˚=ē~NmI] ¾ 0lH[_L hsh_ғߤc_њec)g7VIZ5yrgk̞W#IjӪv>՞y睝M8[|]\շ8M6%|@PZڨI-m>=k='aiRo-x?>Q.}`Ȏ:Wsmu u > .@,&;+!!˱tﭧDQwRW\vF\~Q7>spYw$%A~;~}6¾ g&if_=j,v+UL1(tWake:@Ș>j$Gq2t7S?vL|]u/ .(0E6Mk6hiۺzښOrifޱxm/Gx> Lal%%~{lBsR4*}{0Z/tNIɚpV^#Lf:u@k#RSu =S^ZyuR/.@n&΃z~B=0eg뺆#,Þ[B/?H uUf7y Wy}Bwegל`Wh(||`l`.;Ws?V@"c:iɍL֯PGv6zctM̠':wuW;d=;EveD}9J@B(0iհ bvP1{\P&G7D޴Iy_$-Qjm~Yrr&]CDv%bh|Yzni_ˆR;kg}nJOIIwyuL}{ЌNj}:+3Y?:WJ/N+Rzd=hb;dj͒suݔ@NKMԄ jqzC5@y°hL m;*5ezᕏ=ep XL n?מ:r`۵tŤZ|1v`V뽧_csج'ߤ%oTuumk%%%h)uy]Nk[n 'b2 l.=͜E%gf$[c;s:V-͞WߤWh-j7]4=F-X]>ZLSi[Y*We;Zan(ӇW|e(HNNP5[= r4tP &0<pc#`vTNV GFqvTi*Tyam$ߏWyE*VJKMTfFw>'$-ؽ.Ho.8c"@DADADADADADADADADA~j*֘,N;Pi3599h=goضLgiJ5փy~}&Zd9p֚ e:|hL``b/d9p? fgg+%%hMgXosج, ΩOl0Zh=xdjLmhݻoO[g_l,8a]٭+ӧ0$I]c]:粹:Teꢢ"5a^Kgh,&= =՟^߶“ߢE ܹS J}I%:8 IDAT~,9/ʃPW'Mo}zNƍ쨓zPbNZ~^z=4mswg;5 Y~SVMRXUյڱRf?s:w ;6H:ºi5-maM&O3;1IKeamZh͛7+##v+c ~u~ca]GnF'ټL~PPPbn voC4R,ӟgg %hq}@#M4IÇ Oy^xMZx ) yOw@HkN˖-Sǎmb]X@n+i͖!++K3gd\$mt$^YfJ\8PRF)77Wא!Cl$i:@@_oG I{$# 8磌ŋ91A (Im7֭>}ߴJq7ޗt^ -[ԩSj*}%]&' -ɓ'ꫯVzzvB#;a 7@GxI{j޼ƌ.LÇWBB7`O"I$/@R @eee@۷>}0,ɒ2$53Xs|cS~rpTYYY} kHc %&k.], @ADADADADADADADADA@lT<%''*Lo^={رc5h %$+CnܸQ3fҥK}vUVVs9G R,_{xˇ3o߾;TTTd}馛]uuuG~iԩ@4bnvmvfϞ /Peeeq}}za I~,誫{UWW뮻}_~YƍSMMMYχ֝waw\ďcxꩧtEƍկ_?۷5@u?1kNׯWzz/wy>}zj3 k(ٺuq_Zvf̘:~ ABQ&r|!%KҥKgԞ={<_X-z !CyFUUz~ ABQIIIjݺW$UXXDٳZ~ ABQƍecW$<(~<RSSvZujjjԧOZQu@4 8m&&&jԩg$ď1h ͟?_{768@g =@`)))5o6m3)ѣƌJ;wҿUTT /KZR{~a=@0o<*狔iFɶ[ˎ;T]]OX@?K.ۈxN pppppppppppppppppPfl߾] ,{ァk۶mڿo5BTӦMӴiӴ|r DB2e|An!Dy'tkΝ[A $***t5' "!駟oaDnΝ:t֭[gDШQ06qD;@ x M6v(PiizmZ4ew"@̴ixf [~-Fٱc&IZ2|n!?$@{[HTɏ#@hȎI# _m(F /6Z3z'\r,r!;w2Z3j=~GY7"I$iI.p_"?pN`y DD?: _  Gÿab7J !Bx@0 Bo cG@`1C[@0G @`0C_u V1 aCX>W ` | `!<S `"<. `#c`?cAC4 ?c p#~@0?:08&_MQ1J h#?/`7;I  q 7a wQ A 1 Hp !#<8/#@1Ul7=S=K.4Z?E_$i@!1!E4?`P_  @Bă10#: "aU,xbFY1 [n|n #'vEH:`xb #vD4Y hi.i&EΖv#O H4IŶ}:Ikh @tZRF#(tXҙzZ ?I3l7q@õ|ۍ1,GpuY Ꮿ@hJv#xxk$ v#9 5 }_$c S#=+"K{F*m7`#%H:NRSp6I?sIՖ{Ap$I$I:QRv2$Z @UJ*$]<FO4IENDB`