From a6cfcba95fcf062e9c88e940b4c04da29fadfaae Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Fri, 23 Sep 2022 10:22:13 +0200 Subject: [PATCH] Added documentation downloaded from Lameguy64 --- ....1 Setting up Graphics and Hello World.htm | 796 +++++++++++++++ .../analytics.js | 474 +++++++++ .../banner-styles.css | 500 ++++++++++ .../bufferlayout.svg | 147 +++ .../bundle-playback.js | 3 + .../gpudiagram.svg | 286 ++++++ .../iconochive.css | 116 +++ .../style.css | 70 ++ .../vram-layout.svg | 261 +++++ .../wombat.js | 21 + Docs/Chapter 1.2 Drawing Graphics.htm | 413 ++++++++ .../analytics.js | 474 +++++++++ .../banner-styles.css | 500 ++++++++++ .../bundle-playback.js | 3 + .../iconochive.css | 116 +++ .../ordertable-buffercompare.svg | 876 +++++++++++++++++ .../ordertable-multiprims.svg | 705 ++++++++++++++ .../ordertable-primitive.svg | 657 +++++++++++++ .../ordertable.svg | 633 ++++++++++++ .../primstruct.svg | 350 +++++++ .../style.css | 70 ++ .../wombat.js | 21 + ...Chapter 1.3 Textures, TPages and CLUTs.htm | 919 ++++++++++++++++++ .../ordertable-multiprims.svg | 705 ++++++++++++++ .../page-texcoord-relation.svg | 268 +++++ .../style.css | 49 + .../vram-texture-coordinates.svg | 313 ++++++ .../vram-texture-pages.svg | 192 ++++ Docs/Chapter 1.4 Controllers.htm | 672 +++++++++++++ .../analytics.js | 474 +++++++++ .../banner-styles.css | 500 ++++++++++ .../bundle-playback.js | 3 + .../iconochive.css | 116 +++ Docs/Chapter 1.4 Controllers_files/style.css | 70 ++ Docs/Chapter 1.4 Controllers_files/wombat.js | 21 + Docs/Chapter 1.5 Fixed point Math.htm | 826 ++++++++++++++++ .../style.css | 49 + Docs/Chapter 1.6 Using the CD-ROM.htm | 807 +++++++++++++++ .../style.css | 49 + ...Chapter 2.2 Reading a file from CD-ROM.htm | 508 ++++++++++ .../analytics.js | 474 +++++++++ .../banner-styles.css | 500 ++++++++++ .../bundle-playback.js | 3 + .../iconochive.css | 116 +++ .../style.css | 70 ++ .../wombat.js | 21 + Docs/LibPSn00b Reference.pdf | Bin 0 -> 498989 bytes 47 files changed, 15217 insertions(+) create mode 100644 Docs/Chapter 1.1 Setting up Graphics and Hello World.htm create mode 100644 Docs/Chapter 1.1 Setting up Graphics and Hello World_files/analytics.js create mode 100644 Docs/Chapter 1.1 Setting up Graphics and Hello World_files/banner-styles.css create mode 100644 Docs/Chapter 1.1 Setting up Graphics and Hello World_files/bufferlayout.svg create mode 100644 Docs/Chapter 1.1 Setting up Graphics and Hello World_files/bundle-playback.js create mode 100644 Docs/Chapter 1.1 Setting up Graphics and Hello World_files/gpudiagram.svg create mode 100644 Docs/Chapter 1.1 Setting up Graphics and Hello World_files/iconochive.css create mode 100644 Docs/Chapter 1.1 Setting up Graphics and Hello World_files/style.css create mode 100644 Docs/Chapter 1.1 Setting up Graphics and Hello World_files/vram-layout.svg create mode 100644 Docs/Chapter 1.1 Setting up Graphics and Hello World_files/wombat.js create mode 100644 Docs/Chapter 1.2 Drawing Graphics.htm create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/analytics.js create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/banner-styles.css create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/bundle-playback.js create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/iconochive.css create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/ordertable-buffercompare.svg create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/ordertable-multiprims.svg create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/ordertable-primitive.svg create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/ordertable.svg create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/primstruct.svg create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/style.css create mode 100644 Docs/Chapter 1.2 Drawing Graphics_files/wombat.js create mode 100644 Docs/Chapter 1.3 Textures, TPages and CLUTs.htm create mode 100644 Docs/Chapter 1.3 Textures, TPages and CLUTs_files/ordertable-multiprims.svg create mode 100644 Docs/Chapter 1.3 Textures, TPages and CLUTs_files/page-texcoord-relation.svg create mode 100644 Docs/Chapter 1.3 Textures, TPages and CLUTs_files/style.css create mode 100644 Docs/Chapter 1.3 Textures, TPages and CLUTs_files/vram-texture-coordinates.svg create mode 100644 Docs/Chapter 1.3 Textures, TPages and CLUTs_files/vram-texture-pages.svg create mode 100644 Docs/Chapter 1.4 Controllers.htm create mode 100644 Docs/Chapter 1.4 Controllers_files/analytics.js create mode 100644 Docs/Chapter 1.4 Controllers_files/banner-styles.css create mode 100644 Docs/Chapter 1.4 Controllers_files/bundle-playback.js create mode 100644 Docs/Chapter 1.4 Controllers_files/iconochive.css create mode 100644 Docs/Chapter 1.4 Controllers_files/style.css create mode 100644 Docs/Chapter 1.4 Controllers_files/wombat.js create mode 100644 Docs/Chapter 1.5 Fixed point Math.htm create mode 100644 Docs/Chapter 1.5 Fixed point Math_files/style.css create mode 100644 Docs/Chapter 1.6 Using the CD-ROM.htm create mode 100644 Docs/Chapter 1.6 Using the CD-ROM_files/style.css create mode 100644 Docs/Chapter 2.2 Reading a file from CD-ROM.htm create mode 100644 Docs/Chapter 2.2 Reading a file from CD-ROM_files/analytics.js create mode 100644 Docs/Chapter 2.2 Reading a file from CD-ROM_files/banner-styles.css create mode 100644 Docs/Chapter 2.2 Reading a file from CD-ROM_files/bundle-playback.js create mode 100644 Docs/Chapter 2.2 Reading a file from CD-ROM_files/iconochive.css create mode 100644 Docs/Chapter 2.2 Reading a file from CD-ROM_files/style.css create mode 100644 Docs/Chapter 2.2 Reading a file from CD-ROM_files/wombat.js create mode 100644 Docs/LibPSn00b Reference.pdf diff --git a/Docs/Chapter 1.1 Setting up Graphics and Hello World.htm b/Docs/Chapter 1.1 Setting up Graphics and Hello World.htm new file mode 100644 index 0000000..8c865ad --- /dev/null +++ b/Docs/Chapter 1.1 Setting up Graphics and Hello World.htm @@ -0,0 +1,796 @@ + + + + + + + + + + + +Chapter 1.1: Setting up Graphics and Hello World + + + + + +
+
The Wayback Machine - +http://web.archive.org/web/20220827033533/http://lameguy64.net/tutorials/pstutorials/chapter1/1-display.html
+ + + + +

1.1. Setting up Graphics and Hello World

+

+This chapter teaches the basics of initializing and setting up the GPU of the +PSX. Areas covered in this chapter include the GPU, VRAM and the concept of +display and drawing environments which are essential for better understanding +how the GPU works when programming for the PSX. +

+

+This tutorial series does not and will not cover graphics programming using the +LIBGS library which is a high level graphics library that adds about 100KB +worth of overhead to your project (remember that the PSX only has 2MB of RAM) +and hides many of the inner workings of the GPU, making it difficult to +understand how to use the GPU directly and would often get in the way when +trying to write your own graphics routines... While it may sound elitist +discouraging the use of LIBGS as it provides facilities for rendering 3D models +easily, it is better to learn how to work with LIBGPU (or PSXGPU in PSn00bSDK) +in the long term as the knowledge gained from learning how to use it directly +will become very important in the future for either better performance, or to +accomplish special graphical effects. +

+

Tutorial compatible with PSn00bSDK:Yes

+ +

Chapter Index

+ + + +

Why Start with Graphics?

+

+This tutorial series begins with graphics programming as displaying a hello +world message requires a bit of graphics programming, as neither the official +SDK or PSn00bSDK provide a framebuffer text console for displaying text largely +due to the way how the hardware works. But both provide a means of basic text +drawing functions intended for debugging purposes which will be demonstrated +for this chapter. +

+

+Besides, most of the satisfaction gained when learning to develop for a new +platform comes from seeing the result displayed on the television screen by the +console you're learning to develop for and you're going need to learn graphics +programming anyway to really be able to do anything interesting with the PSX. +It is a video game console afterall. +

+ + +

Brief Summary of the GPU

+

+The GPU, as the name suggests, is the graphics processor responsible for doing +the graphics rendering work for both 2D and 3D visuals. The block diagram shown +below illustrates the relevant components that make up the entirerity of the +PSX's graphics subsystem, including the MDEC and GTE hardware responsible for +video playback and 3D graphics capabilities respectively. +

+ + + +

The GPU is not 3D

+

+A worrying amount often believed that the PSX's GPU is capable of rendering 3D +polygons. While it may seem to be the case to the uneducated, the GPU is in +fact only capable of drawing primitives in 2D space. Therefore, the GPU is +incapable of perspective correct texture mapping which results in affine +texture distortion and the occasional buggy near clipping seen in a lot of 3D +PSX games. It was common for games to minimize the distortion by subdividing +large polygons into smaller polygons with perspective correct subdivision. +

+

+The bulk of the 3D processing is instead done on the CPU which features a +co-processor suited for such tasks known as the GTE or Geometry Transform +Engine. The GTE is effectively an all integer math co-processor that provides +matrix multiplication, vector transformations and projection operations at high +speed which the CPU alone couldn't do at reasonable speed. Software would then +assemble primitive packets using results from the GTE which are then sent to +the GPU as a linked list via high speed DMA transfer for the GPU to draw said +primitives. +

+

+The GTE will not be covered in this chapter as it is not required for simple +2D graphics programming. Whilst in the topic of the GTE, a very important +issue must be taken care of and that is the GTE is NOT a Geometry +Transfer Engine. An equally concerning amount belive that the GTE +stands for Geometry Transfer Engine and not a Transform Engine when in fact, +the GTE only does math calculations and is not capable of doing any +"transfer" operations whatsoever. Also, the GTE can only be accessed +by the CPU through standard co-processor related instructions. Just wanted to +clarify this before going any further in learning how to program for the PSX +as this bothers me to no end. Suppose it can be used to identify if one is a +real PSX programmer or not. +

+ +

Only 16-bit Color Rendering

+

+Some often mistake that the PSX renders graphics in 24-bit color depth. Whilst +the GPU is capable of 24-bit true color output, it cannot draw primitives in +24-bit color. So the 24-bit color mode is only really useful for MDEC video +sequences or static images in 24-bit color. +

+

+The GPU can only draw at 16-bit color depth in a RGB5I1 pixel format (five bits +per RGB component plus one mask bit used as a mask for semi-transparency +effects). This aligns perfectly with the 16-bit data bus of the VRAM. +

+ +

The VRAM

+

+The GPU features it's own 1MB of VRAM. If you look back at the block diagram +shown earlier you'll see that the VRAM is connected to the GPU and is not +connected the system bus at all. This means the VRAM is not memory mapped and +the CPU cannot access it directly. Instead, VRAM access can only be done +through the GPU. Fortunately, transfers are done via high speed DMA. +

+

+Naturally, the GPU uses the VRAM for storing framebuffers and texture images. +The most interesting aspect about the VRAM is how the GPU treats it like a +1024x512 16-bit image, with areas of VRAM addressed by (X,Y) coordinates +instead of a linear memory address range. Display and drawing framebuffers as +well as texture images reside as rectangular images in the VRAM. The following +illustrates a typical VRAM layout for framebuffers and texture images in PSX +games. +

+ + +

Primitive Packets

+

+The GPU is instructed through the use of primitive packets, which are small +bits of formatted data that make up a GPU command which are sent to the GPU +via DMA for drawing. The primitive packets not only specify the type of +primitive but also the color, semi-transparency flags, (X,Y) coordinates, +texture coordinates, color look-up table to use and so forth. Think of them +like arguments for a function call. +

+

+The number of arguments a primitive packet requires depends on the type of +primitive. The simplest primitives such as a texture page primitive only takes +one argument while the most sophisticated primitive; a texture mapped, gouraud +shaded, 4-point polygon takes as many as 14 arguments. This also means the +size of the primitive varies, with the texture page primitive being only a +word in size while a 4-point, texture mapped and gouraud shaded polygon is +12 words long on top of the tag word present at the start of all primitives. +

+

+Further details about primitive packets will be covered in a future chapter. +

+ +

Framebuffers

+

+Framebuffers for graphics display and drawing reside in VRAM as rectangular +areas defined in (X,Y) coordinates. The size of the display area is based on +the video mode (ie. the display area is 320x240 pixels when running in +320x240 mode). On the other hand, the size for the drawing area can be of any +arbitrary size which may be used to render texture images for accomplishing +certain render to texture based visual effects. Normally, the size of the +drawing area should typically be equal to the display area. +

+

+The display and drawing areas are defined as an environment using the +DISPENV and DRAWENV structs. Each struct defines various +parameters that are relevant to their respective environment. The +DISPENV and DRAWENV structs are initialized using +SetDefDispEnv() and SetDefDrawEnv() respectively which defines +the default parameters for each environment, which may be customized later for +your project's requirements. Once the environments have been defined they can +then be applied to the GPU using PutDispEnv() and PutDrawEnv() +to make each environment effective. +

+

+Learning the display and drawing environments are mandatory for being able to +get any graphical output from the PSX and this will be covered extensively in +this chapter. +

+ +

Writing the Hello World Program

+

+As obligatory as it may sound, a hello world is an effective and simple enough +example to get started with PSX homebrew programming. A hello world program for +the PSX can't be a simple call of printf(), unless you only want to see the +output through a tty which, in all honesty, won't look as interesting as +showing the message on the TV screen or emulator window. +

+

+The basic run-down of accomplishing a hello world on the PSX is to perform the +following operations: +

+ +

+Break out your preferred text editor and begin writing the hello world program +as you go along this chapter. +

+ +

Required Headers

+

+First, include some necessary headers in your C file. The most important of which is +libgpu.h as it provides various definitions provided by the libgpu library. libgte.h +is required even if you don't plan to use the GTE as libgpu.h depends on some +definitions provided in it. +

+
#include <sys/types.h>	// This provides typedefs needed by libgte.h and libgpu.h
+#include <stdio.h>	// Not necessary but include it anyway
+#include <libetc.h>	// Includes some functions that controls the display
+#include <libgte.h>	// GTE header, not really used but libgpu.h depends on it
+#include <libgpu.h>	// GPU library header
+
+

+If using PSn00bSDK, replace the lib prefix with psx instead. Most +of the definitions between the official SDK and PSn00bSDK are identical, so the +syntax of things shouldn't be much to worry much about. +

+ +

Write the main() Function

+

+Like with any C program, you must define a main() function somewhere in your +project. You can omit the argc and argv definitions if desired as they don't +work on the PSX. +

+
int main()
+{
+    return 0;
+}
+
+

+A return value cannot be passed to a parent executable as the kernel does not +save the value for the caller to receive it, but is required nonetheless to +keep the compiler from complaining about returning without a value. +

+ + +

Setting up Graphics

+

+The very first thing to do before anything else in your PSX program is to +call ResetGraph(). ResetGraph() not only resets the GPU as the +name suggests, but it also enables interrupts which are mandatory for getting +anything done on the PSX. If ResetGraph() is not called functions that +depend on interrupts such as VSync() and several other things will not +work, and will usually appear as though your program just crashed. +

+
// Reset GPU and enable interrupts
+ResetGraph(0);
+
+

+Resetting the GPU also masks out the video output which results in a black +screen, but the console still produces video sync. The video output is enabled +again using SetDispMask(), ideally after a DISPENV has been +defined and applied to the GPU for a smooth transition from a previously +running program (ie. the startup screen). As ResetGraph() does not clear +the contents of VRAM, so whatever was drawn by the previous program still +remains when your program takes over. Clearing the VRAM is generally not +required in most well coded scenarios. +

+ +

Setting up the DISPENV and DRAWENV Environments

+

+Start by defining two DISPENV and DRAWENV variables as arrays in +your code. Define an int which will be used for keeping track of things which +will make total sense later on. This value must be set to zero as part of your +graphics initialization code just to make sure the variable starts with a value +of zero. +

+
// Define environment pairs and buffer counter
+DISPENV disp[2];
+DRAWENV draw[2];
+int db;
+
+

+Next is to define the DISPENV pair. Initializing the DISPENV +structure is easiest done using the SetDefDispEnv() function with simple +arguments. +

+For NTSC users: +
// Configures the pair of DISPENVs for 320x240 mode (NTSC)
+SetDefDispEnv(&disp;[0], 0, 0, 320, 240);
+SetDefDispEnv(&disp;[1], 0, 240, 320, 240);
+
+For PAL users: +
// Configures the pair of DISPENVs for 320x256 mode (PAL)
+SetDefDispEnv(&disp;[0], 0, 0, 320, 256);
+SetDefDispEnv(&disp;[1], 0, 256, 320, 256);
+
+// Screen offset to center the picture vertically
+disp[0].screen.y = 24;
+disp[1].screen.y = disp[0].screen.y;
+
+// Forces PAL video standard
+SetVideoMode(MODE_PAL);
+
+

+This defines both DISPENVs for 320x240 resolution mode (320x256 if you +used the PAL snippet) which is the most commonly used video mode. The first +DISPENV is set with a position of (0,0) while the second DISPENV +is set with a VRAM offset of (0,240). You might be wondering why it has to be +defined that way. +

+

+Next is to define the DRAWENVs. Much like the DISPENVs you use +SetDefDrawEnv() to initialize the DRAWENV structure with +simple arguments. +

+For NTSC users: +
// Configures the pair of DRAWENVs for the DISPENVs
+SetDefDrawEnv(&draw;[0], 0, 240, 320, 240);
+SetDefDrawEnv(&draw;[1], 0, 0, 320, 240);
+
+For PAL users: +
// Configures the pair of DRAWENVs for the DISPENVs
+SetDefDrawEnv(&draw;[0], 0, 256, 320, 256);
+SetDefDrawEnv(&draw;[1], 0, 0, 320, 256);
+
+

+Unlike DISPENV, DRAWENV can be of any arbitrary size for the +drawing environment. But generally it should be equal to the size of the +DISPENV defined, so the drawn area will align perfectly with the display +environments. Additionally, you'll want to set some parameters within the +DRAWENV struct to enable background clearing as otherwise you'll get a +hall of mirrors effect. The background clear takes effect as soon as the +DRAWENV is applied to the GPU using PutDrawEnv(). +

+
// Specifies the clear color of the DRAWENV
+setRGB0(&draw;[0], 63, 0, 127);
+setRGB0(&draw;[1], 63, 0, 127);
+// Enable background clear
+draw[0].isbg = 1;
+draw[1].isbg = 1;
+
+

+Finally, apply the DISPENV/DRAWENV environments to the GPU to +apply the new video mode and drawing environment to achieve a seamless +transition. +

+
// Apply environments
+PutDispEnv(&disp;[0]);
+PutDrawEnv(&draw;[0]);
+
+

+To keep your code look neat and tidy, you'll want to put all the graphics init +code inside a function, to keep your main() function from looking messy +and will make expanding the program easier in the future. +

+ +

The Concept of Double Buffered Rendering

+

+You may have noticed that the DRAWENV pairs are somewhat positioned in +the opposite order as the DISPENV whilst writing the graphics init code +and are probably wondering why this is the case instead of a DRAWENV +directly overlapping a DISPENV. This is how you implement double +buffered rendering on the PSX and is a standard feature to have when writing +real-time graphics code, not just on the PSX but on almost any system with a +framebuffer. +

+

+If you're not familiar with the concept, you basically need to allocate two +framebuffer areas; one for display and one for drawing. The way you use these +framebuffers is you use one buffer as the display buffer, which is the buffer +the graphics hardware will display on the screen and the other as the drawing +buffer, where all your graphics operations should draw to and is not shown on +the screen. Once drawing is complete the two buffers switch places, the drawing +buffer becomes the display buffer and the display buffer become the drawing +buffer for the next frame to be drawn and the cycle repeats. This basically +guarantees that only completed frames are shown on the screen which yields +seamless graphical animations even during framerate drops when intensive +visuals are being drawn aside from the natural reduction of smoothness. +

+ +

+Having a DISPENV and a DRAWENV simply overlap one another on the +same area counts as single buffered rendering and whilst you may get away with +it, the amount of things you can draw/process will be severely limited as you'll +get nasty flicker if the drawing/processing does not complete before the v-blank +period ends. So, a double buffered rendering scheme is much preferred. +

+ +

The Display Function

+

+Now the last thing that deals with the DISPENV and DRAWENV +environments to write is a so called display function, which is basically +a function that does the all buffer swap stuff in a single call for +convenience. Calling the display function should be done at the end of your +loop as that is usually where all graphics operations have completed +and are ready for drawing or display. For this tutorial, the display function +will be named display(). +

+

+Before performing a buffer swap, you must first call DrawSync() then +VSync(). As the names suggests these functions waits for the GPU to +complete any drawing operations and waits for the vertical blanking period +respectively. Waiting for DrawSync() is important as it makes sure that +the GPU has completed drawing any primitives as otherwise you may get flicker +or possibly instability. Waiting for VSync() is also important as it +not only caps your program loop to the TV refresh rate (60fps for NTSC, 50 +for PAL) but it also prevents screen tearing which will happen if you swap +buffers without waiting for the v-blank period. +

+
// Wait for GPU to finish drawing and V-Blank
+DrawSync(0);
+VSync(0);
+
+

+Now the next step is to perform the buffer swap. If you remember that variable +named db earlier, this variable will be used as a counter to keep track +of which buffer pair to switch to. Since there are only two DISPENV and +DRAWENV pairs this variable will simply alternate between 1 and 0 on +every call of the display function. This easily achieved using a NOT (!) +operator. +

+
// Flip buffer counter
+db = !db;
+
+

+Then apply the environment pair based on the value of db to the GPU. +

+
// Apply environments
+PutDispEnv(&disp;[db]);
+PutDrawEnv(&draw;[db]);
+
+

+And finally, call SetDispMask() to lift the display mask so you get +picture instead of a black screen, as ResetGraph() masks the display +by default. +

+
// Enable display
+SetDispMask(1);
+
+ +

Verifying the Code

+

+To make sure you're right on track, here's a listing of what the code should +look like. +

+
#include <sys/types.h>	// This provides typedefs needed by libgte.h and libgpu.h
+#include <stdio.h>	// Not necessary but include it anyway
+#include <libetc.h>	// Includes some functions that controls the display
+#include <libgte.h>	// GTE header, not really used but libgpu.h depends on it
+#include <libgpu.h>	// GPU library header
+
+// Define environment pairs and buffer counter
+DISPENV disp[2];
+DRAWENV draw[2];
+int db;
+
+void init(void)
+{
+    // Reset GPU and enable interrupts
+    ResetGraph(0);
+    
+    // Configures the pair of DISPENVs for 320x240 mode (NTSC)
+    SetDefDispEnv(&disp;[0], 0, 0, 320, 240);
+    SetDefDispEnv(&disp;[1], 0, 240, 320, 240);
+    
+    // Configures the pair of DRAWENVs for the DISPENVs
+    SetDefDrawEnv(&draw;[0], 0, 240, 320, 240);
+    SetDefDrawEnv(&draw;[1], 0, 0, 320, 240);
+    
+    // Specifies the clear color of the DRAWENV
+    setRGB0(&draw;[0], 63, 0, 127);
+    setRGB0(&draw;[1], 63, 0, 127);
+    
+    // Enable background clear
+    draw[0].isbg = 1;
+    draw[1].isbg = 1;
+    
+    // Apply environments
+    PutDispEnv(&disp;[0]);
+    PutDrawEnv(&draw;[0]);
+
+    // Make sure db starts with zero
+    db = 0;
+}
+
+void display(void)
+{
+    // Wait for GPU to finish drawing and V-Blank
+    DrawSync(0);
+    VSync(0);
+    
+    // Flip buffer counter
+    db = !db;
+    
+    // Apply environments
+    PutDispEnv(&disp;[db]);
+    PutDrawEnv(&draw;[db]);
+    
+    // Enable display
+    SetDispMask(1);
+}
+
+int main()
+{
+    // Initialize graphics and stuff
+    init();
+    
+    // Main loop
+    while(1)
+    {
+        display();
+    }
+    
+    return 0;
+}
+
+ +

Compiling and Testing

+

Now that you've written a considerable amount of code for the graphics +init and buffer swapping stuff, it should be possible to compile the code +and see an output to check if you're right on track. In the official +PsyQ/Programmers' Tool SDK compiling can be done through ccpsx with +a single command line. ccpsx is actually a front for the C, C++ and +linker that makes using the SDK's toolchain easier. +

+
ccpsx -O2 -Xo0x80010000 hello.c -o hello.cpe
+
+

+If you've worked with C before, you should already know that -O2 +specifies the optimization level for the compiler generated code just like +in most other C compilers. The -Xo0x80010000 parameter would likely +be unfamiliar to you and this specifies the target address your executable's +program text is going to reside when it is being loaded by the console. +The target address is usually set to 0x80010000 which is the start of user +space memory on the PSX as the first 64KB is reserved by the kernel. +

+

+The executables ccpsx produces are in CPE format which cannot be +booted from the CD by the PSX and most emulators don't support it. You'll +have to convert the executable into the usable PS-EXE format which can be +done using cpe2x. +

+
cpe2x hello.cpe
+
+

Don't be fooled by the .EXE file extension of a PS-EXE executable file. The +executable files cpe2x produces are neither MS-DOS or Windows +executable programs. +

+

If using PSn00bSDK. It is more complicated to compile a program from within +the command line alone due to the way how the toolchain is currently set up. +It is much easier to just copy a makefile from one of the examples included +in the SDK and tweak the variables for your project. Then use make +to compile the program and it should produce an ELF file and a PS-EXE file. +

+

Run the program and you should get a solid blue image. +

+ + + +

Displaying the Hello World

+

Now that the graphics environment and display routines have been implemented, +the next step is to draw the hello world message. This is easily done by using +the debug font functions FntLoad(), FntOpen() and +FntPrint(). These functions are not suited for general use. Such as in +a game title as it does not support any form of customization and does not +support lowercase letters, but is good enough for testing and debugging +purposes which will be useful later. These functions are provided by libetc, +or psxetc in PSn00bSDK. +

+ +

Setting up the Debug Font

+

The first thing to do before the debug font functions can be used is to is +load the font texture onto VRAM using FntLoad(). The font texture can be +placed anywhere in the VRAM area provided it doesn't get overwritten by +display/draw areas, or textures being loaded onto VRAM. For this tutorial, the +font texture will be placed at (960,0). +

+

Next is to create a text stream using FntOpen() which defines the +area where the text will be drawn at. For this tutorial a text stream of 100 +characters is defined to fill the entire screen, with some overscan +compensation to ensure that the text is visible on the TV. +

+
// Load the internal font texture
+FntLoad(960, 0);
+// Create the text stream
+FntOpen(0, 8, 320, 224, 0, 100);
+
+

The font area coordinates are draw-area relative and not VRAM relative, so +there is no need to define another font area for each of the display/draw areas +in the VRAM. The third argument specifies if a black background for the font +area should be drawn. In PSn00bSDK, you can specify 2 for a semi-transparent +black background. If you try to set it to a non-zero value, the background will +turn black because the font area covers the entire screen. +

+

FntOpen() allows defining multiple font areas by saving the return +value to a persistent variable and passing it as the first argument of +FntPrint() and FntFlush(). Up to eight font areas can be defined +at once, but it cannot be closed or redefined later in your program. +

+

Printing and Displaying Hello World

+

FntPrint() prints text to the last defined font area and works more +or less like printf() and you can also use the newline character +sequence \n to move a line of text down. A font handle can be specified +as an optional first argument of FntPrint(), but in PSn00bSDK a handle +from FntOpen() or -1 must be specified as the first argument. This +

+
FntPrint("HELLO WORLD!");
+
+FntFlush(-1);
+display();
+
+

Calling FntPrint() alone is not enough to display text to the +current draw area, so FntFlush() needs to be called to actually draw +the characters printed from FntPrint() calls. +

+ +

Final Sample Code

+

Compare your code against this listing to make sure you're right on +track. +

+
#include <sys/types.h>	// This provides typedefs needed by libgte.h and libgpu.h
+#include <stdio.h>	// Not necessary but include it anyway
+#include <libetc.h>	// Includes some functions that controls the display
+#include <libgte.h>	// GTE header, not really used but libgpu.h depends on it
+#include <libgpu.h>	// GPU library header
+
+// Define environment pairs and buffer counter
+DISPENV disp[2];
+DRAWENV draw[2];
+int db;
+
+void init(void)
+{
+    // Reset GPU and enable interrupts
+    ResetGraph(0);
+    
+    // Configures the pair of DISPENVs for 320x240 mode (NTSC)
+    SetDefDispEnv(&disp;[0], 0, 0, 320, 240);
+    SetDefDispEnv(&disp;[1], 0, 240, 320, 240);
+    
+    // Configures the pair of DRAWENVs for the DISPENVs
+    SetDefDrawEnv(&draw;[0], 0, 240, 320, 240);
+    SetDefDrawEnv(&draw;[1], 0, 0, 320, 240);
+    
+    // Specifies the clear color of the DRAWENV
+    setRGB0(&draw;[0], 63, 0, 127);
+    setRGB0(&draw;[1], 63, 0, 127);
+    
+    // Enable background clear
+    draw[0].isbg = 1;
+    draw[1].isbg = 1;
+    
+    // Apply environments
+    PutDispEnv(&disp;[0]);
+    PutDrawEnv(&draw;[0]);
+
+    // Make sure db starts with zero
+    db = 0;
+    
+    // Load the internal font texture
+    FntLoad(960, 0);
+    // Create the text stream
+    FntOpen(0, 8, 320, 224, 0, 100);
+}
+
+void display(void)
+{
+    // Wait for GPU to finish drawing and V-Blank
+    DrawSync(0);
+    VSync(0);
+    
+    // Flip buffer counter
+    db = !db;
+    
+    // Apply environments
+    PutDispEnv(&disp;[db]);
+    PutDrawEnv(&draw;[db]);
+    
+    // Enable display
+    SetDispMask(1);
+}
+
+int main()
+{
+    // Initialize graphics and stuff
+    init();
+    
+    // Main loop
+    while(1)
+    {
+        FntPrint("HELLO WORLD!");
+
+        FntFlush(-1);
+        display();
+    }
+    
+    return 0;
+}
+
+ +

Result

+

Run the program on the console or emulator and you should see a +dark purple picture:

+ + +

Conclusion

+

This concludes this chapter of Lameguy64's PSX Tutorial series. You should +be very familiar of how framebuffers are handled on the PSX hardware and +should be ready to take on drawing proper graphics primitives.

+

A few things you may want to experiment with this example yourself:

+ +

The next tutorial will cover how to draw graphics with the GPU using +ordering tables and primitive packets.

+
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/analytics.js b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/analytics.js new file mode 100644 index 0000000..10400f0 --- /dev/null +++ b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/analytics.js @@ -0,0 +1,474 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0 +/* eslint-disable no-var, semi, prefer-arrow-callback, prefer-template */ + +/** + * Collection of methods for sending analytics events to Archive.org's analytics server. + * + * These events are used for internal stats and sent (in anonymized form) to Google Analytics. + * + * @see analytics.md + * + * @type {Object} + */ +window.archive_analytics = (function defineArchiveAnalytics() { + // keep orignal Date object so as not to be affected by wayback's + // hijacking global Date object + var Date = window.Date; + var ARCHIVE_ANALYTICS_VERSION = 2; + var DEFAULT_SERVICE = 'ao_2'; + var NO_SAMPLING_SERVICE = 'ao_no_sampling'; // sends every event instead of a percentage + + var startTime = new Date(); + + /** + * @return {Boolean} + */ + function isPerformanceTimingApiSupported() { + return 'performance' in window && 'timing' in window.performance; + } + + /** + * Determines how many milliseconds elapsed between the browser starting to parse the DOM and + * the current time. + * + * Uses the Performance API or a fallback value if it's not available. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API + * + * @return {Number} + */ + function getLoadTime() { + var start; + + if (isPerformanceTimingApiSupported()) + start = window.performance.timing.domLoading; + else + start = startTime.getTime(); + + return new Date().getTime() - start; + } + + /** + * Determines how many milliseconds elapsed between the user navigating to the page and + * the current time. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API + * + * @return {Number|null} null if the browser doesn't support the Performance API + */ + function getNavToDoneTime() { + if (!isPerformanceTimingApiSupported()) + return null; + + return new Date().getTime() - window.performance.timing.navigationStart; + } + + /** + * Performs an arithmetic calculation on a string with a number and unit, while maintaining + * the unit. + * + * @param {String} original value to modify, with a unit + * @param {Function} doOperation accepts one Number parameter, returns a Number + * @returns {String} + */ + function computeWithUnit(original, doOperation) { + var number = parseFloat(original, 10); + var unit = original.replace(/(\d*\.\d+)|\d+/, ''); + + return doOperation(number) + unit; + } + + /** + * Computes the default font size of the browser. + * + * @returns {String|null} computed font-size with units (typically pixels), null if it cannot be computed + */ + function getDefaultFontSize() { + var fontSizeStr; + + if (!('getComputedStyle' in window)) + return null; + + var style = window.getComputedStyle(document.documentElement); + if (!style) + return null; + + fontSizeStr = style.fontSize; + + // Don't modify the value if tracking book reader. + if (document.querySelector('#BookReader')) + return fontSizeStr; + + return computeWithUnit(fontSizeStr, function reverseBootstrapFontSize(number) { + // Undo the 62.5% size applied in the Bootstrap CSS. + return number * 1.6; + }); + } + + /** + * Get the URL parameters for a given Location + * @param {Location} + * @return {Object} The URL parameters + */ + function getParams(location) { + if (!location) location = window.location; + var vars; + var i; + var pair; + var params = {}; + var query = location.search; + if (!query) return params; + vars = query.substring(1).split('&'); + for (i = 0; i < vars.length; i++) { + pair = vars[i].split('='); + params[pair[0]] = decodeURIComponent(pair[1]); + } + return params; + } + + function getMetaProp(name) { + var metaTag = document.querySelector('meta[property=' + name + ']'); + return metaTag ? metaTag.getAttribute('content') || null : null; + } + + var ArchiveAnalytics = { + /** + * @type {String|null} + */ + service: getMetaProp('service'), + mediaType: getMetaProp('mediatype'), + primaryCollection: getMetaProp('primary_collection'), + + /** + * Key-value pairs to send in pageviews (you can read this after a pageview to see what was + * sent). + * + * @type {Object} + */ + values: {}, + + /** + * Sends an analytics ping, preferably using navigator.sendBeacon() + * @param {Object} values + * @param {Function} [onload_callback] (deprecated) callback to invoke once ping to analytics server is done + * @param {Boolean} [augment_for_ao_site] (deprecated) if true, add some archive.org site-specific values + */ + send_ping: function send_ping(values, onload_callback, augment_for_ao_site) { + if (typeof window.navigator !== 'undefined' && typeof window.navigator.sendBeacon !== 'undefined') + this.send_ping_via_beacon(values); + else + this.send_ping_via_image(values); + }, + + /** + * Sends a ping via Beacon API + * NOTE: Assumes window.navigator.sendBeacon exists + * @param {Object} values Tracking parameters to pass + */ + send_ping_via_beacon: function send_ping_via_beacon(values) { + var url = this.generate_tracking_url(values || {}); + window.navigator.sendBeacon(url); + }, + + /** + * Sends a ping via Image object + * @param {Object} values Tracking parameters to pass + */ + send_ping_via_image: function send_ping_via_image(values) { + var url = this.generate_tracking_url(values || {}); + var loadtime_img = new Image(1, 1); + loadtime_img.src = url; + loadtime_img.alt = ''; + }, + + /** + * Construct complete tracking URL containing payload + * @param {Object} params Tracking parameters to pass + * @return {String} URL to use for tracking call + */ + generate_tracking_url: function generate_tracking_url(params) { + var baseUrl = '//analytics.archive.org/0.gif'; + var keys; + var outputParams = params; + var outputParamsArray = []; + + outputParams.service = outputParams.service || this.service || DEFAULT_SERVICE; + + // Build array of querystring parameters + keys = Object.keys(outputParams); + keys.forEach(function keyIteration(key) { + outputParamsArray.push(encodeURIComponent(key) + '=' + encodeURIComponent(outputParams[key])); + }); + outputParamsArray.push('version=' + ARCHIVE_ANALYTICS_VERSION); + outputParamsArray.push('count=' + (keys.length + 2)); // Include `version` and `count` in count + + return baseUrl + '?' + outputParamsArray.join('&'); + }, + + /** + * @param {int} page Page number + */ + send_scroll_fetch_event: function send_scroll_fetch_event(page) { + var additionalValues = { ev: page }; + var loadTime = getLoadTime(); + var navToDoneTime = getNavToDoneTime(); + if (loadTime) additionalValues.loadtime = loadTime; + if (navToDoneTime) additionalValues.nav_to_done_ms = navToDoneTime; + this.send_event('page_action', 'scroll_fetch', location.pathname, additionalValues); + }, + + send_scroll_fetch_base_event: function send_scroll_fetch_base_event() { + var additionalValues = {}; + var loadTime = getLoadTime(); + var navToDoneTime = getNavToDoneTime(); + if (loadTime) additionalValues.loadtime = loadTime; + if (navToDoneTime) additionalValues.nav_to_done_ms = navToDoneTime; + this.send_event('page_action', 'scroll_fetch_base', location.pathname, additionalValues); + }, + + /** + * @param {Object} [options] + * @param {String} [options.mediaType] + * @param {String} [options.mediaLanguage] + * @param {String} [options.page] The path portion of the page URL + */ + send_pageview: function send_pageview(options) { + var settings = options || {}; + + var defaultFontSize; + var loadTime = getLoadTime(); + var mediaType = settings.mediaType; + var primaryCollection = settings.primaryCollection; + var page = settings.page; + var navToDoneTime = getNavToDoneTime(); + + /** + * @return {String} + */ + function get_locale() { + if (navigator) { + if (navigator.language) + return navigator.language; + + else if (navigator.browserLanguage) + return navigator.browserLanguage; + + else if (navigator.systemLanguage) + return navigator.systemLanguage; + + else if (navigator.userLanguage) + return navigator.userLanguage; + } + return ''; + } + + defaultFontSize = getDefaultFontSize(); + + // Set field values + this.values.kind = 'pageview'; + this.values.timediff = (new Date().getTimezoneOffset()/60)*(-1); // *timezone* diff from UTC + this.values.locale = get_locale(); + this.values.referrer = (document.referrer == '' ? '-' : document.referrer); + + if (loadTime) + this.values.loadtime = loadTime; + + if (navToDoneTime) + this.values.nav_to_done_ms = navToDoneTime; + + if (settings.trackingId) { + this.values.ga_tid = settings.trackingId; + } + + /* START CUSTOM DIMENSIONS */ + if (defaultFontSize) + this.values.ga_cd1 = defaultFontSize; + + if ('devicePixelRatio' in window) + this.values.ga_cd2 = window.devicePixelRatio; + + if (mediaType) + this.values.ga_cd3 = mediaType; + + if (settings.mediaLanguage) { + this.values.ga_cd4 = settings.mediaLanguage; + } + + if (primaryCollection) { + this.values.ga_cd5 = primaryCollection; + } + /* END CUSTOM DIMENSIONS */ + + if (page) + this.values.page = page; + + this.send_ping(this.values); + }, + + /** + * Sends a tracking "Event". + * @param {string} category + * @param {string} action + * @param {string} label + * @param {Object} additionalEventParams + */ + send_event: function send_event( + category, + action, + label, + additionalEventParams + ) { + if (!label) label = window.location.pathname; + if (!additionalEventParams) additionalEventParams = {}; + if (additionalEventParams.mediaLanguage) { + additionalEventParams.ga_cd4 = additionalEventParams.mediaLanguage; + delete additionalEventParams.mediaLanguage; + } + var eventParams = Object.assign( + { + kind: 'event', + ec: category, + ea: action, + el: label, + cache_bust: Math.random(), + }, + additionalEventParams + ); + this.send_ping(eventParams); + }, + + /** + * Sends every event instead of a small percentage. + * + * Use this sparingly as it can generate a lot of events. + * + * @param {string} category + * @param {string} action + * @param {string} label + * @param {Object} additionalEventParams + */ + send_event_no_sampling: function send_event_no_sampling( + category, + action, + label, + additionalEventParams + ) { + var extraParams = additionalEventParams || {}; + extraParams.service = NO_SAMPLING_SERVICE; + this.send_event(category, action, label, extraParams); + }, + + /** + * @param {Object} options see this.send_pageview options + */ + send_pageview_on_load: function send_pageview_on_load(options) { + var self = this; + window.addEventListener('load', function send_pageview_with_options() { + self.send_pageview(options); + }); + }, + + /** + * Handles tracking events passed in URL. + * Assumes category and action values are separated by a "|" character. + * NOTE: Uses the unsampled analytics property. Watch out for future high click links! + * @param {Location} + */ + process_url_events: function process_url_events(location) { + var eventValues; + var actionValue; + var eventValue = getParams(location).iax; + if (!eventValue) return; + eventValues = eventValue.split('|'); + actionValue = eventValues.length >= 1 ? eventValues[1] : ''; + this.send_event_no_sampling( + eventValues[0], + actionValue, + window.location.pathname + ); + }, + + /** + * Attaches handlers for event tracking. + * + * To enable click tracking for a link, add a `data-event-click-tracking` + * attribute containing the Google Analytics Event Category and Action, separated + * by a vertical pipe (|). + * e.g. `` + * + * To enable form submit tracking, add a `data-event-form-tracking` attribute + * to the `form` tag. + * e.g. `
` + * + * Additional tracking options can be added via a `data-event-tracking-options` + * parameter. This parameter, if included, should be a JSON string of the parameters. + * Valid parameters are: + * - service {string}: Corresponds to the Google Analytics property data values flow into + */ + set_up_event_tracking: function set_up_event_tracking() { + var self = this; + var clickTrackingAttributeName = 'event-click-tracking'; + var formTrackingAttributeName = 'event-form-tracking'; + var trackingOptionsAttributeName = 'event-tracking-options'; + + function handleAction(event, attributeName) { + var selector = '[data-' + attributeName + ']'; + var eventTarget = event.target; + if (!eventTarget) return; + var target = eventTarget.closest(selector); + if (!target) return; + var categoryAction; + var categoryActionParts; + var options; + categoryAction = target.dataset[toCamelCase(attributeName)]; + if (!categoryAction) return; + categoryActionParts = categoryAction.split('|'); + options = target.dataset[toCamelCase(trackingOptionsAttributeName)]; + options = options ? JSON.parse(options) : {}; + self.send_event( + categoryActionParts[0], + categoryActionParts[1], + categoryActionParts[2] || window.location.pathname, + options.service ? { service: options.service } : {} + ); + } + + function toCamelCase(str) { + return str.replace(/\W+(.)/g, function (match, chr) { + return chr.toUpperCase(); + }); + }; + + document.addEventListener('click', function(e) { + handleAction(e, clickTrackingAttributeName); + }); + + document.addEventListener('submit', function(e) { + handleAction(e, formTrackingAttributeName); + }); + }, + + /** + * @returns {Object[]} + */ + get_data_packets: function get_data_packets() { + return [this.values]; + }, + + /** + * Creates a tracking image for tracking JS compatibility. + * + * @param {string} type The type value for track_js_case in query params for 0.gif + */ + create_tracking_image: function create_tracking_image(type) { + this.send_ping_via_image({ + cache_bust: Math.random(), + kind: 'track_js', + track_js_case: type, + }); + } + }; + + return ArchiveAnalytics; +}()); +// @license-end diff --git a/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/banner-styles.css b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/banner-styles.css new file mode 100644 index 0000000..8d39621 --- /dev/null +++ b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/banner-styles.css @@ -0,0 +1,500 @@ +@import 'record.css'; /* for SPN1 */ + +#wm-ipp-base { + height:65px;/* initial height just in case js code fails */ + padding:0; + margin:0; + border:none; + background:none transparent; +} +#wm-ipp { + z-index: 2147483647; +} +#wm-ipp, #wm-ipp * { + font-family:Lucida Grande, Helvetica, Arial, sans-serif; + font-size:12px; + line-height:1.2; + letter-spacing:0; + width:auto; + height:auto; + max-width:none; + max-height:none; + min-width:0 !important; + min-height:0; + outline:none; + float:none; + text-align:left; + border:none; + color: #000; + text-indent: 0; + position: initial; + background: none; +} +#wm-ipp div, #wm-ipp canvas { + display: block; +} +#wm-ipp div, #wm-ipp tr, #wm-ipp td, #wm-ipp a, #wm-ipp form { + padding:0; + margin:0; + border:none; + border-radius:0; + background-color:transparent; + background-image:none; + /*z-index:2147483640;*/ + height:auto; +} +#wm-ipp table { + border:none; + border-collapse:collapse; + margin:0; + padding:0; + width:auto; + font-size:inherit; +} +#wm-ipp form input { + padding:1px !important; + height:auto; + display:inline; + margin:0; + color: #000; + background: none #fff; + border: 1px solid #666; +} +#wm-ipp form input[type=submit] { + padding:0 8px !important; + margin:1px 0 1px 5px !important; + width:auto !important; + border: 1px solid #000 !important; + background: #fff !important; + color: #000 !important; +} +#wm-ipp a { + display: inline; +} +#wm-ipp a:hover{ + text-decoration:underline; +} +#wm-ipp a.wm-btn:hover { + text-decoration:none; + color:#ff0 !important; +} +#wm-ipp a.wm-btn:hover span { + color:#ff0 !important; +} +#wm-ipp #wm-ipp-inside { + margin: 0 6px; + border:5px solid #000; + border-top:none; + background-color:rgba(255,255,255,0.9); + -moz-box-shadow:1px 1px 4px #333; + -webkit-box-shadow:1px 1px 4px #333; + box-shadow:1px 1px 4px #333; + border-radius:0 0 8px 8px; +} +/* selectors are intentionally verbose to ensure priority */ +#wm-ipp #wm-logo { + padding:0 10px; + vertical-align:middle; + min-width:100px; + flex: 0 0 100px; +} +#wm-ipp .c { + padding-left: 4px; +} +#wm-ipp .c .u { + margin-top: 4px !important; +} +#wm-ipp .n { + padding:0 0 0 5px !important; + vertical-align: bottom; +} +#wm-ipp .n a { + text-decoration:none; + color:#33f; + font-weight:bold; +} +#wm-ipp .n .b { + padding:0 6px 0 0 !important; + text-align:right !important; + overflow:visible; + white-space:nowrap; + color:#99a; + vertical-align:middle; +} +#wm-ipp .n .y .b { + padding:0 6px 2px 0 !important; +} +#wm-ipp .n .c { + background:#000; + color:#ff0; + font-weight:bold; + padding:0 !important; + text-align:center; +} +#wm-ipp.hi .n td.c { + color:#ec008c; +} +#wm-ipp .n td.f { + padding:0 0 0 6px !important; + text-align:left !important; + overflow:visible; + white-space:nowrap; + color:#99a; + vertical-align:middle; +} +#wm-ipp .n tr.m td { + text-transform:uppercase; + white-space:nowrap; + padding:2px 0; +} +#wm-ipp .c .s { + padding:0 5px 0 0 !important; + vertical-align:bottom; +} +#wm-ipp #wm-nav-captures { + white-space: nowrap; +} +#wm-ipp .c .s a.t { + color:#33f; + font-weight:bold; + line-height: 1.8; +} +#wm-ipp .c .s div.r { + color: #666; + font-size:9px; + white-space:nowrap; +} +#wm-ipp .c .k { + padding-bottom:1px; +} +#wm-ipp .c .s { + padding:0 5px 2px 0 !important; +} +#wm-ipp td#displayMonthEl { + padding: 2px 0 !important; +} +#wm-ipp td#displayYearEl { + padding: 0 0 2px 0 !important; +} + +div#wm-ipp-sparkline { + position:relative;/* for positioning markers */ + white-space:nowrap; + background-color:#fff; + cursor:pointer; + line-height:0.9; +} +#sparklineImgId, #wm-sparkline-canvas { + position:relative; + z-index:9012; + max-width:none; +} +#wm-ipp-sparkline div.yt { + position:absolute; + z-index:9010 !important; + background-color:#ff0 !important; + top: 0; +} +#wm-ipp-sparkline div.mt { + position:absolute; + z-index:9013 !important; + background-color:#ec008c !important; + top: 0; +} +#wm-ipp .r { + margin-left: 4px; +} +#wm-ipp .r a { + color:#33f; + border:none; + position:relative; + background-color:transparent; + background-repeat:no-repeat !important; + background-position:100% 100% !important; + text-decoration: none; +} +#wm-ipp #wm-capinfo { + /* prevents notice div background from sticking into round corners of + #wm-ipp-inside */ + border-radius: 0 0 4px 4px; +} +#wm-ipp #wm-capinfo .c-logo { + display:block; + float:left; + margin-right:3px; + width:90px; + min-height:90px; + max-height: 290px; + border-radius:45px; + overflow:hidden; + background-position:50%; + background-size:auto 90px; + box-shadow: 0 0 2px 2px rgba(208,208,208,128) inset; +} +#wm-ipp #wm-capinfo .c-logo span { + display:inline-block; +} +#wm-ipp #wm-capinfo .c-logo img { + height:90px; + position:relative; + left:-50%; +} +#wm-ipp #wm-capinfo .wm-title { + font-size:130%; +} +#wm-ipp #wm-capinfo a.wm-selector { + display:inline-block; + color: #aaa; + text-decoration:none !important; + padding: 2px 8px; +} +#wm-ipp #wm-capinfo a.wm-selector.selected { + background-color:#666; +} +#wm-ipp #wm-capinfo a.wm-selector:hover { + color: #fff; +} +#wm-ipp #wm-capinfo.notice-only #wm-capinfo-collected-by, +#wm-ipp #wm-capinfo.notice-only #wm-capinfo-timestamps { + display: none; +} +#wm-ipp #wm-capinfo #wm-capinfo-notice .wm-capinfo-content { + background-color:#ff0; + padding:5px; + font-size:14px; + text-align:center; +} +#wm-ipp #wm-capinfo #wm-capinfo-notice .wm-capinfo-content * { + font-size:14px; + text-align:center; +} +#wm-ipp #wm-expand { + right: 1px; + bottom: -1px; + color: #ffffff; + background-color: #666 !important; + padding:0 5px 0 3px !important; + border-radius: 3px 3px 0 0 !important; +} +#wm-ipp #wm-expand span { + color: #ffffff; +} +#wm-ipp #wm-expand #wm-expand-icon { + display: inline-block; + transition: transform 0.5s; + transform-origin: 50% 45%; +} +#wm-ipp #wm-expand.wm-open #wm-expand-icon { + transform: rotate(180deg); +} +#wm-ipp #wmtb { + text-align:right; +} +#wm-ipp #wmtb #wmtbURL { + width: calc(100% - 45px); +} +#wm-ipp #wm-graph-anchor { + border-right:1px solid #ccc; +} +/* time coherence */ +html.wb-highlight { + box-shadow: inset 0 0 0 3px #a50e3a !important; +} +.wb-highlight { + outline: 3px solid #a50e3a !important; +} +#wm-ipp-print { + display:none !important; +} +@media print { +#wm-ipp-base { + display:none !important; +} +#wm-ipp-print { + display:block !important; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +} +@media (max-width:414px) { + #wm-ipp .xxs { + display:none !important; + } +} +@media (min-width:1055px) { +#wm-ipp #wm-graph-anchor { + display:block !important; +} +} +@media (max-width:1054px) { +#wm-ipp #wm-graph-anchor { + display:none !important; +} +} +@media (max-width:1163px) { +#wm-logo { + display:none !important; +} +} + +#wm-btns { + white-space: nowrap; + margin-top: -2px; +} + +#wm-btns #wm-save-snapshot-open { + margin-right: 7px; + top: -6px; +} + +#wm-btns #wm-sign-in { + box-sizing: content-box; + display: none; + margin-right: 7px; + top: -8px; + + /* + round border around sign in button + */ + border: 2px #000 solid; + border-radius: 14px; + padding-right: 2px; + padding-bottom: 2px; + width: 11px; + height: 11px; +} + +#wm-btns #wm-sign-in>.iconochive-person { + font-size: 12.5px; +} + +#wm-save-snapshot-open > .iconochive-web { + color:#000; + font-size:160%; +} + +#wm-ipp #wm-share { + display: flex; + align-items: flex-end; + justify-content: space-between; +} + +#wm-share > #wm-screenshot { + display: inline-block; + margin-right: 3px; + visibility: hidden; +} + +#wm-screenshot > .iconochive-image { + color:#000; + font-size:160%; +} + +#wm-share > #wm-video { + display: inline-block; + margin-right: 3px; + visibility: hidden; +} + +#wm-video > .iconochive-movies { + color: #000; + display: inline-block; + font-size: 150%; + margin-bottom: 2px; +} + +#wm-btns #wm-save-snapshot-in-progress { + display: none; + font-size:160%; + opacity: 0.5; + position: relative; + margin-right: 7px; + top: -5px; +} + +#wm-btns #wm-save-snapshot-success { + display: none; + color: green; + position: relative; + top: -7px; +} + +#wm-btns #wm-save-snapshot-fail { + display: none; + color: red; + position: relative; + top: -7px; +} + +.wm-icon-screen-shot { + background: url("../images/web-screenshot.svg") no-repeat !important; + background-size: contain !important; + width: 22px !important; + height: 19px !important; + + display: inline-block; +} +#donato { + /* transition effect is disable so as to simplify height adjustment */ + /*transition: height 0.5s;*/ + height: 0; + margin: 0; + padding: 0; + border-bottom: 1px solid #999 !important; +} +body.wm-modal { + height: auto !important; + overflow: hidden !important; +} +#donato #donato-base { + width: 100%; + height: 100%; + /*bottom: 0;*/ + margin: 0; + padding: 0; + position: absolute; + z-index: 2147483639; +} +body.wm-modal #donato #donato-base { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 2147483640; +} + +.wb-autocomplete-suggestions { + font-family: Lucida Grande, Helvetica, Arial, sans-serif; + font-size: 12px; + text-align: left; + cursor: default; + border: 1px solid #ccc; + border-top: 0; + background: #fff; + box-shadow: -1px 1px 3px rgba(0,0,0,.1); + position: absolute; + display: none; + z-index: 2147483647; + max-height: 254px; + overflow: hidden; + overflow-y: auto; + box-sizing: border-box; +} +.wb-autocomplete-suggestion { + position: relative; + padding: 0 .6em; + line-height: 23px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-size: 1.02em; + color: #333; +} +.wb-autocomplete-suggestion b { + font-weight: bold; +} +.wb-autocomplete-suggestion.selected { + background: #f0f0f0; +} diff --git a/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/bufferlayout.svg b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/bufferlayout.svg new file mode 100644 index 0000000..0e343cd --- /dev/null +++ b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/bufferlayout.svg @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + (0,0) + (1023,511) + Buffer A + Buffer B + + diff --git a/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/bundle-playback.js b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/bundle-playback.js new file mode 100644 index 0000000..390894d --- /dev/null +++ b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/bundle-playback.js @@ -0,0 +1,3 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0 +!function(e){var t={};function n(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(o,i,function(t){return e[t]}.bind(null,i));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=9)}([function(e,t,n){"use strict";function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function s(e){var t="function"==typeof Map?new Map:void 0;return(s=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,o)}function o(){return a(e,arguments,u(this).constructor)}return o.prototype=Object.create(e.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),l(o,e)})(e)}function a(e,t,n){return(a=c()?Reflect.construct:function(e,t,n){var o=[null];o.push.apply(o,t);var i=new(Function.bind.apply(e,o));return n&&l(i,n.prototype),i}).apply(null,arguments)}function c(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function l(e,t){return(l=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function u(e){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}if(n.d(t,"a",(function(){return f})),n.d(t,"d",(function(){return p})),n.d(t,"c",(function(){return d})),n.d(t,"b",(function(){return v})),"undefiend"!=typeof window.XMLHttpRequest){var h=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&l(e,t)}(o,e);var t,n=(t=o,function(){var e,n=u(t);if(c()){var o=u(this).constructor;e=Reflect.construct(n,arguments,o)}else e=n.apply(this,arguments);return r(this,e)});function o(){return i(this,o),n.apply(this,arguments)}return o}(s(XMLHttpRequest));Object.defineProperty(h.prototype,"responseURL",Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype,"responseURL"))}function f(e,t,n,o,i){var r;if((r=window.XMLHttpRequest?new h:new ActiveXObject("Microsoft.XMLHTTP")).onreadystatechange=function(){4==this.readyState&&n(r)},r.open(e,t,!0),o)for(var s in o)o.hasOwnProperty(s)&&r.setRequestHeader(s,o[s]);r.withCredentials=!0,r.send(i)}function p(e){return void 0!==e&&e&&e.constructor===Array}function d(e){return document.cookie.search(e)>=0}function m(e,t){var n=window["HTML".concat(e,"Element")];if(void 0!==n){var o=Object.getOwnPropertyDescriptor(n.prototype,t);void 0!==o&&Object.defineProperty(n.prototype,"_wm_".concat(t),o)}}function v(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"src",n="_wm_".concat(t);return n in e.__proto__?e[n]:e[t]}m("Image","src"),m("Media","src"),m("Embed","src"),m("IFrame","src"),m("Script","src"),m("Link","href"),m("Anchor","href")},function(e,t,n){"use strict";n.d(t,"c",(function(){return s})),n.d(t,"b",(function(){return a})),n.d(t,"a",(function(){return c}));var o=["January","February","March","April","May","June","July","August","September","October","November","December"],i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],r={Y:function(e){return e.getUTCFullYear()},m:function(e){return e.getUTCMonth()+1},b:function(e){return i[e.getUTCMonth()]},B:function(e){return o[e.getUTCMonth()]},d:function(e){return e.getUTCDate()},H:function(e){return("0"+e.getUTCHours()).slice(-2)},M:function(e){return("0"+e.getUTCMinutes()).slice(-2)},S:function(e){return("0"+e.getUTCSeconds()).slice(-2)},"%":function(){return"%"}};function s(e){var t=function(e){return"number"==typeof e&&(e=e.toString()),[e.slice(-14,-10),e.slice(-10,-8),e.slice(-8,-6),e.slice(-6,-4),e.slice(-4,-2),e.slice(-2)]}(e);return new Date(Date.UTC(t[0],t[1]-1,t[2],t[3],t[4],t[5]))}function a(e){return i[e]}function c(e,t){return t.replace(/%./g,(function(t){var n=r[t[1]];return n?n(s(e)):t}))}},function(e,t,n){"use strict";n.d(t,"b",(function(){return s})),n.d(t,"a",(function(){return a}));var o=n(0);function i(e,t){for(var n=0;n=400?i.failure&&i.failure(e):i.success&&i.success(e)}),{"Content-Type":"application/json"},r.stringify({url:e,snapshot:t,tags:n||[]})),!1}var a=function(){function e(t,n,i){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.el=t,this.url=n,this.timestamp=i,t.onclick=this.save.bind(this),document.addEventListener("DOMContentLoaded",(function(){Object(o.c)("logged-in-user")&&Object(o.c)("logged-in-sig")?r.userIsLoggedIn():r.userIsNotLoggedIn()}))}var t,n,r;return t=e,(n=[{key:"save",value:function(e){this.start(),s(this.url,this.timestamp,[],{failure:this.failure.bind(this),success:this.success.bind(this)})}},{key:"start",value:function(){this.hide(["wm-save-snapshot-fail","wm-save-snapshot-open","wm-save-snapshot-success"]),this.show(["wm-save-snapshot-in-progress"])}},{key:"failure",value:function(e){401==e.status?this.userNotLoggedIn(e):(this.hide(["wm-save-snapshot-in-progress","wm-save-snapshot-success"]),this.show(["wm-save-snapshot-fail","wm-save-snapshot-open"]),console.log("You have got an error."),console.log("If you think something wrong here please send it to support."),console.log('Response: "'+e.responseText+'"'),console.log('status: "'+e.status+'"'))}},{key:"success",value:function(e){this.hide(["wm-save-snapshot-fail","wm-save-snapshot-in-progress"]),this.show(["wm-save-snapshot-open","wm-save-snapshot-success"])}},{key:"userIsLoggedIn",value:function(){this.show("wm-save-snapshot-open"),this.hide("wm-sign-in")}},{key:"userIsNotLoggedIn",value:function(){this.hide(["wm-save-snapshot-open","wm-save-snapshot-in-progress"]),this.show("wm-sign-in")}},{key:"show",value:function(e){this.setDisplayStyle(e,"inline-block")}},{key:"hide",value:function(e){this.setDisplayStyle(e,"none")}},{key:"setDisplayStyle",value:function(e,t){var n=this;(Object(o.d)(e)?e:[e]).forEach((function(e){var o=n.el.getRootNode().getElementById(e);o&&(o.style.display=t)}))}}])&&i(t.prototype,n),r&&i(t,r),e}()},,,,,,,function(e,t,n){"use strict";var o;n.r(t);var i,r={createElementNS:document.createElementNS};var s=!0;function a(e){!function(e,t,n){if(n){var o=new Date;o.setTime(o.getTime()+24*n*60*60*1e3);var i="; expires="+o.toGMTString()}else i="";document.cookie=e+"="+t+i+"; path=/"}(e,"",-1)}var c=n(0),l=n(1),u=window.Date;function h(e,t){return(e=e.toString()).length>=t?e:"00000000".substring(0,t-e.length)+e}function f(e){for(var t=0,n=0;n3}(e)){var o=[];for(n=0;n=e.length?{done:!0}:{done:!1,value:e[t++]}},e:function(e){throw e},f:n}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i,r=!0,s=!1;return{s:function(){o=e[Symbol.iterator]()},n:function(){var e=o.next();return r=e.done,e},e:function(e){s=!0,i=e},f:function(){try{r||null==o.return||o.return()}finally{if(s)throw i}}}}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n2&&void 0!==arguments[2]?arguments[2]:"src",r=window.location.origin,s=b(window,e),l=p(s);try{for(l.s();!(o=l.n()).done;){var u=o.value;if(!n||n(u)){var h=Object(c.b)(u,i);h&&!h.startsWith(t)&&h.startsWith(r)&&(h.startsWith("data:")||a.push(h))}}}catch(e){l.e(e)}finally{l.f()}}u("img"),u("frame"),u("iframe",(function(e){return"playback"!==e.id})),u("script"),u("link",(function(e){return"stylesheet"===e.rel}),"href");var h=a.filter((function(e,t,n){return n.indexOf(e)===t}));h.length>0?(s=0,h.map((function(e){e.match("^https?://")&&(s++,Object(c.a)("HEAD",e,(function(e){if(200==e.status){var t=e.getResponseHeader("Memento-Datetime");if(null==t)console.log("%s: no Memento-Datetime",u);else{var n=document.createElement("span"),a=function(e,t){var n=new Date(e).getTime()-t,o="";n<0?(o+="-",n=Math.abs(n)):o+="+";var i=!1;if(n<1e3)return{delta:n,text:"",highlight:i};var r=n,s=Math.floor(n/1e3/60/60/24/30/12);n-=1e3*s*60*60*24*30*12;var a=Math.floor(n/1e3/60/60/24/30);n-=1e3*a*60*60*24*30;var c=Math.floor(n/1e3/60/60/24);n-=1e3*c*60*60*24;var l=Math.floor(n/1e3/60/60);n-=1e3*l*60*60;var u=Math.floor(n/1e3/60);n-=1e3*u*60;var h=Math.floor(n/1e3),f=[];s>1?(f.push(s+" years"),i=!0):1==s&&(f.push(s+" year"),i=!0);a>1?(f.push(a+" months"),i=!0):1==a&&(f.push(a+" month"),i=!0);c>1?f.push(c+" days"):1==c&&f.push(c+" day");l>1?f.push(l+" hours"):1==l&&f.push(l+" hour");u>1?f.push(u+" minutes"):1==u&&f.push(u+" minute");h>1?f.push(h+" seconds"):1==h&&f.push(h+" second");f.length>2&&(f=f.slice(0,2));return{delta:r,text:o+f.join(" "),highlight:i}}(t,r),c=a.highlight?"color:red;":"";n.innerHTML=" "+a.text,n.title=t,n.setAttribute("style",c);var l=e.getResponseHeader("Content-Type"),u=e.responseURL.replace(window.location.origin,""),h=document.createElement("a");h.innerHTML=u.split("/").splice(3).join("/"),h._wm_href=u,h.title=l,h.onmouseover=y,h.onmouseout=w;var f=document.createElement("div");f.setAttribute("data-delta",a.delta),f.appendChild(h),f.append(n),o.appendChild(f);var p=Array.prototype.slice.call(o.childNodes,0);p.sort((function(e,t){return t.getAttribute("data-delta")-e.getAttribute("data-delta")})),o.innerHTML="";for(var d=0,m=p.length;d0)for(var n=0;n0)for(var n=0;n0?this.sc.scrollTop=i+this.sc.suggestionHeight+o-this.sc.maxHeight:i<0&&(this.sc.scrollTop=i+o)}}},{key:"blurHandler",value:function(){var e=this;try{var t=this.root.querySelector(".wb-autocomplete-suggestions:hover")}catch(e){t=null}t?this.input!==document.activeElement&&setTimeout((function(){return e.focus()}),20):(this.last_val=this.input.value,this.sc.style.display="none",setTimeout((function(){return e.sc.style.display="none"}),350))}},{key:"suggest",value:function(e){var t=this.input.value;if(this.cache[t]=e,e.length&&t.length>=this.minChars){for(var n="",o=0;o40)&&13!=n&&27!=n){var o=this.input.value;if(o.length>=this.minChars){if(o!=this.last_val){if(this.last_val=o,clearTimeout(this.timer),this.cache){if(o in this.cache)return void this.suggest(this.cache[o]);for(var i=1;i'+e.replace(n,"$1")+""}},{key:"onSelect",value:function(e,t,n){}}]),e}(),j=function(){function e(t,n){S(this,e);var o=t.getRootNode();if(o.querySelector){var i="object"==_(t)?[t]:o.querySelectorAll(t);this.elems=i.map((function(e){return new E(e,n)}))}}return T(e,[{key:"destroy",value:function(){for(;this.elems.length>0;)this.elems.pop().unload()}}]),e}(),R=n(2),A=window.JSON,N=window.open,U=window.Date,I=document,D=document,P=function(e){return D.getElementById(e)};var q,F="/static/";function B(e){L.classList.contains("wm-closed")?(e&&O.classList.add("notice-only"),L.classList.replace("wm-closed","wm-open"),O.style.display="block",m(q,F,P)):(L.classList.replace("wm-open","wm-closed"),O.style.display="none",O.classList.remove("notice-only"))}function W(e,t){var n=P(e);n&&(n.style.visibility=t?"visible":"hidden")}function X(e,t){Object(c.d)(e)||(e=[e]);for(var n=0;n0&&r<60,r)}))}window.__wm={init:function(e){!function(){var e=document.cookie.split(";");if(e.length>40)for(var t=0;t1?t-1:0),o=1;o0;)x.appendChild(C.children[0]);if(d)for(var H=0;H'+((""+n).replace(/\B(?=(\d{3})+$)/g,",")+" ")+(n>1?"captures":"capture")+"",f=l.a(i,"%d %b %Y");s!=i&&(f+=" - "+l.a(s,"%d %b %Y")),h+='
'+f+"
",t.innerHTML=h}(o),function(e,t,n,o,i,r,s){var a=o.getContext("2d");if(a){a.fillStyle="#FFF";var c=(new u).getUTCFullYear(),l=t/(c-i+1),h=f(e.years),p=h[0],d=n/h[1];if(r>=i){var m=T(r);a.fillStyle="#FFFFA5",a.fillRect(m,0,l,n)}for(var v=i;v<=c;v++){m=T(v);a.beginPath(),a.moveTo(m,0),a.lineTo(m,n),a.lineWidth=1,a.strokeStyle="#CCC",a.stroke()}s=parseInt(s)-1;for(var g=(l-1)/12,y=0;y0){var M=Math.ceil(S*d);a.fillStyle=v==r&&_==s?"#EC008C":"#000",a.fillRect(Math.round(b),Math.ceil(n-M),Math.ceil(g),Math.round(M))}b+=g}}}function T(e){return Math.ceil((e-i)*l)+.5}}(o,e,t,Z,a,_,S)}}))}else{var te=new Image;te.src="/__wb/sparkline?url="+encodeURIComponent(r)+"&width="+e+"&height="+t+"&selected_year="+_+"&selected_month="+S+(i&&"&collection="+i||""),te.alt="sparkline",te.width=e,te.height=t,te.id="sparklineImgId",te.border="0",Q.parentNode.replaceChild(te,Q)}function ne(e){for(var t=[],n=e.length,o=0;o + + + + CPU - GPU Block Diagram + + + + + + + + image/svg+xml + + CPU - GPU Block Diagram + + + + + + + + + + + + + + + + + + GPU + CPU + GTE + RAM + + + + + + VRAM + + + Bus + MDEC + + Video + + diff --git a/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/iconochive.css b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/iconochive.css new file mode 100644 index 0000000..7a95ea7 --- /dev/null +++ b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/iconochive.css @@ -0,0 +1,116 @@ +@font-face{font-family:'Iconochive-Regular';src:url('https://archive.org/includes/fonts/Iconochive-Regular.eot?-ccsheb');src:url('https://archive.org/includes/fonts/Iconochive-Regular.eot?#iefix-ccsheb') format('embedded-opentype'),url('https://archive.org/includes/fonts/Iconochive-Regular.woff?-ccsheb') format('woff'),url('https://archive.org/includes/fonts/Iconochive-Regular.ttf?-ccsheb') format('truetype'),url('https://archive.org/includes/fonts/Iconochive-Regular.svg?-ccsheb#Iconochive-Regular') format('svg');font-weight:normal;font-style:normal} +[class^="iconochive-"],[class*=" iconochive-"]{font-family:'Iconochive-Regular'!important;speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale} +.iconochive-Uplevel:before{content:"\21b5"} +.iconochive-exit:before{content:"\1f6a3"} +.iconochive-beta:before{content:"\3b2"} +.iconochive-logo:before{content:"\1f3db"} +.iconochive-audio:before{content:"\1f568"} +.iconochive-movies:before{content:"\1f39e"} +.iconochive-software:before{content:"\1f4be"} +.iconochive-texts:before{content:"\1f56e"} +.iconochive-etree:before{content:"\1f3a4"} +.iconochive-image:before{content:"\1f5bc"} +.iconochive-web:before{content:"\1f5d4"} +.iconochive-collection:before{content:"\2211"} +.iconochive-folder:before{content:"\1f4c2"} +.iconochive-data:before{content:"\1f5c3"} +.iconochive-tv:before{content:"\1f4fa"} +.iconochive-article:before{content:"\1f5cf"} +.iconochive-question:before{content:"\2370"} +.iconochive-question-dark:before{content:"\3f"} +.iconochive-info:before{content:"\69"} +.iconochive-info-small:before{content:"\24d8"} +.iconochive-comment:before{content:"\1f5e9"} +.iconochive-comments:before{content:"\1f5ea"} +.iconochive-person:before{content:"\1f464"} +.iconochive-people:before{content:"\1f465"} +.iconochive-eye:before{content:"\1f441"} +.iconochive-rss:before{content:"\221e"} +.iconochive-time:before{content:"\1f551"} +.iconochive-quote:before{content:"\275d"} +.iconochive-disc:before{content:"\1f4bf"} +.iconochive-tv-commercial:before{content:"\1f4b0"} +.iconochive-search:before{content:"\1f50d"} +.iconochive-search-star:before{content:"\273d"} +.iconochive-tiles:before{content:"\229e"} +.iconochive-list:before{content:"\21f6"} +.iconochive-list-bulleted:before{content:"\2317"} +.iconochive-latest:before{content:"\2208"} +.iconochive-left:before{content:"\2c2"} +.iconochive-right:before{content:"\2c3"} +.iconochive-left-solid:before{content:"\25c2"} +.iconochive-right-solid:before{content:"\25b8"} +.iconochive-up-solid:before{content:"\25b4"} +.iconochive-down-solid:before{content:"\25be"} +.iconochive-dot:before{content:"\23e4"} +.iconochive-dots:before{content:"\25a6"} +.iconochive-columns:before{content:"\25af"} +.iconochive-sort:before{content:"\21d5"} +.iconochive-atoz:before{content:"\1f524"} +.iconochive-ztoa:before{content:"\1f525"} +.iconochive-upload:before{content:"\1f4e4"} +.iconochive-download:before{content:"\1f4e5"} +.iconochive-favorite:before{content:"\2605"} +.iconochive-heart:before{content:"\2665"} +.iconochive-play:before{content:"\25b6"} +.iconochive-play-framed:before{content:"\1f3ac"} +.iconochive-fullscreen:before{content:"\26f6"} +.iconochive-mute:before{content:"\1f507"} +.iconochive-unmute:before{content:"\1f50a"} +.iconochive-share:before{content:"\1f381"} +.iconochive-edit:before{content:"\270e"} +.iconochive-reedit:before{content:"\2710"} +.iconochive-gear:before{content:"\2699"} +.iconochive-remove-circle:before{content:"\274e"} +.iconochive-plus-circle:before{content:"\1f5d6"} +.iconochive-minus-circle:before{content:"\1f5d5"} +.iconochive-x:before{content:"\1f5d9"} +.iconochive-fork:before{content:"\22d4"} +.iconochive-trash:before{content:"\1f5d1"} +.iconochive-warning:before{content:"\26a0"} +.iconochive-flash:before{content:"\1f5f2"} +.iconochive-world:before{content:"\1f5fa"} +.iconochive-lock:before{content:"\1f512"} +.iconochive-unlock:before{content:"\1f513"} +.iconochive-twitter:before{content:"\1f426"} +.iconochive-facebook:before{content:"\66"} +.iconochive-googleplus:before{content:"\67"} +.iconochive-reddit:before{content:"\1f47d"} +.iconochive-tumblr:before{content:"\54"} +.iconochive-pinterest:before{content:"\1d4df"} +.iconochive-popcorn:before{content:"\1f4a5"} +.iconochive-email:before{content:"\1f4e7"} +.iconochive-embed:before{content:"\1f517"} +.iconochive-gamepad:before{content:"\1f579"} +.iconochive-Zoom_In:before{content:"\2b"} +.iconochive-Zoom_Out:before{content:"\2d"} +.iconochive-RSS:before{content:"\1f4e8"} +.iconochive-Light_Bulb:before{content:"\1f4a1"} +.iconochive-Add:before{content:"\2295"} +.iconochive-Tab_Activity:before{content:"\2318"} +.iconochive-Forward:before{content:"\23e9"} +.iconochive-Backward:before{content:"\23ea"} +.iconochive-No_Audio:before{content:"\1f508"} +.iconochive-Pause:before{content:"\23f8"} +.iconochive-No_Favorite:before{content:"\2606"} +.iconochive-Unike:before{content:"\2661"} +.iconochive-Song:before{content:"\266b"} +.iconochive-No_Flag:before{content:"\2690"} +.iconochive-Flag:before{content:"\2691"} +.iconochive-Done:before{content:"\2713"} +.iconochive-Check:before{content:"\2714"} +.iconochive-Refresh:before{content:"\27f3"} +.iconochive-Headphones:before{content:"\1f3a7"} +.iconochive-Chart:before{content:"\1f4c8"} +.iconochive-Bookmark:before{content:"\1f4d1"} +.iconochive-Documents:before{content:"\1f4da"} +.iconochive-Newspaper:before{content:"\1f4f0"} +.iconochive-Podcast:before{content:"\1f4f6"} +.iconochive-Radio:before{content:"\1f4fb"} +.iconochive-Cassette:before{content:"\1f4fc"} +.iconochive-Shuffle:before{content:"\1f500"} +.iconochive-Loop:before{content:"\1f501"} +.iconochive-Low_Audio:before{content:"\1f509"} +.iconochive-First:before{content:"\1f396"} +.iconochive-Invisible:before{content:"\1f576"} +.iconochive-Computer:before{content:"\1f5b3"} diff --git a/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/style.css b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/style.css new file mode 100644 index 0000000..1eac881 --- /dev/null +++ b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/style.css @@ -0,0 +1,70 @@ +body { + max-width: 900px; + margin: auto; + padding: 8px; + font-family: sans-serif; + font-size: 14px; + //color: white; + //background: black; +} + +h { + background-color: #e0e0e0; + padding: 2px; +} + +h2 { + border-bottom: 1px solid; + //padding-left: 8px; +} + +img { + display: block; +} + +.footer-table { + font-size: 14px; +} + +.bordered-table { + border-collapse: collapse; + font-size: 11px; +} + +.bordered-table th, .bordered-table td { + border: 1px solid; + padding: 4px; +} + +hr { + border: none; + border-bottom: 1px solid black; +} + +pre { + padding: 8px; + font-size: 12px; + color: black; + background-color: LightGray; +} +/* + FILE ARCHIVED ON 03:35:25 Aug 27, 2022 AND RETRIEVED FROM THE + INTERNET ARCHIVE ON 15:39:09 Sep 05, 2022. + JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE. + + ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C. + SECTION 108(a)(3)). +*/ +/* +playback timings (ms): + captures_list: 107.165 + exclusion.robots: 0.073 + exclusion.robots.policy: 0.067 + cdx.remote: 0.064 + esindex: 0.009 + LoadShardBlock: 52.713 (3) + PetaboxLoader3.datanode: 140.466 (4) + CDXLines.iter: 14.771 (3) + load_resource: 139.896 + PetaboxLoader3.resolve: 47.824 +*/ \ No newline at end of file diff --git a/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/vram-layout.svg b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/vram-layout.svg new file mode 100644 index 0000000..882055c --- /dev/null +++ b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/vram-layout.svg @@ -0,0 +1,261 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + (0,0) + (1023,511) + Buffer A + Buffer B + + CLUTS + + Textures + + Textures + + Textures + + Textures + + + Textures + Textures + + diff --git a/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/wombat.js b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/wombat.js new file mode 100644 index 0000000..19d1a47 --- /dev/null +++ b/Docs/Chapter 1.1 Setting up Graphics and Hello World_files/wombat.js @@ -0,0 +1,21 @@ +/* +Wombat.js client-side rewriting engine for web archive replay +Copyright (C) 2014-2020 Webrecorder Software, Rhizome, and Contributors. Released under the GNU Affero General Public License. + +This file is part of wombat.js, see https://github.com/webrecorder/wombat.js for the full source +Wombat.js is part of the Webrecorder project (https://github.com/webrecorder) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . + */ +(function(){function FuncMap(){this._map=[]}function ensureNumber(maybeNumber){try{switch(typeof maybeNumber){case"number":case"bigint":return maybeNumber;}var converted=Number(maybeNumber);return isNaN(converted)?null:converted}catch(e){}return null}function addToStringTagToClass(clazz,tag){typeof self.Symbol!=="undefined"&&typeof self.Symbol.toStringTag!=="undefined"&&Object.defineProperty(clazz.prototype,self.Symbol.toStringTag,{value:tag,enumerable:false})}function autobind(clazz){for(var prop,propValue,proto=clazz.__proto__||clazz.constructor.prototype||clazz.prototype,clazzProps=Object.getOwnPropertyNames(proto),len=clazzProps.length,i=0;i=0){var fnMapping=this._map.splice(idx,1);return fnMapping[0][1]}return null},FuncMap.prototype.map=function(param){for(var i=0;i0&&afw.preserveMedia(media)})},AutoFetcher.prototype.terminate=function(){this.worker.terminate()},AutoFetcher.prototype.justFetch=function(urls){this.worker.postMessage({type:"fetch-all",values:urls})},AutoFetcher.prototype.fetchAsPage=function(url,originalUrl,title){if(url){var headers={"X-Wombat-History-Page":originalUrl};if(title){var encodedTitle=encodeURIComponent(title.trim());title&&(headers["X-Wombat-History-Title"]=encodedTitle)}var fetchData={url:url,options:{headers:headers,cache:"no-store"}};this.justFetch([fetchData])}},AutoFetcher.prototype.postMessage=function(msg,deferred){if(deferred){var afWorker=this;return void Promise.resolve().then(function(){afWorker.worker.postMessage(msg)})}this.worker.postMessage(msg)},AutoFetcher.prototype.preserveSrcset=function(srcset,mod){this.postMessage({type:"values",srcset:{value:srcset,mod:mod,presplit:true}},true)},AutoFetcher.prototype.preserveDataSrcset=function(elem){this.postMessage({type:"values",srcset:{value:elem.dataset.srcset,mod:this.rwMod(elem),presplit:false}},true)},AutoFetcher.prototype.preserveMedia=function(media){this.postMessage({type:"values",media:media},true)},AutoFetcher.prototype.getSrcset=function(elem){return this.wombat.wb_getAttribute?this.wombat.wb_getAttribute.call(elem,"srcset"):elem.getAttribute("srcset")},AutoFetcher.prototype.rwMod=function(elem){switch(elem.tagName){case"SOURCE":return elem.parentElement&&elem.parentElement.tagName==="PICTURE"?"im_":"oe_";case"IMG":return"im_";}return"oe_"},AutoFetcher.prototype.extractFromLocalDoc=function(){var afw=this;Promise.resolve().then(function(){for(var msg={type:"values",context:{docBaseURI:document.baseURI}},media=[],i=0,sheets=document.styleSheets;i=0)||scriptType.indexOf("text/template")>=0)},Wombat.prototype.skipWrapScriptTextBasedOnText=function(text){if(!text||text.indexOf(this.WB_ASSIGN_FUNC)>=0||text.indexOf("<")===0)return true;for(var override_props=["window","self","document","location","top","parent","frames","opener"],i=0;i=0)return false;return true},Wombat.prototype.nodeHasChildren=function(node){if(!node)return false;if(typeof node.hasChildNodes==="function")return node.hasChildNodes();var kids=node.children||node.childNodes;return!!kids&&kids.length>0},Wombat.prototype.rwModForElement=function(elem,attrName){if(!elem)return undefined;var mod="mp_";if(!(elem.tagName==="LINK"&&attrName==="href")){var maybeMod=this.tagToMod[elem.tagName];maybeMod!=null&&(mod=maybeMod[attrName])}else if(elem.rel){var relV=elem.rel.trim().toLowerCase(),asV=this.wb_getAttribute.call(elem,"as");if(asV&&this.linkTagMods.linkRelToAs[relV]!=null){var asMods=this.linkTagMods.linkRelToAs[relV];mod=asMods[asV.toLowerCase()]}else this.linkTagMods[relV]!=null&&(mod=this.linkTagMods[relV])}return mod},Wombat.prototype.removeWBOSRC=function(elem){elem.tagName!=="SCRIPT"||elem.__$removedWBOSRC$__||(elem.hasAttribute("__wb_orig_src")&&elem.removeAttribute("__wb_orig_src"),elem.__$removedWBOSRC$__=true)},Wombat.prototype.retrieveWBOSRC=function(elem){if(elem.tagName==="SCRIPT"&&!elem.__$removedWBOSRC$__){var maybeWBOSRC;return maybeWBOSRC=this.wb_getAttribute?this.wb_getAttribute.call(elem,"__wb_orig_src"):elem.getAttribute("__wb_orig_src"),maybeWBOSRC==null&&(elem.__$removedWBOSRC$__=true),maybeWBOSRC}return undefined},Wombat.prototype.wrapScriptTextJsProxy=function(scriptText){return"var _____WB$wombat$assign$function_____ = function(name) {return (self._wb_wombat && self._wb_wombat.local_init && self._wb_wombat.local_init(name)) || self[name]; };\nif (!self.__WB_pmw) { self.__WB_pmw = function(obj) { this.__WB_source = obj; return this; } }\n{\nlet window = _____WB$wombat$assign$function_____(\"window\");\nlet self = _____WB$wombat$assign$function_____(\"self\");\nlet document = _____WB$wombat$assign$function_____(\"document\");\nlet location = _____WB$wombat$assign$function_____(\"location\");\nlet top = _____WB$wombat$assign$function_____(\"top\");\nlet parent = _____WB$wombat$assign$function_____(\"parent\");\nlet frames = _____WB$wombat$assign$function_____(\"frames\");\nlet opener = _____WB$wombat$assign$function_____(\"opener\");\n"+scriptText.replace(this.DotPostMessageRe,".__WB_pmw(self.window)$1")+"\n\n}"},Wombat.prototype.watchElem=function(elem,func){if(!this.$wbwindow.MutationObserver)return false;var m=new this.$wbwindow.MutationObserver(function(records,observer){for(var r,i=0;i"},Wombat.prototype.getFinalUrl=function(useRel,mod,url){var prefix=useRel?this.wb_rel_prefix:this.wb_abs_prefix;return mod==null&&(mod=this.wb_info.mod),this.wb_info.is_live||(prefix+=this.wb_info.wombat_ts),prefix+=mod,prefix[prefix.length-1]!=="/"&&(prefix+="/"),prefix+url},Wombat.prototype.resolveRelUrl=function(url,doc){var docObj=doc||this.$wbwindow.document,parser=this.makeParser(docObj.baseURI,docObj),hash=parser.href.lastIndexOf("#"),href=hash>=0?parser.href.substring(0,hash):parser.href,lastslash=href.lastIndexOf("/");return parser.href=lastslash>=0&&lastslash!==href.length-1?href.substring(0,lastslash+1)+url:href+url,parser.href},Wombat.prototype.extractOriginalURL=function(rewrittenUrl){if(!rewrittenUrl)return"";if(this.wb_is_proxy)return rewrittenUrl;var rwURLString=rewrittenUrl.toString(),url=rwURLString;if(this.startsWithOneOf(url,this.IGNORE_PREFIXES))return url;var start;start=this.startsWith(url,this.wb_abs_prefix)?this.wb_abs_prefix.length:this.wb_rel_prefix&&this.startsWith(url,this.wb_rel_prefix)?this.wb_rel_prefix.length:this.wb_rel_prefix?1:0;var index=url.indexOf("/http",start);return index<0&&(index=url.indexOf("///",start)),index<0&&(index=url.indexOf("/blob:",start)),index<0&&(index=url.indexOf("/about:blank",start)),index>=0?url=url.substr(index+1):(index=url.indexOf(this.wb_replay_prefix),index>=0&&(url=url.substr(index+this.wb_replay_prefix.length)),url.length>4&&url.charAt(2)==="_"&&url.charAt(3)==="/"&&(url=url.substr(4)),url!==rwURLString&&!this.startsWithOneOf(url,this.VALID_PREFIXES)&&!this.startsWith(url,"blob:")&&(url=this.wb_orig_scheme+url)),rwURLString.charAt(0)==="/"&&rwURLString.charAt(1)!=="/"&&this.startsWith(url,this.wb_orig_origin)&&(url=url.substr(this.wb_orig_origin.length)),this.startsWith(url,this.REL_PREFIX)?this.wb_info.wombat_scheme+":"+url:url},Wombat.prototype.makeParser=function(maybeRewrittenURL,doc){var originalURL=this.extractOriginalURL(maybeRewrittenURL),docElem=doc;return doc||(this.$wbwindow.location.href==="about:blank"&&this.$wbwindow.opener?docElem=this.$wbwindow.opener.document:docElem=this.$wbwindow.document),this._makeURLParser(originalURL,docElem)},Wombat.prototype._makeURLParser=function(url,docElem){try{return new this.$wbwindow.URL(url,docElem.baseURI)}catch(e){}var p=docElem.createElement("a");return p._no_rewrite=true,p.href=url,p},Wombat.prototype.defProp=function(obj,prop,setFunc,getFunc,enumerable){var existingDescriptor=Object.getOwnPropertyDescriptor(obj,prop);if(existingDescriptor&&!existingDescriptor.configurable)return false;if(!getFunc)return false;var descriptor={configurable:true,enumerable:enumerable||false,get:getFunc};setFunc&&(descriptor.set=setFunc);try{return Object.defineProperty(obj,prop,descriptor),true}catch(e){return console.warn("Failed to redefine property %s",prop,e.message),false}},Wombat.prototype.defGetterProp=function(obj,prop,getFunc,enumerable){var existingDescriptor=Object.getOwnPropertyDescriptor(obj,prop);if(existingDescriptor&&!existingDescriptor.configurable)return false;if(!getFunc)return false;try{return Object.defineProperty(obj,prop,{configurable:true,enumerable:enumerable||false,get:getFunc}),true}catch(e){return console.warn("Failed to redefine property %s",prop,e.message),false}},Wombat.prototype.getOrigGetter=function(obj,prop){var orig_getter;if(obj.__lookupGetter__&&(orig_getter=obj.__lookupGetter__(prop)),!orig_getter&&Object.getOwnPropertyDescriptor){var props=Object.getOwnPropertyDescriptor(obj,prop);props&&(orig_getter=props.get)}return orig_getter},Wombat.prototype.getOrigSetter=function(obj,prop){var orig_setter;if(obj.__lookupSetter__&&(orig_setter=obj.__lookupSetter__(prop)),!orig_setter&&Object.getOwnPropertyDescriptor){var props=Object.getOwnPropertyDescriptor(obj,prop);props&&(orig_setter=props.set)}return orig_setter},Wombat.prototype.getAllOwnProps=function(obj){for(var ownProps=[],props=Object.getOwnPropertyNames(obj),i=0;i "+final_href),actualLocation.href=final_href}}},Wombat.prototype.checkLocationChange=function(wombatLoc,isTop){var locType=typeof wombatLoc,actual_location=isTop?this.$wbwindow.__WB_replay_top.location:this.$wbwindow.location;locType==="string"?this.updateLocation(wombatLoc,actual_location.href,actual_location):locType==="object"&&this.updateLocation(wombatLoc.href,wombatLoc._orig_href,actual_location)},Wombat.prototype.checkAllLocations=function(){return!this.wb_wombat_updating&&void(this.wb_wombat_updating=true,this.checkLocationChange(this.$wbwindow.WB_wombat_location,false),this.$wbwindow.WB_wombat_location!=this.$wbwindow.__WB_replay_top.WB_wombat_location&&this.checkLocationChange(this.$wbwindow.__WB_replay_top.WB_wombat_location,true),this.wb_wombat_updating=false)},Wombat.prototype.proxyToObj=function(source){if(source)try{var proxyRealObj=source.__WBProxyRealObj__;if(proxyRealObj)return proxyRealObj}catch(e){}return source},Wombat.prototype.objToProxy=function(obj){if(obj)try{var maybeWbProxy=obj._WB_wombat_obj_proxy;if(maybeWbProxy)return maybeWbProxy}catch(e){}return obj},Wombat.prototype.defaultProxyGet=function(obj,prop,ownProps,fnCache){switch(prop){case"__WBProxyRealObj__":return obj;case"location":case"WB_wombat_location":return obj.WB_wombat_location;case"_WB_wombat_obj_proxy":return obj._WB_wombat_obj_proxy;case"__WB_pmw":case"WB_wombat_eval":case this.WB_ASSIGN_FUNC:case this.WB_CHECK_THIS_FUNC:return obj[prop];case"origin":return obj.WB_wombat_location.origin;case"constructor":if(obj.constructor===Window)return obj.constructor;}var retVal=obj[prop],type=typeof retVal;if(type==="function"&&ownProps.indexOf(prop)!==-1){switch(prop){case"requestAnimationFrame":case"cancelAnimationFrame":{if(!this.isNativeFunction(retVal))return retVal;break}}var cachedFN=fnCache[prop];return cachedFN&&cachedFN.original===retVal||(cachedFN={original:retVal,boundFn:retVal.bind(obj)},fnCache[prop]=cachedFN),cachedFN.boundFn}return type==="object"&&retVal&&retVal._WB_wombat_obj_proxy?(retVal instanceof Window&&this.initNewWindowWombat(retVal),retVal._WB_wombat_obj_proxy):retVal},Wombat.prototype.setLoc=function(loc,originalURL){var parser=this.makeParser(originalURL,loc.ownerDocument);loc._orig_href=originalURL,loc._parser=parser;var href=parser.href;loc._hash=parser.hash,loc._href=href,loc._host=parser.host,loc._hostname=parser.hostname,loc._origin=parser.origin?parser.host?parser.origin:"null":parser.protocol+"//"+parser.hostname+(parser.port?":"+parser.port:""),loc._pathname=parser.pathname,loc._port=parser.port,loc._protocol=parser.protocol,loc._search=parser.search,Object.defineProperty||(loc.href=href,loc.hash=parser.hash,loc.host=loc._host,loc.hostname=loc._hostname,loc.origin=loc._origin,loc.pathname=loc._pathname,loc.port=loc._port,loc.protocol=loc._protocol,loc.search=loc._search)},Wombat.prototype.makeGetLocProp=function(prop,origGetter){var wombat=this;return function newGetLocProp(){if(this._no_rewrite)return origGetter.call(this,prop);var curr_orig_href=origGetter.call(this,"href");return prop==="href"?wombat.extractOriginalURL(curr_orig_href):prop==="ancestorOrigins"?[]:(this._orig_href!==curr_orig_href&&wombat.setLoc(this,curr_orig_href),this["_"+prop])}},Wombat.prototype.makeSetLocProp=function(prop,origSetter,origGetter){var wombat=this;return function newSetLocProp(value){if(this._no_rewrite)return origSetter.call(this,prop,value);if(this["_"+prop]!==value){if(this["_"+prop]=value,!this._parser){var href=origGetter.call(this);this._parser=wombat.makeParser(href,this.ownerDocument)}var rel=false;prop==="href"&&typeof value==="string"&&value&&(value[0]==="."?value=wombat.resolveRelUrl(value,this.ownerDocument):value[0]==="/"&&(value.length<=1||value[1]!=="/")&&(rel=true,value=WB_wombat_location.origin+value));try{this._parser[prop]=value}catch(e){console.log("Error setting "+prop+" = "+value)}prop==="hash"?(value=this._parser[prop],origSetter.call(this,"hash",value)):(rel=rel||value===this._parser.pathname,value=wombat.rewriteUrl(this._parser.href,rel),origSetter.call(this,"href",value))}}},Wombat.prototype.styleReplacer=function(match,n1,n2,n3,offset,string){return n1+this.rewriteUrl(n2)+n3},Wombat.prototype.domConstructorErrorChecker=function(thisObj,what,args,numRequiredArgs){var errorMsg,needArgs=typeof numRequiredArgs==="number"?numRequiredArgs:1;if(thisObj instanceof Window?errorMsg="Failed to construct '"+what+"': Please use the 'new' operator, this DOM object constructor cannot be called as a function.":args&&args.length=0)return url;if(url.indexOf(this.wb_rel_prefix)===0&&url.indexOf("http")>1){var scheme_sep=url.indexOf(":/");return scheme_sep>0&&url[scheme_sep+2]!=="/"?url.substring(0,scheme_sep+2)+"/"+url.substring(scheme_sep+2):url}return this.getFinalUrl(true,mod,this.wb_orig_origin+url)}url.charAt(0)==="."&&(url=this.resolveRelUrl(url,doc));var prefix=this.startsWithOneOf(url.toLowerCase(),this.VALID_PREFIXES);if(prefix){var orig_host=this.$wbwindow.__WB_replay_top.location.host,orig_protocol=this.$wbwindow.__WB_replay_top.location.protocol,prefix_host=prefix+orig_host+"/";if(this.startsWith(url,prefix_host)){if(this.startsWith(url,this.wb_replay_prefix))return url;var curr_scheme=orig_protocol+"//",path=url.substring(prefix_host.length),rebuild=false;return path.indexOf(this.wb_rel_prefix)<0&&url.indexOf("/static/")<0&&(path=this.getFinalUrl(true,mod,WB_wombat_location.origin+"/"+path),rebuild=true),prefix!==curr_scheme&&prefix!==this.REL_PREFIX&&(rebuild=true),rebuild&&(url=useRel?"":curr_scheme+orig_host,path&&path[0]!=="/"&&(url+="/"),url+=path),url}return this.getFinalUrl(useRel,mod,url)}return prefix=this.startsWithOneOf(url,this.BAD_PREFIXES),prefix?this.getFinalUrl(useRel,mod,this.extractOriginalURL(url)):this.isHostUrl(url)&&!this.startsWith(url,originalLoc.host+"/")?this.getFinalUrl(useRel,mod,this.wb_orig_scheme+url):url},Wombat.prototype.rewriteUrl=function(url,useRel,mod,doc){var rewritten=this.rewriteUrl_(url,useRel,mod,doc);return this.debug_rw&&(url===rewritten?console.log("NOT REWRITTEN "+url):console.log("REWRITE: "+url+" -> "+rewritten)),rewritten},Wombat.prototype.performAttributeRewrite=function(elem,name,value,absUrlOnly){switch(name){case"innerHTML":case"outerHTML":return this.rewriteHtml(value);case"filter":return this.rewriteInlineStyle(value);case"style":return this.rewriteStyle(value);case"srcset":return this.rewriteSrcset(value,elem);}if(absUrlOnly&&!this.startsWithOneOf(value,this.VALID_PREFIXES))return value;var mod=this.rwModForElement(elem,name);return this.wbUseAFWorker&&this.WBAutoFetchWorker&&this.isSavedDataSrcSrcset(elem)&&this.WBAutoFetchWorker.preserveDataSrcset(elem),this.rewriteUrl(value,false,mod,elem.ownerDocument)},Wombat.prototype.rewriteAttr=function(elem,name,absUrlOnly){var changed=false;if(!elem||!elem.getAttribute||elem._no_rewrite||elem["_"+name])return changed;var value=this.wb_getAttribute.call(elem,name);if(!value||this.startsWith(value,"javascript:"))return changed;var new_value=this.performAttributeRewrite(elem,name,value,absUrlOnly);return new_value!==value&&(this.removeWBOSRC(elem),this.wb_setAttribute.call(elem,name,new_value),changed=true),changed},Wombat.prototype.noExceptRewriteStyle=function(style){try{return this.rewriteStyle(style)}catch(e){return style}},Wombat.prototype.rewriteStyle=function(style){if(!style)return style;var value=style;return typeof style==="object"&&(value=style.toString()),typeof value==="string"?value.replace(this.STYLE_REGEX,this.styleReplacer).replace(this.IMPORT_REGEX,this.styleReplacer).replace(this.no_wombatRe,""):value},Wombat.prototype.rewriteSrcset=function(value,elem){if(!value)return"";for(var split=value.split(this.srcsetRe),values=[],mod=this.rwModForElement(elem,"srcset"),i=0;i=0){var JS="javascript:";new_value="javascript:window.parent._wb_wombat.initNewWindowWombat(window);"+value.substr(11)}return new_value||(new_value=this.rewriteUrl(value,false,this.rwModForElement(elem,attrName))),new_value!==value&&(this.wb_setAttribute.call(elem,attrName,new_value),true)},Wombat.prototype.rewriteScript=function(elem){if(elem.hasAttribute("src")||!elem.textContent||!this.$wbwindow.Proxy)return this.rewriteAttr(elem,"src");if(this.skipWrapScriptBasedOnType(elem.type))return false;var text=elem.textContent.trim();return!this.skipWrapScriptTextBasedOnText(text)&&(elem.textContent=this.wrapScriptTextJsProxy(text),true)},Wombat.prototype.rewriteSVGElem=function(elem){var changed=this.rewriteAttr(elem,"filter");return changed=this.rewriteAttr(elem,"style")||changed,changed=this.rewriteAttr(elem,"xlink:href")||changed,changed=this.rewriteAttr(elem,"href")||changed,changed=this.rewriteAttr(elem,"src")||changed,changed},Wombat.prototype.rewriteElem=function(elem){var changed=false;if(!elem)return changed;if(elem instanceof SVGElement)changed=this.rewriteSVGElem(elem);else switch(elem.tagName){case"META":var maybeCSP=this.wb_getAttribute.call(elem,"http-equiv");maybeCSP&&maybeCSP.toLowerCase()==="content-security-policy"&&(this.wb_setAttribute.call(elem,"http-equiv","_"+maybeCSP),changed=true);break;case"STYLE":var new_content=this.rewriteStyle(elem.textContent);elem.textContent!==new_content&&(elem.textContent=new_content,changed=true,this.wbUseAFWorker&&this.WBAutoFetchWorker&&elem.sheet!=null&&this.WBAutoFetchWorker.deferredSheetExtraction(elem.sheet));break;case"LINK":changed=this.rewriteAttr(elem,"href"),this.wbUseAFWorker&&elem.rel==="stylesheet"&&this._addEventListener(elem,"load",this.utilFns.wbSheetMediaQChecker);break;case"IMG":changed=this.rewriteAttr(elem,"src"),changed=this.rewriteAttr(elem,"srcset")||changed,changed=this.rewriteAttr(elem,"style")||changed,this.wbUseAFWorker&&this.WBAutoFetchWorker&&elem.dataset.srcset&&this.WBAutoFetchWorker.preserveDataSrcset(elem);break;case"OBJECT":if(this.wb_info.isSW&&elem.parentElement&&elem.getAttribute("type")==="application/pdf"){for(var iframe=this.$wbwindow.document.createElement("IFRAME"),i=0;i0;)for(var child,children=rewriteQ.shift(),i=0;i"+rwString+"","text/html");if(!inner_doc||!this.nodeHasChildren(inner_doc.head)||!inner_doc.head.children[0].content)return rwString;var template=inner_doc.head.children[0];if(template._no_rewrite=true,this.recurseRewriteElem(template.content)){var new_html=template.innerHTML;if(checkEndTag){var first_elem=template.content.children&&template.content.children[0];if(first_elem){var end_tag="";this.endsWith(new_html,end_tag)&&!this.endsWith(rwString.toLowerCase(),end_tag)&&(new_html=new_html.substring(0,new_html.length-end_tag.length))}else if(rwString[0]!=="<"||rwString[rwString.length-1]!==">")return this.write_buff+=rwString,undefined}return new_html}return rwString},Wombat.prototype.rewriteHtmlFull=function(string,checkEndTag){var inner_doc=new DOMParser().parseFromString(string,"text/html");if(!inner_doc)return string;for(var changed=false,i=0;i=0)inner_doc.documentElement._no_rewrite=true,new_html=this.reconstructDocType(inner_doc.doctype)+inner_doc.documentElement.outerHTML;else{inner_doc.head._no_rewrite=true,inner_doc.body._no_rewrite=true;var headHasKids=this.nodeHasChildren(inner_doc.head),bodyHasKids=this.nodeHasChildren(inner_doc.body);if(new_html=(headHasKids?inner_doc.head.outerHTML:"")+(bodyHasKids?inner_doc.body.outerHTML:""),checkEndTag)if(inner_doc.all.length>3){var end_tag="";this.endsWith(new_html,end_tag)&&!this.endsWith(string.toLowerCase(),end_tag)&&(new_html=new_html.substring(0,new_html.length-end_tag.length))}else if(string[0]!=="<"||string[string.length-1]!==">")return void(this.write_buff+=string);new_html=this.reconstructDocType(inner_doc.doctype)+new_html}return new_html}return string},Wombat.prototype.rewriteInlineStyle=function(orig){var decoded;try{decoded=decodeURIComponent(orig)}catch(e){decoded=orig}if(decoded!==orig){var parts=this.rewriteStyle(decoded).split(",",2);return parts[0]+","+encodeURIComponent(parts[1])}return this.rewriteStyle(orig)},Wombat.prototype.rewriteCookie=function(cookie){var wombat=this,rwCookie=cookie.replace(this.wb_abs_prefix,"").replace(this.wb_rel_prefix,"");return rwCookie=rwCookie.replace(this.cookie_domain_regex,function(m,m1){var message={domain:m1,cookie:rwCookie,wb_type:"cookie"};return wombat.sendTopMessage(message,true),wombat.$wbwindow.location.hostname.indexOf(".")>=0&&!wombat.IP_RX.test(wombat.$wbwindow.location.hostname)?"Domain=."+wombat.$wbwindow.location.hostname:""}).replace(this.cookie_path_regex,function(m,m1){var rewritten=wombat.rewriteUrl(m1);return rewritten.indexOf(wombat.wb_curr_host)===0&&(rewritten=rewritten.substring(wombat.wb_curr_host.length)),"Path="+rewritten}),wombat.$wbwindow.location.protocol!=="https:"&&(rwCookie=rwCookie.replace("secure","")),rwCookie.replace(",|",",")},Wombat.prototype.rewriteWorker=function(workerUrl){if(!workerUrl)return workerUrl;var isBlob=workerUrl.indexOf("blob:")===0,isJS=workerUrl.indexOf("javascript:")===0;if(!isBlob&&!isJS){if(!this.startsWithOneOf(workerUrl,this.VALID_PREFIXES)&&!this.startsWith(workerUrl,"/")&&!this.startsWithOneOf(workerUrl,this.BAD_PREFIXES)){var rurl=this.resolveRelUrl(workerUrl,this.$wbwindow.document);return this.rewriteUrl(rurl,false,"wkr_",this.$wbwindow.document)}return this.rewriteUrl(workerUrl,false,"wkr_",this.$wbwindow.document)}var workerCode=isJS?workerUrl.replace("javascript:",""):null;if(isBlob){var x=new XMLHttpRequest;this.utilFns.XHRopen.call(x,"GET",workerUrl,false),this.utilFns.XHRsend.call(x),workerCode=x.responseText.replace(this.workerBlobRe,"").replace(this.rmCheckThisInjectRe,"this")}if(this.wb_info.static_prefix||this.wb_info.ww_rw_script){var originalURL=this.$wbwindow.document.baseURI,ww_rw=this.wb_info.ww_rw_script||this.wb_info.static_prefix+"wombatWorkers.js",rw="(function() { self.importScripts('"+ww_rw+"'); new WBWombat({'prefix': '"+this.wb_abs_prefix+"', 'prefixMod': '"+this.wb_abs_prefix+"wkrf_/', 'originalURL': '"+originalURL+"'}); })();";workerCode=rw+workerCode}var blob=new Blob([workerCode],{type:"application/javascript"});return URL.createObjectURL(blob)},Wombat.prototype.rewriteTextNodeFn=function(fnThis,originalFn,argsObj){var args,deproxiedThis=this.proxyToObj(fnThis);if(argsObj.length>0&&deproxiedThis.parentElement&&deproxiedThis.parentElement.tagName==="STYLE"){args=new Array(argsObj.length);var dataIndex=argsObj.length-1;dataIndex===2?(args[0]=argsObj[0],args[1]=argsObj[1]):dataIndex===1&&(args[0]=argsObj[0]),args[dataIndex]=this.rewriteStyle(argsObj[dataIndex])}else args=argsObj;return originalFn.__WB_orig_apply?originalFn.__WB_orig_apply(deproxiedThis,args):originalFn.apply(deproxiedThis,args)},Wombat.prototype.rewriteDocWriteWriteln=function(fnThis,originalFn,argsObj){var string,thisObj=this.proxyToObj(fnThis),argLen=argsObj.length;if(argLen===0)return originalFn.call(thisObj);string=argLen===1?argsObj[0]:Array.prototype.join.call(argsObj,"");var new_buff=this.rewriteHtml(string,true),res=originalFn.call(thisObj,new_buff);return this.initNewWindowWombat(thisObj.defaultView),res},Wombat.prototype.rewriteChildNodeFn=function(fnThis,originalFn,argsObj){var thisObj=this.proxyToObj(fnThis);if(argsObj.length===0)return originalFn.call(thisObj);var newArgs=this.rewriteElementsInArguments(argsObj);return originalFn.__WB_orig_apply?originalFn.__WB_orig_apply(thisObj,newArgs):originalFn.apply(thisObj,newArgs)},Wombat.prototype.rewriteInsertAdjHTMLOrElemArgs=function(fnThis,originalFn,position,textOrElem,rwHTML){var fnThisObj=this.proxyToObj(fnThis);return fnThisObj._no_rewrite?originalFn.call(fnThisObj,position,textOrElem):rwHTML?originalFn.call(fnThisObj,position,this.rewriteHtml(textOrElem)):(this.rewriteElemComplete(textOrElem),originalFn.call(fnThisObj,position,textOrElem))},Wombat.prototype.rewriteSetTimeoutInterval=function(fnThis,originalFn,argsObj){var rw=this.isString(argsObj[0]),args=rw?new Array(argsObj.length):argsObj;if(rw){args[0]=this.$wbwindow.Proxy?this.wrapScriptTextJsProxy(argsObj[0]):argsObj[0].replace(/\blocation\b/g,"WB_wombat_$&");for(var i=1;i0&&cssStyleValueOverride(this.$wbwindow.CSSStyleValue,"parse"),this.$wbwindow.CSSStyleValue.parseAll&&this.$wbwindow.CSSStyleValue.parseAll.toString().indexOf("[native code]")>0&&cssStyleValueOverride(this.$wbwindow.CSSStyleValue,"parseAll")}if(this.$wbwindow.CSSKeywordValue&&this.$wbwindow.CSSKeywordValue.prototype){var oCSSKV=this.$wbwindow.CSSKeywordValue;this.$wbwindow.CSSKeywordValue=function(CSSKeywordValue_){return function CSSKeywordValue(cssValue){return wombat.domConstructorErrorChecker(this,"CSSKeywordValue",arguments),new CSSKeywordValue_(wombat.rewriteStyle(cssValue))}}(this.$wbwindow.CSSKeywordValue),this.$wbwindow.CSSKeywordValue.prototype=oCSSKV.prototype,Object.defineProperty(this.$wbwindow.CSSKeywordValue.prototype,"constructor",{value:this.$wbwindow.CSSKeywordValue}),addToStringTagToClass(this.$wbwindow.CSSKeywordValue,"CSSKeywordValue")}if(this.$wbwindow.StylePropertyMap&&this.$wbwindow.StylePropertyMap.prototype){var originalSet=this.$wbwindow.StylePropertyMap.prototype.set;this.$wbwindow.StylePropertyMap.prototype.set=function set(){if(arguments.length<=1)return originalSet.__WB_orig_apply?originalSet.__WB_orig_apply(this,arguments):originalSet.apply(this,arguments);var newArgs=new Array(arguments.length);newArgs[0]=arguments[0];for(var i=1;i")&&(array[0]=wombat.rewriteHtml(array[0]),options.type="text/html"),new Blob_(array,options)}}(this.$wbwindow.Blob),this.$wbwindow.Blob.prototype=orig_blob.prototype}},Wombat.prototype.initDocTitleOverride=function(){var orig_get_title=this.getOrigGetter(this.$wbwindow.document,"title"),orig_set_title=this.getOrigSetter(this.$wbwindow.document,"title"),wombat=this,set_title=function title(value){var res=orig_set_title.call(this,value),message={wb_type:"title",title:value};return wombat.sendTopMessage(message),res};this.defProp(this.$wbwindow.document,"title",set_title,orig_get_title)},Wombat.prototype.initFontFaceOverride=function(){if(this.$wbwindow.FontFace){var wombat=this,origFontFace=this.$wbwindow.FontFace;this.$wbwindow.FontFace=function(FontFace_){return function FontFace(family,source,descriptors){wombat.domConstructorErrorChecker(this,"FontFace",arguments,2);var rwSource=source;return source!=null&&(typeof source==="string"?rwSource=wombat.rewriteInlineStyle(source):rwSource=wombat.rewriteInlineStyle(source.toString())),new FontFace_(family,rwSource,descriptors)}}(this.$wbwindow.FontFace),this.$wbwindow.FontFace.prototype=origFontFace.prototype,Object.defineProperty(this.$wbwindow.FontFace.prototype,"constructor",{value:this.$wbwindow.FontFace}),addToStringTagToClass(this.$wbwindow.FontFace,"FontFace")}},Wombat.prototype.initFixedRatio=function(){try{this.$wbwindow.devicePixelRatio=1}catch(e){}if(Object.defineProperty)try{Object.defineProperty(this.$wbwindow,"devicePixelRatio",{value:1,writable:false})}catch(e){}},Wombat.prototype.initPaths=function(wbinfo){wbinfo.wombat_opts=wbinfo.wombat_opts||{},Object.assign(this.wb_info,wbinfo),this.wb_opts=wbinfo.wombat_opts,this.wb_replay_prefix=wbinfo.prefix,this.wb_is_proxy=wbinfo.proxy_magic||!this.wb_replay_prefix,this.wb_info.top_host=this.wb_info.top_host||"*",this.wb_curr_host=this.$wbwindow.location.protocol+"//"+this.$wbwindow.location.host,this.wb_info.wombat_opts=this.wb_info.wombat_opts||{},this.wb_orig_scheme=wbinfo.wombat_scheme+"://",this.wb_orig_origin=this.wb_orig_scheme+wbinfo.wombat_host,this.wb_abs_prefix=this.wb_replay_prefix,this.wb_capture_date_part=!wbinfo.is_live&&wbinfo.wombat_ts?"/"+wbinfo.wombat_ts+"/":"",this.initBadPrefixes(this.wb_replay_prefix),this.initCookiePreset()},Wombat.prototype.initSeededRandom=function(seed){this.$wbwindow.Math.seed=parseInt(seed);var wombat=this;this.$wbwindow.Math.random=function random(){return wombat.$wbwindow.Math.seed=(wombat.$wbwindow.Math.seed*9301+49297)%233280,wombat.$wbwindow.Math.seed/233280}},Wombat.prototype.initHistoryOverrides=function(){this.overrideHistoryFunc("pushState"),this.overrideHistoryFunc("replaceState");var wombat=this;this.$wbwindow.addEventListener("popstate",function(event){wombat.sendHistoryUpdate(wombat.$wbwindow.WB_wombat_location.href,wombat.$wbwindow.document.title)})},Wombat.prototype.initCookiePreset=function(){if(this.wb_info.presetCookie)for(var splitCookies=this.wb_info.presetCookie.split(";"),i=0;i0?"&":"?")+value.toString(),value=null):contentType==="application/json"||contentType==="text/plain"?(this.__WB_xhr_open_arguments[0]="GET",this.__WB_xhr_open_arguments[1]+=(this.__WB_xhr_open_arguments[1].indexOf("?")>0?"&":"?")+jsonToQueryString(value),value=null):wombat.startsWith(contentType,"multipart/form-data")&&(this.__WB_xhr_open_arguments[0]="GET",this.__WB_xhr_open_arguments[1]+=(this.__WB_xhr_open_arguments[1].indexOf("?")>0?"&":"?")+mfdToQueryString(value,contentType))}if(this.__WB_xhr_open_arguments.length>2&&(this.__WB_xhr_open_arguments[2]=true),this._no_rewrite||(this.__WB_xhr_open_arguments[1]=wombat.rewriteUrl(this.__WB_xhr_open_arguments[1])),origOpen.apply(this,this.__WB_xhr_open_arguments),!wombat.startsWith(this.__WB_xhr_open_arguments[1],"data:")){for(const[name,value]of this.__WB_xhr_headers.entries())origSetRequestHeader.call(this,name,value);origSetRequestHeader.call(this,"X-Pywb-Requested-With","XMLHttpRequest")}origSend.call(this,value)}}if(this.$wbwindow.fetch){var orig_fetch=this.$wbwindow.fetch;this.$wbwindow.fetch=function fetch(input,init_opts){var rwInput=input,inputType=typeof input;if(inputType==="string")rwInput=wombat.rewriteUrl(input);else if(inputType==="object"&&input.url){var new_url=wombat.rewriteUrl(input.url);new_url!==input.url&&(rwInput=new Request(new_url,init_opts))}else inputType==="object"&&input.href&&(rwInput=wombat.rewriteUrl(input.href));if(init_opts||(init_opts={}),init_opts.credentials===undefined)try{init_opts.credentials="include"}catch(e){}return orig_fetch.call(wombat.proxyToObj(this),rwInput,init_opts)}}if(this.$wbwindow.Request&&this.$wbwindow.Request.prototype){var orig_request=this.$wbwindow.Request;this.$wbwindow.Request=function(Request_){return function Request(input,init_opts){wombat.domConstructorErrorChecker(this,"Request",arguments);var newInitOpts=init_opts||{},newInput=input,inputType=typeof input;switch(inputType){case"string":newInput=wombat.rewriteUrl(input);break;case"object":if(newInput=input,input.url){var new_url=wombat.rewriteUrl(input.url);new_url!==input.url&&(newInput=new Request_(new_url,input))}else input.href&&(newInput=wombat.rewriteUrl(input.toString(),true));}return newInitOpts.credentials="include",new Request_(newInput,newInitOpts)}}(this.$wbwindow.Request),this.$wbwindow.Request.prototype=orig_request.prototype,Object.defineProperty(this.$wbwindow.Request.prototype,"constructor",{value:this.$wbwindow.Request})}if(this.$wbwindow.Response&&this.$wbwindow.Response.prototype){var originalRedirect=this.$wbwindow.Response.prototype.redirect;this.$wbwindow.Response.prototype.redirect=function redirect(url,status){var rwURL=wombat.rewriteUrl(url,true,null,wombat.$wbwindow.document);return originalRedirect.call(this,rwURL,status)}}if(this.$wbwindow.EventSource&&this.$wbwindow.EventSource.prototype){var origEventSource=this.$wbwindow.EventSource;this.$wbwindow.EventSource=function(EventSource_){return function EventSource(url,configuration){wombat.domConstructorErrorChecker(this,"EventSource",arguments);var rwURL=url;return url!=null&&(rwURL=wombat.rewriteUrl(url)),new EventSource_(rwURL,configuration)}}(this.$wbwindow.EventSource),this.$wbwindow.EventSource.prototype=origEventSource.prototype,Object.defineProperty(this.$wbwindow.EventSource.prototype,"constructor",{value:this.$wbwindow.EventSource}),addToStringTagToClass(this.$wbwindow.EventSource,"EventSource")}if(this.$wbwindow.WebSocket&&this.$wbwindow.WebSocket.prototype){var origWebSocket=this.$wbwindow.WebSocket;this.$wbwindow.WebSocket=function(WebSocket_){return function WebSocket(url,configuration){wombat.domConstructorErrorChecker(this,"WebSocket",arguments);var rwURL=url;return url!=null&&(rwURL=wombat.rewriteWSURL(url)),new WebSocket_(rwURL,configuration)}}(this.$wbwindow.WebSocket),this.$wbwindow.WebSocket.prototype=origWebSocket.prototype,Object.defineProperty(this.$wbwindow.WebSocket.prototype,"constructor",{value:this.$wbwindow.WebSocket}),addToStringTagToClass(this.$wbwindow.WebSocket,"WebSocket")}},Wombat.prototype.initElementGetSetAttributeOverride=function(){if(!this.wb_opts.skip_setAttribute&&this.$wbwindow.Element&&this.$wbwindow.Element.prototype){var wombat=this,ElementProto=this.$wbwindow.Element.prototype;if(ElementProto.setAttribute){var orig_setAttribute=ElementProto.setAttribute;ElementProto._orig_setAttribute=orig_setAttribute,ElementProto.setAttribute=function setAttribute(name,value){var rwValue=value;if(name&&typeof rwValue==="string"){var lowername=name.toLowerCase();if(this.tagName==="LINK"&&lowername==="href"&&rwValue.indexOf("data:text/css")===0)rwValue=wombat.rewriteInlineStyle(value);else if(lowername==="style")rwValue=wombat.rewriteStyle(value);else if(lowername==="srcset")rwValue=wombat.rewriteSrcset(value,this);else{var shouldRW=wombat.shouldRewriteAttr(this.tagName,lowername);shouldRW&&(wombat.removeWBOSRC(this),!this._no_rewrite&&(rwValue=wombat.rewriteUrl(value,false,wombat.rwModForElement(this,lowername))))}}return orig_setAttribute.call(this,name,rwValue)}}if(ElementProto.getAttribute){var orig_getAttribute=ElementProto.getAttribute;this.wb_getAttribute=orig_getAttribute,ElementProto.getAttribute=function getAttribute(name){var result=orig_getAttribute.call(this,name);if(result===null)return result;var lowerName=name;if(name&&(lowerName=name.toLowerCase()),wombat.shouldRewriteAttr(this.tagName,lowerName)){var maybeWBOSRC=wombat.retrieveWBOSRC(this);return maybeWBOSRC?maybeWBOSRC:wombat.extractOriginalURL(result)}return wombat.startsWith(lowerName,"data-")&&wombat.startsWithOneOf(result,wombat.wb_prefixes)?wombat.extractOriginalURL(result):result}}}},Wombat.prototype.initSvgImageOverrides=function(){if(this.$wbwindow.SVGImageElement){var svgImgProto=this.$wbwindow.SVGImageElement.prototype,orig_getAttr=svgImgProto.getAttribute,orig_getAttrNS=svgImgProto.getAttributeNS,orig_setAttr=svgImgProto.setAttribute,orig_setAttrNS=svgImgProto.setAttributeNS,wombat=this;svgImgProto.getAttribute=function getAttribute(name){var value=orig_getAttr.call(this,name);return name.indexOf("xlink:href")>=0||name==="href"?wombat.extractOriginalURL(value):value},svgImgProto.getAttributeNS=function getAttributeNS(ns,name){var value=orig_getAttrNS.call(this,ns,name);return name.indexOf("xlink:href")>=0||name==="href"?wombat.extractOriginalURL(value):value},svgImgProto.setAttribute=function setAttribute(name,value){var rwValue=value;return(name.indexOf("xlink:href")>=0||name==="href")&&(rwValue=wombat.rewriteUrl(value)),orig_setAttr.call(this,name,rwValue)},svgImgProto.setAttributeNS=function setAttributeNS(ns,name,value){var rwValue=value;return(name.indexOf("xlink:href")>=0||name==="href")&&(rwValue=wombat.rewriteUrl(value)),orig_setAttrNS.call(this,ns,name,rwValue)}}},Wombat.prototype.initCreateElementNSFix=function(){if(this.$wbwindow.document.createElementNS&&this.$wbwindow.Document.prototype.createElementNS){var orig_createElementNS=this.$wbwindow.document.createElementNS,wombat=this,createElementNS=function createElementNS(namespaceURI,qualifiedName){return orig_createElementNS.call(wombat.proxyToObj(this),wombat.extractOriginalURL(namespaceURI),qualifiedName)};this.$wbwindow.Document.prototype.createElementNS=createElementNS,this.$wbwindow.document.createElementNS=createElementNS}},Wombat.prototype.initInsertAdjacentElementHTMLOverrides=function(){var Element=this.$wbwindow.Element;if(Element&&Element.prototype){var elementProto=Element.prototype,rewriteFn=this.rewriteInsertAdjHTMLOrElemArgs;if(elementProto.insertAdjacentHTML){var origInsertAdjacentHTML=elementProto.insertAdjacentHTML;elementProto.insertAdjacentHTML=function insertAdjacentHTML(position,text){return rewriteFn(this,origInsertAdjacentHTML,position,text,true)}}if(elementProto.insertAdjacentElement){var origIAdjElem=elementProto.insertAdjacentElement;elementProto.insertAdjacentElement=function insertAdjacentElement(position,element){return rewriteFn(this,origIAdjElem,position,element,false)}}}},Wombat.prototype.initDomOverride=function(){var Node=this.$wbwindow.Node;if(Node&&Node.prototype){var rewriteFn=this.rewriteNodeFuncArgs;if(Node.prototype.appendChild){var originalAppendChild=Node.prototype.appendChild;Node.prototype.appendChild=function appendChild(newNode,oldNode){return rewriteFn(this,originalAppendChild,newNode,oldNode)}}if(Node.prototype.insertBefore){var originalInsertBefore=Node.prototype.insertBefore;Node.prototype.insertBefore=function insertBefore(newNode,oldNode){return rewriteFn(this,originalInsertBefore,newNode,oldNode)}}if(Node.prototype.replaceChild){var originalReplaceChild=Node.prototype.replaceChild;Node.prototype.replaceChild=function replaceChild(newNode,oldNode){return rewriteFn(this,originalReplaceChild,newNode,oldNode)}}this.overridePropToProxy(Node.prototype,"ownerDocument"),this.overridePropToProxy(this.$wbwindow.HTMLHtmlElement.prototype,"parentNode"),this.overridePropToProxy(this.$wbwindow.Event.prototype,"target")}this.$wbwindow.Element&&this.$wbwindow.Element.prototype&&(this.overrideParentNodeAppendPrepend(this.$wbwindow.Element),this.overrideChildNodeInterface(this.$wbwindow.Element,false)),this.$wbwindow.DocumentFragment&&this.$wbwindow.DocumentFragment.prototype&&this.overrideParentNodeAppendPrepend(this.$wbwindow.DocumentFragment)},Wombat.prototype.initDocOverrides=function($document){if(Object.defineProperty){this.overrideReferrer($document),this.defGetterProp($document,"origin",function origin(){return this.WB_wombat_location.origin}),this.defGetterProp(this.$wbwindow,"origin",function origin(){return this.WB_wombat_location.origin});var wombat=this,domain_setter=function domain(val){var loc=this.WB_wombat_location;loc&&wombat.endsWith(loc.hostname,val)&&(this.__wb_domain=val)},domain_getter=function domain(){return this.__wb_domain||this.WB_wombat_location.hostname};this.defProp($document,"domain",domain_setter,domain_getter)}},Wombat.prototype.initDocWriteOpenCloseOverride=function(){if(this.$wbwindow.DOMParser){var DocumentProto=this.$wbwindow.Document.prototype,$wbDocument=this.$wbwindow.document,docWriteWritelnRWFn=this.rewriteDocWriteWriteln,orig_doc_write=$wbDocument.write,new_write=function write(){return docWriteWritelnRWFn(this,orig_doc_write,arguments)};$wbDocument.write=new_write,DocumentProto.write=new_write;var orig_doc_writeln=$wbDocument.writeln,new_writeln=function writeln(){return docWriteWritelnRWFn(this,orig_doc_writeln,arguments)};$wbDocument.writeln=new_writeln,DocumentProto.writeln=new_writeln;var wombat=this,orig_doc_open=$wbDocument.open,new_open=function open(){var res,thisObj=wombat.proxyToObj(this);if(arguments.length===3){var rwUrl=wombat.rewriteUrl(arguments[0],false,"mp_");res=orig_doc_open.call(thisObj,rwUrl,arguments[1],arguments[2]),wombat.initNewWindowWombat(res,arguments[0])}else res=orig_doc_open.call(thisObj),wombat.initNewWindowWombat(thisObj.defaultView);return res};$wbDocument.open=new_open,DocumentProto.open=new_open;var originalClose=$wbDocument.close,newClose=function close(){var thisObj=wombat.proxyToObj(this);return wombat.initNewWindowWombat(thisObj.defaultView),originalClose.__WB_orig_apply?originalClose.__WB_orig_apply(thisObj,arguments):originalClose.apply(thisObj,arguments)};$wbDocument.close=newClose,DocumentProto.close=newClose;var oBodyGetter=this.getOrigGetter(DocumentProto,"body"),oBodySetter=this.getOrigSetter(DocumentProto,"body");oBodyGetter&&oBodySetter&&this.defProp(DocumentProto,"body",function body(newBody){return newBody&&(newBody instanceof HTMLBodyElement||newBody instanceof HTMLFrameSetElement)&&wombat.rewriteElemComplete(newBody),oBodySetter.call(wombat.proxyToObj(this),newBody)},oBodyGetter)}},Wombat.prototype.initIframeWombat=function(iframe){var win;win=iframe._get_contentWindow?iframe._get_contentWindow.call(iframe):iframe.contentWindow;try{if(!win||win===this.$wbwindow||win._skip_wombat||win._wb_wombat)return}catch(e){return}var src=iframe.src;this.initNewWindowWombat(win,src)},Wombat.prototype.initNewWindowWombat=function(win,src){var fullWombat=false;if(win&&!win._wb_wombat){if((!src||src===""||this.startsWithOneOf(src,["about:blank","javascript:"]))&&(fullWombat=true),!fullWombat&&this.wb_info.isSW){var origURL=this.extractOriginalURL(src);(origURL==="about:blank"||origURL.startsWith("srcdoc:")||origURL.startsWith("blob:"))&&(fullWombat=true)}if(fullWombat){var newInfo={};Object.assign(newInfo,this.wb_info);var wombat=new Wombat(win,newInfo);win._wb_wombat=wombat.wombatInit()}else this.initProtoPmOrigin(win),this.initPostMessageOverride(win),this.initMessageEventOverride(win),this.initCheckThisFunc(win)}},Wombat.prototype.initTimeoutIntervalOverrides=function(){var rewriteFn=this.rewriteSetTimeoutInterval;if(this.$wbwindow.setTimeout&&!this.$wbwindow.setTimeout.__$wbpatched$__){var originalSetTimeout=this.$wbwindow.setTimeout;this.$wbwindow.setTimeout=function setTimeout(){return rewriteFn(this,originalSetTimeout,arguments)},this.$wbwindow.setTimeout.__$wbpatched$__=true}if(this.$wbwindow.setInterval&&!this.$wbwindow.setInterval.__$wbpatched$__){var originalSetInterval=this.$wbwindow.setInterval;this.$wbwindow.setInterval=function setInterval(){return rewriteFn(this,originalSetInterval,arguments)},this.$wbwindow.setInterval.__$wbpatched$__=true}},Wombat.prototype.initWorkerOverrides=function(){var wombat=this;if(this.$wbwindow.Worker&&!this.$wbwindow.Worker._wb_worker_overriden){var orig_worker=this.$wbwindow.Worker;this.$wbwindow.Worker=function(Worker_){return function Worker(url,options){return wombat.domConstructorErrorChecker(this,"Worker",arguments),new Worker_(wombat.rewriteWorker(url),options)}}(orig_worker),this.$wbwindow.Worker.prototype=orig_worker.prototype,Object.defineProperty(this.$wbwindow.Worker.prototype,"constructor",{value:this.$wbwindow.Worker}),this.$wbwindow.Worker._wb_worker_overriden=true}if(this.$wbwindow.SharedWorker&&!this.$wbwindow.SharedWorker.__wb_sharedWorker_overriden){var oSharedWorker=this.$wbwindow.SharedWorker;this.$wbwindow.SharedWorker=function(SharedWorker_){return function SharedWorker(url,options){return wombat.domConstructorErrorChecker(this,"SharedWorker",arguments),new SharedWorker_(wombat.rewriteWorker(url),options)}}(oSharedWorker),this.$wbwindow.SharedWorker.prototype=oSharedWorker.prototype,Object.defineProperty(this.$wbwindow.SharedWorker.prototype,"constructor",{value:this.$wbwindow.SharedWorker}),this.$wbwindow.SharedWorker.__wb_sharedWorker_overriden=true}if(this.$wbwindow.ServiceWorkerContainer&&this.$wbwindow.ServiceWorkerContainer.prototype&&this.$wbwindow.ServiceWorkerContainer.prototype.register){var orig_register=this.$wbwindow.ServiceWorkerContainer.prototype.register;this.$wbwindow.ServiceWorkerContainer.prototype.register=function register(scriptURL,options){var newScriptURL=new URL(scriptURL,wombat.$wbwindow.document.baseURI).href,mod=wombat.getPageUnderModifier();return options&&options.scope?options.scope=wombat.rewriteUrl(options.scope,false,mod):options={scope:wombat.rewriteUrl("/",false,mod)},orig_register.call(this,wombat.rewriteUrl(newScriptURL,false,"sw_"),options)}}if(this.$wbwindow.Worklet&&this.$wbwindow.Worklet.prototype&&this.$wbwindow.Worklet.prototype.addModule&&!this.$wbwindow.Worklet.__wb_workerlet_overriden){var oAddModule=this.$wbwindow.Worklet.prototype.addModule;this.$wbwindow.Worklet.prototype.addModule=function addModule(moduleURL,options){var rwModuleURL=wombat.rewriteUrl(moduleURL,false,"js_");return oAddModule.call(this,rwModuleURL,options)},this.$wbwindow.Worklet.__wb_workerlet_overriden=true}},Wombat.prototype.initLocOverride=function(loc,oSetter,oGetter){if(Object.defineProperty)for(var prop,i=0;i=0&&props.splice(foundInx,1);return props}})}catch(e){console.log(e)}},Wombat.prototype.initHashChange=function(){if(this.$wbwindow.__WB_top_frame){var wombat=this,receive_hash_change=function receive_hash_change(event){if(event.data&&event.data.from_top){var message=event.data.message;message.wb_type&&(message.wb_type!=="outer_hashchange"||wombat.$wbwindow.location.hash==message.hash||(wombat.$wbwindow.location.hash=message.hash))}},send_hash_change=function send_hash_change(){var message={wb_type:"hashchange",hash:wombat.$wbwindow.location.hash};wombat.sendTopMessage(message)};this.$wbwindow.addEventListener("message",receive_hash_change),this.$wbwindow.addEventListener("hashchange",send_hash_change)}},Wombat.prototype.initPostMessageOverride=function($wbwindow){if($wbwindow.postMessage&&!$wbwindow.__orig_postMessage){var orig=$wbwindow.postMessage,wombat=this;$wbwindow.__orig_postMessage=orig;var postmessage_rewritten=function postMessage(message,targetOrigin,transfer,from_top){var from,src_id,this_obj=wombat.proxyToObj(this);if(this_obj.__WB_source&&this_obj.__WB_source.WB_wombat_location){var source=this_obj.__WB_source;if(from=source.WB_wombat_location.origin,this_obj.__WB_win_id||(this_obj.__WB_win_id={},this_obj.__WB_counter=0),!source.__WB_id){var id=this_obj.__WB_counter;source.__WB_id=id+source.WB_wombat_location.href,this_obj.__WB_counter+=1}this_obj.__WB_win_id[source.__WB_id]=source,src_id=source.__WB_id,this_obj.__WB_source=undefined}else from=window.WB_wombat_location.origin;var to_origin=targetOrigin;to_origin===this_obj.location.origin&&(to_origin=from);var new_message={from:from,to_origin:to_origin,src_id:src_id,message:message,from_top:from_top};if(targetOrigin!=="*"){if(this_obj.location.origin==="null"||this_obj.location.origin==="")return;targetOrigin=this_obj.location.origin}return orig.call(this_obj,new_message,targetOrigin,transfer)};$wbwindow.postMessage=postmessage_rewritten,$wbwindow.Window.prototype.postMessage=postmessage_rewritten;var eventTarget=null;eventTarget=$wbwindow.EventTarget&&$wbwindow.EventTarget.prototype?$wbwindow.EventTarget.prototype:$wbwindow;var _oAddEventListener=eventTarget.addEventListener;eventTarget.addEventListener=function addEventListener(type,listener,useCapture){var rwListener,obj=wombat.proxyToObj(this);if(type==="message"?rwListener=wombat.message_listeners.add_or_get(listener,function(){return wrapEventListener(listener,obj,wombat)}):type==="storage"?wombat.storage_listeners.add_or_get(listener,function(){return wrapSameOriginEventListener(listener,obj)}):rwListener=listener,rwListener)return _oAddEventListener.call(obj,type,rwListener,useCapture)};var _oRemoveEventListener=eventTarget.removeEventListener;eventTarget.removeEventListener=function removeEventListener(type,listener,useCapture){var rwListener,obj=wombat.proxyToObj(this);if(type==="message"?rwListener=wombat.message_listeners.remove(listener):type==="storage"?wombat.storage_listeners.remove(listener):rwListener=listener,rwListener)return _oRemoveEventListener.call(obj,type,rwListener,useCapture)};var override_on_prop=function(onevent,wrapperFN){var orig_setter=wombat.getOrigSetter($wbwindow,onevent),setter=function(value){this["__orig_"+onevent]=value;var obj=wombat.proxyToObj(this),listener=value?wrapperFN(value,obj,wombat):value;return orig_setter.call(obj,listener)},getter=function(){return this["__orig_"+onevent]};wombat.defProp($wbwindow,onevent,setter,getter)};override_on_prop("onmessage",wrapEventListener),override_on_prop("onstorage",wrapSameOriginEventListener)}},Wombat.prototype.initMessageEventOverride=function($wbwindow){!$wbwindow.MessageEvent||$wbwindow.MessageEvent.prototype.__extended||(this.addEventOverride("target"),this.addEventOverride("srcElement"),this.addEventOverride("currentTarget"),this.addEventOverride("eventPhase"),this.addEventOverride("path"),this.overridePropToProxy($wbwindow.MessageEvent.prototype,"source"),$wbwindow.MessageEvent.prototype.__extended=true)},Wombat.prototype.initUIEventsOverrides=function(){this.overrideAnUIEvent("UIEvent"),this.overrideAnUIEvent("MouseEvent"),this.overrideAnUIEvent("TouchEvent"),this.overrideAnUIEvent("FocusEvent"),this.overrideAnUIEvent("KeyboardEvent"),this.overrideAnUIEvent("WheelEvent"),this.overrideAnUIEvent("InputEvent"),this.overrideAnUIEvent("CompositionEvent")},Wombat.prototype.initOpenOverride=function(){var orig=this.$wbwindow.open;this.$wbwindow.Window.prototype.open&&(orig=this.$wbwindow.Window.prototype.open);var wombat=this,open_rewritten=function open(strUrl,strWindowName,strWindowFeatures){var rwStrUrl=wombat.rewriteUrl(strUrl,false,""),res=orig.call(wombat.proxyToObj(this),rwStrUrl,strWindowName,strWindowFeatures);return wombat.initNewWindowWombat(res,strUrl),res};this.$wbwindow.open=open_rewritten,this.$wbwindow.Window.prototype.open&&(this.$wbwindow.Window.prototype.open=open_rewritten);for(var i=0;i + + + + + + + + + + +Chapter 1.2: Drawing Graphics + + + + + +
+
The Wayback Machine - +http://web.archive.org/web/20220827033534/http://lameguy64.net/tutorials/pstutorials/chapter1/2-graphics.html
+ + + +

1.2. Drawing Graphics

+

This tutorial will teach you how to draw graphics primitives with the GPU +using an ordering table and primitive packets. This is a very essential part +to learn about the PS1 as you need graphics to do anything on the console +really.

+

Just like in the last tutorial, libgs will not be covered here. Also, the +GPU is not responsible for 3D graphics. While it does render out (affine) +polygon all the 3D processing is actually done in a co-processor, called +the GTE or Geometry Transformation Engine.

+

Trivia: The easiest way to tell if a person is not a PS1 programmer +is if they call the GTE the Geometry Transfer Engine instead of +Transformation Engine. The GTE does NOT transfer anything, it is +essentially like a math co-processor on the CPU as nothing but the CPU has +access to it, and it does nothing else but vector transformations that helps +greatly in 3D graphics processing.

+

Tutorial compatible with PSn00bSDK:Yes

+ +

Tutorial Index

+ + +

Theory of Operation

+

The PS1 GPU draws graphics by means of primitive packets, which are +essentially messages that command the GPU to draw a specified primitive +in a specified color to specified screen coordinates to name a few.

+

Drawing packets are normally sent to the GPU by an ordering table, +which is essentially an array of pointers that form a chain. Primitive +packets are normally linked to the ordering table to draw them.

+ +

Ordering Tables

+

An ordering table is an array of elements of pointers that point from +one element to another, the ordering table usually ends with an array element +with the value of 0xFFFFFFFF which is used as a terminator value for ordering +table processing. An ordering table is normally created using ClearOTagR() +on an array of 32-bit ints.

+

The following figure visually describes the general structure of an ordering table.

+ +

Adding primitives to an ordering table is normally achieved using +addPrim()/AddPrim() functions. DrawOTag() is used to begin +processing of an ordering table.

+

The type of ordering table shown above is called a reverse ordering table +because the chain starts at the end of the array and ends at the beginning of +the array. This type of ordering table is most commonly used as the reverse +order allows for depth ordering of polygons which is essential for 3D graphics. +Use ClearOTag() if you wish to use a non-reverse ordering table but the +initialization speed won't be as fast as ClearOTagR() for larger tables +as ClearOTagR() is DMA accelerated, but it can only generate reverse +ordering tables.

+

For simplicity, a global ordering table array of 8 elements should suffice +for this tutorial.

+
int ot[2][8];
+
+

The reason two arrays of ot are defined is for double buffered +rendering reasons, which will be explained later in this tutorial.

+ +

Primitive Packets

+

Primitive packets are more or less commands that instruct the GPU to draw +a specified primitive to specified coordinates of the drawing area carried by +the packet. Primitive packets are always aligned 4-byte aligned.

+

The following illustrates the typical structure of a primitive packet +(the packet represents a SPRT primitive):

+ +

C implementation of the above structure

+
typedef struct {
+    unsigned int  tag;             // First 24 bits are address, last 8 bits are length
+    unsigned char  r0,g0,b0,code;  // RGB color and primitive code
+    short          x0,y0;          // X,Y coordinates of sprite
+    unsigned char  u0,v0;          // U,V texture coordinates of sprite
+    unsigned short clut;           // Texture CLUT
+    unsigned short w,h;            // Sprite width and height
+} SPRT;
+
+

The number of parameter words of a primitive packet varies on the primitive +command. Simpler commands such as a fixed sized, solid color sprite is only 3 +words long whereas a shaded, textured 4-point polygon is 13 words long, the +length of the primitive in words is specified to the Len field minus the +tag word. The Next Pointer field is an address to the next primitive or +return pointer to an ordering table it was sorted to.

+

A word in this context is a 4 byte integer.

+

Primitives are normally defined using primitive structures and macros +defined in libgpu.h, or psxgpu.h in PSn00bSDK.

+ +

Preparing a Primitive

+

Primitive packets are normally prepared using primitive structures and +macros. A solid color rectangular sprite (TILE) will be used for this +tutorial.

+

Primitive preparation is as follows.

+
TILE tile;                      // Primitive structure
+
+setTile(&tile;);                 // Initialize the primitive (very important)
+setXY0(&tile;, 32, 32);          // Set primitive (x,y) position
+setWH(&tile;, 64, 64);           // Set primitive size
+setRGB0(&tile;, 255, 255, 0);    // Set color yellow
+
+

The setTile() macro simply fills in the appropriate values to the tag +length and primitive code fields to the specified primitive. These values are +mandatory and must be correct, otherwise the GPU will lock up. Always use the +appropriate initializer macro for a primitive.

+

The setXY0(), setWH() and setRGB0() macros sets the +(x,y) coordinates, size and color of the primitive respectively. While the +fields of a primitive can be set directly via struct elements of the +primitive, using macros helps make the code looking tidy.

+

Normally, primitive packets are defined to a primitive buffer.

+ +

Primitive Buffers

+

A primitive buffer is simply a global array of char elements used as a +buffer to define primitive packets to. It is also a lot less wasteful than +defining multiple arrays for different primitive types as all primitive types +can be defined in just a single global buffer.

+

The reason it is recommended that primitive packets must be defined in a +global buffer is because the primitives must exist in memory until the GPU +gets around to processing it. If you were to define primitives as a local +variable in a function and register it to an ordering table, that primitive +has most likely been overwritten by other things (since locals are generally +temporary variables), resulting in a corrupted ordering table which would +result to a GPU lock up or crash.

+

A primitive buffer can be defined as such, 32KB buffer for primitives +should be plenty.

+
char primbuff[2][32768];
+char *nextpri;
+
+

The nextpri variable will be used to keep track where the next +primitive should be written to. Therefore, this variable must be set to +the first primitive buffer and reset in your display function.

+

To prepare a primitive to the primitive buffer, simply cast the +nextpri pointer into a primitive pointer.

+
TILE *tile;                    // Primitive pointer
+
+tile = (TILE*)nextpri;         // Cast hext primitive
+
+setTile(tile);                 // Initialize the primitive (very important)
+setXY0(tile, 32, 32);          // Set primitive (x,y) position
+setWH(tile, 64, 64);           // Set primitive size
+setRGB0(tile, 255, 255, 0);    // Set color yellow
+
+

After registering the primitive to the ordering table, you'll want to +advance the nextpri pointer for another primitive to be written to.

+
nextpri += sizeof(TILE);
+
+

It is very important to advance this pointer, otherwise previously defined +packets would get overwritten, corrupting the primitive buffer.

+ +

Sorting a Primitive to an Ordering Table

+

The term 'sorting' in the context of PS1 graphics programming refers to +linking a primitive to an ordering table element. Its often called sorting +because an ordering table is also used to control the order of which +primitives are drawn. In a reverse ordering table (initialized using +ClearOTagR()) a primitive sorted highest will be drawn first and primitives +sorted lowest will be drawn last, which would make a lot of sense in 3D +graphics.

+

Sorting a primitive to an ordering table is achieved using the +addPrim() macro.

+
addPrim(ot[db], tile);
+
+

There's also a function version called AddPrim() but the macro version +would be faster in the long run, mainly because code jumps are kept a minimum when +using macros.

+

Taking the code snippet earlier, this is the process of how to create and sort +a primitive to be drawn.

+
tile = (TILE*)nextpri;         // Cast next primitive
+
+setTile(tile);                 // Initialize the primitive (very important)
+setXY0(tile, 32, 32);          // Set primitive (x,y) position
+setWH(tile, 64, 64);           // Set primitive size
+setRGB0(tile, 255, 255, 0);    // Set color yellow
+
+addPrim(ot[db], tile);         // Add primitive to the ordering table
+
+nextpri += sizeof(TILE);       // Advance the next primitive pointer
+
+

Primitives need to be sorted to an ordering table for the GPU to process it. +To sort the primitive to a higher ordering table element, simply use (+) to +increment the ordering table address. But don't increment by a value that +will exceed the length of your ordering table, or that will result to memory +overflow corruption.

+

Sorting a primitive to an ordering table links the specified primitive into +the chain, so it gets processed when the OT is proceessed by the GPU. The +following figure visually describes the result of sorting a primitive to ordering +table element 4.

+ +

A very common misconception among many PS1 homebrew programmers is they believe +only a single primitive can be sorted to an ordering table element. This is +absolutely untrue because sorting a primitive to an element that has a primitive +already linked to it will only add further to the chain, not replace the previous +element.

+ +

You can sort any number of primitives to a single ordering table, so an ordering +table of 4 to 8 elements should be sufficient for 2D projects. But remember that the +newest primitive sorted will be the first to be processed, as shown in the figure +earlier.

+ +

Drawing an Ordering Table

+

Ordering table processing is done using the DrawOTag() function. +DrawOTag() starts a DMA transfer process of the specified ordering +table for the GPU to process. This is the most recommended method of +processing ordering tables as this is the fastest way to deliver graphics +primitives to the GPU.

+

Since this tutorial demonstrates the use of a reverse ordering table, the +last element of the ordering table must be specified to DrawOTag(), as +the chain starts at the last element and ends at the first.

+
DrawOTag(ot[db]+31);
+
+

The transfer operation is asynchronous so the function returns very +quickly. It is recommended to wait for the transfer and the GPU to finish +processing which is achieved using DrawSync() before processing another +ordering table.

+ +

Double Ordering Tables/Primitive Buffers

+

You may have noticed by now that ordering tables and primitive buffers are +defined in pairs. This is so that a commonly used optimization trick can be +achieved and is another form of double buffering. Because the CPU can continue +running while the GPU is busy processing graphics, you can utilize this to +continue processing graphics primitives for drawing the next frame while the +GPU is drawing. The following figure visually describes the performance +difference.

+ +

Having double buffers essentially minimizes keeping the GPU idle which +comes off as being most efficient, as having single buffers would prevent +you from preparing primitives for the next frame which results to leaving +the GPU in an idle state. While this may not be apparent in small programs, +it will be once you start pushing the GPU with thousands of primitives.

+ +

Sample Code

+

The sample code works off of the one from the previous example, but with +graphics drawing code implemented.

+
#include <sys/types.h>	// This provides typedefs needed by libgte.h and libgpu.h
+#include <stdio.h>	// Not necessary but include it anyway
+#include <libetc.h>	// Includes some functions that controls the display
+#include <libgte.h>	// GTE header, not really used but libgpu.h depends on it
+#include <libgpu.h>	// GPU library header
+
+#define OTLEN 8         // Ordering table length (recommended to set as a define
+                        // so it can be changed easily)
+
+DISPENV disp[2];
+DRAWENV draw[2];
+int db = 0;
+
+u_long ot[2][OTLEN];    // Ordering table length
+char pribuff[2][32768]; // Primitive buffer
+char *nextpri;          // Next primitive pointer
+
+void display() {
+    
+    DrawSync(0);                // Wait for any graphics processing to finish
+    
+    VSync(0);                   // Wait for vertical retrace
+
+    PutDispEnv(&disp;[db]);      // Apply the DISPENV/DRAWENVs
+    PutDrawEnv(&draw;[db]);
+
+    SetDispMask(1);             // Enable the display
+
+    DrawOTag(ot[db]+OTLEN-1);   // Draw the ordering table
+    
+    db = !db;                   // Swap buffers on every pass (alternates between 1 and 0)
+    nextpri = pribuff[db];      // Reset next primitive pointer
+    
+}
+
+int main() {
+    
+    TILE *tile;                     // Primitive pointer
+    
+    // Reset graphics
+    ResetGraph(0);
+
+    // First buffer
+    SetDefDispEnv(&disp;[0], 0, 0, 320, 240);
+    SetDefDrawEnv(&draw;[0], 0, 240, 320, 240);
+    // Second buffer
+    SetDefDispEnv(&disp;[1], 0, 240, 320, 240);
+    SetDefDrawEnv(&draw;[1], 0, 0, 320, 240);
+
+    draw[0].isbg = 1;               // Enable clear
+    setRGB0(&draw;[0], 63, 0, 127);  // Set clear color (dark purple)
+    draw[1].isbg = 1;
+    setRGB0(&draw;[1], 63, 0, 127);
+
+    nextpri = pribuff[0];           // Set initial primitive pointer address
+    
+    while(1) {
+
+        ClearOTagR(ot[db], OTLEN);  // Clear ordering table
+    
+        
+        tile = (TILE*)nextpri;      // Cast next primitive
+
+        setTile(tile);              // Initialize the primitive (very important)
+        setXY0(tile, 32, 32);       // Set primitive (x,y) position
+        setWH(tile, 64, 64);        // Set primitive size
+        setRGB0(tile, 255, 255, 0); // Set color yellow
+        addPrim(ot[db], tile);      // Add primitive to the ordering table
+        
+        nextpri += sizeof(TILE);    // Advance the next primitive pointer
+        
+    
+        // Update the display
+        display();
+        
+    }
+    
+    return 0;
+}
+
+

Compile and run the program and you should get a yellow square. +Your very first graphic done with the GPU!

+ + +

Conclusion

+

This concludes Chapter 1.2. of Lameguy64's PSX Tutorial series. +You should know more about drawing graphics on the PS1 after reading +through this chapter.

+

A few things you may want to experiment with yourself for further +learning:

+
    +
  • Play around with the values specified in setXY0(), setRGB0() +and setWH() to change the position, color and size of the sprite +respectively.
  • +
  • Try drawing more sprites by repeating the primitive creation process. +Make sure the nextpri and tile pointers have been advanced before +creating a new primitive.
  • +
  • You can advance the primitive pointer with tile++;, and set the +updated address to nextpri by converting types back +(nextpri = (char*)tile;)
  • +
  • Try making the yellow square bounce around the screen, by defining +two variables for (x,y) coordinates and two more for the direction flags, +and write some logic that makes the (x,y) coordinates move and bounce +around the screen.
  • +
+

The next tutorial will cover how to convert and upload texture data, as +well as drawing said textures with sprite and polygon primitives.

+
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Docs/Chapter 1.2 Drawing Graphics_files/analytics.js b/Docs/Chapter 1.2 Drawing Graphics_files/analytics.js new file mode 100644 index 0000000..10400f0 --- /dev/null +++ b/Docs/Chapter 1.2 Drawing Graphics_files/analytics.js @@ -0,0 +1,474 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0 +/* eslint-disable no-var, semi, prefer-arrow-callback, prefer-template */ + +/** + * Collection of methods for sending analytics events to Archive.org's analytics server. + * + * These events are used for internal stats and sent (in anonymized form) to Google Analytics. + * + * @see analytics.md + * + * @type {Object} + */ +window.archive_analytics = (function defineArchiveAnalytics() { + // keep orignal Date object so as not to be affected by wayback's + // hijacking global Date object + var Date = window.Date; + var ARCHIVE_ANALYTICS_VERSION = 2; + var DEFAULT_SERVICE = 'ao_2'; + var NO_SAMPLING_SERVICE = 'ao_no_sampling'; // sends every event instead of a percentage + + var startTime = new Date(); + + /** + * @return {Boolean} + */ + function isPerformanceTimingApiSupported() { + return 'performance' in window && 'timing' in window.performance; + } + + /** + * Determines how many milliseconds elapsed between the browser starting to parse the DOM and + * the current time. + * + * Uses the Performance API or a fallback value if it's not available. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API + * + * @return {Number} + */ + function getLoadTime() { + var start; + + if (isPerformanceTimingApiSupported()) + start = window.performance.timing.domLoading; + else + start = startTime.getTime(); + + return new Date().getTime() - start; + } + + /** + * Determines how many milliseconds elapsed between the user navigating to the page and + * the current time. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API + * + * @return {Number|null} null if the browser doesn't support the Performance API + */ + function getNavToDoneTime() { + if (!isPerformanceTimingApiSupported()) + return null; + + return new Date().getTime() - window.performance.timing.navigationStart; + } + + /** + * Performs an arithmetic calculation on a string with a number and unit, while maintaining + * the unit. + * + * @param {String} original value to modify, with a unit + * @param {Function} doOperation accepts one Number parameter, returns a Number + * @returns {String} + */ + function computeWithUnit(original, doOperation) { + var number = parseFloat(original, 10); + var unit = original.replace(/(\d*\.\d+)|\d+/, ''); + + return doOperation(number) + unit; + } + + /** + * Computes the default font size of the browser. + * + * @returns {String|null} computed font-size with units (typically pixels), null if it cannot be computed + */ + function getDefaultFontSize() { + var fontSizeStr; + + if (!('getComputedStyle' in window)) + return null; + + var style = window.getComputedStyle(document.documentElement); + if (!style) + return null; + + fontSizeStr = style.fontSize; + + // Don't modify the value if tracking book reader. + if (document.querySelector('#BookReader')) + return fontSizeStr; + + return computeWithUnit(fontSizeStr, function reverseBootstrapFontSize(number) { + // Undo the 62.5% size applied in the Bootstrap CSS. + return number * 1.6; + }); + } + + /** + * Get the URL parameters for a given Location + * @param {Location} + * @return {Object} The URL parameters + */ + function getParams(location) { + if (!location) location = window.location; + var vars; + var i; + var pair; + var params = {}; + var query = location.search; + if (!query) return params; + vars = query.substring(1).split('&'); + for (i = 0; i < vars.length; i++) { + pair = vars[i].split('='); + params[pair[0]] = decodeURIComponent(pair[1]); + } + return params; + } + + function getMetaProp(name) { + var metaTag = document.querySelector('meta[property=' + name + ']'); + return metaTag ? metaTag.getAttribute('content') || null : null; + } + + var ArchiveAnalytics = { + /** + * @type {String|null} + */ + service: getMetaProp('service'), + mediaType: getMetaProp('mediatype'), + primaryCollection: getMetaProp('primary_collection'), + + /** + * Key-value pairs to send in pageviews (you can read this after a pageview to see what was + * sent). + * + * @type {Object} + */ + values: {}, + + /** + * Sends an analytics ping, preferably using navigator.sendBeacon() + * @param {Object} values + * @param {Function} [onload_callback] (deprecated) callback to invoke once ping to analytics server is done + * @param {Boolean} [augment_for_ao_site] (deprecated) if true, add some archive.org site-specific values + */ + send_ping: function send_ping(values, onload_callback, augment_for_ao_site) { + if (typeof window.navigator !== 'undefined' && typeof window.navigator.sendBeacon !== 'undefined') + this.send_ping_via_beacon(values); + else + this.send_ping_via_image(values); + }, + + /** + * Sends a ping via Beacon API + * NOTE: Assumes window.navigator.sendBeacon exists + * @param {Object} values Tracking parameters to pass + */ + send_ping_via_beacon: function send_ping_via_beacon(values) { + var url = this.generate_tracking_url(values || {}); + window.navigator.sendBeacon(url); + }, + + /** + * Sends a ping via Image object + * @param {Object} values Tracking parameters to pass + */ + send_ping_via_image: function send_ping_via_image(values) { + var url = this.generate_tracking_url(values || {}); + var loadtime_img = new Image(1, 1); + loadtime_img.src = url; + loadtime_img.alt = ''; + }, + + /** + * Construct complete tracking URL containing payload + * @param {Object} params Tracking parameters to pass + * @return {String} URL to use for tracking call + */ + generate_tracking_url: function generate_tracking_url(params) { + var baseUrl = '//analytics.archive.org/0.gif'; + var keys; + var outputParams = params; + var outputParamsArray = []; + + outputParams.service = outputParams.service || this.service || DEFAULT_SERVICE; + + // Build array of querystring parameters + keys = Object.keys(outputParams); + keys.forEach(function keyIteration(key) { + outputParamsArray.push(encodeURIComponent(key) + '=' + encodeURIComponent(outputParams[key])); + }); + outputParamsArray.push('version=' + ARCHIVE_ANALYTICS_VERSION); + outputParamsArray.push('count=' + (keys.length + 2)); // Include `version` and `count` in count + + return baseUrl + '?' + outputParamsArray.join('&'); + }, + + /** + * @param {int} page Page number + */ + send_scroll_fetch_event: function send_scroll_fetch_event(page) { + var additionalValues = { ev: page }; + var loadTime = getLoadTime(); + var navToDoneTime = getNavToDoneTime(); + if (loadTime) additionalValues.loadtime = loadTime; + if (navToDoneTime) additionalValues.nav_to_done_ms = navToDoneTime; + this.send_event('page_action', 'scroll_fetch', location.pathname, additionalValues); + }, + + send_scroll_fetch_base_event: function send_scroll_fetch_base_event() { + var additionalValues = {}; + var loadTime = getLoadTime(); + var navToDoneTime = getNavToDoneTime(); + if (loadTime) additionalValues.loadtime = loadTime; + if (navToDoneTime) additionalValues.nav_to_done_ms = navToDoneTime; + this.send_event('page_action', 'scroll_fetch_base', location.pathname, additionalValues); + }, + + /** + * @param {Object} [options] + * @param {String} [options.mediaType] + * @param {String} [options.mediaLanguage] + * @param {String} [options.page] The path portion of the page URL + */ + send_pageview: function send_pageview(options) { + var settings = options || {}; + + var defaultFontSize; + var loadTime = getLoadTime(); + var mediaType = settings.mediaType; + var primaryCollection = settings.primaryCollection; + var page = settings.page; + var navToDoneTime = getNavToDoneTime(); + + /** + * @return {String} + */ + function get_locale() { + if (navigator) { + if (navigator.language) + return navigator.language; + + else if (navigator.browserLanguage) + return navigator.browserLanguage; + + else if (navigator.systemLanguage) + return navigator.systemLanguage; + + else if (navigator.userLanguage) + return navigator.userLanguage; + } + return ''; + } + + defaultFontSize = getDefaultFontSize(); + + // Set field values + this.values.kind = 'pageview'; + this.values.timediff = (new Date().getTimezoneOffset()/60)*(-1); // *timezone* diff from UTC + this.values.locale = get_locale(); + this.values.referrer = (document.referrer == '' ? '-' : document.referrer); + + if (loadTime) + this.values.loadtime = loadTime; + + if (navToDoneTime) + this.values.nav_to_done_ms = navToDoneTime; + + if (settings.trackingId) { + this.values.ga_tid = settings.trackingId; + } + + /* START CUSTOM DIMENSIONS */ + if (defaultFontSize) + this.values.ga_cd1 = defaultFontSize; + + if ('devicePixelRatio' in window) + this.values.ga_cd2 = window.devicePixelRatio; + + if (mediaType) + this.values.ga_cd3 = mediaType; + + if (settings.mediaLanguage) { + this.values.ga_cd4 = settings.mediaLanguage; + } + + if (primaryCollection) { + this.values.ga_cd5 = primaryCollection; + } + /* END CUSTOM DIMENSIONS */ + + if (page) + this.values.page = page; + + this.send_ping(this.values); + }, + + /** + * Sends a tracking "Event". + * @param {string} category + * @param {string} action + * @param {string} label + * @param {Object} additionalEventParams + */ + send_event: function send_event( + category, + action, + label, + additionalEventParams + ) { + if (!label) label = window.location.pathname; + if (!additionalEventParams) additionalEventParams = {}; + if (additionalEventParams.mediaLanguage) { + additionalEventParams.ga_cd4 = additionalEventParams.mediaLanguage; + delete additionalEventParams.mediaLanguage; + } + var eventParams = Object.assign( + { + kind: 'event', + ec: category, + ea: action, + el: label, + cache_bust: Math.random(), + }, + additionalEventParams + ); + this.send_ping(eventParams); + }, + + /** + * Sends every event instead of a small percentage. + * + * Use this sparingly as it can generate a lot of events. + * + * @param {string} category + * @param {string} action + * @param {string} label + * @param {Object} additionalEventParams + */ + send_event_no_sampling: function send_event_no_sampling( + category, + action, + label, + additionalEventParams + ) { + var extraParams = additionalEventParams || {}; + extraParams.service = NO_SAMPLING_SERVICE; + this.send_event(category, action, label, extraParams); + }, + + /** + * @param {Object} options see this.send_pageview options + */ + send_pageview_on_load: function send_pageview_on_load(options) { + var self = this; + window.addEventListener('load', function send_pageview_with_options() { + self.send_pageview(options); + }); + }, + + /** + * Handles tracking events passed in URL. + * Assumes category and action values are separated by a "|" character. + * NOTE: Uses the unsampled analytics property. Watch out for future high click links! + * @param {Location} + */ + process_url_events: function process_url_events(location) { + var eventValues; + var actionValue; + var eventValue = getParams(location).iax; + if (!eventValue) return; + eventValues = eventValue.split('|'); + actionValue = eventValues.length >= 1 ? eventValues[1] : ''; + this.send_event_no_sampling( + eventValues[0], + actionValue, + window.location.pathname + ); + }, + + /** + * Attaches handlers for event tracking. + * + * To enable click tracking for a link, add a `data-event-click-tracking` + * attribute containing the Google Analytics Event Category and Action, separated + * by a vertical pipe (|). + * e.g. `` + * + * To enable form submit tracking, add a `data-event-form-tracking` attribute + * to the `form` tag. + * e.g. `` + * + * Additional tracking options can be added via a `data-event-tracking-options` + * parameter. This parameter, if included, should be a JSON string of the parameters. + * Valid parameters are: + * - service {string}: Corresponds to the Google Analytics property data values flow into + */ + set_up_event_tracking: function set_up_event_tracking() { + var self = this; + var clickTrackingAttributeName = 'event-click-tracking'; + var formTrackingAttributeName = 'event-form-tracking'; + var trackingOptionsAttributeName = 'event-tracking-options'; + + function handleAction(event, attributeName) { + var selector = '[data-' + attributeName + ']'; + var eventTarget = event.target; + if (!eventTarget) return; + var target = eventTarget.closest(selector); + if (!target) return; + var categoryAction; + var categoryActionParts; + var options; + categoryAction = target.dataset[toCamelCase(attributeName)]; + if (!categoryAction) return; + categoryActionParts = categoryAction.split('|'); + options = target.dataset[toCamelCase(trackingOptionsAttributeName)]; + options = options ? JSON.parse(options) : {}; + self.send_event( + categoryActionParts[0], + categoryActionParts[1], + categoryActionParts[2] || window.location.pathname, + options.service ? { service: options.service } : {} + ); + } + + function toCamelCase(str) { + return str.replace(/\W+(.)/g, function (match, chr) { + return chr.toUpperCase(); + }); + }; + + document.addEventListener('click', function(e) { + handleAction(e, clickTrackingAttributeName); + }); + + document.addEventListener('submit', function(e) { + handleAction(e, formTrackingAttributeName); + }); + }, + + /** + * @returns {Object[]} + */ + get_data_packets: function get_data_packets() { + return [this.values]; + }, + + /** + * Creates a tracking image for tracking JS compatibility. + * + * @param {string} type The type value for track_js_case in query params for 0.gif + */ + create_tracking_image: function create_tracking_image(type) { + this.send_ping_via_image({ + cache_bust: Math.random(), + kind: 'track_js', + track_js_case: type, + }); + } + }; + + return ArchiveAnalytics; +}()); +// @license-end diff --git a/Docs/Chapter 1.2 Drawing Graphics_files/banner-styles.css b/Docs/Chapter 1.2 Drawing Graphics_files/banner-styles.css new file mode 100644 index 0000000..8d39621 --- /dev/null +++ b/Docs/Chapter 1.2 Drawing Graphics_files/banner-styles.css @@ -0,0 +1,500 @@ +@import 'record.css'; /* for SPN1 */ + +#wm-ipp-base { + height:65px;/* initial height just in case js code fails */ + padding:0; + margin:0; + border:none; + background:none transparent; +} +#wm-ipp { + z-index: 2147483647; +} +#wm-ipp, #wm-ipp * { + font-family:Lucida Grande, Helvetica, Arial, sans-serif; + font-size:12px; + line-height:1.2; + letter-spacing:0; + width:auto; + height:auto; + max-width:none; + max-height:none; + min-width:0 !important; + min-height:0; + outline:none; + float:none; + text-align:left; + border:none; + color: #000; + text-indent: 0; + position: initial; + background: none; +} +#wm-ipp div, #wm-ipp canvas { + display: block; +} +#wm-ipp div, #wm-ipp tr, #wm-ipp td, #wm-ipp a, #wm-ipp form { + padding:0; + margin:0; + border:none; + border-radius:0; + background-color:transparent; + background-image:none; + /*z-index:2147483640;*/ + height:auto; +} +#wm-ipp table { + border:none; + border-collapse:collapse; + margin:0; + padding:0; + width:auto; + font-size:inherit; +} +#wm-ipp form input { + padding:1px !important; + height:auto; + display:inline; + margin:0; + color: #000; + background: none #fff; + border: 1px solid #666; +} +#wm-ipp form input[type=submit] { + padding:0 8px !important; + margin:1px 0 1px 5px !important; + width:auto !important; + border: 1px solid #000 !important; + background: #fff !important; + color: #000 !important; +} +#wm-ipp a { + display: inline; +} +#wm-ipp a:hover{ + text-decoration:underline; +} +#wm-ipp a.wm-btn:hover { + text-decoration:none; + color:#ff0 !important; +} +#wm-ipp a.wm-btn:hover span { + color:#ff0 !important; +} +#wm-ipp #wm-ipp-inside { + margin: 0 6px; + border:5px solid #000; + border-top:none; + background-color:rgba(255,255,255,0.9); + -moz-box-shadow:1px 1px 4px #333; + -webkit-box-shadow:1px 1px 4px #333; + box-shadow:1px 1px 4px #333; + border-radius:0 0 8px 8px; +} +/* selectors are intentionally verbose to ensure priority */ +#wm-ipp #wm-logo { + padding:0 10px; + vertical-align:middle; + min-width:100px; + flex: 0 0 100px; +} +#wm-ipp .c { + padding-left: 4px; +} +#wm-ipp .c .u { + margin-top: 4px !important; +} +#wm-ipp .n { + padding:0 0 0 5px !important; + vertical-align: bottom; +} +#wm-ipp .n a { + text-decoration:none; + color:#33f; + font-weight:bold; +} +#wm-ipp .n .b { + padding:0 6px 0 0 !important; + text-align:right !important; + overflow:visible; + white-space:nowrap; + color:#99a; + vertical-align:middle; +} +#wm-ipp .n .y .b { + padding:0 6px 2px 0 !important; +} +#wm-ipp .n .c { + background:#000; + color:#ff0; + font-weight:bold; + padding:0 !important; + text-align:center; +} +#wm-ipp.hi .n td.c { + color:#ec008c; +} +#wm-ipp .n td.f { + padding:0 0 0 6px !important; + text-align:left !important; + overflow:visible; + white-space:nowrap; + color:#99a; + vertical-align:middle; +} +#wm-ipp .n tr.m td { + text-transform:uppercase; + white-space:nowrap; + padding:2px 0; +} +#wm-ipp .c .s { + padding:0 5px 0 0 !important; + vertical-align:bottom; +} +#wm-ipp #wm-nav-captures { + white-space: nowrap; +} +#wm-ipp .c .s a.t { + color:#33f; + font-weight:bold; + line-height: 1.8; +} +#wm-ipp .c .s div.r { + color: #666; + font-size:9px; + white-space:nowrap; +} +#wm-ipp .c .k { + padding-bottom:1px; +} +#wm-ipp .c .s { + padding:0 5px 2px 0 !important; +} +#wm-ipp td#displayMonthEl { + padding: 2px 0 !important; +} +#wm-ipp td#displayYearEl { + padding: 0 0 2px 0 !important; +} + +div#wm-ipp-sparkline { + position:relative;/* for positioning markers */ + white-space:nowrap; + background-color:#fff; + cursor:pointer; + line-height:0.9; +} +#sparklineImgId, #wm-sparkline-canvas { + position:relative; + z-index:9012; + max-width:none; +} +#wm-ipp-sparkline div.yt { + position:absolute; + z-index:9010 !important; + background-color:#ff0 !important; + top: 0; +} +#wm-ipp-sparkline div.mt { + position:absolute; + z-index:9013 !important; + background-color:#ec008c !important; + top: 0; +} +#wm-ipp .r { + margin-left: 4px; +} +#wm-ipp .r a { + color:#33f; + border:none; + position:relative; + background-color:transparent; + background-repeat:no-repeat !important; + background-position:100% 100% !important; + text-decoration: none; +} +#wm-ipp #wm-capinfo { + /* prevents notice div background from sticking into round corners of + #wm-ipp-inside */ + border-radius: 0 0 4px 4px; +} +#wm-ipp #wm-capinfo .c-logo { + display:block; + float:left; + margin-right:3px; + width:90px; + min-height:90px; + max-height: 290px; + border-radius:45px; + overflow:hidden; + background-position:50%; + background-size:auto 90px; + box-shadow: 0 0 2px 2px rgba(208,208,208,128) inset; +} +#wm-ipp #wm-capinfo .c-logo span { + display:inline-block; +} +#wm-ipp #wm-capinfo .c-logo img { + height:90px; + position:relative; + left:-50%; +} +#wm-ipp #wm-capinfo .wm-title { + font-size:130%; +} +#wm-ipp #wm-capinfo a.wm-selector { + display:inline-block; + color: #aaa; + text-decoration:none !important; + padding: 2px 8px; +} +#wm-ipp #wm-capinfo a.wm-selector.selected { + background-color:#666; +} +#wm-ipp #wm-capinfo a.wm-selector:hover { + color: #fff; +} +#wm-ipp #wm-capinfo.notice-only #wm-capinfo-collected-by, +#wm-ipp #wm-capinfo.notice-only #wm-capinfo-timestamps { + display: none; +} +#wm-ipp #wm-capinfo #wm-capinfo-notice .wm-capinfo-content { + background-color:#ff0; + padding:5px; + font-size:14px; + text-align:center; +} +#wm-ipp #wm-capinfo #wm-capinfo-notice .wm-capinfo-content * { + font-size:14px; + text-align:center; +} +#wm-ipp #wm-expand { + right: 1px; + bottom: -1px; + color: #ffffff; + background-color: #666 !important; + padding:0 5px 0 3px !important; + border-radius: 3px 3px 0 0 !important; +} +#wm-ipp #wm-expand span { + color: #ffffff; +} +#wm-ipp #wm-expand #wm-expand-icon { + display: inline-block; + transition: transform 0.5s; + transform-origin: 50% 45%; +} +#wm-ipp #wm-expand.wm-open #wm-expand-icon { + transform: rotate(180deg); +} +#wm-ipp #wmtb { + text-align:right; +} +#wm-ipp #wmtb #wmtbURL { + width: calc(100% - 45px); +} +#wm-ipp #wm-graph-anchor { + border-right:1px solid #ccc; +} +/* time coherence */ +html.wb-highlight { + box-shadow: inset 0 0 0 3px #a50e3a !important; +} +.wb-highlight { + outline: 3px solid #a50e3a !important; +} +#wm-ipp-print { + display:none !important; +} +@media print { +#wm-ipp-base { + display:none !important; +} +#wm-ipp-print { + display:block !important; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +} +@media (max-width:414px) { + #wm-ipp .xxs { + display:none !important; + } +} +@media (min-width:1055px) { +#wm-ipp #wm-graph-anchor { + display:block !important; +} +} +@media (max-width:1054px) { +#wm-ipp #wm-graph-anchor { + display:none !important; +} +} +@media (max-width:1163px) { +#wm-logo { + display:none !important; +} +} + +#wm-btns { + white-space: nowrap; + margin-top: -2px; +} + +#wm-btns #wm-save-snapshot-open { + margin-right: 7px; + top: -6px; +} + +#wm-btns #wm-sign-in { + box-sizing: content-box; + display: none; + margin-right: 7px; + top: -8px; + + /* + round border around sign in button + */ + border: 2px #000 solid; + border-radius: 14px; + padding-right: 2px; + padding-bottom: 2px; + width: 11px; + height: 11px; +} + +#wm-btns #wm-sign-in>.iconochive-person { + font-size: 12.5px; +} + +#wm-save-snapshot-open > .iconochive-web { + color:#000; + font-size:160%; +} + +#wm-ipp #wm-share { + display: flex; + align-items: flex-end; + justify-content: space-between; +} + +#wm-share > #wm-screenshot { + display: inline-block; + margin-right: 3px; + visibility: hidden; +} + +#wm-screenshot > .iconochive-image { + color:#000; + font-size:160%; +} + +#wm-share > #wm-video { + display: inline-block; + margin-right: 3px; + visibility: hidden; +} + +#wm-video > .iconochive-movies { + color: #000; + display: inline-block; + font-size: 150%; + margin-bottom: 2px; +} + +#wm-btns #wm-save-snapshot-in-progress { + display: none; + font-size:160%; + opacity: 0.5; + position: relative; + margin-right: 7px; + top: -5px; +} + +#wm-btns #wm-save-snapshot-success { + display: none; + color: green; + position: relative; + top: -7px; +} + +#wm-btns #wm-save-snapshot-fail { + display: none; + color: red; + position: relative; + top: -7px; +} + +.wm-icon-screen-shot { + background: url("../images/web-screenshot.svg") no-repeat !important; + background-size: contain !important; + width: 22px !important; + height: 19px !important; + + display: inline-block; +} +#donato { + /* transition effect is disable so as to simplify height adjustment */ + /*transition: height 0.5s;*/ + height: 0; + margin: 0; + padding: 0; + border-bottom: 1px solid #999 !important; +} +body.wm-modal { + height: auto !important; + overflow: hidden !important; +} +#donato #donato-base { + width: 100%; + height: 100%; + /*bottom: 0;*/ + margin: 0; + padding: 0; + position: absolute; + z-index: 2147483639; +} +body.wm-modal #donato #donato-base { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 2147483640; +} + +.wb-autocomplete-suggestions { + font-family: Lucida Grande, Helvetica, Arial, sans-serif; + font-size: 12px; + text-align: left; + cursor: default; + border: 1px solid #ccc; + border-top: 0; + background: #fff; + box-shadow: -1px 1px 3px rgba(0,0,0,.1); + position: absolute; + display: none; + z-index: 2147483647; + max-height: 254px; + overflow: hidden; + overflow-y: auto; + box-sizing: border-box; +} +.wb-autocomplete-suggestion { + position: relative; + padding: 0 .6em; + line-height: 23px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-size: 1.02em; + color: #333; +} +.wb-autocomplete-suggestion b { + font-weight: bold; +} +.wb-autocomplete-suggestion.selected { + background: #f0f0f0; +} diff --git a/Docs/Chapter 1.2 Drawing Graphics_files/bundle-playback.js b/Docs/Chapter 1.2 Drawing Graphics_files/bundle-playback.js new file mode 100644 index 0000000..390894d --- /dev/null +++ b/Docs/Chapter 1.2 Drawing Graphics_files/bundle-playback.js @@ -0,0 +1,3 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0 +!function(e){var t={};function n(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(o,i,function(t){return e[t]}.bind(null,i));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=9)}([function(e,t,n){"use strict";function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function s(e){var t="function"==typeof Map?new Map:void 0;return(s=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,o)}function o(){return a(e,arguments,u(this).constructor)}return o.prototype=Object.create(e.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),l(o,e)})(e)}function a(e,t,n){return(a=c()?Reflect.construct:function(e,t,n){var o=[null];o.push.apply(o,t);var i=new(Function.bind.apply(e,o));return n&&l(i,n.prototype),i}).apply(null,arguments)}function c(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function l(e,t){return(l=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function u(e){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}if(n.d(t,"a",(function(){return f})),n.d(t,"d",(function(){return p})),n.d(t,"c",(function(){return d})),n.d(t,"b",(function(){return v})),"undefiend"!=typeof window.XMLHttpRequest){var h=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&l(e,t)}(o,e);var t,n=(t=o,function(){var e,n=u(t);if(c()){var o=u(this).constructor;e=Reflect.construct(n,arguments,o)}else e=n.apply(this,arguments);return r(this,e)});function o(){return i(this,o),n.apply(this,arguments)}return o}(s(XMLHttpRequest));Object.defineProperty(h.prototype,"responseURL",Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype,"responseURL"))}function f(e,t,n,o,i){var r;if((r=window.XMLHttpRequest?new h:new ActiveXObject("Microsoft.XMLHTTP")).onreadystatechange=function(){4==this.readyState&&n(r)},r.open(e,t,!0),o)for(var s in o)o.hasOwnProperty(s)&&r.setRequestHeader(s,o[s]);r.withCredentials=!0,r.send(i)}function p(e){return void 0!==e&&e&&e.constructor===Array}function d(e){return document.cookie.search(e)>=0}function m(e,t){var n=window["HTML".concat(e,"Element")];if(void 0!==n){var o=Object.getOwnPropertyDescriptor(n.prototype,t);void 0!==o&&Object.defineProperty(n.prototype,"_wm_".concat(t),o)}}function v(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"src",n="_wm_".concat(t);return n in e.__proto__?e[n]:e[t]}m("Image","src"),m("Media","src"),m("Embed","src"),m("IFrame","src"),m("Script","src"),m("Link","href"),m("Anchor","href")},function(e,t,n){"use strict";n.d(t,"c",(function(){return s})),n.d(t,"b",(function(){return a})),n.d(t,"a",(function(){return c}));var o=["January","February","March","April","May","June","July","August","September","October","November","December"],i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],r={Y:function(e){return e.getUTCFullYear()},m:function(e){return e.getUTCMonth()+1},b:function(e){return i[e.getUTCMonth()]},B:function(e){return o[e.getUTCMonth()]},d:function(e){return e.getUTCDate()},H:function(e){return("0"+e.getUTCHours()).slice(-2)},M:function(e){return("0"+e.getUTCMinutes()).slice(-2)},S:function(e){return("0"+e.getUTCSeconds()).slice(-2)},"%":function(){return"%"}};function s(e){var t=function(e){return"number"==typeof e&&(e=e.toString()),[e.slice(-14,-10),e.slice(-10,-8),e.slice(-8,-6),e.slice(-6,-4),e.slice(-4,-2),e.slice(-2)]}(e);return new Date(Date.UTC(t[0],t[1]-1,t[2],t[3],t[4],t[5]))}function a(e){return i[e]}function c(e,t){return t.replace(/%./g,(function(t){var n=r[t[1]];return n?n(s(e)):t}))}},function(e,t,n){"use strict";n.d(t,"b",(function(){return s})),n.d(t,"a",(function(){return a}));var o=n(0);function i(e,t){for(var n=0;n=400?i.failure&&i.failure(e):i.success&&i.success(e)}),{"Content-Type":"application/json"},r.stringify({url:e,snapshot:t,tags:n||[]})),!1}var a=function(){function e(t,n,i){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.el=t,this.url=n,this.timestamp=i,t.onclick=this.save.bind(this),document.addEventListener("DOMContentLoaded",(function(){Object(o.c)("logged-in-user")&&Object(o.c)("logged-in-sig")?r.userIsLoggedIn():r.userIsNotLoggedIn()}))}var t,n,r;return t=e,(n=[{key:"save",value:function(e){this.start(),s(this.url,this.timestamp,[],{failure:this.failure.bind(this),success:this.success.bind(this)})}},{key:"start",value:function(){this.hide(["wm-save-snapshot-fail","wm-save-snapshot-open","wm-save-snapshot-success"]),this.show(["wm-save-snapshot-in-progress"])}},{key:"failure",value:function(e){401==e.status?this.userNotLoggedIn(e):(this.hide(["wm-save-snapshot-in-progress","wm-save-snapshot-success"]),this.show(["wm-save-snapshot-fail","wm-save-snapshot-open"]),console.log("You have got an error."),console.log("If you think something wrong here please send it to support."),console.log('Response: "'+e.responseText+'"'),console.log('status: "'+e.status+'"'))}},{key:"success",value:function(e){this.hide(["wm-save-snapshot-fail","wm-save-snapshot-in-progress"]),this.show(["wm-save-snapshot-open","wm-save-snapshot-success"])}},{key:"userIsLoggedIn",value:function(){this.show("wm-save-snapshot-open"),this.hide("wm-sign-in")}},{key:"userIsNotLoggedIn",value:function(){this.hide(["wm-save-snapshot-open","wm-save-snapshot-in-progress"]),this.show("wm-sign-in")}},{key:"show",value:function(e){this.setDisplayStyle(e,"inline-block")}},{key:"hide",value:function(e){this.setDisplayStyle(e,"none")}},{key:"setDisplayStyle",value:function(e,t){var n=this;(Object(o.d)(e)?e:[e]).forEach((function(e){var o=n.el.getRootNode().getElementById(e);o&&(o.style.display=t)}))}}])&&i(t.prototype,n),r&&i(t,r),e}()},,,,,,,function(e,t,n){"use strict";var o;n.r(t);var i,r={createElementNS:document.createElementNS};var s=!0;function a(e){!function(e,t,n){if(n){var o=new Date;o.setTime(o.getTime()+24*n*60*60*1e3);var i="; expires="+o.toGMTString()}else i="";document.cookie=e+"="+t+i+"; path=/"}(e,"",-1)}var c=n(0),l=n(1),u=window.Date;function h(e,t){return(e=e.toString()).length>=t?e:"00000000".substring(0,t-e.length)+e}function f(e){for(var t=0,n=0;n3}(e)){var o=[];for(n=0;n=e.length?{done:!0}:{done:!1,value:e[t++]}},e:function(e){throw e},f:n}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i,r=!0,s=!1;return{s:function(){o=e[Symbol.iterator]()},n:function(){var e=o.next();return r=e.done,e},e:function(e){s=!0,i=e},f:function(){try{r||null==o.return||o.return()}finally{if(s)throw i}}}}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n2&&void 0!==arguments[2]?arguments[2]:"src",r=window.location.origin,s=b(window,e),l=p(s);try{for(l.s();!(o=l.n()).done;){var u=o.value;if(!n||n(u)){var h=Object(c.b)(u,i);h&&!h.startsWith(t)&&h.startsWith(r)&&(h.startsWith("data:")||a.push(h))}}}catch(e){l.e(e)}finally{l.f()}}u("img"),u("frame"),u("iframe",(function(e){return"playback"!==e.id})),u("script"),u("link",(function(e){return"stylesheet"===e.rel}),"href");var h=a.filter((function(e,t,n){return n.indexOf(e)===t}));h.length>0?(s=0,h.map((function(e){e.match("^https?://")&&(s++,Object(c.a)("HEAD",e,(function(e){if(200==e.status){var t=e.getResponseHeader("Memento-Datetime");if(null==t)console.log("%s: no Memento-Datetime",u);else{var n=document.createElement("span"),a=function(e,t){var n=new Date(e).getTime()-t,o="";n<0?(o+="-",n=Math.abs(n)):o+="+";var i=!1;if(n<1e3)return{delta:n,text:"",highlight:i};var r=n,s=Math.floor(n/1e3/60/60/24/30/12);n-=1e3*s*60*60*24*30*12;var a=Math.floor(n/1e3/60/60/24/30);n-=1e3*a*60*60*24*30;var c=Math.floor(n/1e3/60/60/24);n-=1e3*c*60*60*24;var l=Math.floor(n/1e3/60/60);n-=1e3*l*60*60;var u=Math.floor(n/1e3/60);n-=1e3*u*60;var h=Math.floor(n/1e3),f=[];s>1?(f.push(s+" years"),i=!0):1==s&&(f.push(s+" year"),i=!0);a>1?(f.push(a+" months"),i=!0):1==a&&(f.push(a+" month"),i=!0);c>1?f.push(c+" days"):1==c&&f.push(c+" day");l>1?f.push(l+" hours"):1==l&&f.push(l+" hour");u>1?f.push(u+" minutes"):1==u&&f.push(u+" minute");h>1?f.push(h+" seconds"):1==h&&f.push(h+" second");f.length>2&&(f=f.slice(0,2));return{delta:r,text:o+f.join(" "),highlight:i}}(t,r),c=a.highlight?"color:red;":"";n.innerHTML=" "+a.text,n.title=t,n.setAttribute("style",c);var l=e.getResponseHeader("Content-Type"),u=e.responseURL.replace(window.location.origin,""),h=document.createElement("a");h.innerHTML=u.split("/").splice(3).join("/"),h._wm_href=u,h.title=l,h.onmouseover=y,h.onmouseout=w;var f=document.createElement("div");f.setAttribute("data-delta",a.delta),f.appendChild(h),f.append(n),o.appendChild(f);var p=Array.prototype.slice.call(o.childNodes,0);p.sort((function(e,t){return t.getAttribute("data-delta")-e.getAttribute("data-delta")})),o.innerHTML="";for(var d=0,m=p.length;d0)for(var n=0;n0)for(var n=0;n0?this.sc.scrollTop=i+this.sc.suggestionHeight+o-this.sc.maxHeight:i<0&&(this.sc.scrollTop=i+o)}}},{key:"blurHandler",value:function(){var e=this;try{var t=this.root.querySelector(".wb-autocomplete-suggestions:hover")}catch(e){t=null}t?this.input!==document.activeElement&&setTimeout((function(){return e.focus()}),20):(this.last_val=this.input.value,this.sc.style.display="none",setTimeout((function(){return e.sc.style.display="none"}),350))}},{key:"suggest",value:function(e){var t=this.input.value;if(this.cache[t]=e,e.length&&t.length>=this.minChars){for(var n="",o=0;o40)&&13!=n&&27!=n){var o=this.input.value;if(o.length>=this.minChars){if(o!=this.last_val){if(this.last_val=o,clearTimeout(this.timer),this.cache){if(o in this.cache)return void this.suggest(this.cache[o]);for(var i=1;i'+e.replace(n,"$1")+""}},{key:"onSelect",value:function(e,t,n){}}]),e}(),j=function(){function e(t,n){S(this,e);var o=t.getRootNode();if(o.querySelector){var i="object"==_(t)?[t]:o.querySelectorAll(t);this.elems=i.map((function(e){return new E(e,n)}))}}return T(e,[{key:"destroy",value:function(){for(;this.elems.length>0;)this.elems.pop().unload()}}]),e}(),R=n(2),A=window.JSON,N=window.open,U=window.Date,I=document,D=document,P=function(e){return D.getElementById(e)};var q,F="/static/";function B(e){L.classList.contains("wm-closed")?(e&&O.classList.add("notice-only"),L.classList.replace("wm-closed","wm-open"),O.style.display="block",m(q,F,P)):(L.classList.replace("wm-open","wm-closed"),O.style.display="none",O.classList.remove("notice-only"))}function W(e,t){var n=P(e);n&&(n.style.visibility=t?"visible":"hidden")}function X(e,t){Object(c.d)(e)||(e=[e]);for(var n=0;n0&&r<60,r)}))}window.__wm={init:function(e){!function(){var e=document.cookie.split(";");if(e.length>40)for(var t=0;t1?t-1:0),o=1;o0;)x.appendChild(C.children[0]);if(d)for(var H=0;H'+((""+n).replace(/\B(?=(\d{3})+$)/g,",")+" ")+(n>1?"captures":"capture")+"",f=l.a(i,"%d %b %Y");s!=i&&(f+=" - "+l.a(s,"%d %b %Y")),h+='
'+f+"
",t.innerHTML=h}(o),function(e,t,n,o,i,r,s){var a=o.getContext("2d");if(a){a.fillStyle="#FFF";var c=(new u).getUTCFullYear(),l=t/(c-i+1),h=f(e.years),p=h[0],d=n/h[1];if(r>=i){var m=T(r);a.fillStyle="#FFFFA5",a.fillRect(m,0,l,n)}for(var v=i;v<=c;v++){m=T(v);a.beginPath(),a.moveTo(m,0),a.lineTo(m,n),a.lineWidth=1,a.strokeStyle="#CCC",a.stroke()}s=parseInt(s)-1;for(var g=(l-1)/12,y=0;y0){var M=Math.ceil(S*d);a.fillStyle=v==r&&_==s?"#EC008C":"#000",a.fillRect(Math.round(b),Math.ceil(n-M),Math.ceil(g),Math.round(M))}b+=g}}}function T(e){return Math.ceil((e-i)*l)+.5}}(o,e,t,Z,a,_,S)}}))}else{var te=new Image;te.src="/__wb/sparkline?url="+encodeURIComponent(r)+"&width="+e+"&height="+t+"&selected_year="+_+"&selected_month="+S+(i&&"&collection="+i||""),te.alt="sparkline",te.width=e,te.height=t,te.id="sparklineImgId",te.border="0",Q.parentNode.replaceChild(te,Q)}function ne(e){for(var t=[],n=e.length,o=0;o + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Process graphics to OT + OT sent to GPU + GPU idle + GPU busy + Process graphics to OT + GPU busy + OT sent to GPU + GPU busy + + + Wait for GPU (DrawSync()) + GPU finished + + Process graphics to OT + GPU idle + OT sent to GPU + GPU busy + + Wait for GPU (DrawSync()) + GPU finished + GPU idle + Process graphics to OT + OT sent to GPU + GPU busy + + + Single OT+Prim. Buffer + Double OT+Prim. Buffer + + + + + + + + + + + + + + + + + + + + + diff --git a/Docs/Chapter 1.2 Drawing Graphics_files/ordertable-multiprims.svg b/Docs/Chapter 1.2 Drawing Graphics_files/ordertable-multiprims.svg new file mode 100644 index 0000000..980bef1 --- /dev/null +++ b/Docs/Chapter 1.2 Drawing Graphics_files/ordertable-multiprims.svg @@ -0,0 +1,705 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + Primitive 2 + + OT[0]=0xffffffff (end) + Start of table + + + OT[1] + + OT[2] + + OT[3] + + OT[4] + + OT[5] + + OT[6] + + OT[7] + + + + + + + + + + + + + + Primitive 1 + Primitive 3 + + diff --git a/Docs/Chapter 1.2 Drawing Graphics_files/ordertable-primitive.svg b/Docs/Chapter 1.2 Drawing Graphics_files/ordertable-primitive.svg new file mode 100644 index 0000000..d1987ae --- /dev/null +++ b/Docs/Chapter 1.2 Drawing Graphics_files/ordertable-primitive.svg @@ -0,0 +1,657 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + Primitive + + OT[0]=0xffffffff (end) + Start of table + + + OT[1] + + OT[2] + + OT[3] + + OT[4] + + OT[5] + + OT[6] + + OT[7] + + + + + + + + + + + diff --git a/Docs/Chapter 1.2 Drawing Graphics_files/ordertable.svg b/Docs/Chapter 1.2 Drawing Graphics_files/ordertable.svg new file mode 100644 index 0000000..a11b238 --- /dev/null +++ b/Docs/Chapter 1.2 Drawing Graphics_files/ordertable.svg @@ -0,0 +1,633 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + OT[0]=0xffffffff (end) + Start of table + + + OT[1] + + OT[2] + + OT[3] + + OT[4] + + OT[5] + + OT[6] + + OT[7] + + + + + + + + + diff --git a/Docs/Chapter 1.2 Drawing Graphics_files/primstruct.svg b/Docs/Chapter 1.2 Drawing Graphics_files/primstruct.svg new file mode 100644 index 0000000..a4b5e44 --- /dev/null +++ b/Docs/Chapter 1.2 Drawing Graphics_files/primstruct.svg @@ -0,0 +1,350 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + 31 + 0 + Next Pointer + Len + R + G + B + Code + X + Y + U + V + CLUT + Width + Height + + + + + + + + + + + + + + + + diff --git a/Docs/Chapter 1.2 Drawing Graphics_files/style.css b/Docs/Chapter 1.2 Drawing Graphics_files/style.css new file mode 100644 index 0000000..1eac881 --- /dev/null +++ b/Docs/Chapter 1.2 Drawing Graphics_files/style.css @@ -0,0 +1,70 @@ +body { + max-width: 900px; + margin: auto; + padding: 8px; + font-family: sans-serif; + font-size: 14px; + //color: white; + //background: black; +} + +h { + background-color: #e0e0e0; + padding: 2px; +} + +h2 { + border-bottom: 1px solid; + //padding-left: 8px; +} + +img { + display: block; +} + +.footer-table { + font-size: 14px; +} + +.bordered-table { + border-collapse: collapse; + font-size: 11px; +} + +.bordered-table th, .bordered-table td { + border: 1px solid; + padding: 4px; +} + +hr { + border: none; + border-bottom: 1px solid black; +} + +pre { + padding: 8px; + font-size: 12px; + color: black; + background-color: LightGray; +} +/* + FILE ARCHIVED ON 03:35:25 Aug 27, 2022 AND RETRIEVED FROM THE + INTERNET ARCHIVE ON 15:39:09 Sep 05, 2022. + JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE. + + ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C. + SECTION 108(a)(3)). +*/ +/* +playback timings (ms): + captures_list: 107.165 + exclusion.robots: 0.073 + exclusion.robots.policy: 0.067 + cdx.remote: 0.064 + esindex: 0.009 + LoadShardBlock: 52.713 (3) + PetaboxLoader3.datanode: 140.466 (4) + CDXLines.iter: 14.771 (3) + load_resource: 139.896 + PetaboxLoader3.resolve: 47.824 +*/ \ No newline at end of file diff --git a/Docs/Chapter 1.2 Drawing Graphics_files/wombat.js b/Docs/Chapter 1.2 Drawing Graphics_files/wombat.js new file mode 100644 index 0000000..19d1a47 --- /dev/null +++ b/Docs/Chapter 1.2 Drawing Graphics_files/wombat.js @@ -0,0 +1,21 @@ +/* +Wombat.js client-side rewriting engine for web archive replay +Copyright (C) 2014-2020 Webrecorder Software, Rhizome, and Contributors. Released under the GNU Affero General Public License. + +This file is part of wombat.js, see https://github.com/webrecorder/wombat.js for the full source +Wombat.js is part of the Webrecorder project (https://github.com/webrecorder) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . + */ +(function(){function FuncMap(){this._map=[]}function ensureNumber(maybeNumber){try{switch(typeof maybeNumber){case"number":case"bigint":return maybeNumber;}var converted=Number(maybeNumber);return isNaN(converted)?null:converted}catch(e){}return null}function addToStringTagToClass(clazz,tag){typeof self.Symbol!=="undefined"&&typeof self.Symbol.toStringTag!=="undefined"&&Object.defineProperty(clazz.prototype,self.Symbol.toStringTag,{value:tag,enumerable:false})}function autobind(clazz){for(var prop,propValue,proto=clazz.__proto__||clazz.constructor.prototype||clazz.prototype,clazzProps=Object.getOwnPropertyNames(proto),len=clazzProps.length,i=0;i=0){var fnMapping=this._map.splice(idx,1);return fnMapping[0][1]}return null},FuncMap.prototype.map=function(param){for(var i=0;i0&&afw.preserveMedia(media)})},AutoFetcher.prototype.terminate=function(){this.worker.terminate()},AutoFetcher.prototype.justFetch=function(urls){this.worker.postMessage({type:"fetch-all",values:urls})},AutoFetcher.prototype.fetchAsPage=function(url,originalUrl,title){if(url){var headers={"X-Wombat-History-Page":originalUrl};if(title){var encodedTitle=encodeURIComponent(title.trim());title&&(headers["X-Wombat-History-Title"]=encodedTitle)}var fetchData={url:url,options:{headers:headers,cache:"no-store"}};this.justFetch([fetchData])}},AutoFetcher.prototype.postMessage=function(msg,deferred){if(deferred){var afWorker=this;return void Promise.resolve().then(function(){afWorker.worker.postMessage(msg)})}this.worker.postMessage(msg)},AutoFetcher.prototype.preserveSrcset=function(srcset,mod){this.postMessage({type:"values",srcset:{value:srcset,mod:mod,presplit:true}},true)},AutoFetcher.prototype.preserveDataSrcset=function(elem){this.postMessage({type:"values",srcset:{value:elem.dataset.srcset,mod:this.rwMod(elem),presplit:false}},true)},AutoFetcher.prototype.preserveMedia=function(media){this.postMessage({type:"values",media:media},true)},AutoFetcher.prototype.getSrcset=function(elem){return this.wombat.wb_getAttribute?this.wombat.wb_getAttribute.call(elem,"srcset"):elem.getAttribute("srcset")},AutoFetcher.prototype.rwMod=function(elem){switch(elem.tagName){case"SOURCE":return elem.parentElement&&elem.parentElement.tagName==="PICTURE"?"im_":"oe_";case"IMG":return"im_";}return"oe_"},AutoFetcher.prototype.extractFromLocalDoc=function(){var afw=this;Promise.resolve().then(function(){for(var msg={type:"values",context:{docBaseURI:document.baseURI}},media=[],i=0,sheets=document.styleSheets;i=0)||scriptType.indexOf("text/template")>=0)},Wombat.prototype.skipWrapScriptTextBasedOnText=function(text){if(!text||text.indexOf(this.WB_ASSIGN_FUNC)>=0||text.indexOf("<")===0)return true;for(var override_props=["window","self","document","location","top","parent","frames","opener"],i=0;i=0)return false;return true},Wombat.prototype.nodeHasChildren=function(node){if(!node)return false;if(typeof node.hasChildNodes==="function")return node.hasChildNodes();var kids=node.children||node.childNodes;return!!kids&&kids.length>0},Wombat.prototype.rwModForElement=function(elem,attrName){if(!elem)return undefined;var mod="mp_";if(!(elem.tagName==="LINK"&&attrName==="href")){var maybeMod=this.tagToMod[elem.tagName];maybeMod!=null&&(mod=maybeMod[attrName])}else if(elem.rel){var relV=elem.rel.trim().toLowerCase(),asV=this.wb_getAttribute.call(elem,"as");if(asV&&this.linkTagMods.linkRelToAs[relV]!=null){var asMods=this.linkTagMods.linkRelToAs[relV];mod=asMods[asV.toLowerCase()]}else this.linkTagMods[relV]!=null&&(mod=this.linkTagMods[relV])}return mod},Wombat.prototype.removeWBOSRC=function(elem){elem.tagName!=="SCRIPT"||elem.__$removedWBOSRC$__||(elem.hasAttribute("__wb_orig_src")&&elem.removeAttribute("__wb_orig_src"),elem.__$removedWBOSRC$__=true)},Wombat.prototype.retrieveWBOSRC=function(elem){if(elem.tagName==="SCRIPT"&&!elem.__$removedWBOSRC$__){var maybeWBOSRC;return maybeWBOSRC=this.wb_getAttribute?this.wb_getAttribute.call(elem,"__wb_orig_src"):elem.getAttribute("__wb_orig_src"),maybeWBOSRC==null&&(elem.__$removedWBOSRC$__=true),maybeWBOSRC}return undefined},Wombat.prototype.wrapScriptTextJsProxy=function(scriptText){return"var _____WB$wombat$assign$function_____ = function(name) {return (self._wb_wombat && self._wb_wombat.local_init && self._wb_wombat.local_init(name)) || self[name]; };\nif (!self.__WB_pmw) { self.__WB_pmw = function(obj) { this.__WB_source = obj; return this; } }\n{\nlet window = _____WB$wombat$assign$function_____(\"window\");\nlet self = _____WB$wombat$assign$function_____(\"self\");\nlet document = _____WB$wombat$assign$function_____(\"document\");\nlet location = _____WB$wombat$assign$function_____(\"location\");\nlet top = _____WB$wombat$assign$function_____(\"top\");\nlet parent = _____WB$wombat$assign$function_____(\"parent\");\nlet frames = _____WB$wombat$assign$function_____(\"frames\");\nlet opener = _____WB$wombat$assign$function_____(\"opener\");\n"+scriptText.replace(this.DotPostMessageRe,".__WB_pmw(self.window)$1")+"\n\n}"},Wombat.prototype.watchElem=function(elem,func){if(!this.$wbwindow.MutationObserver)return false;var m=new this.$wbwindow.MutationObserver(function(records,observer){for(var r,i=0;i"},Wombat.prototype.getFinalUrl=function(useRel,mod,url){var prefix=useRel?this.wb_rel_prefix:this.wb_abs_prefix;return mod==null&&(mod=this.wb_info.mod),this.wb_info.is_live||(prefix+=this.wb_info.wombat_ts),prefix+=mod,prefix[prefix.length-1]!=="/"&&(prefix+="/"),prefix+url},Wombat.prototype.resolveRelUrl=function(url,doc){var docObj=doc||this.$wbwindow.document,parser=this.makeParser(docObj.baseURI,docObj),hash=parser.href.lastIndexOf("#"),href=hash>=0?parser.href.substring(0,hash):parser.href,lastslash=href.lastIndexOf("/");return parser.href=lastslash>=0&&lastslash!==href.length-1?href.substring(0,lastslash+1)+url:href+url,parser.href},Wombat.prototype.extractOriginalURL=function(rewrittenUrl){if(!rewrittenUrl)return"";if(this.wb_is_proxy)return rewrittenUrl;var rwURLString=rewrittenUrl.toString(),url=rwURLString;if(this.startsWithOneOf(url,this.IGNORE_PREFIXES))return url;var start;start=this.startsWith(url,this.wb_abs_prefix)?this.wb_abs_prefix.length:this.wb_rel_prefix&&this.startsWith(url,this.wb_rel_prefix)?this.wb_rel_prefix.length:this.wb_rel_prefix?1:0;var index=url.indexOf("/http",start);return index<0&&(index=url.indexOf("///",start)),index<0&&(index=url.indexOf("/blob:",start)),index<0&&(index=url.indexOf("/about:blank",start)),index>=0?url=url.substr(index+1):(index=url.indexOf(this.wb_replay_prefix),index>=0&&(url=url.substr(index+this.wb_replay_prefix.length)),url.length>4&&url.charAt(2)==="_"&&url.charAt(3)==="/"&&(url=url.substr(4)),url!==rwURLString&&!this.startsWithOneOf(url,this.VALID_PREFIXES)&&!this.startsWith(url,"blob:")&&(url=this.wb_orig_scheme+url)),rwURLString.charAt(0)==="/"&&rwURLString.charAt(1)!=="/"&&this.startsWith(url,this.wb_orig_origin)&&(url=url.substr(this.wb_orig_origin.length)),this.startsWith(url,this.REL_PREFIX)?this.wb_info.wombat_scheme+":"+url:url},Wombat.prototype.makeParser=function(maybeRewrittenURL,doc){var originalURL=this.extractOriginalURL(maybeRewrittenURL),docElem=doc;return doc||(this.$wbwindow.location.href==="about:blank"&&this.$wbwindow.opener?docElem=this.$wbwindow.opener.document:docElem=this.$wbwindow.document),this._makeURLParser(originalURL,docElem)},Wombat.prototype._makeURLParser=function(url,docElem){try{return new this.$wbwindow.URL(url,docElem.baseURI)}catch(e){}var p=docElem.createElement("a");return p._no_rewrite=true,p.href=url,p},Wombat.prototype.defProp=function(obj,prop,setFunc,getFunc,enumerable){var existingDescriptor=Object.getOwnPropertyDescriptor(obj,prop);if(existingDescriptor&&!existingDescriptor.configurable)return false;if(!getFunc)return false;var descriptor={configurable:true,enumerable:enumerable||false,get:getFunc};setFunc&&(descriptor.set=setFunc);try{return Object.defineProperty(obj,prop,descriptor),true}catch(e){return console.warn("Failed to redefine property %s",prop,e.message),false}},Wombat.prototype.defGetterProp=function(obj,prop,getFunc,enumerable){var existingDescriptor=Object.getOwnPropertyDescriptor(obj,prop);if(existingDescriptor&&!existingDescriptor.configurable)return false;if(!getFunc)return false;try{return Object.defineProperty(obj,prop,{configurable:true,enumerable:enumerable||false,get:getFunc}),true}catch(e){return console.warn("Failed to redefine property %s",prop,e.message),false}},Wombat.prototype.getOrigGetter=function(obj,prop){var orig_getter;if(obj.__lookupGetter__&&(orig_getter=obj.__lookupGetter__(prop)),!orig_getter&&Object.getOwnPropertyDescriptor){var props=Object.getOwnPropertyDescriptor(obj,prop);props&&(orig_getter=props.get)}return orig_getter},Wombat.prototype.getOrigSetter=function(obj,prop){var orig_setter;if(obj.__lookupSetter__&&(orig_setter=obj.__lookupSetter__(prop)),!orig_setter&&Object.getOwnPropertyDescriptor){var props=Object.getOwnPropertyDescriptor(obj,prop);props&&(orig_setter=props.set)}return orig_setter},Wombat.prototype.getAllOwnProps=function(obj){for(var ownProps=[],props=Object.getOwnPropertyNames(obj),i=0;i "+final_href),actualLocation.href=final_href}}},Wombat.prototype.checkLocationChange=function(wombatLoc,isTop){var locType=typeof wombatLoc,actual_location=isTop?this.$wbwindow.__WB_replay_top.location:this.$wbwindow.location;locType==="string"?this.updateLocation(wombatLoc,actual_location.href,actual_location):locType==="object"&&this.updateLocation(wombatLoc.href,wombatLoc._orig_href,actual_location)},Wombat.prototype.checkAllLocations=function(){return!this.wb_wombat_updating&&void(this.wb_wombat_updating=true,this.checkLocationChange(this.$wbwindow.WB_wombat_location,false),this.$wbwindow.WB_wombat_location!=this.$wbwindow.__WB_replay_top.WB_wombat_location&&this.checkLocationChange(this.$wbwindow.__WB_replay_top.WB_wombat_location,true),this.wb_wombat_updating=false)},Wombat.prototype.proxyToObj=function(source){if(source)try{var proxyRealObj=source.__WBProxyRealObj__;if(proxyRealObj)return proxyRealObj}catch(e){}return source},Wombat.prototype.objToProxy=function(obj){if(obj)try{var maybeWbProxy=obj._WB_wombat_obj_proxy;if(maybeWbProxy)return maybeWbProxy}catch(e){}return obj},Wombat.prototype.defaultProxyGet=function(obj,prop,ownProps,fnCache){switch(prop){case"__WBProxyRealObj__":return obj;case"location":case"WB_wombat_location":return obj.WB_wombat_location;case"_WB_wombat_obj_proxy":return obj._WB_wombat_obj_proxy;case"__WB_pmw":case"WB_wombat_eval":case this.WB_ASSIGN_FUNC:case this.WB_CHECK_THIS_FUNC:return obj[prop];case"origin":return obj.WB_wombat_location.origin;case"constructor":if(obj.constructor===Window)return obj.constructor;}var retVal=obj[prop],type=typeof retVal;if(type==="function"&&ownProps.indexOf(prop)!==-1){switch(prop){case"requestAnimationFrame":case"cancelAnimationFrame":{if(!this.isNativeFunction(retVal))return retVal;break}}var cachedFN=fnCache[prop];return cachedFN&&cachedFN.original===retVal||(cachedFN={original:retVal,boundFn:retVal.bind(obj)},fnCache[prop]=cachedFN),cachedFN.boundFn}return type==="object"&&retVal&&retVal._WB_wombat_obj_proxy?(retVal instanceof Window&&this.initNewWindowWombat(retVal),retVal._WB_wombat_obj_proxy):retVal},Wombat.prototype.setLoc=function(loc,originalURL){var parser=this.makeParser(originalURL,loc.ownerDocument);loc._orig_href=originalURL,loc._parser=parser;var href=parser.href;loc._hash=parser.hash,loc._href=href,loc._host=parser.host,loc._hostname=parser.hostname,loc._origin=parser.origin?parser.host?parser.origin:"null":parser.protocol+"//"+parser.hostname+(parser.port?":"+parser.port:""),loc._pathname=parser.pathname,loc._port=parser.port,loc._protocol=parser.protocol,loc._search=parser.search,Object.defineProperty||(loc.href=href,loc.hash=parser.hash,loc.host=loc._host,loc.hostname=loc._hostname,loc.origin=loc._origin,loc.pathname=loc._pathname,loc.port=loc._port,loc.protocol=loc._protocol,loc.search=loc._search)},Wombat.prototype.makeGetLocProp=function(prop,origGetter){var wombat=this;return function newGetLocProp(){if(this._no_rewrite)return origGetter.call(this,prop);var curr_orig_href=origGetter.call(this,"href");return prop==="href"?wombat.extractOriginalURL(curr_orig_href):prop==="ancestorOrigins"?[]:(this._orig_href!==curr_orig_href&&wombat.setLoc(this,curr_orig_href),this["_"+prop])}},Wombat.prototype.makeSetLocProp=function(prop,origSetter,origGetter){var wombat=this;return function newSetLocProp(value){if(this._no_rewrite)return origSetter.call(this,prop,value);if(this["_"+prop]!==value){if(this["_"+prop]=value,!this._parser){var href=origGetter.call(this);this._parser=wombat.makeParser(href,this.ownerDocument)}var rel=false;prop==="href"&&typeof value==="string"&&value&&(value[0]==="."?value=wombat.resolveRelUrl(value,this.ownerDocument):value[0]==="/"&&(value.length<=1||value[1]!=="/")&&(rel=true,value=WB_wombat_location.origin+value));try{this._parser[prop]=value}catch(e){console.log("Error setting "+prop+" = "+value)}prop==="hash"?(value=this._parser[prop],origSetter.call(this,"hash",value)):(rel=rel||value===this._parser.pathname,value=wombat.rewriteUrl(this._parser.href,rel),origSetter.call(this,"href",value))}}},Wombat.prototype.styleReplacer=function(match,n1,n2,n3,offset,string){return n1+this.rewriteUrl(n2)+n3},Wombat.prototype.domConstructorErrorChecker=function(thisObj,what,args,numRequiredArgs){var errorMsg,needArgs=typeof numRequiredArgs==="number"?numRequiredArgs:1;if(thisObj instanceof Window?errorMsg="Failed to construct '"+what+"': Please use the 'new' operator, this DOM object constructor cannot be called as a function.":args&&args.length=0)return url;if(url.indexOf(this.wb_rel_prefix)===0&&url.indexOf("http")>1){var scheme_sep=url.indexOf(":/");return scheme_sep>0&&url[scheme_sep+2]!=="/"?url.substring(0,scheme_sep+2)+"/"+url.substring(scheme_sep+2):url}return this.getFinalUrl(true,mod,this.wb_orig_origin+url)}url.charAt(0)==="."&&(url=this.resolveRelUrl(url,doc));var prefix=this.startsWithOneOf(url.toLowerCase(),this.VALID_PREFIXES);if(prefix){var orig_host=this.$wbwindow.__WB_replay_top.location.host,orig_protocol=this.$wbwindow.__WB_replay_top.location.protocol,prefix_host=prefix+orig_host+"/";if(this.startsWith(url,prefix_host)){if(this.startsWith(url,this.wb_replay_prefix))return url;var curr_scheme=orig_protocol+"//",path=url.substring(prefix_host.length),rebuild=false;return path.indexOf(this.wb_rel_prefix)<0&&url.indexOf("/static/")<0&&(path=this.getFinalUrl(true,mod,WB_wombat_location.origin+"/"+path),rebuild=true),prefix!==curr_scheme&&prefix!==this.REL_PREFIX&&(rebuild=true),rebuild&&(url=useRel?"":curr_scheme+orig_host,path&&path[0]!=="/"&&(url+="/"),url+=path),url}return this.getFinalUrl(useRel,mod,url)}return prefix=this.startsWithOneOf(url,this.BAD_PREFIXES),prefix?this.getFinalUrl(useRel,mod,this.extractOriginalURL(url)):this.isHostUrl(url)&&!this.startsWith(url,originalLoc.host+"/")?this.getFinalUrl(useRel,mod,this.wb_orig_scheme+url):url},Wombat.prototype.rewriteUrl=function(url,useRel,mod,doc){var rewritten=this.rewriteUrl_(url,useRel,mod,doc);return this.debug_rw&&(url===rewritten?console.log("NOT REWRITTEN "+url):console.log("REWRITE: "+url+" -> "+rewritten)),rewritten},Wombat.prototype.performAttributeRewrite=function(elem,name,value,absUrlOnly){switch(name){case"innerHTML":case"outerHTML":return this.rewriteHtml(value);case"filter":return this.rewriteInlineStyle(value);case"style":return this.rewriteStyle(value);case"srcset":return this.rewriteSrcset(value,elem);}if(absUrlOnly&&!this.startsWithOneOf(value,this.VALID_PREFIXES))return value;var mod=this.rwModForElement(elem,name);return this.wbUseAFWorker&&this.WBAutoFetchWorker&&this.isSavedDataSrcSrcset(elem)&&this.WBAutoFetchWorker.preserveDataSrcset(elem),this.rewriteUrl(value,false,mod,elem.ownerDocument)},Wombat.prototype.rewriteAttr=function(elem,name,absUrlOnly){var changed=false;if(!elem||!elem.getAttribute||elem._no_rewrite||elem["_"+name])return changed;var value=this.wb_getAttribute.call(elem,name);if(!value||this.startsWith(value,"javascript:"))return changed;var new_value=this.performAttributeRewrite(elem,name,value,absUrlOnly);return new_value!==value&&(this.removeWBOSRC(elem),this.wb_setAttribute.call(elem,name,new_value),changed=true),changed},Wombat.prototype.noExceptRewriteStyle=function(style){try{return this.rewriteStyle(style)}catch(e){return style}},Wombat.prototype.rewriteStyle=function(style){if(!style)return style;var value=style;return typeof style==="object"&&(value=style.toString()),typeof value==="string"?value.replace(this.STYLE_REGEX,this.styleReplacer).replace(this.IMPORT_REGEX,this.styleReplacer).replace(this.no_wombatRe,""):value},Wombat.prototype.rewriteSrcset=function(value,elem){if(!value)return"";for(var split=value.split(this.srcsetRe),values=[],mod=this.rwModForElement(elem,"srcset"),i=0;i=0){var JS="javascript:";new_value="javascript:window.parent._wb_wombat.initNewWindowWombat(window);"+value.substr(11)}return new_value||(new_value=this.rewriteUrl(value,false,this.rwModForElement(elem,attrName))),new_value!==value&&(this.wb_setAttribute.call(elem,attrName,new_value),true)},Wombat.prototype.rewriteScript=function(elem){if(elem.hasAttribute("src")||!elem.textContent||!this.$wbwindow.Proxy)return this.rewriteAttr(elem,"src");if(this.skipWrapScriptBasedOnType(elem.type))return false;var text=elem.textContent.trim();return!this.skipWrapScriptTextBasedOnText(text)&&(elem.textContent=this.wrapScriptTextJsProxy(text),true)},Wombat.prototype.rewriteSVGElem=function(elem){var changed=this.rewriteAttr(elem,"filter");return changed=this.rewriteAttr(elem,"style")||changed,changed=this.rewriteAttr(elem,"xlink:href")||changed,changed=this.rewriteAttr(elem,"href")||changed,changed=this.rewriteAttr(elem,"src")||changed,changed},Wombat.prototype.rewriteElem=function(elem){var changed=false;if(!elem)return changed;if(elem instanceof SVGElement)changed=this.rewriteSVGElem(elem);else switch(elem.tagName){case"META":var maybeCSP=this.wb_getAttribute.call(elem,"http-equiv");maybeCSP&&maybeCSP.toLowerCase()==="content-security-policy"&&(this.wb_setAttribute.call(elem,"http-equiv","_"+maybeCSP),changed=true);break;case"STYLE":var new_content=this.rewriteStyle(elem.textContent);elem.textContent!==new_content&&(elem.textContent=new_content,changed=true,this.wbUseAFWorker&&this.WBAutoFetchWorker&&elem.sheet!=null&&this.WBAutoFetchWorker.deferredSheetExtraction(elem.sheet));break;case"LINK":changed=this.rewriteAttr(elem,"href"),this.wbUseAFWorker&&elem.rel==="stylesheet"&&this._addEventListener(elem,"load",this.utilFns.wbSheetMediaQChecker);break;case"IMG":changed=this.rewriteAttr(elem,"src"),changed=this.rewriteAttr(elem,"srcset")||changed,changed=this.rewriteAttr(elem,"style")||changed,this.wbUseAFWorker&&this.WBAutoFetchWorker&&elem.dataset.srcset&&this.WBAutoFetchWorker.preserveDataSrcset(elem);break;case"OBJECT":if(this.wb_info.isSW&&elem.parentElement&&elem.getAttribute("type")==="application/pdf"){for(var iframe=this.$wbwindow.document.createElement("IFRAME"),i=0;i0;)for(var child,children=rewriteQ.shift(),i=0;i"+rwString+"","text/html");if(!inner_doc||!this.nodeHasChildren(inner_doc.head)||!inner_doc.head.children[0].content)return rwString;var template=inner_doc.head.children[0];if(template._no_rewrite=true,this.recurseRewriteElem(template.content)){var new_html=template.innerHTML;if(checkEndTag){var first_elem=template.content.children&&template.content.children[0];if(first_elem){var end_tag="";this.endsWith(new_html,end_tag)&&!this.endsWith(rwString.toLowerCase(),end_tag)&&(new_html=new_html.substring(0,new_html.length-end_tag.length))}else if(rwString[0]!=="<"||rwString[rwString.length-1]!==">")return this.write_buff+=rwString,undefined}return new_html}return rwString},Wombat.prototype.rewriteHtmlFull=function(string,checkEndTag){var inner_doc=new DOMParser().parseFromString(string,"text/html");if(!inner_doc)return string;for(var changed=false,i=0;i=0)inner_doc.documentElement._no_rewrite=true,new_html=this.reconstructDocType(inner_doc.doctype)+inner_doc.documentElement.outerHTML;else{inner_doc.head._no_rewrite=true,inner_doc.body._no_rewrite=true;var headHasKids=this.nodeHasChildren(inner_doc.head),bodyHasKids=this.nodeHasChildren(inner_doc.body);if(new_html=(headHasKids?inner_doc.head.outerHTML:"")+(bodyHasKids?inner_doc.body.outerHTML:""),checkEndTag)if(inner_doc.all.length>3){var end_tag="";this.endsWith(new_html,end_tag)&&!this.endsWith(string.toLowerCase(),end_tag)&&(new_html=new_html.substring(0,new_html.length-end_tag.length))}else if(string[0]!=="<"||string[string.length-1]!==">")return void(this.write_buff+=string);new_html=this.reconstructDocType(inner_doc.doctype)+new_html}return new_html}return string},Wombat.prototype.rewriteInlineStyle=function(orig){var decoded;try{decoded=decodeURIComponent(orig)}catch(e){decoded=orig}if(decoded!==orig){var parts=this.rewriteStyle(decoded).split(",",2);return parts[0]+","+encodeURIComponent(parts[1])}return this.rewriteStyle(orig)},Wombat.prototype.rewriteCookie=function(cookie){var wombat=this,rwCookie=cookie.replace(this.wb_abs_prefix,"").replace(this.wb_rel_prefix,"");return rwCookie=rwCookie.replace(this.cookie_domain_regex,function(m,m1){var message={domain:m1,cookie:rwCookie,wb_type:"cookie"};return wombat.sendTopMessage(message,true),wombat.$wbwindow.location.hostname.indexOf(".")>=0&&!wombat.IP_RX.test(wombat.$wbwindow.location.hostname)?"Domain=."+wombat.$wbwindow.location.hostname:""}).replace(this.cookie_path_regex,function(m,m1){var rewritten=wombat.rewriteUrl(m1);return rewritten.indexOf(wombat.wb_curr_host)===0&&(rewritten=rewritten.substring(wombat.wb_curr_host.length)),"Path="+rewritten}),wombat.$wbwindow.location.protocol!=="https:"&&(rwCookie=rwCookie.replace("secure","")),rwCookie.replace(",|",",")},Wombat.prototype.rewriteWorker=function(workerUrl){if(!workerUrl)return workerUrl;var isBlob=workerUrl.indexOf("blob:")===0,isJS=workerUrl.indexOf("javascript:")===0;if(!isBlob&&!isJS){if(!this.startsWithOneOf(workerUrl,this.VALID_PREFIXES)&&!this.startsWith(workerUrl,"/")&&!this.startsWithOneOf(workerUrl,this.BAD_PREFIXES)){var rurl=this.resolveRelUrl(workerUrl,this.$wbwindow.document);return this.rewriteUrl(rurl,false,"wkr_",this.$wbwindow.document)}return this.rewriteUrl(workerUrl,false,"wkr_",this.$wbwindow.document)}var workerCode=isJS?workerUrl.replace("javascript:",""):null;if(isBlob){var x=new XMLHttpRequest;this.utilFns.XHRopen.call(x,"GET",workerUrl,false),this.utilFns.XHRsend.call(x),workerCode=x.responseText.replace(this.workerBlobRe,"").replace(this.rmCheckThisInjectRe,"this")}if(this.wb_info.static_prefix||this.wb_info.ww_rw_script){var originalURL=this.$wbwindow.document.baseURI,ww_rw=this.wb_info.ww_rw_script||this.wb_info.static_prefix+"wombatWorkers.js",rw="(function() { self.importScripts('"+ww_rw+"'); new WBWombat({'prefix': '"+this.wb_abs_prefix+"', 'prefixMod': '"+this.wb_abs_prefix+"wkrf_/', 'originalURL': '"+originalURL+"'}); })();";workerCode=rw+workerCode}var blob=new Blob([workerCode],{type:"application/javascript"});return URL.createObjectURL(blob)},Wombat.prototype.rewriteTextNodeFn=function(fnThis,originalFn,argsObj){var args,deproxiedThis=this.proxyToObj(fnThis);if(argsObj.length>0&&deproxiedThis.parentElement&&deproxiedThis.parentElement.tagName==="STYLE"){args=new Array(argsObj.length);var dataIndex=argsObj.length-1;dataIndex===2?(args[0]=argsObj[0],args[1]=argsObj[1]):dataIndex===1&&(args[0]=argsObj[0]),args[dataIndex]=this.rewriteStyle(argsObj[dataIndex])}else args=argsObj;return originalFn.__WB_orig_apply?originalFn.__WB_orig_apply(deproxiedThis,args):originalFn.apply(deproxiedThis,args)},Wombat.prototype.rewriteDocWriteWriteln=function(fnThis,originalFn,argsObj){var string,thisObj=this.proxyToObj(fnThis),argLen=argsObj.length;if(argLen===0)return originalFn.call(thisObj);string=argLen===1?argsObj[0]:Array.prototype.join.call(argsObj,"");var new_buff=this.rewriteHtml(string,true),res=originalFn.call(thisObj,new_buff);return this.initNewWindowWombat(thisObj.defaultView),res},Wombat.prototype.rewriteChildNodeFn=function(fnThis,originalFn,argsObj){var thisObj=this.proxyToObj(fnThis);if(argsObj.length===0)return originalFn.call(thisObj);var newArgs=this.rewriteElementsInArguments(argsObj);return originalFn.__WB_orig_apply?originalFn.__WB_orig_apply(thisObj,newArgs):originalFn.apply(thisObj,newArgs)},Wombat.prototype.rewriteInsertAdjHTMLOrElemArgs=function(fnThis,originalFn,position,textOrElem,rwHTML){var fnThisObj=this.proxyToObj(fnThis);return fnThisObj._no_rewrite?originalFn.call(fnThisObj,position,textOrElem):rwHTML?originalFn.call(fnThisObj,position,this.rewriteHtml(textOrElem)):(this.rewriteElemComplete(textOrElem),originalFn.call(fnThisObj,position,textOrElem))},Wombat.prototype.rewriteSetTimeoutInterval=function(fnThis,originalFn,argsObj){var rw=this.isString(argsObj[0]),args=rw?new Array(argsObj.length):argsObj;if(rw){args[0]=this.$wbwindow.Proxy?this.wrapScriptTextJsProxy(argsObj[0]):argsObj[0].replace(/\blocation\b/g,"WB_wombat_$&");for(var i=1;i0&&cssStyleValueOverride(this.$wbwindow.CSSStyleValue,"parse"),this.$wbwindow.CSSStyleValue.parseAll&&this.$wbwindow.CSSStyleValue.parseAll.toString().indexOf("[native code]")>0&&cssStyleValueOverride(this.$wbwindow.CSSStyleValue,"parseAll")}if(this.$wbwindow.CSSKeywordValue&&this.$wbwindow.CSSKeywordValue.prototype){var oCSSKV=this.$wbwindow.CSSKeywordValue;this.$wbwindow.CSSKeywordValue=function(CSSKeywordValue_){return function CSSKeywordValue(cssValue){return wombat.domConstructorErrorChecker(this,"CSSKeywordValue",arguments),new CSSKeywordValue_(wombat.rewriteStyle(cssValue))}}(this.$wbwindow.CSSKeywordValue),this.$wbwindow.CSSKeywordValue.prototype=oCSSKV.prototype,Object.defineProperty(this.$wbwindow.CSSKeywordValue.prototype,"constructor",{value:this.$wbwindow.CSSKeywordValue}),addToStringTagToClass(this.$wbwindow.CSSKeywordValue,"CSSKeywordValue")}if(this.$wbwindow.StylePropertyMap&&this.$wbwindow.StylePropertyMap.prototype){var originalSet=this.$wbwindow.StylePropertyMap.prototype.set;this.$wbwindow.StylePropertyMap.prototype.set=function set(){if(arguments.length<=1)return originalSet.__WB_orig_apply?originalSet.__WB_orig_apply(this,arguments):originalSet.apply(this,arguments);var newArgs=new Array(arguments.length);newArgs[0]=arguments[0];for(var i=1;i")&&(array[0]=wombat.rewriteHtml(array[0]),options.type="text/html"),new Blob_(array,options)}}(this.$wbwindow.Blob),this.$wbwindow.Blob.prototype=orig_blob.prototype}},Wombat.prototype.initDocTitleOverride=function(){var orig_get_title=this.getOrigGetter(this.$wbwindow.document,"title"),orig_set_title=this.getOrigSetter(this.$wbwindow.document,"title"),wombat=this,set_title=function title(value){var res=orig_set_title.call(this,value),message={wb_type:"title",title:value};return wombat.sendTopMessage(message),res};this.defProp(this.$wbwindow.document,"title",set_title,orig_get_title)},Wombat.prototype.initFontFaceOverride=function(){if(this.$wbwindow.FontFace){var wombat=this,origFontFace=this.$wbwindow.FontFace;this.$wbwindow.FontFace=function(FontFace_){return function FontFace(family,source,descriptors){wombat.domConstructorErrorChecker(this,"FontFace",arguments,2);var rwSource=source;return source!=null&&(typeof source==="string"?rwSource=wombat.rewriteInlineStyle(source):rwSource=wombat.rewriteInlineStyle(source.toString())),new FontFace_(family,rwSource,descriptors)}}(this.$wbwindow.FontFace),this.$wbwindow.FontFace.prototype=origFontFace.prototype,Object.defineProperty(this.$wbwindow.FontFace.prototype,"constructor",{value:this.$wbwindow.FontFace}),addToStringTagToClass(this.$wbwindow.FontFace,"FontFace")}},Wombat.prototype.initFixedRatio=function(){try{this.$wbwindow.devicePixelRatio=1}catch(e){}if(Object.defineProperty)try{Object.defineProperty(this.$wbwindow,"devicePixelRatio",{value:1,writable:false})}catch(e){}},Wombat.prototype.initPaths=function(wbinfo){wbinfo.wombat_opts=wbinfo.wombat_opts||{},Object.assign(this.wb_info,wbinfo),this.wb_opts=wbinfo.wombat_opts,this.wb_replay_prefix=wbinfo.prefix,this.wb_is_proxy=wbinfo.proxy_magic||!this.wb_replay_prefix,this.wb_info.top_host=this.wb_info.top_host||"*",this.wb_curr_host=this.$wbwindow.location.protocol+"//"+this.$wbwindow.location.host,this.wb_info.wombat_opts=this.wb_info.wombat_opts||{},this.wb_orig_scheme=wbinfo.wombat_scheme+"://",this.wb_orig_origin=this.wb_orig_scheme+wbinfo.wombat_host,this.wb_abs_prefix=this.wb_replay_prefix,this.wb_capture_date_part=!wbinfo.is_live&&wbinfo.wombat_ts?"/"+wbinfo.wombat_ts+"/":"",this.initBadPrefixes(this.wb_replay_prefix),this.initCookiePreset()},Wombat.prototype.initSeededRandom=function(seed){this.$wbwindow.Math.seed=parseInt(seed);var wombat=this;this.$wbwindow.Math.random=function random(){return wombat.$wbwindow.Math.seed=(wombat.$wbwindow.Math.seed*9301+49297)%233280,wombat.$wbwindow.Math.seed/233280}},Wombat.prototype.initHistoryOverrides=function(){this.overrideHistoryFunc("pushState"),this.overrideHistoryFunc("replaceState");var wombat=this;this.$wbwindow.addEventListener("popstate",function(event){wombat.sendHistoryUpdate(wombat.$wbwindow.WB_wombat_location.href,wombat.$wbwindow.document.title)})},Wombat.prototype.initCookiePreset=function(){if(this.wb_info.presetCookie)for(var splitCookies=this.wb_info.presetCookie.split(";"),i=0;i0?"&":"?")+value.toString(),value=null):contentType==="application/json"||contentType==="text/plain"?(this.__WB_xhr_open_arguments[0]="GET",this.__WB_xhr_open_arguments[1]+=(this.__WB_xhr_open_arguments[1].indexOf("?")>0?"&":"?")+jsonToQueryString(value),value=null):wombat.startsWith(contentType,"multipart/form-data")&&(this.__WB_xhr_open_arguments[0]="GET",this.__WB_xhr_open_arguments[1]+=(this.__WB_xhr_open_arguments[1].indexOf("?")>0?"&":"?")+mfdToQueryString(value,contentType))}if(this.__WB_xhr_open_arguments.length>2&&(this.__WB_xhr_open_arguments[2]=true),this._no_rewrite||(this.__WB_xhr_open_arguments[1]=wombat.rewriteUrl(this.__WB_xhr_open_arguments[1])),origOpen.apply(this,this.__WB_xhr_open_arguments),!wombat.startsWith(this.__WB_xhr_open_arguments[1],"data:")){for(const[name,value]of this.__WB_xhr_headers.entries())origSetRequestHeader.call(this,name,value);origSetRequestHeader.call(this,"X-Pywb-Requested-With","XMLHttpRequest")}origSend.call(this,value)}}if(this.$wbwindow.fetch){var orig_fetch=this.$wbwindow.fetch;this.$wbwindow.fetch=function fetch(input,init_opts){var rwInput=input,inputType=typeof input;if(inputType==="string")rwInput=wombat.rewriteUrl(input);else if(inputType==="object"&&input.url){var new_url=wombat.rewriteUrl(input.url);new_url!==input.url&&(rwInput=new Request(new_url,init_opts))}else inputType==="object"&&input.href&&(rwInput=wombat.rewriteUrl(input.href));if(init_opts||(init_opts={}),init_opts.credentials===undefined)try{init_opts.credentials="include"}catch(e){}return orig_fetch.call(wombat.proxyToObj(this),rwInput,init_opts)}}if(this.$wbwindow.Request&&this.$wbwindow.Request.prototype){var orig_request=this.$wbwindow.Request;this.$wbwindow.Request=function(Request_){return function Request(input,init_opts){wombat.domConstructorErrorChecker(this,"Request",arguments);var newInitOpts=init_opts||{},newInput=input,inputType=typeof input;switch(inputType){case"string":newInput=wombat.rewriteUrl(input);break;case"object":if(newInput=input,input.url){var new_url=wombat.rewriteUrl(input.url);new_url!==input.url&&(newInput=new Request_(new_url,input))}else input.href&&(newInput=wombat.rewriteUrl(input.toString(),true));}return newInitOpts.credentials="include",new Request_(newInput,newInitOpts)}}(this.$wbwindow.Request),this.$wbwindow.Request.prototype=orig_request.prototype,Object.defineProperty(this.$wbwindow.Request.prototype,"constructor",{value:this.$wbwindow.Request})}if(this.$wbwindow.Response&&this.$wbwindow.Response.prototype){var originalRedirect=this.$wbwindow.Response.prototype.redirect;this.$wbwindow.Response.prototype.redirect=function redirect(url,status){var rwURL=wombat.rewriteUrl(url,true,null,wombat.$wbwindow.document);return originalRedirect.call(this,rwURL,status)}}if(this.$wbwindow.EventSource&&this.$wbwindow.EventSource.prototype){var origEventSource=this.$wbwindow.EventSource;this.$wbwindow.EventSource=function(EventSource_){return function EventSource(url,configuration){wombat.domConstructorErrorChecker(this,"EventSource",arguments);var rwURL=url;return url!=null&&(rwURL=wombat.rewriteUrl(url)),new EventSource_(rwURL,configuration)}}(this.$wbwindow.EventSource),this.$wbwindow.EventSource.prototype=origEventSource.prototype,Object.defineProperty(this.$wbwindow.EventSource.prototype,"constructor",{value:this.$wbwindow.EventSource}),addToStringTagToClass(this.$wbwindow.EventSource,"EventSource")}if(this.$wbwindow.WebSocket&&this.$wbwindow.WebSocket.prototype){var origWebSocket=this.$wbwindow.WebSocket;this.$wbwindow.WebSocket=function(WebSocket_){return function WebSocket(url,configuration){wombat.domConstructorErrorChecker(this,"WebSocket",arguments);var rwURL=url;return url!=null&&(rwURL=wombat.rewriteWSURL(url)),new WebSocket_(rwURL,configuration)}}(this.$wbwindow.WebSocket),this.$wbwindow.WebSocket.prototype=origWebSocket.prototype,Object.defineProperty(this.$wbwindow.WebSocket.prototype,"constructor",{value:this.$wbwindow.WebSocket}),addToStringTagToClass(this.$wbwindow.WebSocket,"WebSocket")}},Wombat.prototype.initElementGetSetAttributeOverride=function(){if(!this.wb_opts.skip_setAttribute&&this.$wbwindow.Element&&this.$wbwindow.Element.prototype){var wombat=this,ElementProto=this.$wbwindow.Element.prototype;if(ElementProto.setAttribute){var orig_setAttribute=ElementProto.setAttribute;ElementProto._orig_setAttribute=orig_setAttribute,ElementProto.setAttribute=function setAttribute(name,value){var rwValue=value;if(name&&typeof rwValue==="string"){var lowername=name.toLowerCase();if(this.tagName==="LINK"&&lowername==="href"&&rwValue.indexOf("data:text/css")===0)rwValue=wombat.rewriteInlineStyle(value);else if(lowername==="style")rwValue=wombat.rewriteStyle(value);else if(lowername==="srcset")rwValue=wombat.rewriteSrcset(value,this);else{var shouldRW=wombat.shouldRewriteAttr(this.tagName,lowername);shouldRW&&(wombat.removeWBOSRC(this),!this._no_rewrite&&(rwValue=wombat.rewriteUrl(value,false,wombat.rwModForElement(this,lowername))))}}return orig_setAttribute.call(this,name,rwValue)}}if(ElementProto.getAttribute){var orig_getAttribute=ElementProto.getAttribute;this.wb_getAttribute=orig_getAttribute,ElementProto.getAttribute=function getAttribute(name){var result=orig_getAttribute.call(this,name);if(result===null)return result;var lowerName=name;if(name&&(lowerName=name.toLowerCase()),wombat.shouldRewriteAttr(this.tagName,lowerName)){var maybeWBOSRC=wombat.retrieveWBOSRC(this);return maybeWBOSRC?maybeWBOSRC:wombat.extractOriginalURL(result)}return wombat.startsWith(lowerName,"data-")&&wombat.startsWithOneOf(result,wombat.wb_prefixes)?wombat.extractOriginalURL(result):result}}}},Wombat.prototype.initSvgImageOverrides=function(){if(this.$wbwindow.SVGImageElement){var svgImgProto=this.$wbwindow.SVGImageElement.prototype,orig_getAttr=svgImgProto.getAttribute,orig_getAttrNS=svgImgProto.getAttributeNS,orig_setAttr=svgImgProto.setAttribute,orig_setAttrNS=svgImgProto.setAttributeNS,wombat=this;svgImgProto.getAttribute=function getAttribute(name){var value=orig_getAttr.call(this,name);return name.indexOf("xlink:href")>=0||name==="href"?wombat.extractOriginalURL(value):value},svgImgProto.getAttributeNS=function getAttributeNS(ns,name){var value=orig_getAttrNS.call(this,ns,name);return name.indexOf("xlink:href")>=0||name==="href"?wombat.extractOriginalURL(value):value},svgImgProto.setAttribute=function setAttribute(name,value){var rwValue=value;return(name.indexOf("xlink:href")>=0||name==="href")&&(rwValue=wombat.rewriteUrl(value)),orig_setAttr.call(this,name,rwValue)},svgImgProto.setAttributeNS=function setAttributeNS(ns,name,value){var rwValue=value;return(name.indexOf("xlink:href")>=0||name==="href")&&(rwValue=wombat.rewriteUrl(value)),orig_setAttrNS.call(this,ns,name,rwValue)}}},Wombat.prototype.initCreateElementNSFix=function(){if(this.$wbwindow.document.createElementNS&&this.$wbwindow.Document.prototype.createElementNS){var orig_createElementNS=this.$wbwindow.document.createElementNS,wombat=this,createElementNS=function createElementNS(namespaceURI,qualifiedName){return orig_createElementNS.call(wombat.proxyToObj(this),wombat.extractOriginalURL(namespaceURI),qualifiedName)};this.$wbwindow.Document.prototype.createElementNS=createElementNS,this.$wbwindow.document.createElementNS=createElementNS}},Wombat.prototype.initInsertAdjacentElementHTMLOverrides=function(){var Element=this.$wbwindow.Element;if(Element&&Element.prototype){var elementProto=Element.prototype,rewriteFn=this.rewriteInsertAdjHTMLOrElemArgs;if(elementProto.insertAdjacentHTML){var origInsertAdjacentHTML=elementProto.insertAdjacentHTML;elementProto.insertAdjacentHTML=function insertAdjacentHTML(position,text){return rewriteFn(this,origInsertAdjacentHTML,position,text,true)}}if(elementProto.insertAdjacentElement){var origIAdjElem=elementProto.insertAdjacentElement;elementProto.insertAdjacentElement=function insertAdjacentElement(position,element){return rewriteFn(this,origIAdjElem,position,element,false)}}}},Wombat.prototype.initDomOverride=function(){var Node=this.$wbwindow.Node;if(Node&&Node.prototype){var rewriteFn=this.rewriteNodeFuncArgs;if(Node.prototype.appendChild){var originalAppendChild=Node.prototype.appendChild;Node.prototype.appendChild=function appendChild(newNode,oldNode){return rewriteFn(this,originalAppendChild,newNode,oldNode)}}if(Node.prototype.insertBefore){var originalInsertBefore=Node.prototype.insertBefore;Node.prototype.insertBefore=function insertBefore(newNode,oldNode){return rewriteFn(this,originalInsertBefore,newNode,oldNode)}}if(Node.prototype.replaceChild){var originalReplaceChild=Node.prototype.replaceChild;Node.prototype.replaceChild=function replaceChild(newNode,oldNode){return rewriteFn(this,originalReplaceChild,newNode,oldNode)}}this.overridePropToProxy(Node.prototype,"ownerDocument"),this.overridePropToProxy(this.$wbwindow.HTMLHtmlElement.prototype,"parentNode"),this.overridePropToProxy(this.$wbwindow.Event.prototype,"target")}this.$wbwindow.Element&&this.$wbwindow.Element.prototype&&(this.overrideParentNodeAppendPrepend(this.$wbwindow.Element),this.overrideChildNodeInterface(this.$wbwindow.Element,false)),this.$wbwindow.DocumentFragment&&this.$wbwindow.DocumentFragment.prototype&&this.overrideParentNodeAppendPrepend(this.$wbwindow.DocumentFragment)},Wombat.prototype.initDocOverrides=function($document){if(Object.defineProperty){this.overrideReferrer($document),this.defGetterProp($document,"origin",function origin(){return this.WB_wombat_location.origin}),this.defGetterProp(this.$wbwindow,"origin",function origin(){return this.WB_wombat_location.origin});var wombat=this,domain_setter=function domain(val){var loc=this.WB_wombat_location;loc&&wombat.endsWith(loc.hostname,val)&&(this.__wb_domain=val)},domain_getter=function domain(){return this.__wb_domain||this.WB_wombat_location.hostname};this.defProp($document,"domain",domain_setter,domain_getter)}},Wombat.prototype.initDocWriteOpenCloseOverride=function(){if(this.$wbwindow.DOMParser){var DocumentProto=this.$wbwindow.Document.prototype,$wbDocument=this.$wbwindow.document,docWriteWritelnRWFn=this.rewriteDocWriteWriteln,orig_doc_write=$wbDocument.write,new_write=function write(){return docWriteWritelnRWFn(this,orig_doc_write,arguments)};$wbDocument.write=new_write,DocumentProto.write=new_write;var orig_doc_writeln=$wbDocument.writeln,new_writeln=function writeln(){return docWriteWritelnRWFn(this,orig_doc_writeln,arguments)};$wbDocument.writeln=new_writeln,DocumentProto.writeln=new_writeln;var wombat=this,orig_doc_open=$wbDocument.open,new_open=function open(){var res,thisObj=wombat.proxyToObj(this);if(arguments.length===3){var rwUrl=wombat.rewriteUrl(arguments[0],false,"mp_");res=orig_doc_open.call(thisObj,rwUrl,arguments[1],arguments[2]),wombat.initNewWindowWombat(res,arguments[0])}else res=orig_doc_open.call(thisObj),wombat.initNewWindowWombat(thisObj.defaultView);return res};$wbDocument.open=new_open,DocumentProto.open=new_open;var originalClose=$wbDocument.close,newClose=function close(){var thisObj=wombat.proxyToObj(this);return wombat.initNewWindowWombat(thisObj.defaultView),originalClose.__WB_orig_apply?originalClose.__WB_orig_apply(thisObj,arguments):originalClose.apply(thisObj,arguments)};$wbDocument.close=newClose,DocumentProto.close=newClose;var oBodyGetter=this.getOrigGetter(DocumentProto,"body"),oBodySetter=this.getOrigSetter(DocumentProto,"body");oBodyGetter&&oBodySetter&&this.defProp(DocumentProto,"body",function body(newBody){return newBody&&(newBody instanceof HTMLBodyElement||newBody instanceof HTMLFrameSetElement)&&wombat.rewriteElemComplete(newBody),oBodySetter.call(wombat.proxyToObj(this),newBody)},oBodyGetter)}},Wombat.prototype.initIframeWombat=function(iframe){var win;win=iframe._get_contentWindow?iframe._get_contentWindow.call(iframe):iframe.contentWindow;try{if(!win||win===this.$wbwindow||win._skip_wombat||win._wb_wombat)return}catch(e){return}var src=iframe.src;this.initNewWindowWombat(win,src)},Wombat.prototype.initNewWindowWombat=function(win,src){var fullWombat=false;if(win&&!win._wb_wombat){if((!src||src===""||this.startsWithOneOf(src,["about:blank","javascript:"]))&&(fullWombat=true),!fullWombat&&this.wb_info.isSW){var origURL=this.extractOriginalURL(src);(origURL==="about:blank"||origURL.startsWith("srcdoc:")||origURL.startsWith("blob:"))&&(fullWombat=true)}if(fullWombat){var newInfo={};Object.assign(newInfo,this.wb_info);var wombat=new Wombat(win,newInfo);win._wb_wombat=wombat.wombatInit()}else this.initProtoPmOrigin(win),this.initPostMessageOverride(win),this.initMessageEventOverride(win),this.initCheckThisFunc(win)}},Wombat.prototype.initTimeoutIntervalOverrides=function(){var rewriteFn=this.rewriteSetTimeoutInterval;if(this.$wbwindow.setTimeout&&!this.$wbwindow.setTimeout.__$wbpatched$__){var originalSetTimeout=this.$wbwindow.setTimeout;this.$wbwindow.setTimeout=function setTimeout(){return rewriteFn(this,originalSetTimeout,arguments)},this.$wbwindow.setTimeout.__$wbpatched$__=true}if(this.$wbwindow.setInterval&&!this.$wbwindow.setInterval.__$wbpatched$__){var originalSetInterval=this.$wbwindow.setInterval;this.$wbwindow.setInterval=function setInterval(){return rewriteFn(this,originalSetInterval,arguments)},this.$wbwindow.setInterval.__$wbpatched$__=true}},Wombat.prototype.initWorkerOverrides=function(){var wombat=this;if(this.$wbwindow.Worker&&!this.$wbwindow.Worker._wb_worker_overriden){var orig_worker=this.$wbwindow.Worker;this.$wbwindow.Worker=function(Worker_){return function Worker(url,options){return wombat.domConstructorErrorChecker(this,"Worker",arguments),new Worker_(wombat.rewriteWorker(url),options)}}(orig_worker),this.$wbwindow.Worker.prototype=orig_worker.prototype,Object.defineProperty(this.$wbwindow.Worker.prototype,"constructor",{value:this.$wbwindow.Worker}),this.$wbwindow.Worker._wb_worker_overriden=true}if(this.$wbwindow.SharedWorker&&!this.$wbwindow.SharedWorker.__wb_sharedWorker_overriden){var oSharedWorker=this.$wbwindow.SharedWorker;this.$wbwindow.SharedWorker=function(SharedWorker_){return function SharedWorker(url,options){return wombat.domConstructorErrorChecker(this,"SharedWorker",arguments),new SharedWorker_(wombat.rewriteWorker(url),options)}}(oSharedWorker),this.$wbwindow.SharedWorker.prototype=oSharedWorker.prototype,Object.defineProperty(this.$wbwindow.SharedWorker.prototype,"constructor",{value:this.$wbwindow.SharedWorker}),this.$wbwindow.SharedWorker.__wb_sharedWorker_overriden=true}if(this.$wbwindow.ServiceWorkerContainer&&this.$wbwindow.ServiceWorkerContainer.prototype&&this.$wbwindow.ServiceWorkerContainer.prototype.register){var orig_register=this.$wbwindow.ServiceWorkerContainer.prototype.register;this.$wbwindow.ServiceWorkerContainer.prototype.register=function register(scriptURL,options){var newScriptURL=new URL(scriptURL,wombat.$wbwindow.document.baseURI).href,mod=wombat.getPageUnderModifier();return options&&options.scope?options.scope=wombat.rewriteUrl(options.scope,false,mod):options={scope:wombat.rewriteUrl("/",false,mod)},orig_register.call(this,wombat.rewriteUrl(newScriptURL,false,"sw_"),options)}}if(this.$wbwindow.Worklet&&this.$wbwindow.Worklet.prototype&&this.$wbwindow.Worklet.prototype.addModule&&!this.$wbwindow.Worklet.__wb_workerlet_overriden){var oAddModule=this.$wbwindow.Worklet.prototype.addModule;this.$wbwindow.Worklet.prototype.addModule=function addModule(moduleURL,options){var rwModuleURL=wombat.rewriteUrl(moduleURL,false,"js_");return oAddModule.call(this,rwModuleURL,options)},this.$wbwindow.Worklet.__wb_workerlet_overriden=true}},Wombat.prototype.initLocOverride=function(loc,oSetter,oGetter){if(Object.defineProperty)for(var prop,i=0;i=0&&props.splice(foundInx,1);return props}})}catch(e){console.log(e)}},Wombat.prototype.initHashChange=function(){if(this.$wbwindow.__WB_top_frame){var wombat=this,receive_hash_change=function receive_hash_change(event){if(event.data&&event.data.from_top){var message=event.data.message;message.wb_type&&(message.wb_type!=="outer_hashchange"||wombat.$wbwindow.location.hash==message.hash||(wombat.$wbwindow.location.hash=message.hash))}},send_hash_change=function send_hash_change(){var message={wb_type:"hashchange",hash:wombat.$wbwindow.location.hash};wombat.sendTopMessage(message)};this.$wbwindow.addEventListener("message",receive_hash_change),this.$wbwindow.addEventListener("hashchange",send_hash_change)}},Wombat.prototype.initPostMessageOverride=function($wbwindow){if($wbwindow.postMessage&&!$wbwindow.__orig_postMessage){var orig=$wbwindow.postMessage,wombat=this;$wbwindow.__orig_postMessage=orig;var postmessage_rewritten=function postMessage(message,targetOrigin,transfer,from_top){var from,src_id,this_obj=wombat.proxyToObj(this);if(this_obj.__WB_source&&this_obj.__WB_source.WB_wombat_location){var source=this_obj.__WB_source;if(from=source.WB_wombat_location.origin,this_obj.__WB_win_id||(this_obj.__WB_win_id={},this_obj.__WB_counter=0),!source.__WB_id){var id=this_obj.__WB_counter;source.__WB_id=id+source.WB_wombat_location.href,this_obj.__WB_counter+=1}this_obj.__WB_win_id[source.__WB_id]=source,src_id=source.__WB_id,this_obj.__WB_source=undefined}else from=window.WB_wombat_location.origin;var to_origin=targetOrigin;to_origin===this_obj.location.origin&&(to_origin=from);var new_message={from:from,to_origin:to_origin,src_id:src_id,message:message,from_top:from_top};if(targetOrigin!=="*"){if(this_obj.location.origin==="null"||this_obj.location.origin==="")return;targetOrigin=this_obj.location.origin}return orig.call(this_obj,new_message,targetOrigin,transfer)};$wbwindow.postMessage=postmessage_rewritten,$wbwindow.Window.prototype.postMessage=postmessage_rewritten;var eventTarget=null;eventTarget=$wbwindow.EventTarget&&$wbwindow.EventTarget.prototype?$wbwindow.EventTarget.prototype:$wbwindow;var _oAddEventListener=eventTarget.addEventListener;eventTarget.addEventListener=function addEventListener(type,listener,useCapture){var rwListener,obj=wombat.proxyToObj(this);if(type==="message"?rwListener=wombat.message_listeners.add_or_get(listener,function(){return wrapEventListener(listener,obj,wombat)}):type==="storage"?wombat.storage_listeners.add_or_get(listener,function(){return wrapSameOriginEventListener(listener,obj)}):rwListener=listener,rwListener)return _oAddEventListener.call(obj,type,rwListener,useCapture)};var _oRemoveEventListener=eventTarget.removeEventListener;eventTarget.removeEventListener=function removeEventListener(type,listener,useCapture){var rwListener,obj=wombat.proxyToObj(this);if(type==="message"?rwListener=wombat.message_listeners.remove(listener):type==="storage"?wombat.storage_listeners.remove(listener):rwListener=listener,rwListener)return _oRemoveEventListener.call(obj,type,rwListener,useCapture)};var override_on_prop=function(onevent,wrapperFN){var orig_setter=wombat.getOrigSetter($wbwindow,onevent),setter=function(value){this["__orig_"+onevent]=value;var obj=wombat.proxyToObj(this),listener=value?wrapperFN(value,obj,wombat):value;return orig_setter.call(obj,listener)},getter=function(){return this["__orig_"+onevent]};wombat.defProp($wbwindow,onevent,setter,getter)};override_on_prop("onmessage",wrapEventListener),override_on_prop("onstorage",wrapSameOriginEventListener)}},Wombat.prototype.initMessageEventOverride=function($wbwindow){!$wbwindow.MessageEvent||$wbwindow.MessageEvent.prototype.__extended||(this.addEventOverride("target"),this.addEventOverride("srcElement"),this.addEventOverride("currentTarget"),this.addEventOverride("eventPhase"),this.addEventOverride("path"),this.overridePropToProxy($wbwindow.MessageEvent.prototype,"source"),$wbwindow.MessageEvent.prototype.__extended=true)},Wombat.prototype.initUIEventsOverrides=function(){this.overrideAnUIEvent("UIEvent"),this.overrideAnUIEvent("MouseEvent"),this.overrideAnUIEvent("TouchEvent"),this.overrideAnUIEvent("FocusEvent"),this.overrideAnUIEvent("KeyboardEvent"),this.overrideAnUIEvent("WheelEvent"),this.overrideAnUIEvent("InputEvent"),this.overrideAnUIEvent("CompositionEvent")},Wombat.prototype.initOpenOverride=function(){var orig=this.$wbwindow.open;this.$wbwindow.Window.prototype.open&&(orig=this.$wbwindow.Window.prototype.open);var wombat=this,open_rewritten=function open(strUrl,strWindowName,strWindowFeatures){var rwStrUrl=wombat.rewriteUrl(strUrl,false,""),res=orig.call(wombat.proxyToObj(this),rwStrUrl,strWindowName,strWindowFeatures);return wombat.initNewWindowWombat(res,strUrl),res};this.$wbwindow.open=open_rewritten,this.$wbwindow.Window.prototype.open&&(this.$wbwindow.Window.prototype.open=open_rewritten);for(var i=0;i + + +Chapter 1.3: Textures, TPages and CLUTs + + + + +
+

Chapter 1.3: Textures, TPages and CLUTs

+
+

+This tutorial will teach you how to draw graphics with textures, from +converting texture data to loading it onto VRAM, and finally drawing said +texture. This is yet another essential part in PS1 graphics programming, +as not having any textures would not always make for a pretty looking game. +

+

+This chapter will also cover some development tools to be used for +preparing texture data, such as timtool and img2tim. +

+

+Compatible with PSn00bSDK: Yes +

+ +

Tutorial Index

+ + +

Textures

+

+A texture in the context of graphics programming, is basically a bitmap +of pixels that can either be drawn to the screen as a 2D image or +mapped onto polygons to add textures on 3D models. +

+

+On the PS1 hardware, textures are naturally stored in VRAM alongside the +display and drawing buffers described in previous tutorials. Textures are +generally positioned outside of said visual areas so to not get overwritten +by graphics frames drawn by the GPU. Once texture images have been loaded, +it can then be drawn by textured sprite and/or polygon primitives. +

+

+The PS1 supports texture color depths of 4, 8 and 16 bits per pixel. 4-bit +and 8-bit textures are usually accompanied with CLUT or Color Lookup Table. +A CLUT is essentially the color palette of its associated texture image. +

+

+Because the VRAM addresses pixels in 16-bit words, 4-bit and 8-bit textures +are stored at quarter and half of the actual width of the texture respectively +as shown in the image below. +

+
+ +4-bit, 8-bit and 16-bit texture images as they appear logically in VRAM +
+

+This also means that 8-bit textures must have a width that is of a multiple +of 2 whilst 4-bit textures must be of a multiple of 4 to ensure that the pixel +data is word-aligned in VRAM. Failing to do so will often yield artifacts, or +corrupted texture images when trying to upload odd-width images into VRAM. +

+

+Texture images are usually handled on the PS1 in the TIM file format, which +is a very simple image format designed specifically for the PS1 as it can +hold X and Y coordinates for either image and CLUT data which are used as +target coordinates when uploading the texture to VRAM. TIM files are typically +created from regular image files (bmp, pcx, jpeg or bmp) with tools such as +timtool included in the PsyQ/Programmer Tool SDK, +img2tim which is a free +command-line driven TIM converter and finally, +timedit which is essentially +a free albeit slightly dodgy equivalent of timtool. +

+

+For beginners it may be best to use timedit as its the only free tool +(or at the very least one that I'm aware of) that features a graphical preview +of the TIM image layout in VRAM or stick to timtool if you're using the +PsyQ/Programmers Tool SDK. +

+ +

Color Look-up Tables (CLUT)

+

+A CLUT is simply a 16x1 or 256x1 16-bit pixel image that normally accompanies +4-bit and 8-bit texture images respectively. If you haven't guessed by now, a +CLUT is essentially the color palette of the image it accompanies, where each +pixel of the CLUT represents a 16-bit color entry for the texture image +starting from the left (ie. the first pixel from the left represents the color +for index 0 while the very last pixel of the CLUT represents the color for +index 15 or index 255). CLUTs are normally used with 4-bit and 8-bit texture +images, though it can also be used for procedurally generated textures such as +animated plasma effects. +

+

+The TIM file format could support multiple CLUTs on a single TIM file, +as the CLUT headers in the file format allow for more than 1 pixel high +CLUTs. This is beyond the scope of this part of the tutorial series however. +

+ +

Texture Addressing on the PS1

+

+You may have learned from the last tutorial that the PS1 accesses the VRAM +as a two-dimensional image rather than a more conventional linear framebuffer. +Well, this also applies on how textures in VRAM are 'selected' for drawing with +textured primitives. +

+

+The PS1 addresses the VRAM in pages, in which the VRAM is divided into a +grid of 16x2 cells of 64x256 16-bit pixels each. The actual texture page +coordinates are still X,Y but with a 64x256 granularity instead. The image +below visually illustrates the cells of each texture page. +

+
+ +Texture page grid of the VRAM +
+

+Texture pages only applies to the selection of the area at which textures would +be read from by textured graphics primitives, as VRAM coordinates of display +and drawing environments do not adhere to this texture page granularity at all. +Setting a texture page serves as an anchor point at which textured primitives +would source texture data from starting from the top-left corner of the texture +page, with the U,V coordinates of the primitive serving as an offset relative to +the current texture page allowing small portions of a texture page to be read +and drawn, such as animation frames of one particular character in a large +sprite sheet. +

+
+ +An example of using U,V coordinates to select a particular sprite (in this +case at 48,32) in a sprite sheet +
+

+Of course this would mean that the texture images would have to be arranged +such that it is placed on the top-right corner of a texture page boundary for +the U,V coordinates to make the most sense. However, some simple offset +translation based on the texture image's position relative to the page boundary +should get around that issue and is going to be covered in this chapter. +

+

+One thing to consider about texture coordinates that may initially confuse +beginners is that while the width of a 4-bit and 8-bit texture on VRAM varies +from the actual width of the image itself, the texture coordinates does not +need to be adjusted to take that into account as long as the correct color +depth is specified in the texture page value. In this case, if you want to +draw a texture at 96,24 from a 256x256 4-bit texture sheet, you just simply +specify a U,V coordinate of 96,24 in your primitive as if the texture were +still 16-bit. +

+
+ +Texture coordinates are always true to the actual size of the +texture image +
+

+And because the U,V coordinates only have a range of 0-255, it is not possible +to draw a texture image larger than 256x256 pixels regardless of color depth. +To draw larger textures one has to draw multiple primitives to span the entire +size of a larger image, trying to draw a SPRT primitive with a size greater +than 256x256 will only result in a wrap around. +

+ +

Defining and Selecting a Texture Page

+

+A texture page value is easily defined using the getTPage() macro. +A function version of this macro is present in the PsyQ/Programmers Tool SDK +as GetTPage(), but this is not available in PSn00bSDK as it would be +considered redundant. +

+
tpage = getTPage( tp, abr, x, y );
+
+

+tp specifies the color depth for the texture page in the range of +0 to 2 (0:4-bit, 1:8-bit, 2:16-bit). abr specifies the blend operator +for both non-textured and textured semi-transparent primitives which can be +ignored for now and lastly, x,y specifies the X,Y coordinates of the +VRAM in 16-bit pixel units. Keep in mind that the coordinates will be rounded +down to the next lowest texture page. +

+

+Now that a texture page value has been defined, there are a number of ways to +set it to the GPU. One is through the tpage field of the DRAWENV +struct which specifies the initial texture page value whenever the drawing +environment is applied. Another is to use a DR_TPAGE primitive which +can be defined with the setDrawTPage() macro which follows the same +syntax as getTPage(). DR_TPAGE is needed for SPRT +primitives which lack a tpage field, though it is also useful for non-textured +primitives to set the blend operator for semi-transparent primitives. +

+

+Because the PS1 usually processes primitives that have been sorted last first, +DR_TPAGE primitives must be sorted after SPRT or other similar +primitives have been sorted. +

+

+The following table describes the bit fields of a texture page value which may +come in handy for the more crafty programmers. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bits15-141312111098-76-543-0
DescriptionReservedY-flip*X-flip*Texture disable*Draw on displayed areaDither enableTexture color depthBlend operatorTexture page Y (n*256)Texutre page X (n*64)
*Does not work on really early units, not recommended +to use to maintain compatibility
+
+

+Whilst on the topic of texture page selection, when working with 4-bit and +8-bit texture images you will also need to use getClut() to define a +CLUT value and is required for 4-bit and 8-bit texture images to draw properly. +Obviously this is not required for 16-bit texture images. +

+
clut = getClut( x, y );
+
+

+x,y specifies the X,Y coordinate of the CLUT within the VRAM. +However, keep in mind that the X axis must be a multiple to 16 pixels for a +CLUT to be defined correctly as otherwise it will be rounded down to the +lowest CLUT value. +

+

+As for selecting the CLUT, all textured primitives usually have a clut +field in the struct in which the CLUT value can be set to. There is also a +setClut() macro for setting CLUT coordinates to a primitive directly. +

+

+Usually, the coordinates for texture page and CLUT values are typically derived +from the X,Y coordinates of the TIM image file to take into account TIM images +that are not placed on the top-left corner of the texture page boundary. +

+

+The following describes the bit fields of a CLUT value. +

+
+ + + + + + + + + + + + + +
Bits1514-65-0
DescriptionReservedY coordinateX coordinate (n*16)
+
+ +

Creating a TIM Texture Image

+

+There are numerous ways to convert image files into the TIM format, the most +common is by using timtool from the official PsyQ/Programmers Tool SDKs, +or at least those who chose to use that SDK. Another is to use my free but old +command-line converter called img2tim, which follows the same command +line syntax as bmp2tim but supports many more image formats supported +by the FreeImage library and has better conversion options related to +transparencies. +

+

+Perhaps the most preferable tool to use for those who've stuck to using +PSn00bSDK is timedit, as not only is it free but also features a +similar graphical interface to timtool, on top of extra features +useful for managing a large amount of TIM images, such as grouping. +

+

+Whichever tool you use, convert the image below into a 8-bit TIM file with +image coordinates of 640,0 and CLUT coordinates of 0,480. You will have to +convert it into a 4-bit or 8-bit TIM as this tutorial is also going to cover +how to work with CLUTs. +

+
+ +
+

+When converting the image, always remember that texture image and CLUT +coordinates in the tools are always absolute coordinates to the VRAM +regardless of color depth. And in case you're wondering, the PS1 cannot +use 24-bit TIM images, as the GPU can only draw graphics in 16-bit color +depth but can display 24-bit images by entering 24-bit color mode, but +this is beyond the scope of this chapter. +

+ +

Including TIM Image Data

+

+In the meantime, the easiest way to include a binary file into your program +is to include it as an object file by means of a very simple assembler file, +and access that file as an array by defining its symbol name with extern. +Its not ideal for larger projects, but this will do the job for testing purposes. +

+

PsyQ/Programmers Tool SDK

+

+Save the following as my_image.asm. +

+
    opt	m+,l.,c+
+
+    section data            ; Store the array in the data section
+
+    global tim_my_image     ; Define label as global
+tim_my_image:
+    incbin 'my_image.tim'   ; Include file data (your TIM)
+
+

+The name of the data is defined by the label, in this case tim_my_image. +Make sure the label is also defined by a global directive so the linker can find +it when linked against your C program. When writing the assembler file, make sure +line indentations are created with real TAB characters as ASMPSX will throw an +error otherwise. +

+

+Assemble the file using ASMPSX to turn it into an object file. +

+
asmpsx /l my_image.asm,my_image.obj
+
+

Then link it with your program by simply specifying the object file.

+
ccpsx -O2 -Xm -Xo$80010000 my_image.obj program.c -o program.cpe
+
+

PSn00bSDK

+

+In PSn00bSDK, it works in much the same principle as in the PsyQ SDK, +but this one will be written in GNU assembler syntax. Save the assembler +file with a .s file extension. +

+
.section .data
+
+.global tim_my_image
+.type tim_my_image, @object
+tim_my_image:
+    .incbin "my_image.tim"
+
+

+It is recommended to use the makefile from one of the example programs included +with PSn00bSDK, as it has parameters for building with assembler files already +defined and should automatically pick your assembler file as long as it has +a .s file extension. +

+

Accessing the Array

+

+On both SDKs, the binary file can be accessed as an array by simply defining +it with an extern. Make sure the name matches with the label name defined +in the assembler file. +

+
extern int tim_my_image[];
+
+

+If you get mismatching type errors when compiling, you can simply cast it with a +different pointer type with (u_long*) or (u_int*) depending on +the compiler warnings you're getting. u_int is typically used in PSn00bSDK +instead of u_long as modern GCC interprets u_long as a 64-bit integer +whereas it is a 32-bit integer in PsyQ. +

+ +

Parsing and Uploading the TIM to VRAM

+

+To parse a TIM image file, use OpenTIM() to set the TIM file data for +parsing and ReadTIM() to retrieve header information of the TIM file to +a TIM_IMAGE struct. The TIM_IMAGE would contain not only a pointer +to the X,Y and size coordinates of either texture image and CLUT but also +pointers to the image and CLUT data within the TIM file. +

+

+In PSn00bSDK, GetTimInfo() function instead. It still returns the same +TIM_IMAGE struct. +

+

+The TIM image coordinates are in the *prect field and CLUT in +the *crect field, both are of type RECT. The actual texture image data +is at *paddr and the CLUT data at *caddr. The color depth of +the TIM file are in bits 0-3 of the mode field and CLUT presence is +determined by testing bit 4. +

+

+Uploading either pixel or CLUT data is done using LoadImage(), followed +by a call to DrawSync() to wait for texture upload to complete. Whilst +you might be able to get away with not waiting for the texture upload to +finish processing, it is recommended to wait for upload completion as +unpredictable results may occur otherwise. +

+

+The TIM image upload function should go like this. +

+
void LoadTexture(u_long *tim, TIM_IMAGE *tparam) {
+
+    // Read TIM information (PsyQ)
+    OpenTIM(tim);
+    ReadTIM(tparam);
+
+    // Read TIM information (PSn00bSDK)
+    //GetTimInfo(tim, tparam);
+
+    // Upload pixel data to framebuffer
+    LoadImage(tparam->prect, (u_long*)tparam->paddr);
+    DrawSync(0);
+
+    // Upload CLUT to framebuffer if present
+    if( tparam->mode & 0x8 ) {
+
+        LoadImage(tparam->crect, (u_long*)tparam->caddr);
+        DrawSync(0);
+
+    }
+
+}
+
+

+In PSn00bSDK, you may additionally replace u_long to u_int. They are actually +the same in PsyQ/Programmers Tool whereas in modern GCC/PSn00bSDK u_long +usually defines a 64-bit unsigned integer. +

+

+Now that you have a TIM upload function, the TIM loading sequence should go like so. +

+
extern int tim_my_image[];
+
+// To keep a copy of the TIM coordinates for later
+int tim_mode;
+RECT tim_prect,tim_crect;
+
+..
+
+void LoadStuff(void) {
+
+    // This can be defined locally, if you don't need the TIM coordinates
+    TIM_IMAGE my_image;
+
+    // Load the TIM
+    LoadTexture((u_long*)tim_my_image, &my_image);
+    
+    // Copy the TIM coordinates
+    tim_prect   = *my_image.prect;
+    tim_crect   = *my_image.crect;
+    tim_mode    = my_image.mode;
+    
+}
+
+

+Reason you may want to keep a copy of the TIM coordinates separate from the +TIM_IMAGE variable is that once you've figured out how to load files +from CD and load the TIM file to a dynamically allocated buffer, relying on +the TIM_IMAGE struct may not be a good idea as the *prect and +*crect fields point to the TIM file data directly, and will most +likely become undefined data once you've finished uploading that TIM to +VRAM and deallocated its buffer in later parts of your program. +

+ +

Drawing the TIM

+

+Now that a texture image has been loaded. The next thing to do is to set +it's texture page to the drawing environment. Since there's only one texture +to deal with, the texture page can be set to the DRAWENV struct. +

+
draw[0].tpage = getTPage( tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+draw[1].tpage = getTPage( tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+
+

+To deal with TIMs that are not page aligned, the U,V offset relative to +the TIM's rounded down texture page can be determined with the following +and should work for texture images of any color depth. +

+
int tim_uoffs,tim_voffs;
+
+tim_uoffs = (tim_prect.x%64)<<(2-(tim_mode&0x3));
+tim_voffs = (tim_prect.y&0xff);
+
+

+Whilst this would allow texture images to not require being aligned to the +top-left corner of the texture page boundary, texture images cannot cross +between the vertical texture page bounds and for 4-bit texture images, +should not cross the horizontal texture page bounds as otherwise trying to +draw the texture image with a SPRT will result in wrapping in +relation to the texture page. +

+

+Now to actually draw the texture image. This can be done with a SPRT +primitive which simply draws a textured sprite of a specified size. It doesn't +do fancy things such as rotation and scaling but its a useful primitive for +drawing simple sprites. +

+
SPRT *sprt;
+
+...
+
+sprt = (SPRT*)nextpri;
+
+setSprt(sprt);              // Initialize the primitive (important)
+setXY0(sprt, 48, 48);       // Position the sprite at (48,48)
+setWH(sprt, 64, 64);        // Set sprite size to 64x64 pixels
+setUV0(sprt,                // Set UV coordinates from TIM offsets
+    tim_uoffs, 
+    tim_voffs);
+setClut(sprt,               // Set CLUT coordinates from TIM to sprite
+    tim_crect.x,
+    tim_crect.y);
+setRGB0(sprt,               // Set color of sprite, 128 is neutral
+    128, 128, 128);
+
+addPrim(ot[db], sprt);      // Sort primitive to OT
+nextpri += sizeof(SPRT);    // Advance next primitive
+
+

+When dealing with multiple texture images that tend to reside on different +texture pages, you will have to sort a DR_TPAGE primitive right after +the SPRT primitive that requires a particular texture page value set, +as the PS1 processes primitives that are sorted last first. +

+

+Whilst not required in this chapter, this is how you sort a DR_TPAGE +for when you start playing around with more texture images. +

+
DR_TPAGE *tpage;
+
+...
+
+tpage = (DR_TPAGE*)nextpri;
+
+setDrawTPage(tpage, 0, 1,       // Set TPage primitive
+    getTPage(my_image.mode&0x3, 0, 
+    my_image.prect->x, my_image.prect->y));
+
+addPrim(ot[db], tpage);         // Sort primitive to OT
+
+nextpri += sizeof(DR_TPAGE);    // Advance next primitive address
+
+

+A very simple optimization practice you may want to consider when you start +getting into larger projects is that you only need to sort one DR_TPAGE +primitive if all the sprites sorted prior share a common texture page. +

+ +

Sample Code

+

+Working from code in the last tutorial, here's what the code should +look like: +

+
#include <sys/types.h>	// This provides typedefs needed by libgte.h and libgpu.h
+#include <stdio.h>	// Not necessary but include it anyway
+#include <libetc.h>	// Includes some functions that controls the display
+#include <libgte.h>	// GTE header, not really used but libgpu.h depends on it
+#include <libgpu.h>	// GPU library header
+
+#define OTLEN 8         // Ordering table length (recommended to set as a define
+                        // so it can be changed easily)
+
+DISPENV disp[2];        // Display/drawing buffer parameters
+DRAWENV draw[2];
+int db = 0;
+
+// PSn00bSDK requires having all u_long types replaced with
+// u_int, as u_long in modern GCC that PSn00bSDK uses defines it as a 64-bit integer.
+
+u_long ot[2][OTLEN];    // Ordering table length
+char pribuff[2][32768]; // Primitive buffer
+char *nextpri;          // Next primitive pointer
+
+int tim_mode;           // TIM image parameters
+RECT tim_prect,tim_crect;
+int tim_uoffs,tim_voffs;
+
+void display() {
+    
+    DrawSync(0);                // Wait for any graphics processing to finish
+    
+    VSync(0);                   // Wait for vertical retrace
+
+    PutDispEnv(&disp[db]);      // Apply the DISPENV/DRAWENVs
+    PutDrawEnv(&draw[db]);
+
+    SetDispMask(1);             // Enable the display
+
+    DrawOTag(ot[db]+OTLEN-1);   // Draw the ordering table
+    
+    db = !db;                   // Swap buffers on every pass (alternates between 1 and 0)
+    nextpri = pribuff[db];      // Reset next primitive pointer
+    
+}
+
+// Texture upload function
+void LoadTexture(u_long *tim, TIM_IMAGE *tparam) {
+
+    // Read TIM parameters (PsyQ)
+    OpenTIM(tim);
+    ReadTIM(tparam);
+
+    // Read TIM parameters (PSn00bSDK)
+    //GetTimInfo(tim, tparam);
+
+    // Upload pixel data to framebuffer
+    LoadImage(tparam->prect, (u_long*)tparam->paddr);
+    DrawSync(0);
+
+    // Upload CLUT to framebuffer if present
+    if( tparam->mode & 0x8 ) {
+
+        LoadImage(tparam->crect, (u_long*)tparam->caddr);
+        DrawSync(0);
+
+    }
+
+}
+
+void loadstuff(void) {
+
+    TIM_IMAGE my_image;         // TIM image parameters
+
+    extern u_long tim_my_image[];
+
+    // Load the texture
+    LoadTexture(tim_my_image, &my_image);
+
+    // Copy the TIM coordinates
+    tim_prect   = *my_image.prect;
+    tim_crect   = *my_image.crect;
+    tim_mode    = my_image.mode;
+
+    // Calculate U,V offset for TIMs that are not page aligned
+    tim_uoffs = (tim_prect.x%64)<<(2-(tim_mode&0x3));
+    tim_voffs = (tim_prect.y&0xff);
+
+}
+
+// To make main look tidy, init stuff has to be moved here
+void init(void) {
+	
+    // Reset graphics
+    ResetGraph(0);
+
+    // First buffer
+    SetDefDispEnv(&disp[0], 0, 0, 320, 240);
+    SetDefDrawEnv(&draw[0], 0, 240, 320, 240);
+    // Second buffer
+    SetDefDispEnv(&disp[1], 0, 240, 320, 240);
+    SetDefDrawEnv(&draw[1], 0, 0, 320, 240);
+
+    draw[0].isbg = 1;               // Enable clear
+    setRGB0(&draw[0], 63, 0, 127);  // Set clear color (dark purple)
+    draw[1].isbg = 1;
+    setRGB0(&draw[1], 63, 0, 127);
+
+    nextpri = pribuff[0];           // Set initial primitive pointer address
+ 
+    // load textures and possibly other stuff
+    loadstuff();
+
+    // set tpage of lone texture as initial tpage
+    draw[0].tpage = getTPage( tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+    draw[1].tpage = getTPage( tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+
+    // apply initial drawing environment
+    PutDrawEnv(&draw[!db]);
+ 
+}
+
+int main() {
+    
+    TILE *tile;                         // Pointer for TILE
+    SPRT *sprt;                         // Pointer for SPRT
+
+    // Init stuff
+    init();
+	
+    while(1) {
+
+        ClearOTagR(ot[db], OTLEN);      // Clear ordering table
+    
+        // Sort textured sprite
+        
+        sprt = (SPRT*)nextpri;
+
+        setSprt(sprt);                  // Initialize the primitive (very important)
+        setXY0(sprt, 48, 48);           // Position the sprite at (48,48)
+        setWH(sprt, 64, 64);            // Set size to 64x64 pixels
+        setUV0(sprt,                    // Set UV coordinates
+            tim_uoffs, 
+            tim_voffs);
+        setClut(sprt,                   // Set CLUT coordinates to sprite
+            tim_crect.x,
+            tim_crect.y);
+        setRGB0(sprt,                   // Set primitive color
+            128, 128, 128);
+        addPrim(ot[db], sprt);          // Sort primitive to OT
+
+        nextpri += sizeof(SPRT);        // Advance next primitive address
+        
+        
+        // Sort untextured tile primitive from the last tutorial
+        
+        tile = (TILE*)nextpri;          // Cast next primitive
+
+        setTile(tile);                  // Initialize the primitive (very important)
+        setXY0(tile, 32, 32);           // Set primitive (x,y) position
+        setWH(tile, 64, 64);            // Set primitive size
+        setRGB0(tile, 255, 255, 0);     // Set color yellow
+        addPrim(ot[db], tile);          // Add primitive to the ordering table
+        
+        nextpri += sizeof(TILE);        // Advance the next primitive pointer
+        
+    
+        // Update the display
+        display();
+        
+    }
+    
+    return 0;
+}
+
+

+Compile the example, run it and you should get a yellow square cascaded by +a sprite with your texture image. +

+
+ +
+

+You may notice that the untextured rectangle is drawn before the textured +sprite even though the textured sprite was sorted first and the untextured +rectangle last. That's because of the way how primitives are appended to +the ordering table in addPrim(), where the primitive being sorted +is linked right after a primitive that has been sorted to it previously, +and the PS1 hardware parses the ordering table from the top of the array +to the bottom with a reverse ordering table (created with ClearOTagR()). +

+
+ +How primitives are appended to a preoccupied ordering table entry +
+

+Primitive 1 would be the SPRT primitive, Primitive 2 would be the +DR_TPAGE primitive (if there was) and lastly, Primitive 3 would be +the untextured TILE primitive. You may think that a reverse +order ordering table makes no sense at first, but this technique is +integral to the PS1's ability to do on-the-fly sorting of polygons when +rendering 3D graphics. +

+ +

Tips, Tricks and Improvements

+

Pre-calculate tpage, CLUT and UV offset in a struct

+

+Using getTPage(), getClut() and setClut() macros on +every sprite sorted isn't exactly the most efficient way of doing things +especially when drawing lots of sprites, not to mention makes your code +look cluttered when managing several TIM images at once. This can be +addressed by defining a struct that contains all the parameters you +need precomputed for drawing a sprite. +

+
typedef struct _SPRITE {
+    u_short tpage;  // Tpage value
+    u_short clut;   // CLUT value
+    u_char  u,v;    // UV offset (useful for non page aligned TIMs)
+    u_char  w,h;    // Size (primitives can only draw 256x256 anyway)
+    CVECTOR col;
+} SPRITE;
+
+...
+
+// Sets parameters to a MYSPRITE using coordinates from TIM_INFO
+
+void GetSprite(TIM_IMAGE *tim, SPRITE *sprite) {
+
+    // Get tpage value
+    sprite->tpage = getTPage(tim->mode&0x3, 0, 
+        tim->prect->x, tim->prect->y);
+        
+    // Get CLUT value
+    if( tim->mode & 0x8 ) {
+        sprite->clut = getClut(tim->crect->x, tim->crect->y);
+    }
+    
+    // Set sprite size
+    sprite->w = tim->prect->w<<(2-tim->mode&0x3);
+    sprite->h = tim->prect->h;
+    
+    // Set UV offset
+    sprite->u = (tim->prect->x&0x3f)<<(2-tim->mode&0x3);
+    sprite->v = tim->prect->y&0xff;
+    
+    // Set neutral color
+    sprite->col.r = 128;
+    sprite->col.g = 128;
+    sprite->col.b = 128;
+    
+}
+
+

And to draw the sprite, you can write a simple function for it:

+
char *SortSprite(int x, int y, u_long *ot, char *pri, SPRITE *sprite) {
+
+    SPRT *sprt;
+    DR_TPAGE *tpage;
+    
+    sprt = (SPRT*)pri;                  // initialize the sprite
+    setSprt(sprt);
+
+    setXY0(sprt, x, y);                 // Set position
+    setWH(sprt, sprite->w, sprite->h);  // Set size
+    setUV0(sprt, sprite->u, sprite->v); // Set UV coordinate of sprite
+    setRGB0(sprt,                       // Set the color
+        sprite->col.r, 
+        sprite->col.g, 
+        sprite->col.b);
+    sprt->clut = sprite->clut;          // Set the CLUT value
+    
+    addPrim(ot, sprt);                  // Sort the primitive and advance
+    pri += sizeof(SPRT);
+
+    tpage = (DR_TPAGE*)pri;             // Sort the texture page value
+    setDrawTPage(tpage, 0, 1, sprite->tpage);
+    addPrim(ot, tpage);
+
+    return pri+sizeof(DR_TPAGE);        // Return new primitive pointer
+                                        // (set to nextpri)
+
+}
+
+

+This method will also work for sprite sheets by simply modifying the +GetSprite() function mentioned earlier such that you can specify an U,V +offset relative to the TIM's U,V offset and the size of the sprite. +

+ +

Use Sprite Sheets

+

+Instead of creating a single TIM image for each and every animation frame +of your character sprite, it is best to compile such small images as one +large image. This is called a sprite sheet and allows all sprite frames +to share a common palette if you use 4-bit or 8-bit color depth. If all +sprite frames have the same size, arrange the sprites in a grid where +each cell is the same size as the sprites. This way you can compute the +U,V coordinate of the sprites in the grid easily. +

+ +

Lower color depth textures are faster

+

+A 4-bit texture is faster to draw than a 8-bit texture, and a 8-bit +texture is faster to draw than a 16-bit texture, as the GPU has to read +less data from VRAM when drawing textures of lower color depth. Find a +balance that achieves best possible performance without degrading the +quality of your sprites or texture images too much. +

+ +

SPRT_8 and SPRT_16 are faster than SPRT

+

+The fixed size sprite primitives are a bit faster than SPRT +primitives, making them best suited for particle sprites of a fixed size +or when drawing tiles of a 2D map. +

+ +

Minimize tpage primitive changes

+

+This technique is most applicable when drawing tile maps. If your tile +sheet fits in a single texture page (less than 256x256), you only have +to sort a single DR_TPAGE primitive for all the tiles. This may +also help the GPU maintain texture cache coherency, as well as minimizing +redundant primitive packets.

+

Textures don't need to be powers of two

+

+Texutures of any size can be used by the GPU, though it is recommended to +make the width of 8-bit TIMs a multiples of 2 and multiples of 4 for 4-bit +TIMs as mentioned earlier in this chapter. +

+ +

Conclusion

+

+This concludes Chapter 1.3. of Lameguy64's PSX Tutorial series. If you've +sifted though this chapter well enough, you should have figured out how to +handle TIM images, uploading them to VRAM and drawing them. +

+

A few things you may want to experiment with for further learning:

+
    +
  • Try loading more TIMs and drawing them as individual sprites. Make sure +the TIM image and CLUT do not overlap one another in the TIM editing tool +you're using.
  • +
+ +
+ + + + + + +
PreviousBack to IndexNext
+ + + + \ No newline at end of file diff --git a/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/ordertable-multiprims.svg b/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/ordertable-multiprims.svg new file mode 100644 index 0000000..980bef1 --- /dev/null +++ b/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/ordertable-multiprims.svg @@ -0,0 +1,705 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + Primitive 2 + + OT[0]=0xffffffff (end) + Start of table + + + OT[1] + + OT[2] + + OT[3] + + OT[4] + + OT[5] + + OT[6] + + OT[7] + + + + + + + + + + + + + + Primitive 1 + Primitive 3 + + diff --git a/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/page-texcoord-relation.svg b/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/page-texcoord-relation.svg new file mode 100644 index 0000000..3e83f8a --- /dev/null +++ b/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/page-texcoord-relation.svg @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + Texture PageBoundary + (48,32) + + + (0,0) + + diff --git a/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/style.css b/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/style.css new file mode 100644 index 0000000..50d70a8 --- /dev/null +++ b/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/style.css @@ -0,0 +1,49 @@ +body { + max-width: 900px; + margin: auto; + padding: 8px; + font-family: sans-serif; + font-size: 14px; + //color: white; + //background: black; +} + +h { + background-color: #e0e0e0; + padding: 2px; +} + +h2 { + border-bottom: 1px solid; + //padding-left: 8px; +} + +img { + display: block; +} + +.footer-table { + font-size: 14px; +} + +.bordered-table { + border-collapse: collapse; + font-size: 11px; +} + +.bordered-table th, .bordered-table td { + border: 1px solid; + padding: 4px; +} + +hr { + border: none; + border-bottom: 1px solid black; +} + +pre { + padding: 8px; + font-size: 12px; + color: black; + background-color: LightGray; +} \ No newline at end of file diff --git a/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/vram-texture-coordinates.svg b/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/vram-texture-coordinates.svg new file mode 100644 index 0000000..b24e4f1 --- /dev/null +++ b/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/vram-texture-coordinates.svg @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + (0,0) + (1023,511) + + + + + + + + + + + + + + + + + (0,0) + (255,255) + 16-bit + + (0,0) + (255,255) + 8-bit + + 4-bit + (0,0) + (255,255) + + + diff --git a/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/vram-texture-pages.svg b/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/vram-texture-pages.svg new file mode 100644 index 0000000..ad4330d --- /dev/null +++ b/Docs/Chapter 1.3 Textures, TPages and CLUTs_files/vram-texture-pages.svg @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + (0,0) + (1023,511) + + + + + + + + + + + + + + + + + + diff --git a/Docs/Chapter 1.4 Controllers.htm b/Docs/Chapter 1.4 Controllers.htm new file mode 100644 index 0000000..ccd3d77 --- /dev/null +++ b/Docs/Chapter 1.4 Controllers.htm @@ -0,0 +1,672 @@ + + + + + + + + + + + +Chapter 1.4: Controllers + + + + + +
+
The Wayback Machine - +http://web.archive.org/web/20220827033533/http://lameguy64.net/tutorials/pstutorials/chapter1/4-controllers.html
+ + + +

Chapter 1.4: Controllers

+ +

One of the most important aspects when writing software for a game +console is taking input from a controller, as otherwise what's the point of +a game where the player can't take control of it? Unless its some demoscene +stuff you intend to write for the console.

+ +

This chapter goes over how to initialize and handle controller input in +your PS1 program. This is something that hasn't really been explained very +well in many tutorials that I've seen in my personal experience, so I'll try +my best to explain how controller input is handled on the PS1 in great +detail.

+ +

Compatible with PSn00bSDK: Yes

+ +

Tutorial Index

+ + +

Methods to Obtain Controller Input

+ +

There are a number of ways to obtain input from the controller on the +PS1; direct hardware access (complicated), through BIOS +InitPAD()/StartPAD() (simpler, but has some limitations), though +PadInit()/PadRead() (even simpler, but only works with digital +pads), and through various controller related libraries such as +libtap, libgun and libpad provided in the PsyQ/Programmers' Tool SDK.

+ +

The most common method people tend to use is PadInit() and +PadRead(), and whilst it is the most simplest to use it is not +exactly the most ideal method for a proper game project. For one it only +works with digital pads and Dual-shock pads with analog turned off. Secondly, +there's no way to determine if a pad is disconnected or not and rumble +features on Dual-shock pads cannot be accessed with it. It is, however, +ideal for prototype test programs.

+ +

Another method which is a little more ideal is to use InitPAD() +and StartPAD() which are provided by the BIOS ROM of the console. This +method is not only capable of determining if a controller is attached or not +but it also works with a wider variety of controllers including multi-taps. +The only controllers that it doesn't really support properly are both the +Namco and Konami lightguns as they need to be polled in a specific way for +it to work, which is not supported by these functions. Lightguns are beyond +the scope for this chapter anyway. It still cannot access rumble features +of Dual-analog and Dual-shock controllers however.

+ +

For compatibility with PSn00bSDK, only the BIOS InitPAD() and +StartPAD() functions will be covered in this chapter. In the future, +I will look into making a follow-up that uses libpad or a similar equivalent +library for PSn00bSDK that would also cover accessing rumble features of +Dual-analog and Dual-shock pads.

+ + +

Initializing the Pad Subsystem

+ +

The first step is to define an array of two 34 byte elements. This array +will be used as a buffer for storing incoming controller data which requires +at least about 34 bytes per controller port. It may sound a bit excessive for +storing input data, but this is necessary in case a multitap is connected to +one of the ports, as a multitap will return up to 34 bytes from all four +controllers connected to the tap.

+ +
u_char padbuff[2][34];
+
+ +

Next is to call InitPAD() to define the pad array to the BIOS +controller subsystem. libpad still uses the same buffer format that +InitPAD() would return data to, so upgrading from the BIOS pad +routines to libpad should be pretty trivial.

+ +
InitPAD( padbuff[0], 34, padbuff[1], 34 );
+
+ +

Before you start controller polling, it may be a good idea to set the +first two elements of both arrays with 0xff, so that your program won't +process faulty input when the array is parsed with zero filled data. You'll +figure out why later in this chapter.

+ +
padbuff[0][0] = padbuff[0][1] = 0xff;
+padbuff[1][0] = padbuff[1][1] = 0xff;
+
+ +

Then start controller polling with StartPAD().

+ +
StartPAD();
+
+ +

After calling StartPAD() and you have a tty console in your +development setup (or the message window in no$psx), you may see the +message "VSync: Timeout" pop-up when your program reaches a +VSync call. This happens because StartPAD() annoyingly +re-enables automatic VSync interrupt acknowledge in the PS1's kernel, +preventing the VSync() function from detecting a VSync interrupt +from occuring. Fortunately, it has a timeout, of which it will disable +the automatic VSync acknowledge so it can detect VSync interrupts again. +This can happen on both Programmer's Tool and PSn00bSDK.

+ +

In PSn00bSDK, you can avoid this message by calling +ChangeClearPAD(1) after StartPAD(), but this function is only +really exposed in PSn00bSDK.

+ +

It is generally unnecessary to stop controller polling using +StopPAD(), plus it may cause Dual-shock controllers to reset their +controller mode back to digital mode. If you're using BIOS memory card +functions later down the line, stopping pads will also stop memory cards +as well. Using StopPAD() is only really required when transferring +execution to a child PS-EXE or another PS-EXE altogether.

+ + +

Parsing Controller Data

+ +

After calling StartPAD(), the padbuff array will be filled +with controller data in every frame. For NTSC systems this is 60 times a +second and 50 for PAL systems. Therefore, the controller ports are polled +automatically, so the only thing to do next is to parse the input data +stored in the arrays.

+ +

Because the PS1's BIOS controller handler depends on VSync interrupts to +poll the controller ports, you will not be able to receive further inputs +when interrupts are disabled, but this isn't really something to worry about +yet at this point in this tutorial series.

+ +

Now, onto the pad buffer data. The first byte stored in the padbuff +array denotes the status of the port. A value of zero indicates that a +device (ie. controller) is connected to the port and the rest of the array +contains valid controller data.

+
if( padbuff[0][0] == 0 )
+{
+    // controller on port 1 connected
+}
+
+

The following byte is the controller ID, denoting both the controller +type and the number of bytes the controller has sent to the console. The +controller type is stored in the upper 4 bits of the ID byte while the data +byte is at the lower 4 bits.

+ +
padtype = padbuff[0][1]>>4;    // get the controller type
+padlen  = padbuff[0][1]&0xF;   // get the data length (normally not needed)
+
+ +

The following table lists controller type values that are relevant to this +chapter. Lightgun IDs are omitted as you won't be able to poll them properly +anyway.

+ +
+ + + + + + + + + + +
ControllerType Value
Mouse0x1
Namco NegCon0x2
Digital pad or Dual-shock in digital mode (no light)0x4
Analog Stick or Dual-analog in green mode0x5
Dual-shock in analog mode or Dual-analog in red mode0x7
Namco JogCon0xE
+
+ +

The two bytes following the ID byte are usually the controller's digital +button states as a 16-bit integer, with each bit representing the state +of one button. Oddly, the bit states are inverted, where a bit value of 1 +means released and a value of 0 means pressed.

+ +

The following table lists which bit of the 16-bit word corresponds to each +button of a standard digital pad or Dual-shock controller. Both controllers +share the same bit positions.

+ +
+ + + + + + + + + + + + + + + + + + +
BitButton
0Select
1L3 (Dual-shock only)
2R3 (Dual-shock only)
3Start
4Up
5Right
6Down
7Left
8L2
9R2
10L1
11R1
12Triangle
13Circle
14Cross
15Square
+
+ +

It may be a good idea to define a list of constants for each button so +you can specify which bit to test with more coherent names. In PSn00bSDK, +these are already defined in psxpad.h.

+ +
#define PAD_SELECT      1
+#define PAD_L3          2
+#define PAD_R3          4
+#define PAD_START       8
+#define PAD_UP          16
+#define PAD_RIGHT       32
+#define PAD_DOWN        64
+#define PAD_LEFT        128
+#define PAD_L2          256
+#define PAD_R2          512
+#define PAD_L1          1024
+#define PAD_R1          2048
+#define PAD_TRIANGLE    4096
+#define PAD_CIRCLE      8192
+#define PAD_CROSS       16384
+#define PAD_SQUARE      32768
+
+ +

To test if a button is pressed, simply mask the 16-bit integer against the +bit value of the button you want to test using an AND (&) operator. Because +the pressed state of a button is zero, you'll have to follow it up with a +NOT (!) operator as well.

+ +
u_short button;
+
+...
+
+button = *((u_short*)(padbuff[0]+2));
+
+// is cross pressed?
+if( !( button & PAD_CROSS ) )
+{
+    // do something when cross is pressed
+}
+
+ +

If you only need to support regular controllers (digital, analog stick, +Dual-analog, Dual-shock), a simplle struct like this should suffice for +all the four controller types and with analog input on controllers with +such features. In PSn00bSDK, the following struct is already defined in +psxpad.h.

+ +
typedef struct _PADTYPE
+{
+    unsigned char	stat;
+    unsigned char	len:4;
+    unsigned char	type:4;
+    unsigned short	btn;
+    unsigned char	rs_x,rs_y;
+    unsigned char	ls_x,ls_y;
+} PADTYPE;
+
+ +

If the connected controller doesn't feature any analog inputs, the +elements following btn relating to analog sticks can be ignored.

+ +

When parsing analog stick inputs, remember that the coordinates when the +stick is at its center position is not always 128, due to deadzones and +other factors that affect the potentiometers. Its recommended to implement +a simple threshold to make sure your code does not register false inputs +(at least to the player) when the stick is placed at its center position.

+ +

For more information about controller input data, you may want to check +the +Controllers Chapter in nocash's PSX specs document.

+ + +

Implementation

+ +

As an exercise for this chapter, we're going to make the textured sprite +from the last chapter move using the controller. Begin by adding the button +definitions, structs and padbuff array described in this chapter near +the beginning of the source file, but must be placed after the +#include directives. When using PSn00bSDK, you can simply include +psxpad.h instead, which already has those defined.

+ +

Next, place the InitPAD() and StartPAD() calls at the end +of your init() function, so pads get initialized alongside the +graphics. If you're using PSn00bSDK, you can add ChangeClearPAD(1) +after StartPAD() to avoid the VSync: Timeout message from +cropping up in your tty terminal.

+ +

Next, define two variables named pos_x and pos_y of type +int at the start of the main() function, preferably before +the line that defines the TILE variable. These will be for storing +the X,Y coordinates for the textured sprite. Following that, define a +variable pad of type PADTYPE, this will be used for reading +controller inputs more easily.

+ +

Before the while loop, set both pos_x and pos_y to 48 to +make sure they don't contain a random undefined value. Within the loop, add +the following code that parses the controller and performs actions according +to controller inputs.

+ +
pad = (PADTYPE*)padbuff[0];
+
+// Only parse inputs when a controller is connected
+if( pad->stat == 0 )
+{
+    // Only parse when a digital pad, 
+    // dual-analog and dual-shock is connected
+    if( ( pad->type == 0x4 ) || 
+        ( pad->type == 0x5 ) || 
+        ( pad->type == 0x7 ) )
+    {
+        if( !(pad->btn&PAD;_UP) )            // test UP
+        {
+            pos_y--;
+        }
+        else if( !(pad->btn&PAD;_UP) )       // test DOWN
+        {
+            pos_y++;
+        }
+        if( !(pad->btn&PAD;_LEFT) )          // test LEFT
+        {
+            pos_x--;
+        }
+        else if( !(pad->btn&PAD;_RIGHT) )    // test RIGHT
+        {
+            pos_x++;
+        }
+    }
+}
+
+ +

Now, go to the bit of code that sorts the textured sprite, and modify +the setXY0 macro call to use X,Y coordinates from pos_x and +pos_y.

+ +
setXY0(sprt, pos_x, pos_y);
+
+ +

If you followed the instructions properly, the source code should look +like this:

+ +
#include <sys/types.h>	// This provides typedefs needed by libgte.h and libgpu.h
+#include <stdio.h>	// Not necessary but include it anyway
+#include <libetc.h>	// Includes some functions that controls the display
+#include <libgte.h>	// GTE header, not really used but libgpu.h depends on it
+#include <libgpu.h>	// GPU library header
+#include <libapi.h>     // API header, has InitPAD() and StartPAD() defs
+
+#define OTLEN 8         // Ordering table length (recommended to set as a define
+                        // so it can be changed easily)
+
+DISPENV disp[2];        // Display/drawing buffer parameters
+DRAWENV draw[2];
+int db = 0;
+
+// PSn00bSDK requires having all u_long types replaced with
+// u_int, as u_long in modern GCC that PSn00bSDK uses defines it as a 64-bit integer.
+
+u_long ot[2][OTLEN];    // Ordering table length
+char pribuff[2][32768]; // Primitive buffer
+char *nextpri;          // Next primitive pointer
+
+int tim_mode;           // TIM image parameters
+RECT tim_prect,tim_crect;
+int tim_uoffs,tim_voffs;
+
+// Pad stuff (omit when using PSn00bSDK)
+#define PAD_SELECT      1
+#define PAD_L3          2
+#define PAD_R3          4
+#define PAD_START       8
+#define PAD_UP          16
+#define PAD_RIGHT       32
+#define PAD_DOWN        64
+#define PAD_LEFT        128
+#define PAD_L2          256
+#define PAD_R2          512
+#define PAD_L1          1024
+#define PAD_R1          2048
+#define PAD_TRIANGLE    4096
+#define PAD_CIRCLE      8192
+#define PAD_CROSS       16384
+#define PAD_SQUARE      32768
+
+typedef struct _PADTYPE
+{
+    unsigned char	stat;
+    unsigned char	len:4;
+    unsigned char	type:4;
+    unsigned short	btn;
+    unsigned char	rs_x,rs_y;
+    unsigned char	ls_x,ls_y;
+} PADTYPE;
+
+// pad buffer arrays
+u_char padbuff[2][34];
+
+void display() {
+    
+    DrawSync(0);                // Wait for any graphics processing to finish
+    
+    VSync(0);                   // Wait for vertical retrace
+
+    PutDispEnv(&disp;[db]);      // Apply the DISPENV/DRAWENVs
+    PutDrawEnv(&draw;[db]);
+
+    SetDispMask(1);             // Enable the display
+
+    DrawOTag(ot[db]+OTLEN-1);   // Draw the ordering table
+    
+    db = !db;                   // Swap buffers on every pass (alternates between 1 and 0)
+    nextpri = pribuff[db];      // Reset next primitive pointer
+    
+}
+
+// Texture upload function
+void LoadTexture(u_long *tim, TIM_IMAGE *tparam) {
+
+    // Read TIM parameters (PsyQ)
+    OpenTIM(tim);
+    ReadTIM(tparam);
+
+    // Read TIM parameters (PSn00bSDK)
+    //GetTimInfo(tim, tparam);
+
+    // Upload pixel data to framebuffer
+    LoadImage(tparam->prect, (u_long*)tparam->paddr);
+    DrawSync(0);
+
+    // Upload CLUT to framebuffer if present
+    if( tparam->mode & 0x8 ) {
+
+        LoadImage(tparam->crect, (u_long*)tparam->caddr);
+        DrawSync(0);
+
+    }
+
+}
+
+void loadstuff(void) {
+
+    TIM_IMAGE my_image;         // TIM image parameters
+
+    extern u_long tim_my_image[];
+
+    // Load the texture
+    LoadTexture(tim_my_image, &my;_image);
+
+    // Copy the TIM coordinates
+    tim_prect   = *my_image.prect;
+    tim_crect   = *my_image.crect;
+    tim_mode    = my_image.mode;
+
+    // Calculate U,V offset for TIMs that are not page aligned
+    tim_uoffs = (tim_prect.x%64)<<(2-(tim_mode&0x3));
+    tim_voffs = (tim_prect.y&0xff);
+
+}
+
+// To make main look tidy, init stuff has to be moved here
+void init(void) {
+	
+    // Reset graphics
+    ResetGraph(0);
+
+    // First buffer
+    SetDefDispEnv(&disp;[0], 0, 0, 320, 240);
+    SetDefDrawEnv(&draw;[0], 0, 240, 320, 240);
+    // Second buffer
+    SetDefDispEnv(&disp;[1], 0, 240, 320, 240);
+    SetDefDrawEnv(&draw;[1], 0, 0, 320, 240);
+
+    draw[0].isbg = 1;               // Enable clear
+    setRGB0(&draw;[0], 63, 0, 127);  // Set clear color (dark purple)
+    draw[1].isbg = 1;
+    setRGB0(&draw;[1], 63, 0, 127);
+
+    nextpri = pribuff[0];           // Set initial primitive pointer address
+ 
+    // load textures and possibly other stuff
+    loadstuff();
+
+    // set tpage of lone texture as initial tpage
+    draw[0].tpage = getTPage( tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+    draw[1].tpage = getTPage( tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+
+    // apply initial drawing environment
+    PutDrawEnv(&draw;[!db]);
+    
+    // Initialize the pads
+    InitPAD( padbuff[0], 34, padbuff[1], 34 );
+    
+    // Begin polling
+    StartPAD();
+    
+    // To avoid VSync Timeout error, may not be defined in PsyQ
+    ChangeClearPAD( 1 );
+ 
+}
+
+int main() {
+    
+    int pos_x,pos_y;
+    PADTYPE *pad;
+    
+    TILE *tile;                         // Pointer for TILE
+    SPRT *sprt;                         // Pointer for SPRT
+
+    // Init stuff
+    init();
+	
+    pos_x = pos_y = 48;
+    
+    while(1) {
+    
+        // Parse controller input
+        pad = (PADTYPE*)padbuff[0];
+
+        // Only parse inputs when a controller is connected
+        if( pad->stat == 0 )
+        {
+            // Only parse when a digital pad, 
+            // dual-analog and dual-shock is connected
+            if( ( pad->type == 0x4 ) || 
+                ( pad->type == 0x5 ) || 
+                ( pad->type == 0x7 ) )
+            {
+                if( !(pad->btn&PAD;_UP) )            // test UP
+                {
+                    pos_y--;
+                }
+                else if( !(pad->btn&PAD;_DOWN) )       // test DOWN
+                {
+                    pos_y++;
+                }
+                if( !(pad->btn&PAD;_LEFT) )          // test LEFT
+                {
+                    pos_x--;
+                }
+                else if( !(pad->btn&PAD;_RIGHT) )    // test RIGHT
+                {
+                    pos_x++;
+                }
+            }
+        }
+
+        ClearOTagR(ot[db], OTLEN);      // Clear ordering table
+    
+        // Sort textured sprite
+        
+        sprt = (SPRT*)nextpri;
+
+        setSprt(sprt);                  // Initialize the primitive (very important)
+        setXY0(sprt, pos_x, pos_y);           // Position the sprite at (48,48)
+        setWH(sprt, 64, 64);            // Set size to 64x64 pixels
+        setUV0(sprt,                    // Set UV coordinates
+            tim_uoffs, 
+            tim_voffs);
+        setClut(sprt,                   // Set CLUT coordinates to sprite
+            tim_crect.x,
+            tim_crect.y);
+        setRGB0(sprt,                   // Set primitive color
+            128, 128, 128);
+        addPrim(ot[db], sprt);          // Sort primitive to OT
+
+        nextpri += sizeof(SPRT);        // Advance next primitive address
+        
+        
+        // Sort untextured tile primitive from the last tutorial
+        
+        tile = (TILE*)nextpri;          // Cast next primitive
+
+        setTile(tile);                  // Initialize the primitive (very important)
+        setXY0(tile, 32, 32);           // Set primitive (x,y) position
+        setWH(tile, 64, 64);            // Set primitive size
+        setRGB0(tile, 255, 255, 0);     // Set color yellow
+        addPrim(ot[db], tile);          // Add primitive to the ordering table
+        
+        nextpri += sizeof(TILE);        // Advance the next primitive pointer
+        
+    
+        // Update the display
+        display();
+        
+    }
+    
+    return 0;
+}
+
+ +

Compile, execute and you should get a textured sprite that you can move +around with the directional pad of the controller.

+ +
+ +
+ + +

Conclusion

+ +

Hopefully, this chapter should teach you about getting controller input +more than using PadInit() and PadStart(). The only downside +with this method is that you can't control the vibration motors of either +Dual-analog or Dual-shock controllers, or enabling analog mode on Dual-shock +controllers in software. Hopefully, this will be covered in a future chapter +of this tutorial series.

+ +

In the next chapter, we'll be looking into handling analog inputs and a +glimpse of fixed-point integer math for performing fractional calculations +without using floats.

+ +
+ + + + + + +
PreviousBack to IndexNext
+ + + + + + \ No newline at end of file diff --git a/Docs/Chapter 1.4 Controllers_files/analytics.js b/Docs/Chapter 1.4 Controllers_files/analytics.js new file mode 100644 index 0000000..10400f0 --- /dev/null +++ b/Docs/Chapter 1.4 Controllers_files/analytics.js @@ -0,0 +1,474 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0 +/* eslint-disable no-var, semi, prefer-arrow-callback, prefer-template */ + +/** + * Collection of methods for sending analytics events to Archive.org's analytics server. + * + * These events are used for internal stats and sent (in anonymized form) to Google Analytics. + * + * @see analytics.md + * + * @type {Object} + */ +window.archive_analytics = (function defineArchiveAnalytics() { + // keep orignal Date object so as not to be affected by wayback's + // hijacking global Date object + var Date = window.Date; + var ARCHIVE_ANALYTICS_VERSION = 2; + var DEFAULT_SERVICE = 'ao_2'; + var NO_SAMPLING_SERVICE = 'ao_no_sampling'; // sends every event instead of a percentage + + var startTime = new Date(); + + /** + * @return {Boolean} + */ + function isPerformanceTimingApiSupported() { + return 'performance' in window && 'timing' in window.performance; + } + + /** + * Determines how many milliseconds elapsed between the browser starting to parse the DOM and + * the current time. + * + * Uses the Performance API or a fallback value if it's not available. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API + * + * @return {Number} + */ + function getLoadTime() { + var start; + + if (isPerformanceTimingApiSupported()) + start = window.performance.timing.domLoading; + else + start = startTime.getTime(); + + return new Date().getTime() - start; + } + + /** + * Determines how many milliseconds elapsed between the user navigating to the page and + * the current time. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API + * + * @return {Number|null} null if the browser doesn't support the Performance API + */ + function getNavToDoneTime() { + if (!isPerformanceTimingApiSupported()) + return null; + + return new Date().getTime() - window.performance.timing.navigationStart; + } + + /** + * Performs an arithmetic calculation on a string with a number and unit, while maintaining + * the unit. + * + * @param {String} original value to modify, with a unit + * @param {Function} doOperation accepts one Number parameter, returns a Number + * @returns {String} + */ + function computeWithUnit(original, doOperation) { + var number = parseFloat(original, 10); + var unit = original.replace(/(\d*\.\d+)|\d+/, ''); + + return doOperation(number) + unit; + } + + /** + * Computes the default font size of the browser. + * + * @returns {String|null} computed font-size with units (typically pixels), null if it cannot be computed + */ + function getDefaultFontSize() { + var fontSizeStr; + + if (!('getComputedStyle' in window)) + return null; + + var style = window.getComputedStyle(document.documentElement); + if (!style) + return null; + + fontSizeStr = style.fontSize; + + // Don't modify the value if tracking book reader. + if (document.querySelector('#BookReader')) + return fontSizeStr; + + return computeWithUnit(fontSizeStr, function reverseBootstrapFontSize(number) { + // Undo the 62.5% size applied in the Bootstrap CSS. + return number * 1.6; + }); + } + + /** + * Get the URL parameters for a given Location + * @param {Location} + * @return {Object} The URL parameters + */ + function getParams(location) { + if (!location) location = window.location; + var vars; + var i; + var pair; + var params = {}; + var query = location.search; + if (!query) return params; + vars = query.substring(1).split('&'); + for (i = 0; i < vars.length; i++) { + pair = vars[i].split('='); + params[pair[0]] = decodeURIComponent(pair[1]); + } + return params; + } + + function getMetaProp(name) { + var metaTag = document.querySelector('meta[property=' + name + ']'); + return metaTag ? metaTag.getAttribute('content') || null : null; + } + + var ArchiveAnalytics = { + /** + * @type {String|null} + */ + service: getMetaProp('service'), + mediaType: getMetaProp('mediatype'), + primaryCollection: getMetaProp('primary_collection'), + + /** + * Key-value pairs to send in pageviews (you can read this after a pageview to see what was + * sent). + * + * @type {Object} + */ + values: {}, + + /** + * Sends an analytics ping, preferably using navigator.sendBeacon() + * @param {Object} values + * @param {Function} [onload_callback] (deprecated) callback to invoke once ping to analytics server is done + * @param {Boolean} [augment_for_ao_site] (deprecated) if true, add some archive.org site-specific values + */ + send_ping: function send_ping(values, onload_callback, augment_for_ao_site) { + if (typeof window.navigator !== 'undefined' && typeof window.navigator.sendBeacon !== 'undefined') + this.send_ping_via_beacon(values); + else + this.send_ping_via_image(values); + }, + + /** + * Sends a ping via Beacon API + * NOTE: Assumes window.navigator.sendBeacon exists + * @param {Object} values Tracking parameters to pass + */ + send_ping_via_beacon: function send_ping_via_beacon(values) { + var url = this.generate_tracking_url(values || {}); + window.navigator.sendBeacon(url); + }, + + /** + * Sends a ping via Image object + * @param {Object} values Tracking parameters to pass + */ + send_ping_via_image: function send_ping_via_image(values) { + var url = this.generate_tracking_url(values || {}); + var loadtime_img = new Image(1, 1); + loadtime_img.src = url; + loadtime_img.alt = ''; + }, + + /** + * Construct complete tracking URL containing payload + * @param {Object} params Tracking parameters to pass + * @return {String} URL to use for tracking call + */ + generate_tracking_url: function generate_tracking_url(params) { + var baseUrl = '//analytics.archive.org/0.gif'; + var keys; + var outputParams = params; + var outputParamsArray = []; + + outputParams.service = outputParams.service || this.service || DEFAULT_SERVICE; + + // Build array of querystring parameters + keys = Object.keys(outputParams); + keys.forEach(function keyIteration(key) { + outputParamsArray.push(encodeURIComponent(key) + '=' + encodeURIComponent(outputParams[key])); + }); + outputParamsArray.push('version=' + ARCHIVE_ANALYTICS_VERSION); + outputParamsArray.push('count=' + (keys.length + 2)); // Include `version` and `count` in count + + return baseUrl + '?' + outputParamsArray.join('&'); + }, + + /** + * @param {int} page Page number + */ + send_scroll_fetch_event: function send_scroll_fetch_event(page) { + var additionalValues = { ev: page }; + var loadTime = getLoadTime(); + var navToDoneTime = getNavToDoneTime(); + if (loadTime) additionalValues.loadtime = loadTime; + if (navToDoneTime) additionalValues.nav_to_done_ms = navToDoneTime; + this.send_event('page_action', 'scroll_fetch', location.pathname, additionalValues); + }, + + send_scroll_fetch_base_event: function send_scroll_fetch_base_event() { + var additionalValues = {}; + var loadTime = getLoadTime(); + var navToDoneTime = getNavToDoneTime(); + if (loadTime) additionalValues.loadtime = loadTime; + if (navToDoneTime) additionalValues.nav_to_done_ms = navToDoneTime; + this.send_event('page_action', 'scroll_fetch_base', location.pathname, additionalValues); + }, + + /** + * @param {Object} [options] + * @param {String} [options.mediaType] + * @param {String} [options.mediaLanguage] + * @param {String} [options.page] The path portion of the page URL + */ + send_pageview: function send_pageview(options) { + var settings = options || {}; + + var defaultFontSize; + var loadTime = getLoadTime(); + var mediaType = settings.mediaType; + var primaryCollection = settings.primaryCollection; + var page = settings.page; + var navToDoneTime = getNavToDoneTime(); + + /** + * @return {String} + */ + function get_locale() { + if (navigator) { + if (navigator.language) + return navigator.language; + + else if (navigator.browserLanguage) + return navigator.browserLanguage; + + else if (navigator.systemLanguage) + return navigator.systemLanguage; + + else if (navigator.userLanguage) + return navigator.userLanguage; + } + return ''; + } + + defaultFontSize = getDefaultFontSize(); + + // Set field values + this.values.kind = 'pageview'; + this.values.timediff = (new Date().getTimezoneOffset()/60)*(-1); // *timezone* diff from UTC + this.values.locale = get_locale(); + this.values.referrer = (document.referrer == '' ? '-' : document.referrer); + + if (loadTime) + this.values.loadtime = loadTime; + + if (navToDoneTime) + this.values.nav_to_done_ms = navToDoneTime; + + if (settings.trackingId) { + this.values.ga_tid = settings.trackingId; + } + + /* START CUSTOM DIMENSIONS */ + if (defaultFontSize) + this.values.ga_cd1 = defaultFontSize; + + if ('devicePixelRatio' in window) + this.values.ga_cd2 = window.devicePixelRatio; + + if (mediaType) + this.values.ga_cd3 = mediaType; + + if (settings.mediaLanguage) { + this.values.ga_cd4 = settings.mediaLanguage; + } + + if (primaryCollection) { + this.values.ga_cd5 = primaryCollection; + } + /* END CUSTOM DIMENSIONS */ + + if (page) + this.values.page = page; + + this.send_ping(this.values); + }, + + /** + * Sends a tracking "Event". + * @param {string} category + * @param {string} action + * @param {string} label + * @param {Object} additionalEventParams + */ + send_event: function send_event( + category, + action, + label, + additionalEventParams + ) { + if (!label) label = window.location.pathname; + if (!additionalEventParams) additionalEventParams = {}; + if (additionalEventParams.mediaLanguage) { + additionalEventParams.ga_cd4 = additionalEventParams.mediaLanguage; + delete additionalEventParams.mediaLanguage; + } + var eventParams = Object.assign( + { + kind: 'event', + ec: category, + ea: action, + el: label, + cache_bust: Math.random(), + }, + additionalEventParams + ); + this.send_ping(eventParams); + }, + + /** + * Sends every event instead of a small percentage. + * + * Use this sparingly as it can generate a lot of events. + * + * @param {string} category + * @param {string} action + * @param {string} label + * @param {Object} additionalEventParams + */ + send_event_no_sampling: function send_event_no_sampling( + category, + action, + label, + additionalEventParams + ) { + var extraParams = additionalEventParams || {}; + extraParams.service = NO_SAMPLING_SERVICE; + this.send_event(category, action, label, extraParams); + }, + + /** + * @param {Object} options see this.send_pageview options + */ + send_pageview_on_load: function send_pageview_on_load(options) { + var self = this; + window.addEventListener('load', function send_pageview_with_options() { + self.send_pageview(options); + }); + }, + + /** + * Handles tracking events passed in URL. + * Assumes category and action values are separated by a "|" character. + * NOTE: Uses the unsampled analytics property. Watch out for future high click links! + * @param {Location} + */ + process_url_events: function process_url_events(location) { + var eventValues; + var actionValue; + var eventValue = getParams(location).iax; + if (!eventValue) return; + eventValues = eventValue.split('|'); + actionValue = eventValues.length >= 1 ? eventValues[1] : ''; + this.send_event_no_sampling( + eventValues[0], + actionValue, + window.location.pathname + ); + }, + + /** + * Attaches handlers for event tracking. + * + * To enable click tracking for a link, add a `data-event-click-tracking` + * attribute containing the Google Analytics Event Category and Action, separated + * by a vertical pipe (|). + * e.g. `` + * + * To enable form submit tracking, add a `data-event-form-tracking` attribute + * to the `form` tag. + * e.g. `` + * + * Additional tracking options can be added via a `data-event-tracking-options` + * parameter. This parameter, if included, should be a JSON string of the parameters. + * Valid parameters are: + * - service {string}: Corresponds to the Google Analytics property data values flow into + */ + set_up_event_tracking: function set_up_event_tracking() { + var self = this; + var clickTrackingAttributeName = 'event-click-tracking'; + var formTrackingAttributeName = 'event-form-tracking'; + var trackingOptionsAttributeName = 'event-tracking-options'; + + function handleAction(event, attributeName) { + var selector = '[data-' + attributeName + ']'; + var eventTarget = event.target; + if (!eventTarget) return; + var target = eventTarget.closest(selector); + if (!target) return; + var categoryAction; + var categoryActionParts; + var options; + categoryAction = target.dataset[toCamelCase(attributeName)]; + if (!categoryAction) return; + categoryActionParts = categoryAction.split('|'); + options = target.dataset[toCamelCase(trackingOptionsAttributeName)]; + options = options ? JSON.parse(options) : {}; + self.send_event( + categoryActionParts[0], + categoryActionParts[1], + categoryActionParts[2] || window.location.pathname, + options.service ? { service: options.service } : {} + ); + } + + function toCamelCase(str) { + return str.replace(/\W+(.)/g, function (match, chr) { + return chr.toUpperCase(); + }); + }; + + document.addEventListener('click', function(e) { + handleAction(e, clickTrackingAttributeName); + }); + + document.addEventListener('submit', function(e) { + handleAction(e, formTrackingAttributeName); + }); + }, + + /** + * @returns {Object[]} + */ + get_data_packets: function get_data_packets() { + return [this.values]; + }, + + /** + * Creates a tracking image for tracking JS compatibility. + * + * @param {string} type The type value for track_js_case in query params for 0.gif + */ + create_tracking_image: function create_tracking_image(type) { + this.send_ping_via_image({ + cache_bust: Math.random(), + kind: 'track_js', + track_js_case: type, + }); + } + }; + + return ArchiveAnalytics; +}()); +// @license-end diff --git a/Docs/Chapter 1.4 Controllers_files/banner-styles.css b/Docs/Chapter 1.4 Controllers_files/banner-styles.css new file mode 100644 index 0000000..8d39621 --- /dev/null +++ b/Docs/Chapter 1.4 Controllers_files/banner-styles.css @@ -0,0 +1,500 @@ +@import 'record.css'; /* for SPN1 */ + +#wm-ipp-base { + height:65px;/* initial height just in case js code fails */ + padding:0; + margin:0; + border:none; + background:none transparent; +} +#wm-ipp { + z-index: 2147483647; +} +#wm-ipp, #wm-ipp * { + font-family:Lucida Grande, Helvetica, Arial, sans-serif; + font-size:12px; + line-height:1.2; + letter-spacing:0; + width:auto; + height:auto; + max-width:none; + max-height:none; + min-width:0 !important; + min-height:0; + outline:none; + float:none; + text-align:left; + border:none; + color: #000; + text-indent: 0; + position: initial; + background: none; +} +#wm-ipp div, #wm-ipp canvas { + display: block; +} +#wm-ipp div, #wm-ipp tr, #wm-ipp td, #wm-ipp a, #wm-ipp form { + padding:0; + margin:0; + border:none; + border-radius:0; + background-color:transparent; + background-image:none; + /*z-index:2147483640;*/ + height:auto; +} +#wm-ipp table { + border:none; + border-collapse:collapse; + margin:0; + padding:0; + width:auto; + font-size:inherit; +} +#wm-ipp form input { + padding:1px !important; + height:auto; + display:inline; + margin:0; + color: #000; + background: none #fff; + border: 1px solid #666; +} +#wm-ipp form input[type=submit] { + padding:0 8px !important; + margin:1px 0 1px 5px !important; + width:auto !important; + border: 1px solid #000 !important; + background: #fff !important; + color: #000 !important; +} +#wm-ipp a { + display: inline; +} +#wm-ipp a:hover{ + text-decoration:underline; +} +#wm-ipp a.wm-btn:hover { + text-decoration:none; + color:#ff0 !important; +} +#wm-ipp a.wm-btn:hover span { + color:#ff0 !important; +} +#wm-ipp #wm-ipp-inside { + margin: 0 6px; + border:5px solid #000; + border-top:none; + background-color:rgba(255,255,255,0.9); + -moz-box-shadow:1px 1px 4px #333; + -webkit-box-shadow:1px 1px 4px #333; + box-shadow:1px 1px 4px #333; + border-radius:0 0 8px 8px; +} +/* selectors are intentionally verbose to ensure priority */ +#wm-ipp #wm-logo { + padding:0 10px; + vertical-align:middle; + min-width:100px; + flex: 0 0 100px; +} +#wm-ipp .c { + padding-left: 4px; +} +#wm-ipp .c .u { + margin-top: 4px !important; +} +#wm-ipp .n { + padding:0 0 0 5px !important; + vertical-align: bottom; +} +#wm-ipp .n a { + text-decoration:none; + color:#33f; + font-weight:bold; +} +#wm-ipp .n .b { + padding:0 6px 0 0 !important; + text-align:right !important; + overflow:visible; + white-space:nowrap; + color:#99a; + vertical-align:middle; +} +#wm-ipp .n .y .b { + padding:0 6px 2px 0 !important; +} +#wm-ipp .n .c { + background:#000; + color:#ff0; + font-weight:bold; + padding:0 !important; + text-align:center; +} +#wm-ipp.hi .n td.c { + color:#ec008c; +} +#wm-ipp .n td.f { + padding:0 0 0 6px !important; + text-align:left !important; + overflow:visible; + white-space:nowrap; + color:#99a; + vertical-align:middle; +} +#wm-ipp .n tr.m td { + text-transform:uppercase; + white-space:nowrap; + padding:2px 0; +} +#wm-ipp .c .s { + padding:0 5px 0 0 !important; + vertical-align:bottom; +} +#wm-ipp #wm-nav-captures { + white-space: nowrap; +} +#wm-ipp .c .s a.t { + color:#33f; + font-weight:bold; + line-height: 1.8; +} +#wm-ipp .c .s div.r { + color: #666; + font-size:9px; + white-space:nowrap; +} +#wm-ipp .c .k { + padding-bottom:1px; +} +#wm-ipp .c .s { + padding:0 5px 2px 0 !important; +} +#wm-ipp td#displayMonthEl { + padding: 2px 0 !important; +} +#wm-ipp td#displayYearEl { + padding: 0 0 2px 0 !important; +} + +div#wm-ipp-sparkline { + position:relative;/* for positioning markers */ + white-space:nowrap; + background-color:#fff; + cursor:pointer; + line-height:0.9; +} +#sparklineImgId, #wm-sparkline-canvas { + position:relative; + z-index:9012; + max-width:none; +} +#wm-ipp-sparkline div.yt { + position:absolute; + z-index:9010 !important; + background-color:#ff0 !important; + top: 0; +} +#wm-ipp-sparkline div.mt { + position:absolute; + z-index:9013 !important; + background-color:#ec008c !important; + top: 0; +} +#wm-ipp .r { + margin-left: 4px; +} +#wm-ipp .r a { + color:#33f; + border:none; + position:relative; + background-color:transparent; + background-repeat:no-repeat !important; + background-position:100% 100% !important; + text-decoration: none; +} +#wm-ipp #wm-capinfo { + /* prevents notice div background from sticking into round corners of + #wm-ipp-inside */ + border-radius: 0 0 4px 4px; +} +#wm-ipp #wm-capinfo .c-logo { + display:block; + float:left; + margin-right:3px; + width:90px; + min-height:90px; + max-height: 290px; + border-radius:45px; + overflow:hidden; + background-position:50%; + background-size:auto 90px; + box-shadow: 0 0 2px 2px rgba(208,208,208,128) inset; +} +#wm-ipp #wm-capinfo .c-logo span { + display:inline-block; +} +#wm-ipp #wm-capinfo .c-logo img { + height:90px; + position:relative; + left:-50%; +} +#wm-ipp #wm-capinfo .wm-title { + font-size:130%; +} +#wm-ipp #wm-capinfo a.wm-selector { + display:inline-block; + color: #aaa; + text-decoration:none !important; + padding: 2px 8px; +} +#wm-ipp #wm-capinfo a.wm-selector.selected { + background-color:#666; +} +#wm-ipp #wm-capinfo a.wm-selector:hover { + color: #fff; +} +#wm-ipp #wm-capinfo.notice-only #wm-capinfo-collected-by, +#wm-ipp #wm-capinfo.notice-only #wm-capinfo-timestamps { + display: none; +} +#wm-ipp #wm-capinfo #wm-capinfo-notice .wm-capinfo-content { + background-color:#ff0; + padding:5px; + font-size:14px; + text-align:center; +} +#wm-ipp #wm-capinfo #wm-capinfo-notice .wm-capinfo-content * { + font-size:14px; + text-align:center; +} +#wm-ipp #wm-expand { + right: 1px; + bottom: -1px; + color: #ffffff; + background-color: #666 !important; + padding:0 5px 0 3px !important; + border-radius: 3px 3px 0 0 !important; +} +#wm-ipp #wm-expand span { + color: #ffffff; +} +#wm-ipp #wm-expand #wm-expand-icon { + display: inline-block; + transition: transform 0.5s; + transform-origin: 50% 45%; +} +#wm-ipp #wm-expand.wm-open #wm-expand-icon { + transform: rotate(180deg); +} +#wm-ipp #wmtb { + text-align:right; +} +#wm-ipp #wmtb #wmtbURL { + width: calc(100% - 45px); +} +#wm-ipp #wm-graph-anchor { + border-right:1px solid #ccc; +} +/* time coherence */ +html.wb-highlight { + box-shadow: inset 0 0 0 3px #a50e3a !important; +} +.wb-highlight { + outline: 3px solid #a50e3a !important; +} +#wm-ipp-print { + display:none !important; +} +@media print { +#wm-ipp-base { + display:none !important; +} +#wm-ipp-print { + display:block !important; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +} +@media (max-width:414px) { + #wm-ipp .xxs { + display:none !important; + } +} +@media (min-width:1055px) { +#wm-ipp #wm-graph-anchor { + display:block !important; +} +} +@media (max-width:1054px) { +#wm-ipp #wm-graph-anchor { + display:none !important; +} +} +@media (max-width:1163px) { +#wm-logo { + display:none !important; +} +} + +#wm-btns { + white-space: nowrap; + margin-top: -2px; +} + +#wm-btns #wm-save-snapshot-open { + margin-right: 7px; + top: -6px; +} + +#wm-btns #wm-sign-in { + box-sizing: content-box; + display: none; + margin-right: 7px; + top: -8px; + + /* + round border around sign in button + */ + border: 2px #000 solid; + border-radius: 14px; + padding-right: 2px; + padding-bottom: 2px; + width: 11px; + height: 11px; +} + +#wm-btns #wm-sign-in>.iconochive-person { + font-size: 12.5px; +} + +#wm-save-snapshot-open > .iconochive-web { + color:#000; + font-size:160%; +} + +#wm-ipp #wm-share { + display: flex; + align-items: flex-end; + justify-content: space-between; +} + +#wm-share > #wm-screenshot { + display: inline-block; + margin-right: 3px; + visibility: hidden; +} + +#wm-screenshot > .iconochive-image { + color:#000; + font-size:160%; +} + +#wm-share > #wm-video { + display: inline-block; + margin-right: 3px; + visibility: hidden; +} + +#wm-video > .iconochive-movies { + color: #000; + display: inline-block; + font-size: 150%; + margin-bottom: 2px; +} + +#wm-btns #wm-save-snapshot-in-progress { + display: none; + font-size:160%; + opacity: 0.5; + position: relative; + margin-right: 7px; + top: -5px; +} + +#wm-btns #wm-save-snapshot-success { + display: none; + color: green; + position: relative; + top: -7px; +} + +#wm-btns #wm-save-snapshot-fail { + display: none; + color: red; + position: relative; + top: -7px; +} + +.wm-icon-screen-shot { + background: url("../images/web-screenshot.svg") no-repeat !important; + background-size: contain !important; + width: 22px !important; + height: 19px !important; + + display: inline-block; +} +#donato { + /* transition effect is disable so as to simplify height adjustment */ + /*transition: height 0.5s;*/ + height: 0; + margin: 0; + padding: 0; + border-bottom: 1px solid #999 !important; +} +body.wm-modal { + height: auto !important; + overflow: hidden !important; +} +#donato #donato-base { + width: 100%; + height: 100%; + /*bottom: 0;*/ + margin: 0; + padding: 0; + position: absolute; + z-index: 2147483639; +} +body.wm-modal #donato #donato-base { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 2147483640; +} + +.wb-autocomplete-suggestions { + font-family: Lucida Grande, Helvetica, Arial, sans-serif; + font-size: 12px; + text-align: left; + cursor: default; + border: 1px solid #ccc; + border-top: 0; + background: #fff; + box-shadow: -1px 1px 3px rgba(0,0,0,.1); + position: absolute; + display: none; + z-index: 2147483647; + max-height: 254px; + overflow: hidden; + overflow-y: auto; + box-sizing: border-box; +} +.wb-autocomplete-suggestion { + position: relative; + padding: 0 .6em; + line-height: 23px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-size: 1.02em; + color: #333; +} +.wb-autocomplete-suggestion b { + font-weight: bold; +} +.wb-autocomplete-suggestion.selected { + background: #f0f0f0; +} diff --git a/Docs/Chapter 1.4 Controllers_files/bundle-playback.js b/Docs/Chapter 1.4 Controllers_files/bundle-playback.js new file mode 100644 index 0000000..390894d --- /dev/null +++ b/Docs/Chapter 1.4 Controllers_files/bundle-playback.js @@ -0,0 +1,3 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0 +!function(e){var t={};function n(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(o,i,function(t){return e[t]}.bind(null,i));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=9)}([function(e,t,n){"use strict";function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function s(e){var t="function"==typeof Map?new Map:void 0;return(s=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,o)}function o(){return a(e,arguments,u(this).constructor)}return o.prototype=Object.create(e.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),l(o,e)})(e)}function a(e,t,n){return(a=c()?Reflect.construct:function(e,t,n){var o=[null];o.push.apply(o,t);var i=new(Function.bind.apply(e,o));return n&&l(i,n.prototype),i}).apply(null,arguments)}function c(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function l(e,t){return(l=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function u(e){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}if(n.d(t,"a",(function(){return f})),n.d(t,"d",(function(){return p})),n.d(t,"c",(function(){return d})),n.d(t,"b",(function(){return v})),"undefiend"!=typeof window.XMLHttpRequest){var h=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&l(e,t)}(o,e);var t,n=(t=o,function(){var e,n=u(t);if(c()){var o=u(this).constructor;e=Reflect.construct(n,arguments,o)}else e=n.apply(this,arguments);return r(this,e)});function o(){return i(this,o),n.apply(this,arguments)}return o}(s(XMLHttpRequest));Object.defineProperty(h.prototype,"responseURL",Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype,"responseURL"))}function f(e,t,n,o,i){var r;if((r=window.XMLHttpRequest?new h:new ActiveXObject("Microsoft.XMLHTTP")).onreadystatechange=function(){4==this.readyState&&n(r)},r.open(e,t,!0),o)for(var s in o)o.hasOwnProperty(s)&&r.setRequestHeader(s,o[s]);r.withCredentials=!0,r.send(i)}function p(e){return void 0!==e&&e&&e.constructor===Array}function d(e){return document.cookie.search(e)>=0}function m(e,t){var n=window["HTML".concat(e,"Element")];if(void 0!==n){var o=Object.getOwnPropertyDescriptor(n.prototype,t);void 0!==o&&Object.defineProperty(n.prototype,"_wm_".concat(t),o)}}function v(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"src",n="_wm_".concat(t);return n in e.__proto__?e[n]:e[t]}m("Image","src"),m("Media","src"),m("Embed","src"),m("IFrame","src"),m("Script","src"),m("Link","href"),m("Anchor","href")},function(e,t,n){"use strict";n.d(t,"c",(function(){return s})),n.d(t,"b",(function(){return a})),n.d(t,"a",(function(){return c}));var o=["January","February","March","April","May","June","July","August","September","October","November","December"],i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],r={Y:function(e){return e.getUTCFullYear()},m:function(e){return e.getUTCMonth()+1},b:function(e){return i[e.getUTCMonth()]},B:function(e){return o[e.getUTCMonth()]},d:function(e){return e.getUTCDate()},H:function(e){return("0"+e.getUTCHours()).slice(-2)},M:function(e){return("0"+e.getUTCMinutes()).slice(-2)},S:function(e){return("0"+e.getUTCSeconds()).slice(-2)},"%":function(){return"%"}};function s(e){var t=function(e){return"number"==typeof e&&(e=e.toString()),[e.slice(-14,-10),e.slice(-10,-8),e.slice(-8,-6),e.slice(-6,-4),e.slice(-4,-2),e.slice(-2)]}(e);return new Date(Date.UTC(t[0],t[1]-1,t[2],t[3],t[4],t[5]))}function a(e){return i[e]}function c(e,t){return t.replace(/%./g,(function(t){var n=r[t[1]];return n?n(s(e)):t}))}},function(e,t,n){"use strict";n.d(t,"b",(function(){return s})),n.d(t,"a",(function(){return a}));var o=n(0);function i(e,t){for(var n=0;n=400?i.failure&&i.failure(e):i.success&&i.success(e)}),{"Content-Type":"application/json"},r.stringify({url:e,snapshot:t,tags:n||[]})),!1}var a=function(){function e(t,n,i){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.el=t,this.url=n,this.timestamp=i,t.onclick=this.save.bind(this),document.addEventListener("DOMContentLoaded",(function(){Object(o.c)("logged-in-user")&&Object(o.c)("logged-in-sig")?r.userIsLoggedIn():r.userIsNotLoggedIn()}))}var t,n,r;return t=e,(n=[{key:"save",value:function(e){this.start(),s(this.url,this.timestamp,[],{failure:this.failure.bind(this),success:this.success.bind(this)})}},{key:"start",value:function(){this.hide(["wm-save-snapshot-fail","wm-save-snapshot-open","wm-save-snapshot-success"]),this.show(["wm-save-snapshot-in-progress"])}},{key:"failure",value:function(e){401==e.status?this.userNotLoggedIn(e):(this.hide(["wm-save-snapshot-in-progress","wm-save-snapshot-success"]),this.show(["wm-save-snapshot-fail","wm-save-snapshot-open"]),console.log("You have got an error."),console.log("If you think something wrong here please send it to support."),console.log('Response: "'+e.responseText+'"'),console.log('status: "'+e.status+'"'))}},{key:"success",value:function(e){this.hide(["wm-save-snapshot-fail","wm-save-snapshot-in-progress"]),this.show(["wm-save-snapshot-open","wm-save-snapshot-success"])}},{key:"userIsLoggedIn",value:function(){this.show("wm-save-snapshot-open"),this.hide("wm-sign-in")}},{key:"userIsNotLoggedIn",value:function(){this.hide(["wm-save-snapshot-open","wm-save-snapshot-in-progress"]),this.show("wm-sign-in")}},{key:"show",value:function(e){this.setDisplayStyle(e,"inline-block")}},{key:"hide",value:function(e){this.setDisplayStyle(e,"none")}},{key:"setDisplayStyle",value:function(e,t){var n=this;(Object(o.d)(e)?e:[e]).forEach((function(e){var o=n.el.getRootNode().getElementById(e);o&&(o.style.display=t)}))}}])&&i(t.prototype,n),r&&i(t,r),e}()},,,,,,,function(e,t,n){"use strict";var o;n.r(t);var i,r={createElementNS:document.createElementNS};var s=!0;function a(e){!function(e,t,n){if(n){var o=new Date;o.setTime(o.getTime()+24*n*60*60*1e3);var i="; expires="+o.toGMTString()}else i="";document.cookie=e+"="+t+i+"; path=/"}(e,"",-1)}var c=n(0),l=n(1),u=window.Date;function h(e,t){return(e=e.toString()).length>=t?e:"00000000".substring(0,t-e.length)+e}function f(e){for(var t=0,n=0;n3}(e)){var o=[];for(n=0;n=e.length?{done:!0}:{done:!1,value:e[t++]}},e:function(e){throw e},f:n}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i,r=!0,s=!1;return{s:function(){o=e[Symbol.iterator]()},n:function(){var e=o.next();return r=e.done,e},e:function(e){s=!0,i=e},f:function(){try{r||null==o.return||o.return()}finally{if(s)throw i}}}}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n2&&void 0!==arguments[2]?arguments[2]:"src",r=window.location.origin,s=b(window,e),l=p(s);try{for(l.s();!(o=l.n()).done;){var u=o.value;if(!n||n(u)){var h=Object(c.b)(u,i);h&&!h.startsWith(t)&&h.startsWith(r)&&(h.startsWith("data:")||a.push(h))}}}catch(e){l.e(e)}finally{l.f()}}u("img"),u("frame"),u("iframe",(function(e){return"playback"!==e.id})),u("script"),u("link",(function(e){return"stylesheet"===e.rel}),"href");var h=a.filter((function(e,t,n){return n.indexOf(e)===t}));h.length>0?(s=0,h.map((function(e){e.match("^https?://")&&(s++,Object(c.a)("HEAD",e,(function(e){if(200==e.status){var t=e.getResponseHeader("Memento-Datetime");if(null==t)console.log("%s: no Memento-Datetime",u);else{var n=document.createElement("span"),a=function(e,t){var n=new Date(e).getTime()-t,o="";n<0?(o+="-",n=Math.abs(n)):o+="+";var i=!1;if(n<1e3)return{delta:n,text:"",highlight:i};var r=n,s=Math.floor(n/1e3/60/60/24/30/12);n-=1e3*s*60*60*24*30*12;var a=Math.floor(n/1e3/60/60/24/30);n-=1e3*a*60*60*24*30;var c=Math.floor(n/1e3/60/60/24);n-=1e3*c*60*60*24;var l=Math.floor(n/1e3/60/60);n-=1e3*l*60*60;var u=Math.floor(n/1e3/60);n-=1e3*u*60;var h=Math.floor(n/1e3),f=[];s>1?(f.push(s+" years"),i=!0):1==s&&(f.push(s+" year"),i=!0);a>1?(f.push(a+" months"),i=!0):1==a&&(f.push(a+" month"),i=!0);c>1?f.push(c+" days"):1==c&&f.push(c+" day");l>1?f.push(l+" hours"):1==l&&f.push(l+" hour");u>1?f.push(u+" minutes"):1==u&&f.push(u+" minute");h>1?f.push(h+" seconds"):1==h&&f.push(h+" second");f.length>2&&(f=f.slice(0,2));return{delta:r,text:o+f.join(" "),highlight:i}}(t,r),c=a.highlight?"color:red;":"";n.innerHTML=" "+a.text,n.title=t,n.setAttribute("style",c);var l=e.getResponseHeader("Content-Type"),u=e.responseURL.replace(window.location.origin,""),h=document.createElement("a");h.innerHTML=u.split("/").splice(3).join("/"),h._wm_href=u,h.title=l,h.onmouseover=y,h.onmouseout=w;var f=document.createElement("div");f.setAttribute("data-delta",a.delta),f.appendChild(h),f.append(n),o.appendChild(f);var p=Array.prototype.slice.call(o.childNodes,0);p.sort((function(e,t){return t.getAttribute("data-delta")-e.getAttribute("data-delta")})),o.innerHTML="";for(var d=0,m=p.length;d0)for(var n=0;n0)for(var n=0;n0?this.sc.scrollTop=i+this.sc.suggestionHeight+o-this.sc.maxHeight:i<0&&(this.sc.scrollTop=i+o)}}},{key:"blurHandler",value:function(){var e=this;try{var t=this.root.querySelector(".wb-autocomplete-suggestions:hover")}catch(e){t=null}t?this.input!==document.activeElement&&setTimeout((function(){return e.focus()}),20):(this.last_val=this.input.value,this.sc.style.display="none",setTimeout((function(){return e.sc.style.display="none"}),350))}},{key:"suggest",value:function(e){var t=this.input.value;if(this.cache[t]=e,e.length&&t.length>=this.minChars){for(var n="",o=0;o40)&&13!=n&&27!=n){var o=this.input.value;if(o.length>=this.minChars){if(o!=this.last_val){if(this.last_val=o,clearTimeout(this.timer),this.cache){if(o in this.cache)return void this.suggest(this.cache[o]);for(var i=1;i'+e.replace(n,"$1")+""}},{key:"onSelect",value:function(e,t,n){}}]),e}(),j=function(){function e(t,n){S(this,e);var o=t.getRootNode();if(o.querySelector){var i="object"==_(t)?[t]:o.querySelectorAll(t);this.elems=i.map((function(e){return new E(e,n)}))}}return T(e,[{key:"destroy",value:function(){for(;this.elems.length>0;)this.elems.pop().unload()}}]),e}(),R=n(2),A=window.JSON,N=window.open,U=window.Date,I=document,D=document,P=function(e){return D.getElementById(e)};var q,F="/static/";function B(e){L.classList.contains("wm-closed")?(e&&O.classList.add("notice-only"),L.classList.replace("wm-closed","wm-open"),O.style.display="block",m(q,F,P)):(L.classList.replace("wm-open","wm-closed"),O.style.display="none",O.classList.remove("notice-only"))}function W(e,t){var n=P(e);n&&(n.style.visibility=t?"visible":"hidden")}function X(e,t){Object(c.d)(e)||(e=[e]);for(var n=0;n0&&r<60,r)}))}window.__wm={init:function(e){!function(){var e=document.cookie.split(";");if(e.length>40)for(var t=0;t1?t-1:0),o=1;o0;)x.appendChild(C.children[0]);if(d)for(var H=0;H'+((""+n).replace(/\B(?=(\d{3})+$)/g,",")+" ")+(n>1?"captures":"capture")+"",f=l.a(i,"%d %b %Y");s!=i&&(f+=" - "+l.a(s,"%d %b %Y")),h+='
'+f+"
",t.innerHTML=h}(o),function(e,t,n,o,i,r,s){var a=o.getContext("2d");if(a){a.fillStyle="#FFF";var c=(new u).getUTCFullYear(),l=t/(c-i+1),h=f(e.years),p=h[0],d=n/h[1];if(r>=i){var m=T(r);a.fillStyle="#FFFFA5",a.fillRect(m,0,l,n)}for(var v=i;v<=c;v++){m=T(v);a.beginPath(),a.moveTo(m,0),a.lineTo(m,n),a.lineWidth=1,a.strokeStyle="#CCC",a.stroke()}s=parseInt(s)-1;for(var g=(l-1)/12,y=0;y0){var M=Math.ceil(S*d);a.fillStyle=v==r&&_==s?"#EC008C":"#000",a.fillRect(Math.round(b),Math.ceil(n-M),Math.ceil(g),Math.round(M))}b+=g}}}function T(e){return Math.ceil((e-i)*l)+.5}}(o,e,t,Z,a,_,S)}}))}else{var te=new Image;te.src="/__wb/sparkline?url="+encodeURIComponent(r)+"&width="+e+"&height="+t+"&selected_year="+_+"&selected_month="+S+(i&&"&collection="+i||""),te.alt="sparkline",te.width=e,te.height=t,te.id="sparklineImgId",te.border="0",Q.parentNode.replaceChild(te,Q)}function ne(e){for(var t=[],n=e.length,o=0;o. + */ +(function(){function FuncMap(){this._map=[]}function ensureNumber(maybeNumber){try{switch(typeof maybeNumber){case"number":case"bigint":return maybeNumber;}var converted=Number(maybeNumber);return isNaN(converted)?null:converted}catch(e){}return null}function addToStringTagToClass(clazz,tag){typeof self.Symbol!=="undefined"&&typeof self.Symbol.toStringTag!=="undefined"&&Object.defineProperty(clazz.prototype,self.Symbol.toStringTag,{value:tag,enumerable:false})}function autobind(clazz){for(var prop,propValue,proto=clazz.__proto__||clazz.constructor.prototype||clazz.prototype,clazzProps=Object.getOwnPropertyNames(proto),len=clazzProps.length,i=0;i=0){var fnMapping=this._map.splice(idx,1);return fnMapping[0][1]}return null},FuncMap.prototype.map=function(param){for(var i=0;i0&&afw.preserveMedia(media)})},AutoFetcher.prototype.terminate=function(){this.worker.terminate()},AutoFetcher.prototype.justFetch=function(urls){this.worker.postMessage({type:"fetch-all",values:urls})},AutoFetcher.prototype.fetchAsPage=function(url,originalUrl,title){if(url){var headers={"X-Wombat-History-Page":originalUrl};if(title){var encodedTitle=encodeURIComponent(title.trim());title&&(headers["X-Wombat-History-Title"]=encodedTitle)}var fetchData={url:url,options:{headers:headers,cache:"no-store"}};this.justFetch([fetchData])}},AutoFetcher.prototype.postMessage=function(msg,deferred){if(deferred){var afWorker=this;return void Promise.resolve().then(function(){afWorker.worker.postMessage(msg)})}this.worker.postMessage(msg)},AutoFetcher.prototype.preserveSrcset=function(srcset,mod){this.postMessage({type:"values",srcset:{value:srcset,mod:mod,presplit:true}},true)},AutoFetcher.prototype.preserveDataSrcset=function(elem){this.postMessage({type:"values",srcset:{value:elem.dataset.srcset,mod:this.rwMod(elem),presplit:false}},true)},AutoFetcher.prototype.preserveMedia=function(media){this.postMessage({type:"values",media:media},true)},AutoFetcher.prototype.getSrcset=function(elem){return this.wombat.wb_getAttribute?this.wombat.wb_getAttribute.call(elem,"srcset"):elem.getAttribute("srcset")},AutoFetcher.prototype.rwMod=function(elem){switch(elem.tagName){case"SOURCE":return elem.parentElement&&elem.parentElement.tagName==="PICTURE"?"im_":"oe_";case"IMG":return"im_";}return"oe_"},AutoFetcher.prototype.extractFromLocalDoc=function(){var afw=this;Promise.resolve().then(function(){for(var msg={type:"values",context:{docBaseURI:document.baseURI}},media=[],i=0,sheets=document.styleSheets;i=0)||scriptType.indexOf("text/template")>=0)},Wombat.prototype.skipWrapScriptTextBasedOnText=function(text){if(!text||text.indexOf(this.WB_ASSIGN_FUNC)>=0||text.indexOf("<")===0)return true;for(var override_props=["window","self","document","location","top","parent","frames","opener"],i=0;i=0)return false;return true},Wombat.prototype.nodeHasChildren=function(node){if(!node)return false;if(typeof node.hasChildNodes==="function")return node.hasChildNodes();var kids=node.children||node.childNodes;return!!kids&&kids.length>0},Wombat.prototype.rwModForElement=function(elem,attrName){if(!elem)return undefined;var mod="mp_";if(!(elem.tagName==="LINK"&&attrName==="href")){var maybeMod=this.tagToMod[elem.tagName];maybeMod!=null&&(mod=maybeMod[attrName])}else if(elem.rel){var relV=elem.rel.trim().toLowerCase(),asV=this.wb_getAttribute.call(elem,"as");if(asV&&this.linkTagMods.linkRelToAs[relV]!=null){var asMods=this.linkTagMods.linkRelToAs[relV];mod=asMods[asV.toLowerCase()]}else this.linkTagMods[relV]!=null&&(mod=this.linkTagMods[relV])}return mod},Wombat.prototype.removeWBOSRC=function(elem){elem.tagName!=="SCRIPT"||elem.__$removedWBOSRC$__||(elem.hasAttribute("__wb_orig_src")&&elem.removeAttribute("__wb_orig_src"),elem.__$removedWBOSRC$__=true)},Wombat.prototype.retrieveWBOSRC=function(elem){if(elem.tagName==="SCRIPT"&&!elem.__$removedWBOSRC$__){var maybeWBOSRC;return maybeWBOSRC=this.wb_getAttribute?this.wb_getAttribute.call(elem,"__wb_orig_src"):elem.getAttribute("__wb_orig_src"),maybeWBOSRC==null&&(elem.__$removedWBOSRC$__=true),maybeWBOSRC}return undefined},Wombat.prototype.wrapScriptTextJsProxy=function(scriptText){return"var _____WB$wombat$assign$function_____ = function(name) {return (self._wb_wombat && self._wb_wombat.local_init && self._wb_wombat.local_init(name)) || self[name]; };\nif (!self.__WB_pmw) { self.__WB_pmw = function(obj) { this.__WB_source = obj; return this; } }\n{\nlet window = _____WB$wombat$assign$function_____(\"window\");\nlet self = _____WB$wombat$assign$function_____(\"self\");\nlet document = _____WB$wombat$assign$function_____(\"document\");\nlet location = _____WB$wombat$assign$function_____(\"location\");\nlet top = _____WB$wombat$assign$function_____(\"top\");\nlet parent = _____WB$wombat$assign$function_____(\"parent\");\nlet frames = _____WB$wombat$assign$function_____(\"frames\");\nlet opener = _____WB$wombat$assign$function_____(\"opener\");\n"+scriptText.replace(this.DotPostMessageRe,".__WB_pmw(self.window)$1")+"\n\n}"},Wombat.prototype.watchElem=function(elem,func){if(!this.$wbwindow.MutationObserver)return false;var m=new this.$wbwindow.MutationObserver(function(records,observer){for(var r,i=0;i"},Wombat.prototype.getFinalUrl=function(useRel,mod,url){var prefix=useRel?this.wb_rel_prefix:this.wb_abs_prefix;return mod==null&&(mod=this.wb_info.mod),this.wb_info.is_live||(prefix+=this.wb_info.wombat_ts),prefix+=mod,prefix[prefix.length-1]!=="/"&&(prefix+="/"),prefix+url},Wombat.prototype.resolveRelUrl=function(url,doc){var docObj=doc||this.$wbwindow.document,parser=this.makeParser(docObj.baseURI,docObj),hash=parser.href.lastIndexOf("#"),href=hash>=0?parser.href.substring(0,hash):parser.href,lastslash=href.lastIndexOf("/");return parser.href=lastslash>=0&&lastslash!==href.length-1?href.substring(0,lastslash+1)+url:href+url,parser.href},Wombat.prototype.extractOriginalURL=function(rewrittenUrl){if(!rewrittenUrl)return"";if(this.wb_is_proxy)return rewrittenUrl;var rwURLString=rewrittenUrl.toString(),url=rwURLString;if(this.startsWithOneOf(url,this.IGNORE_PREFIXES))return url;var start;start=this.startsWith(url,this.wb_abs_prefix)?this.wb_abs_prefix.length:this.wb_rel_prefix&&this.startsWith(url,this.wb_rel_prefix)?this.wb_rel_prefix.length:this.wb_rel_prefix?1:0;var index=url.indexOf("/http",start);return index<0&&(index=url.indexOf("///",start)),index<0&&(index=url.indexOf("/blob:",start)),index<0&&(index=url.indexOf("/about:blank",start)),index>=0?url=url.substr(index+1):(index=url.indexOf(this.wb_replay_prefix),index>=0&&(url=url.substr(index+this.wb_replay_prefix.length)),url.length>4&&url.charAt(2)==="_"&&url.charAt(3)==="/"&&(url=url.substr(4)),url!==rwURLString&&!this.startsWithOneOf(url,this.VALID_PREFIXES)&&!this.startsWith(url,"blob:")&&(url=this.wb_orig_scheme+url)),rwURLString.charAt(0)==="/"&&rwURLString.charAt(1)!=="/"&&this.startsWith(url,this.wb_orig_origin)&&(url=url.substr(this.wb_orig_origin.length)),this.startsWith(url,this.REL_PREFIX)?this.wb_info.wombat_scheme+":"+url:url},Wombat.prototype.makeParser=function(maybeRewrittenURL,doc){var originalURL=this.extractOriginalURL(maybeRewrittenURL),docElem=doc;return doc||(this.$wbwindow.location.href==="about:blank"&&this.$wbwindow.opener?docElem=this.$wbwindow.opener.document:docElem=this.$wbwindow.document),this._makeURLParser(originalURL,docElem)},Wombat.prototype._makeURLParser=function(url,docElem){try{return new this.$wbwindow.URL(url,docElem.baseURI)}catch(e){}var p=docElem.createElement("a");return p._no_rewrite=true,p.href=url,p},Wombat.prototype.defProp=function(obj,prop,setFunc,getFunc,enumerable){var existingDescriptor=Object.getOwnPropertyDescriptor(obj,prop);if(existingDescriptor&&!existingDescriptor.configurable)return false;if(!getFunc)return false;var descriptor={configurable:true,enumerable:enumerable||false,get:getFunc};setFunc&&(descriptor.set=setFunc);try{return Object.defineProperty(obj,prop,descriptor),true}catch(e){return console.warn("Failed to redefine property %s",prop,e.message),false}},Wombat.prototype.defGetterProp=function(obj,prop,getFunc,enumerable){var existingDescriptor=Object.getOwnPropertyDescriptor(obj,prop);if(existingDescriptor&&!existingDescriptor.configurable)return false;if(!getFunc)return false;try{return Object.defineProperty(obj,prop,{configurable:true,enumerable:enumerable||false,get:getFunc}),true}catch(e){return console.warn("Failed to redefine property %s",prop,e.message),false}},Wombat.prototype.getOrigGetter=function(obj,prop){var orig_getter;if(obj.__lookupGetter__&&(orig_getter=obj.__lookupGetter__(prop)),!orig_getter&&Object.getOwnPropertyDescriptor){var props=Object.getOwnPropertyDescriptor(obj,prop);props&&(orig_getter=props.get)}return orig_getter},Wombat.prototype.getOrigSetter=function(obj,prop){var orig_setter;if(obj.__lookupSetter__&&(orig_setter=obj.__lookupSetter__(prop)),!orig_setter&&Object.getOwnPropertyDescriptor){var props=Object.getOwnPropertyDescriptor(obj,prop);props&&(orig_setter=props.set)}return orig_setter},Wombat.prototype.getAllOwnProps=function(obj){for(var ownProps=[],props=Object.getOwnPropertyNames(obj),i=0;i "+final_href),actualLocation.href=final_href}}},Wombat.prototype.checkLocationChange=function(wombatLoc,isTop){var locType=typeof wombatLoc,actual_location=isTop?this.$wbwindow.__WB_replay_top.location:this.$wbwindow.location;locType==="string"?this.updateLocation(wombatLoc,actual_location.href,actual_location):locType==="object"&&this.updateLocation(wombatLoc.href,wombatLoc._orig_href,actual_location)},Wombat.prototype.checkAllLocations=function(){return!this.wb_wombat_updating&&void(this.wb_wombat_updating=true,this.checkLocationChange(this.$wbwindow.WB_wombat_location,false),this.$wbwindow.WB_wombat_location!=this.$wbwindow.__WB_replay_top.WB_wombat_location&&this.checkLocationChange(this.$wbwindow.__WB_replay_top.WB_wombat_location,true),this.wb_wombat_updating=false)},Wombat.prototype.proxyToObj=function(source){if(source)try{var proxyRealObj=source.__WBProxyRealObj__;if(proxyRealObj)return proxyRealObj}catch(e){}return source},Wombat.prototype.objToProxy=function(obj){if(obj)try{var maybeWbProxy=obj._WB_wombat_obj_proxy;if(maybeWbProxy)return maybeWbProxy}catch(e){}return obj},Wombat.prototype.defaultProxyGet=function(obj,prop,ownProps,fnCache){switch(prop){case"__WBProxyRealObj__":return obj;case"location":case"WB_wombat_location":return obj.WB_wombat_location;case"_WB_wombat_obj_proxy":return obj._WB_wombat_obj_proxy;case"__WB_pmw":case"WB_wombat_eval":case this.WB_ASSIGN_FUNC:case this.WB_CHECK_THIS_FUNC:return obj[prop];case"origin":return obj.WB_wombat_location.origin;case"constructor":if(obj.constructor===Window)return obj.constructor;}var retVal=obj[prop],type=typeof retVal;if(type==="function"&&ownProps.indexOf(prop)!==-1){switch(prop){case"requestAnimationFrame":case"cancelAnimationFrame":{if(!this.isNativeFunction(retVal))return retVal;break}}var cachedFN=fnCache[prop];return cachedFN&&cachedFN.original===retVal||(cachedFN={original:retVal,boundFn:retVal.bind(obj)},fnCache[prop]=cachedFN),cachedFN.boundFn}return type==="object"&&retVal&&retVal._WB_wombat_obj_proxy?(retVal instanceof Window&&this.initNewWindowWombat(retVal),retVal._WB_wombat_obj_proxy):retVal},Wombat.prototype.setLoc=function(loc,originalURL){var parser=this.makeParser(originalURL,loc.ownerDocument);loc._orig_href=originalURL,loc._parser=parser;var href=parser.href;loc._hash=parser.hash,loc._href=href,loc._host=parser.host,loc._hostname=parser.hostname,loc._origin=parser.origin?parser.host?parser.origin:"null":parser.protocol+"//"+parser.hostname+(parser.port?":"+parser.port:""),loc._pathname=parser.pathname,loc._port=parser.port,loc._protocol=parser.protocol,loc._search=parser.search,Object.defineProperty||(loc.href=href,loc.hash=parser.hash,loc.host=loc._host,loc.hostname=loc._hostname,loc.origin=loc._origin,loc.pathname=loc._pathname,loc.port=loc._port,loc.protocol=loc._protocol,loc.search=loc._search)},Wombat.prototype.makeGetLocProp=function(prop,origGetter){var wombat=this;return function newGetLocProp(){if(this._no_rewrite)return origGetter.call(this,prop);var curr_orig_href=origGetter.call(this,"href");return prop==="href"?wombat.extractOriginalURL(curr_orig_href):prop==="ancestorOrigins"?[]:(this._orig_href!==curr_orig_href&&wombat.setLoc(this,curr_orig_href),this["_"+prop])}},Wombat.prototype.makeSetLocProp=function(prop,origSetter,origGetter){var wombat=this;return function newSetLocProp(value){if(this._no_rewrite)return origSetter.call(this,prop,value);if(this["_"+prop]!==value){if(this["_"+prop]=value,!this._parser){var href=origGetter.call(this);this._parser=wombat.makeParser(href,this.ownerDocument)}var rel=false;prop==="href"&&typeof value==="string"&&value&&(value[0]==="."?value=wombat.resolveRelUrl(value,this.ownerDocument):value[0]==="/"&&(value.length<=1||value[1]!=="/")&&(rel=true,value=WB_wombat_location.origin+value));try{this._parser[prop]=value}catch(e){console.log("Error setting "+prop+" = "+value)}prop==="hash"?(value=this._parser[prop],origSetter.call(this,"hash",value)):(rel=rel||value===this._parser.pathname,value=wombat.rewriteUrl(this._parser.href,rel),origSetter.call(this,"href",value))}}},Wombat.prototype.styleReplacer=function(match,n1,n2,n3,offset,string){return n1+this.rewriteUrl(n2)+n3},Wombat.prototype.domConstructorErrorChecker=function(thisObj,what,args,numRequiredArgs){var errorMsg,needArgs=typeof numRequiredArgs==="number"?numRequiredArgs:1;if(thisObj instanceof Window?errorMsg="Failed to construct '"+what+"': Please use the 'new' operator, this DOM object constructor cannot be called as a function.":args&&args.length=0)return url;if(url.indexOf(this.wb_rel_prefix)===0&&url.indexOf("http")>1){var scheme_sep=url.indexOf(":/");return scheme_sep>0&&url[scheme_sep+2]!=="/"?url.substring(0,scheme_sep+2)+"/"+url.substring(scheme_sep+2):url}return this.getFinalUrl(true,mod,this.wb_orig_origin+url)}url.charAt(0)==="."&&(url=this.resolveRelUrl(url,doc));var prefix=this.startsWithOneOf(url.toLowerCase(),this.VALID_PREFIXES);if(prefix){var orig_host=this.$wbwindow.__WB_replay_top.location.host,orig_protocol=this.$wbwindow.__WB_replay_top.location.protocol,prefix_host=prefix+orig_host+"/";if(this.startsWith(url,prefix_host)){if(this.startsWith(url,this.wb_replay_prefix))return url;var curr_scheme=orig_protocol+"//",path=url.substring(prefix_host.length),rebuild=false;return path.indexOf(this.wb_rel_prefix)<0&&url.indexOf("/static/")<0&&(path=this.getFinalUrl(true,mod,WB_wombat_location.origin+"/"+path),rebuild=true),prefix!==curr_scheme&&prefix!==this.REL_PREFIX&&(rebuild=true),rebuild&&(url=useRel?"":curr_scheme+orig_host,path&&path[0]!=="/"&&(url+="/"),url+=path),url}return this.getFinalUrl(useRel,mod,url)}return prefix=this.startsWithOneOf(url,this.BAD_PREFIXES),prefix?this.getFinalUrl(useRel,mod,this.extractOriginalURL(url)):this.isHostUrl(url)&&!this.startsWith(url,originalLoc.host+"/")?this.getFinalUrl(useRel,mod,this.wb_orig_scheme+url):url},Wombat.prototype.rewriteUrl=function(url,useRel,mod,doc){var rewritten=this.rewriteUrl_(url,useRel,mod,doc);return this.debug_rw&&(url===rewritten?console.log("NOT REWRITTEN "+url):console.log("REWRITE: "+url+" -> "+rewritten)),rewritten},Wombat.prototype.performAttributeRewrite=function(elem,name,value,absUrlOnly){switch(name){case"innerHTML":case"outerHTML":return this.rewriteHtml(value);case"filter":return this.rewriteInlineStyle(value);case"style":return this.rewriteStyle(value);case"srcset":return this.rewriteSrcset(value,elem);}if(absUrlOnly&&!this.startsWithOneOf(value,this.VALID_PREFIXES))return value;var mod=this.rwModForElement(elem,name);return this.wbUseAFWorker&&this.WBAutoFetchWorker&&this.isSavedDataSrcSrcset(elem)&&this.WBAutoFetchWorker.preserveDataSrcset(elem),this.rewriteUrl(value,false,mod,elem.ownerDocument)},Wombat.prototype.rewriteAttr=function(elem,name,absUrlOnly){var changed=false;if(!elem||!elem.getAttribute||elem._no_rewrite||elem["_"+name])return changed;var value=this.wb_getAttribute.call(elem,name);if(!value||this.startsWith(value,"javascript:"))return changed;var new_value=this.performAttributeRewrite(elem,name,value,absUrlOnly);return new_value!==value&&(this.removeWBOSRC(elem),this.wb_setAttribute.call(elem,name,new_value),changed=true),changed},Wombat.prototype.noExceptRewriteStyle=function(style){try{return this.rewriteStyle(style)}catch(e){return style}},Wombat.prototype.rewriteStyle=function(style){if(!style)return style;var value=style;return typeof style==="object"&&(value=style.toString()),typeof value==="string"?value.replace(this.STYLE_REGEX,this.styleReplacer).replace(this.IMPORT_REGEX,this.styleReplacer).replace(this.no_wombatRe,""):value},Wombat.prototype.rewriteSrcset=function(value,elem){if(!value)return"";for(var split=value.split(this.srcsetRe),values=[],mod=this.rwModForElement(elem,"srcset"),i=0;i=0){var JS="javascript:";new_value="javascript:window.parent._wb_wombat.initNewWindowWombat(window);"+value.substr(11)}return new_value||(new_value=this.rewriteUrl(value,false,this.rwModForElement(elem,attrName))),new_value!==value&&(this.wb_setAttribute.call(elem,attrName,new_value),true)},Wombat.prototype.rewriteScript=function(elem){if(elem.hasAttribute("src")||!elem.textContent||!this.$wbwindow.Proxy)return this.rewriteAttr(elem,"src");if(this.skipWrapScriptBasedOnType(elem.type))return false;var text=elem.textContent.trim();return!this.skipWrapScriptTextBasedOnText(text)&&(elem.textContent=this.wrapScriptTextJsProxy(text),true)},Wombat.prototype.rewriteSVGElem=function(elem){var changed=this.rewriteAttr(elem,"filter");return changed=this.rewriteAttr(elem,"style")||changed,changed=this.rewriteAttr(elem,"xlink:href")||changed,changed=this.rewriteAttr(elem,"href")||changed,changed=this.rewriteAttr(elem,"src")||changed,changed},Wombat.prototype.rewriteElem=function(elem){var changed=false;if(!elem)return changed;if(elem instanceof SVGElement)changed=this.rewriteSVGElem(elem);else switch(elem.tagName){case"META":var maybeCSP=this.wb_getAttribute.call(elem,"http-equiv");maybeCSP&&maybeCSP.toLowerCase()==="content-security-policy"&&(this.wb_setAttribute.call(elem,"http-equiv","_"+maybeCSP),changed=true);break;case"STYLE":var new_content=this.rewriteStyle(elem.textContent);elem.textContent!==new_content&&(elem.textContent=new_content,changed=true,this.wbUseAFWorker&&this.WBAutoFetchWorker&&elem.sheet!=null&&this.WBAutoFetchWorker.deferredSheetExtraction(elem.sheet));break;case"LINK":changed=this.rewriteAttr(elem,"href"),this.wbUseAFWorker&&elem.rel==="stylesheet"&&this._addEventListener(elem,"load",this.utilFns.wbSheetMediaQChecker);break;case"IMG":changed=this.rewriteAttr(elem,"src"),changed=this.rewriteAttr(elem,"srcset")||changed,changed=this.rewriteAttr(elem,"style")||changed,this.wbUseAFWorker&&this.WBAutoFetchWorker&&elem.dataset.srcset&&this.WBAutoFetchWorker.preserveDataSrcset(elem);break;case"OBJECT":if(this.wb_info.isSW&&elem.parentElement&&elem.getAttribute("type")==="application/pdf"){for(var iframe=this.$wbwindow.document.createElement("IFRAME"),i=0;i0;)for(var child,children=rewriteQ.shift(),i=0;i"+rwString+"","text/html");if(!inner_doc||!this.nodeHasChildren(inner_doc.head)||!inner_doc.head.children[0].content)return rwString;var template=inner_doc.head.children[0];if(template._no_rewrite=true,this.recurseRewriteElem(template.content)){var new_html=template.innerHTML;if(checkEndTag){var first_elem=template.content.children&&template.content.children[0];if(first_elem){var end_tag="";this.endsWith(new_html,end_tag)&&!this.endsWith(rwString.toLowerCase(),end_tag)&&(new_html=new_html.substring(0,new_html.length-end_tag.length))}else if(rwString[0]!=="<"||rwString[rwString.length-1]!==">")return this.write_buff+=rwString,undefined}return new_html}return rwString},Wombat.prototype.rewriteHtmlFull=function(string,checkEndTag){var inner_doc=new DOMParser().parseFromString(string,"text/html");if(!inner_doc)return string;for(var changed=false,i=0;i=0)inner_doc.documentElement._no_rewrite=true,new_html=this.reconstructDocType(inner_doc.doctype)+inner_doc.documentElement.outerHTML;else{inner_doc.head._no_rewrite=true,inner_doc.body._no_rewrite=true;var headHasKids=this.nodeHasChildren(inner_doc.head),bodyHasKids=this.nodeHasChildren(inner_doc.body);if(new_html=(headHasKids?inner_doc.head.outerHTML:"")+(bodyHasKids?inner_doc.body.outerHTML:""),checkEndTag)if(inner_doc.all.length>3){var end_tag="";this.endsWith(new_html,end_tag)&&!this.endsWith(string.toLowerCase(),end_tag)&&(new_html=new_html.substring(0,new_html.length-end_tag.length))}else if(string[0]!=="<"||string[string.length-1]!==">")return void(this.write_buff+=string);new_html=this.reconstructDocType(inner_doc.doctype)+new_html}return new_html}return string},Wombat.prototype.rewriteInlineStyle=function(orig){var decoded;try{decoded=decodeURIComponent(orig)}catch(e){decoded=orig}if(decoded!==orig){var parts=this.rewriteStyle(decoded).split(",",2);return parts[0]+","+encodeURIComponent(parts[1])}return this.rewriteStyle(orig)},Wombat.prototype.rewriteCookie=function(cookie){var wombat=this,rwCookie=cookie.replace(this.wb_abs_prefix,"").replace(this.wb_rel_prefix,"");return rwCookie=rwCookie.replace(this.cookie_domain_regex,function(m,m1){var message={domain:m1,cookie:rwCookie,wb_type:"cookie"};return wombat.sendTopMessage(message,true),wombat.$wbwindow.location.hostname.indexOf(".")>=0&&!wombat.IP_RX.test(wombat.$wbwindow.location.hostname)?"Domain=."+wombat.$wbwindow.location.hostname:""}).replace(this.cookie_path_regex,function(m,m1){var rewritten=wombat.rewriteUrl(m1);return rewritten.indexOf(wombat.wb_curr_host)===0&&(rewritten=rewritten.substring(wombat.wb_curr_host.length)),"Path="+rewritten}),wombat.$wbwindow.location.protocol!=="https:"&&(rwCookie=rwCookie.replace("secure","")),rwCookie.replace(",|",",")},Wombat.prototype.rewriteWorker=function(workerUrl){if(!workerUrl)return workerUrl;var isBlob=workerUrl.indexOf("blob:")===0,isJS=workerUrl.indexOf("javascript:")===0;if(!isBlob&&!isJS){if(!this.startsWithOneOf(workerUrl,this.VALID_PREFIXES)&&!this.startsWith(workerUrl,"/")&&!this.startsWithOneOf(workerUrl,this.BAD_PREFIXES)){var rurl=this.resolveRelUrl(workerUrl,this.$wbwindow.document);return this.rewriteUrl(rurl,false,"wkr_",this.$wbwindow.document)}return this.rewriteUrl(workerUrl,false,"wkr_",this.$wbwindow.document)}var workerCode=isJS?workerUrl.replace("javascript:",""):null;if(isBlob){var x=new XMLHttpRequest;this.utilFns.XHRopen.call(x,"GET",workerUrl,false),this.utilFns.XHRsend.call(x),workerCode=x.responseText.replace(this.workerBlobRe,"").replace(this.rmCheckThisInjectRe,"this")}if(this.wb_info.static_prefix||this.wb_info.ww_rw_script){var originalURL=this.$wbwindow.document.baseURI,ww_rw=this.wb_info.ww_rw_script||this.wb_info.static_prefix+"wombatWorkers.js",rw="(function() { self.importScripts('"+ww_rw+"'); new WBWombat({'prefix': '"+this.wb_abs_prefix+"', 'prefixMod': '"+this.wb_abs_prefix+"wkrf_/', 'originalURL': '"+originalURL+"'}); })();";workerCode=rw+workerCode}var blob=new Blob([workerCode],{type:"application/javascript"});return URL.createObjectURL(blob)},Wombat.prototype.rewriteTextNodeFn=function(fnThis,originalFn,argsObj){var args,deproxiedThis=this.proxyToObj(fnThis);if(argsObj.length>0&&deproxiedThis.parentElement&&deproxiedThis.parentElement.tagName==="STYLE"){args=new Array(argsObj.length);var dataIndex=argsObj.length-1;dataIndex===2?(args[0]=argsObj[0],args[1]=argsObj[1]):dataIndex===1&&(args[0]=argsObj[0]),args[dataIndex]=this.rewriteStyle(argsObj[dataIndex])}else args=argsObj;return originalFn.__WB_orig_apply?originalFn.__WB_orig_apply(deproxiedThis,args):originalFn.apply(deproxiedThis,args)},Wombat.prototype.rewriteDocWriteWriteln=function(fnThis,originalFn,argsObj){var string,thisObj=this.proxyToObj(fnThis),argLen=argsObj.length;if(argLen===0)return originalFn.call(thisObj);string=argLen===1?argsObj[0]:Array.prototype.join.call(argsObj,"");var new_buff=this.rewriteHtml(string,true),res=originalFn.call(thisObj,new_buff);return this.initNewWindowWombat(thisObj.defaultView),res},Wombat.prototype.rewriteChildNodeFn=function(fnThis,originalFn,argsObj){var thisObj=this.proxyToObj(fnThis);if(argsObj.length===0)return originalFn.call(thisObj);var newArgs=this.rewriteElementsInArguments(argsObj);return originalFn.__WB_orig_apply?originalFn.__WB_orig_apply(thisObj,newArgs):originalFn.apply(thisObj,newArgs)},Wombat.prototype.rewriteInsertAdjHTMLOrElemArgs=function(fnThis,originalFn,position,textOrElem,rwHTML){var fnThisObj=this.proxyToObj(fnThis);return fnThisObj._no_rewrite?originalFn.call(fnThisObj,position,textOrElem):rwHTML?originalFn.call(fnThisObj,position,this.rewriteHtml(textOrElem)):(this.rewriteElemComplete(textOrElem),originalFn.call(fnThisObj,position,textOrElem))},Wombat.prototype.rewriteSetTimeoutInterval=function(fnThis,originalFn,argsObj){var rw=this.isString(argsObj[0]),args=rw?new Array(argsObj.length):argsObj;if(rw){args[0]=this.$wbwindow.Proxy?this.wrapScriptTextJsProxy(argsObj[0]):argsObj[0].replace(/\blocation\b/g,"WB_wombat_$&");for(var i=1;i0&&cssStyleValueOverride(this.$wbwindow.CSSStyleValue,"parse"),this.$wbwindow.CSSStyleValue.parseAll&&this.$wbwindow.CSSStyleValue.parseAll.toString().indexOf("[native code]")>0&&cssStyleValueOverride(this.$wbwindow.CSSStyleValue,"parseAll")}if(this.$wbwindow.CSSKeywordValue&&this.$wbwindow.CSSKeywordValue.prototype){var oCSSKV=this.$wbwindow.CSSKeywordValue;this.$wbwindow.CSSKeywordValue=function(CSSKeywordValue_){return function CSSKeywordValue(cssValue){return wombat.domConstructorErrorChecker(this,"CSSKeywordValue",arguments),new CSSKeywordValue_(wombat.rewriteStyle(cssValue))}}(this.$wbwindow.CSSKeywordValue),this.$wbwindow.CSSKeywordValue.prototype=oCSSKV.prototype,Object.defineProperty(this.$wbwindow.CSSKeywordValue.prototype,"constructor",{value:this.$wbwindow.CSSKeywordValue}),addToStringTagToClass(this.$wbwindow.CSSKeywordValue,"CSSKeywordValue")}if(this.$wbwindow.StylePropertyMap&&this.$wbwindow.StylePropertyMap.prototype){var originalSet=this.$wbwindow.StylePropertyMap.prototype.set;this.$wbwindow.StylePropertyMap.prototype.set=function set(){if(arguments.length<=1)return originalSet.__WB_orig_apply?originalSet.__WB_orig_apply(this,arguments):originalSet.apply(this,arguments);var newArgs=new Array(arguments.length);newArgs[0]=arguments[0];for(var i=1;i")&&(array[0]=wombat.rewriteHtml(array[0]),options.type="text/html"),new Blob_(array,options)}}(this.$wbwindow.Blob),this.$wbwindow.Blob.prototype=orig_blob.prototype}},Wombat.prototype.initDocTitleOverride=function(){var orig_get_title=this.getOrigGetter(this.$wbwindow.document,"title"),orig_set_title=this.getOrigSetter(this.$wbwindow.document,"title"),wombat=this,set_title=function title(value){var res=orig_set_title.call(this,value),message={wb_type:"title",title:value};return wombat.sendTopMessage(message),res};this.defProp(this.$wbwindow.document,"title",set_title,orig_get_title)},Wombat.prototype.initFontFaceOverride=function(){if(this.$wbwindow.FontFace){var wombat=this,origFontFace=this.$wbwindow.FontFace;this.$wbwindow.FontFace=function(FontFace_){return function FontFace(family,source,descriptors){wombat.domConstructorErrorChecker(this,"FontFace",arguments,2);var rwSource=source;return source!=null&&(typeof source==="string"?rwSource=wombat.rewriteInlineStyle(source):rwSource=wombat.rewriteInlineStyle(source.toString())),new FontFace_(family,rwSource,descriptors)}}(this.$wbwindow.FontFace),this.$wbwindow.FontFace.prototype=origFontFace.prototype,Object.defineProperty(this.$wbwindow.FontFace.prototype,"constructor",{value:this.$wbwindow.FontFace}),addToStringTagToClass(this.$wbwindow.FontFace,"FontFace")}},Wombat.prototype.initFixedRatio=function(){try{this.$wbwindow.devicePixelRatio=1}catch(e){}if(Object.defineProperty)try{Object.defineProperty(this.$wbwindow,"devicePixelRatio",{value:1,writable:false})}catch(e){}},Wombat.prototype.initPaths=function(wbinfo){wbinfo.wombat_opts=wbinfo.wombat_opts||{},Object.assign(this.wb_info,wbinfo),this.wb_opts=wbinfo.wombat_opts,this.wb_replay_prefix=wbinfo.prefix,this.wb_is_proxy=wbinfo.proxy_magic||!this.wb_replay_prefix,this.wb_info.top_host=this.wb_info.top_host||"*",this.wb_curr_host=this.$wbwindow.location.protocol+"//"+this.$wbwindow.location.host,this.wb_info.wombat_opts=this.wb_info.wombat_opts||{},this.wb_orig_scheme=wbinfo.wombat_scheme+"://",this.wb_orig_origin=this.wb_orig_scheme+wbinfo.wombat_host,this.wb_abs_prefix=this.wb_replay_prefix,this.wb_capture_date_part=!wbinfo.is_live&&wbinfo.wombat_ts?"/"+wbinfo.wombat_ts+"/":"",this.initBadPrefixes(this.wb_replay_prefix),this.initCookiePreset()},Wombat.prototype.initSeededRandom=function(seed){this.$wbwindow.Math.seed=parseInt(seed);var wombat=this;this.$wbwindow.Math.random=function random(){return wombat.$wbwindow.Math.seed=(wombat.$wbwindow.Math.seed*9301+49297)%233280,wombat.$wbwindow.Math.seed/233280}},Wombat.prototype.initHistoryOverrides=function(){this.overrideHistoryFunc("pushState"),this.overrideHistoryFunc("replaceState");var wombat=this;this.$wbwindow.addEventListener("popstate",function(event){wombat.sendHistoryUpdate(wombat.$wbwindow.WB_wombat_location.href,wombat.$wbwindow.document.title)})},Wombat.prototype.initCookiePreset=function(){if(this.wb_info.presetCookie)for(var splitCookies=this.wb_info.presetCookie.split(";"),i=0;i0?"&":"?")+value.toString(),value=null):contentType==="application/json"||contentType==="text/plain"?(this.__WB_xhr_open_arguments[0]="GET",this.__WB_xhr_open_arguments[1]+=(this.__WB_xhr_open_arguments[1].indexOf("?")>0?"&":"?")+jsonToQueryString(value),value=null):wombat.startsWith(contentType,"multipart/form-data")&&(this.__WB_xhr_open_arguments[0]="GET",this.__WB_xhr_open_arguments[1]+=(this.__WB_xhr_open_arguments[1].indexOf("?")>0?"&":"?")+mfdToQueryString(value,contentType))}if(this.__WB_xhr_open_arguments.length>2&&(this.__WB_xhr_open_arguments[2]=true),this._no_rewrite||(this.__WB_xhr_open_arguments[1]=wombat.rewriteUrl(this.__WB_xhr_open_arguments[1])),origOpen.apply(this,this.__WB_xhr_open_arguments),!wombat.startsWith(this.__WB_xhr_open_arguments[1],"data:")){for(const[name,value]of this.__WB_xhr_headers.entries())origSetRequestHeader.call(this,name,value);origSetRequestHeader.call(this,"X-Pywb-Requested-With","XMLHttpRequest")}origSend.call(this,value)}}if(this.$wbwindow.fetch){var orig_fetch=this.$wbwindow.fetch;this.$wbwindow.fetch=function fetch(input,init_opts){var rwInput=input,inputType=typeof input;if(inputType==="string")rwInput=wombat.rewriteUrl(input);else if(inputType==="object"&&input.url){var new_url=wombat.rewriteUrl(input.url);new_url!==input.url&&(rwInput=new Request(new_url,init_opts))}else inputType==="object"&&input.href&&(rwInput=wombat.rewriteUrl(input.href));if(init_opts||(init_opts={}),init_opts.credentials===undefined)try{init_opts.credentials="include"}catch(e){}return orig_fetch.call(wombat.proxyToObj(this),rwInput,init_opts)}}if(this.$wbwindow.Request&&this.$wbwindow.Request.prototype){var orig_request=this.$wbwindow.Request;this.$wbwindow.Request=function(Request_){return function Request(input,init_opts){wombat.domConstructorErrorChecker(this,"Request",arguments);var newInitOpts=init_opts||{},newInput=input,inputType=typeof input;switch(inputType){case"string":newInput=wombat.rewriteUrl(input);break;case"object":if(newInput=input,input.url){var new_url=wombat.rewriteUrl(input.url);new_url!==input.url&&(newInput=new Request_(new_url,input))}else input.href&&(newInput=wombat.rewriteUrl(input.toString(),true));}return newInitOpts.credentials="include",new Request_(newInput,newInitOpts)}}(this.$wbwindow.Request),this.$wbwindow.Request.prototype=orig_request.prototype,Object.defineProperty(this.$wbwindow.Request.prototype,"constructor",{value:this.$wbwindow.Request})}if(this.$wbwindow.Response&&this.$wbwindow.Response.prototype){var originalRedirect=this.$wbwindow.Response.prototype.redirect;this.$wbwindow.Response.prototype.redirect=function redirect(url,status){var rwURL=wombat.rewriteUrl(url,true,null,wombat.$wbwindow.document);return originalRedirect.call(this,rwURL,status)}}if(this.$wbwindow.EventSource&&this.$wbwindow.EventSource.prototype){var origEventSource=this.$wbwindow.EventSource;this.$wbwindow.EventSource=function(EventSource_){return function EventSource(url,configuration){wombat.domConstructorErrorChecker(this,"EventSource",arguments);var rwURL=url;return url!=null&&(rwURL=wombat.rewriteUrl(url)),new EventSource_(rwURL,configuration)}}(this.$wbwindow.EventSource),this.$wbwindow.EventSource.prototype=origEventSource.prototype,Object.defineProperty(this.$wbwindow.EventSource.prototype,"constructor",{value:this.$wbwindow.EventSource}),addToStringTagToClass(this.$wbwindow.EventSource,"EventSource")}if(this.$wbwindow.WebSocket&&this.$wbwindow.WebSocket.prototype){var origWebSocket=this.$wbwindow.WebSocket;this.$wbwindow.WebSocket=function(WebSocket_){return function WebSocket(url,configuration){wombat.domConstructorErrorChecker(this,"WebSocket",arguments);var rwURL=url;return url!=null&&(rwURL=wombat.rewriteWSURL(url)),new WebSocket_(rwURL,configuration)}}(this.$wbwindow.WebSocket),this.$wbwindow.WebSocket.prototype=origWebSocket.prototype,Object.defineProperty(this.$wbwindow.WebSocket.prototype,"constructor",{value:this.$wbwindow.WebSocket}),addToStringTagToClass(this.$wbwindow.WebSocket,"WebSocket")}},Wombat.prototype.initElementGetSetAttributeOverride=function(){if(!this.wb_opts.skip_setAttribute&&this.$wbwindow.Element&&this.$wbwindow.Element.prototype){var wombat=this,ElementProto=this.$wbwindow.Element.prototype;if(ElementProto.setAttribute){var orig_setAttribute=ElementProto.setAttribute;ElementProto._orig_setAttribute=orig_setAttribute,ElementProto.setAttribute=function setAttribute(name,value){var rwValue=value;if(name&&typeof rwValue==="string"){var lowername=name.toLowerCase();if(this.tagName==="LINK"&&lowername==="href"&&rwValue.indexOf("data:text/css")===0)rwValue=wombat.rewriteInlineStyle(value);else if(lowername==="style")rwValue=wombat.rewriteStyle(value);else if(lowername==="srcset")rwValue=wombat.rewriteSrcset(value,this);else{var shouldRW=wombat.shouldRewriteAttr(this.tagName,lowername);shouldRW&&(wombat.removeWBOSRC(this),!this._no_rewrite&&(rwValue=wombat.rewriteUrl(value,false,wombat.rwModForElement(this,lowername))))}}return orig_setAttribute.call(this,name,rwValue)}}if(ElementProto.getAttribute){var orig_getAttribute=ElementProto.getAttribute;this.wb_getAttribute=orig_getAttribute,ElementProto.getAttribute=function getAttribute(name){var result=orig_getAttribute.call(this,name);if(result===null)return result;var lowerName=name;if(name&&(lowerName=name.toLowerCase()),wombat.shouldRewriteAttr(this.tagName,lowerName)){var maybeWBOSRC=wombat.retrieveWBOSRC(this);return maybeWBOSRC?maybeWBOSRC:wombat.extractOriginalURL(result)}return wombat.startsWith(lowerName,"data-")&&wombat.startsWithOneOf(result,wombat.wb_prefixes)?wombat.extractOriginalURL(result):result}}}},Wombat.prototype.initSvgImageOverrides=function(){if(this.$wbwindow.SVGImageElement){var svgImgProto=this.$wbwindow.SVGImageElement.prototype,orig_getAttr=svgImgProto.getAttribute,orig_getAttrNS=svgImgProto.getAttributeNS,orig_setAttr=svgImgProto.setAttribute,orig_setAttrNS=svgImgProto.setAttributeNS,wombat=this;svgImgProto.getAttribute=function getAttribute(name){var value=orig_getAttr.call(this,name);return name.indexOf("xlink:href")>=0||name==="href"?wombat.extractOriginalURL(value):value},svgImgProto.getAttributeNS=function getAttributeNS(ns,name){var value=orig_getAttrNS.call(this,ns,name);return name.indexOf("xlink:href")>=0||name==="href"?wombat.extractOriginalURL(value):value},svgImgProto.setAttribute=function setAttribute(name,value){var rwValue=value;return(name.indexOf("xlink:href")>=0||name==="href")&&(rwValue=wombat.rewriteUrl(value)),orig_setAttr.call(this,name,rwValue)},svgImgProto.setAttributeNS=function setAttributeNS(ns,name,value){var rwValue=value;return(name.indexOf("xlink:href")>=0||name==="href")&&(rwValue=wombat.rewriteUrl(value)),orig_setAttrNS.call(this,ns,name,rwValue)}}},Wombat.prototype.initCreateElementNSFix=function(){if(this.$wbwindow.document.createElementNS&&this.$wbwindow.Document.prototype.createElementNS){var orig_createElementNS=this.$wbwindow.document.createElementNS,wombat=this,createElementNS=function createElementNS(namespaceURI,qualifiedName){return orig_createElementNS.call(wombat.proxyToObj(this),wombat.extractOriginalURL(namespaceURI),qualifiedName)};this.$wbwindow.Document.prototype.createElementNS=createElementNS,this.$wbwindow.document.createElementNS=createElementNS}},Wombat.prototype.initInsertAdjacentElementHTMLOverrides=function(){var Element=this.$wbwindow.Element;if(Element&&Element.prototype){var elementProto=Element.prototype,rewriteFn=this.rewriteInsertAdjHTMLOrElemArgs;if(elementProto.insertAdjacentHTML){var origInsertAdjacentHTML=elementProto.insertAdjacentHTML;elementProto.insertAdjacentHTML=function insertAdjacentHTML(position,text){return rewriteFn(this,origInsertAdjacentHTML,position,text,true)}}if(elementProto.insertAdjacentElement){var origIAdjElem=elementProto.insertAdjacentElement;elementProto.insertAdjacentElement=function insertAdjacentElement(position,element){return rewriteFn(this,origIAdjElem,position,element,false)}}}},Wombat.prototype.initDomOverride=function(){var Node=this.$wbwindow.Node;if(Node&&Node.prototype){var rewriteFn=this.rewriteNodeFuncArgs;if(Node.prototype.appendChild){var originalAppendChild=Node.prototype.appendChild;Node.prototype.appendChild=function appendChild(newNode,oldNode){return rewriteFn(this,originalAppendChild,newNode,oldNode)}}if(Node.prototype.insertBefore){var originalInsertBefore=Node.prototype.insertBefore;Node.prototype.insertBefore=function insertBefore(newNode,oldNode){return rewriteFn(this,originalInsertBefore,newNode,oldNode)}}if(Node.prototype.replaceChild){var originalReplaceChild=Node.prototype.replaceChild;Node.prototype.replaceChild=function replaceChild(newNode,oldNode){return rewriteFn(this,originalReplaceChild,newNode,oldNode)}}this.overridePropToProxy(Node.prototype,"ownerDocument"),this.overridePropToProxy(this.$wbwindow.HTMLHtmlElement.prototype,"parentNode"),this.overridePropToProxy(this.$wbwindow.Event.prototype,"target")}this.$wbwindow.Element&&this.$wbwindow.Element.prototype&&(this.overrideParentNodeAppendPrepend(this.$wbwindow.Element),this.overrideChildNodeInterface(this.$wbwindow.Element,false)),this.$wbwindow.DocumentFragment&&this.$wbwindow.DocumentFragment.prototype&&this.overrideParentNodeAppendPrepend(this.$wbwindow.DocumentFragment)},Wombat.prototype.initDocOverrides=function($document){if(Object.defineProperty){this.overrideReferrer($document),this.defGetterProp($document,"origin",function origin(){return this.WB_wombat_location.origin}),this.defGetterProp(this.$wbwindow,"origin",function origin(){return this.WB_wombat_location.origin});var wombat=this,domain_setter=function domain(val){var loc=this.WB_wombat_location;loc&&wombat.endsWith(loc.hostname,val)&&(this.__wb_domain=val)},domain_getter=function domain(){return this.__wb_domain||this.WB_wombat_location.hostname};this.defProp($document,"domain",domain_setter,domain_getter)}},Wombat.prototype.initDocWriteOpenCloseOverride=function(){if(this.$wbwindow.DOMParser){var DocumentProto=this.$wbwindow.Document.prototype,$wbDocument=this.$wbwindow.document,docWriteWritelnRWFn=this.rewriteDocWriteWriteln,orig_doc_write=$wbDocument.write,new_write=function write(){return docWriteWritelnRWFn(this,orig_doc_write,arguments)};$wbDocument.write=new_write,DocumentProto.write=new_write;var orig_doc_writeln=$wbDocument.writeln,new_writeln=function writeln(){return docWriteWritelnRWFn(this,orig_doc_writeln,arguments)};$wbDocument.writeln=new_writeln,DocumentProto.writeln=new_writeln;var wombat=this,orig_doc_open=$wbDocument.open,new_open=function open(){var res,thisObj=wombat.proxyToObj(this);if(arguments.length===3){var rwUrl=wombat.rewriteUrl(arguments[0],false,"mp_");res=orig_doc_open.call(thisObj,rwUrl,arguments[1],arguments[2]),wombat.initNewWindowWombat(res,arguments[0])}else res=orig_doc_open.call(thisObj),wombat.initNewWindowWombat(thisObj.defaultView);return res};$wbDocument.open=new_open,DocumentProto.open=new_open;var originalClose=$wbDocument.close,newClose=function close(){var thisObj=wombat.proxyToObj(this);return wombat.initNewWindowWombat(thisObj.defaultView),originalClose.__WB_orig_apply?originalClose.__WB_orig_apply(thisObj,arguments):originalClose.apply(thisObj,arguments)};$wbDocument.close=newClose,DocumentProto.close=newClose;var oBodyGetter=this.getOrigGetter(DocumentProto,"body"),oBodySetter=this.getOrigSetter(DocumentProto,"body");oBodyGetter&&oBodySetter&&this.defProp(DocumentProto,"body",function body(newBody){return newBody&&(newBody instanceof HTMLBodyElement||newBody instanceof HTMLFrameSetElement)&&wombat.rewriteElemComplete(newBody),oBodySetter.call(wombat.proxyToObj(this),newBody)},oBodyGetter)}},Wombat.prototype.initIframeWombat=function(iframe){var win;win=iframe._get_contentWindow?iframe._get_contentWindow.call(iframe):iframe.contentWindow;try{if(!win||win===this.$wbwindow||win._skip_wombat||win._wb_wombat)return}catch(e){return}var src=iframe.src;this.initNewWindowWombat(win,src)},Wombat.prototype.initNewWindowWombat=function(win,src){var fullWombat=false;if(win&&!win._wb_wombat){if((!src||src===""||this.startsWithOneOf(src,["about:blank","javascript:"]))&&(fullWombat=true),!fullWombat&&this.wb_info.isSW){var origURL=this.extractOriginalURL(src);(origURL==="about:blank"||origURL.startsWith("srcdoc:")||origURL.startsWith("blob:"))&&(fullWombat=true)}if(fullWombat){var newInfo={};Object.assign(newInfo,this.wb_info);var wombat=new Wombat(win,newInfo);win._wb_wombat=wombat.wombatInit()}else this.initProtoPmOrigin(win),this.initPostMessageOverride(win),this.initMessageEventOverride(win),this.initCheckThisFunc(win)}},Wombat.prototype.initTimeoutIntervalOverrides=function(){var rewriteFn=this.rewriteSetTimeoutInterval;if(this.$wbwindow.setTimeout&&!this.$wbwindow.setTimeout.__$wbpatched$__){var originalSetTimeout=this.$wbwindow.setTimeout;this.$wbwindow.setTimeout=function setTimeout(){return rewriteFn(this,originalSetTimeout,arguments)},this.$wbwindow.setTimeout.__$wbpatched$__=true}if(this.$wbwindow.setInterval&&!this.$wbwindow.setInterval.__$wbpatched$__){var originalSetInterval=this.$wbwindow.setInterval;this.$wbwindow.setInterval=function setInterval(){return rewriteFn(this,originalSetInterval,arguments)},this.$wbwindow.setInterval.__$wbpatched$__=true}},Wombat.prototype.initWorkerOverrides=function(){var wombat=this;if(this.$wbwindow.Worker&&!this.$wbwindow.Worker._wb_worker_overriden){var orig_worker=this.$wbwindow.Worker;this.$wbwindow.Worker=function(Worker_){return function Worker(url,options){return wombat.domConstructorErrorChecker(this,"Worker",arguments),new Worker_(wombat.rewriteWorker(url),options)}}(orig_worker),this.$wbwindow.Worker.prototype=orig_worker.prototype,Object.defineProperty(this.$wbwindow.Worker.prototype,"constructor",{value:this.$wbwindow.Worker}),this.$wbwindow.Worker._wb_worker_overriden=true}if(this.$wbwindow.SharedWorker&&!this.$wbwindow.SharedWorker.__wb_sharedWorker_overriden){var oSharedWorker=this.$wbwindow.SharedWorker;this.$wbwindow.SharedWorker=function(SharedWorker_){return function SharedWorker(url,options){return wombat.domConstructorErrorChecker(this,"SharedWorker",arguments),new SharedWorker_(wombat.rewriteWorker(url),options)}}(oSharedWorker),this.$wbwindow.SharedWorker.prototype=oSharedWorker.prototype,Object.defineProperty(this.$wbwindow.SharedWorker.prototype,"constructor",{value:this.$wbwindow.SharedWorker}),this.$wbwindow.SharedWorker.__wb_sharedWorker_overriden=true}if(this.$wbwindow.ServiceWorkerContainer&&this.$wbwindow.ServiceWorkerContainer.prototype&&this.$wbwindow.ServiceWorkerContainer.prototype.register){var orig_register=this.$wbwindow.ServiceWorkerContainer.prototype.register;this.$wbwindow.ServiceWorkerContainer.prototype.register=function register(scriptURL,options){var newScriptURL=new URL(scriptURL,wombat.$wbwindow.document.baseURI).href,mod=wombat.getPageUnderModifier();return options&&options.scope?options.scope=wombat.rewriteUrl(options.scope,false,mod):options={scope:wombat.rewriteUrl("/",false,mod)},orig_register.call(this,wombat.rewriteUrl(newScriptURL,false,"sw_"),options)}}if(this.$wbwindow.Worklet&&this.$wbwindow.Worklet.prototype&&this.$wbwindow.Worklet.prototype.addModule&&!this.$wbwindow.Worklet.__wb_workerlet_overriden){var oAddModule=this.$wbwindow.Worklet.prototype.addModule;this.$wbwindow.Worklet.prototype.addModule=function addModule(moduleURL,options){var rwModuleURL=wombat.rewriteUrl(moduleURL,false,"js_");return oAddModule.call(this,rwModuleURL,options)},this.$wbwindow.Worklet.__wb_workerlet_overriden=true}},Wombat.prototype.initLocOverride=function(loc,oSetter,oGetter){if(Object.defineProperty)for(var prop,i=0;i=0&&props.splice(foundInx,1);return props}})}catch(e){console.log(e)}},Wombat.prototype.initHashChange=function(){if(this.$wbwindow.__WB_top_frame){var wombat=this,receive_hash_change=function receive_hash_change(event){if(event.data&&event.data.from_top){var message=event.data.message;message.wb_type&&(message.wb_type!=="outer_hashchange"||wombat.$wbwindow.location.hash==message.hash||(wombat.$wbwindow.location.hash=message.hash))}},send_hash_change=function send_hash_change(){var message={wb_type:"hashchange",hash:wombat.$wbwindow.location.hash};wombat.sendTopMessage(message)};this.$wbwindow.addEventListener("message",receive_hash_change),this.$wbwindow.addEventListener("hashchange",send_hash_change)}},Wombat.prototype.initPostMessageOverride=function($wbwindow){if($wbwindow.postMessage&&!$wbwindow.__orig_postMessage){var orig=$wbwindow.postMessage,wombat=this;$wbwindow.__orig_postMessage=orig;var postmessage_rewritten=function postMessage(message,targetOrigin,transfer,from_top){var from,src_id,this_obj=wombat.proxyToObj(this);if(this_obj.__WB_source&&this_obj.__WB_source.WB_wombat_location){var source=this_obj.__WB_source;if(from=source.WB_wombat_location.origin,this_obj.__WB_win_id||(this_obj.__WB_win_id={},this_obj.__WB_counter=0),!source.__WB_id){var id=this_obj.__WB_counter;source.__WB_id=id+source.WB_wombat_location.href,this_obj.__WB_counter+=1}this_obj.__WB_win_id[source.__WB_id]=source,src_id=source.__WB_id,this_obj.__WB_source=undefined}else from=window.WB_wombat_location.origin;var to_origin=targetOrigin;to_origin===this_obj.location.origin&&(to_origin=from);var new_message={from:from,to_origin:to_origin,src_id:src_id,message:message,from_top:from_top};if(targetOrigin!=="*"){if(this_obj.location.origin==="null"||this_obj.location.origin==="")return;targetOrigin=this_obj.location.origin}return orig.call(this_obj,new_message,targetOrigin,transfer)};$wbwindow.postMessage=postmessage_rewritten,$wbwindow.Window.prototype.postMessage=postmessage_rewritten;var eventTarget=null;eventTarget=$wbwindow.EventTarget&&$wbwindow.EventTarget.prototype?$wbwindow.EventTarget.prototype:$wbwindow;var _oAddEventListener=eventTarget.addEventListener;eventTarget.addEventListener=function addEventListener(type,listener,useCapture){var rwListener,obj=wombat.proxyToObj(this);if(type==="message"?rwListener=wombat.message_listeners.add_or_get(listener,function(){return wrapEventListener(listener,obj,wombat)}):type==="storage"?wombat.storage_listeners.add_or_get(listener,function(){return wrapSameOriginEventListener(listener,obj)}):rwListener=listener,rwListener)return _oAddEventListener.call(obj,type,rwListener,useCapture)};var _oRemoveEventListener=eventTarget.removeEventListener;eventTarget.removeEventListener=function removeEventListener(type,listener,useCapture){var rwListener,obj=wombat.proxyToObj(this);if(type==="message"?rwListener=wombat.message_listeners.remove(listener):type==="storage"?wombat.storage_listeners.remove(listener):rwListener=listener,rwListener)return _oRemoveEventListener.call(obj,type,rwListener,useCapture)};var override_on_prop=function(onevent,wrapperFN){var orig_setter=wombat.getOrigSetter($wbwindow,onevent),setter=function(value){this["__orig_"+onevent]=value;var obj=wombat.proxyToObj(this),listener=value?wrapperFN(value,obj,wombat):value;return orig_setter.call(obj,listener)},getter=function(){return this["__orig_"+onevent]};wombat.defProp($wbwindow,onevent,setter,getter)};override_on_prop("onmessage",wrapEventListener),override_on_prop("onstorage",wrapSameOriginEventListener)}},Wombat.prototype.initMessageEventOverride=function($wbwindow){!$wbwindow.MessageEvent||$wbwindow.MessageEvent.prototype.__extended||(this.addEventOverride("target"),this.addEventOverride("srcElement"),this.addEventOverride("currentTarget"),this.addEventOverride("eventPhase"),this.addEventOverride("path"),this.overridePropToProxy($wbwindow.MessageEvent.prototype,"source"),$wbwindow.MessageEvent.prototype.__extended=true)},Wombat.prototype.initUIEventsOverrides=function(){this.overrideAnUIEvent("UIEvent"),this.overrideAnUIEvent("MouseEvent"),this.overrideAnUIEvent("TouchEvent"),this.overrideAnUIEvent("FocusEvent"),this.overrideAnUIEvent("KeyboardEvent"),this.overrideAnUIEvent("WheelEvent"),this.overrideAnUIEvent("InputEvent"),this.overrideAnUIEvent("CompositionEvent")},Wombat.prototype.initOpenOverride=function(){var orig=this.$wbwindow.open;this.$wbwindow.Window.prototype.open&&(orig=this.$wbwindow.Window.prototype.open);var wombat=this,open_rewritten=function open(strUrl,strWindowName,strWindowFeatures){var rwStrUrl=wombat.rewriteUrl(strUrl,false,""),res=orig.call(wombat.proxyToObj(this),rwStrUrl,strWindowName,strWindowFeatures);return wombat.initNewWindowWombat(res,strUrl),res};this.$wbwindow.open=open_rewritten,this.$wbwindow.Window.prototype.open&&(this.$wbwindow.Window.prototype.open=open_rewritten);for(var i=0;i + + +Chapter 1.5: Fixed point Math + + + + +

Chapter 1.5: Fixed Point Math

+ +

If you've been trying to write some games on a modern system (ie. your +PC), you probably already know about using floats to implement momentum and +jumping physics in a 2D platformer, or have something move towards a direction +specified in degrees rather than X,Y velocity values to have said object +move at an angle, like a ship in an Asteroids style game or a car in a +top-down racer... On the PlayStation, these principles still apply. But +there's a problem; the PlayStation does not have a hardware floating point +unit.

+ +

Whilst you can still use floats on the PlayStation as the compiler will +resort to software emulation to perform such operations, which you might +be able to get away with, it's not exactly the most ideal method as software +emulation of floats is quite slow, and will become an issue if used for +collision detection or processing movement of a hundred projectile +entities... The alternative that's better suited for a system without a +floating point unit is to use a integer based fractional number system +commonly known as fixed point math.

+ +

As the name suggests, fixed point math is a trick for storing fractional +numbers with fixed points, in this case an integer scale of 4096 will have +a range between zero to 4095 representing a fractional value, with 4096 +representing a integer value of 1. Fixed point math is used heavily in games +made for systems that lacked a floating point unit (5th generation and older +consoles), or where integer math is considerably faster than floating point +math and not all systems feature a floating point unit +(ie. IBM compatible PCs).

+ +

This chapter covers the general idea and basics of performing fixed point +integer arithmetic. This is a highly essential chapter when getting into +PlayStation homebrew development, as learning it will increase the range of +games you can write for the console immensely. If you've already learned some +binary encoding of numeric values this chapter might be a bit easier to +understand.

+ +

Compatible with PSn00bSDK: Yes

+ +

Tutorial Index

+ + +

Principle of Fixed Point Math

+ +

The basic principle of fixed point integer math is instead of representing +a real number of 1.25 as a floating point number, you instead represent +the number as an integer value from a scale value, in this case 4096 which is +defined as ONE in the GTE library headers. So a real value of 1.25 +will look like 5120 when converted to fixed point math with a scale of 4096. +Converting a floating point number to a fixed point number is achieved by +simply multiplying the real number against the scale value and rounding off +the fractions, turning the result into a plain integer value. The following +table shows some sample floating point values represented in fixed point.

+ +
+ + + + + + + + + +
Floating point representationFixed point representation
1.255120
0.753072
0.2819
21.28487179
1.0 = 4096
+
+ +

Using a scale value of 4096 is most ideal for PlayStation projects not +only because it provides a good balance between precision and the maximum +decimal value it can store, alongside allowing fixed point values to be +rounded and divided quickly with simple bit shift operations and AND masks, +but also because the Geometry Transformation Engine (GTE) also uses the +same scale value for some of its registers. Any scale value can be used to +gain more precision or to increase the decimal range limit. Generally +a power of two scale value is recommended for performance reasons.

+ +
+ + + + + + + + + + + + + + + +
Bits313029282726252423222120191817161514131211109876543210
DescriptionSignDecimal (19 bits)Fractional (12 bits)
+
+ +

The table above illustrates a fixed point value with a scale value +of 4096 in a signed 32-bit integer. As there's only 19 bits available for +the decimal portion the maximum range for the decimal value is -524288 to +524287.

+ + +

Fixed Point Arithmetic Basics

+ +

Simple mathematical operations in fixed point such as addition and +subtraction is not that much different to performing the same operations +with integers, only values have to be based around the scale value.

+
fixed_value += 4096;    // += 1.0
+fixed_value -= 4096;    // -= 1.0
+fixed_value += 2048;    // += 0.5
+fixed_value -= 6144;    // -= 1.5
+
+ +

For decimal multiplication and divide operations, the value for the +dividend or multiplicand stays as-is.

+
fixed_value *= 5;       // *= 5;
+fixed_value /= 10;      // /= 10;
+
+ +

The equation for performing fractional multiplications is a little +tricky, but still not too complicated.

+
multiplicand    = 2048;                             // multiplicand = 0.5;
+fixed_value     = (fixed_value*multiplicand)>>12;   // fixed_value *= multiplicand;
+
+multiplicand    = 6144;                             // multiplicand = 1.5;
+fixed_value     = (fixed_value*multiplicand)>>12;   // fixed_value *= multiplicand;
+
+ +

For fractional divisions, the value will need to be multiplied by the +scale value and then divided by the dividend. Keep in mind that division by +zero would still occur if the dividend is zero. +

dividend        = 2048;                             // dividend = 0.5;
+fixed_value     = (fixed_value*4096)/dividend;      // fixed_value /= dividend;
+
+dividend        = 6144;                             // dividend = 1.5;
+fixed_value     = (fixed_value*4096)/dividend;      // fixed_value /= dividend;
+
+ + +

Implementing Tank Controls with Fixed Point

+ +

As a little exercise, this part of the chapter will go through using fixed +point math to implement tank controls. The basic jist of this is that instead +of moving the player position directly by which direction of the D-pad is +pressed, instead, left and right will adjust the angle the player is facing +while up and down moves the player forward and backward perpendicular to +where the player is facing. To do this requires using sine and cosine values +and conveniently, the GTE libraries of both SDKs feature integer based sine +and cosine functions which is exactly what's needed for this exercise.

+ +

In the official PsyQ or Programmer's Tool SDKs there are two integer based +sine and cosine functions which are rsin()/rcos() and +csin()/ccos(). The differences between the two is that +rsin()/rcos() takes up less code but is slower, whereas +csin()/ccos() takes up more code but is faster. PSn00bSDK on +the other hand only has one set of functions called isin()/icos(), +which are based on a Taylor series implementation which is both small and fast. +PSn00bSDK provides definitions for rsin()/rcos() and +csin()/ccos() that simply points to isin()/icos() +for compatibility with PsyQ / Programmer's Tool projects and sample code.

+ +

These functions also take degrees in a fixed point range of 0 to 4096 +where 4096 equals to 360 degrees, so a value of 45 degrees will be +specified as 512. The value returned is also in a fixed point notation +with a scale of 4096, where 4096 equals to 1.0.

+ +

Working from code from the controllers chapter, rewrite the code that +defines the initial values of the player position to begin at the center +of the screen. Because the player coordinates will be in fixed point, the +screen center coordinate must be multiplied by ONE.

+ +
pos_x = ONE*(disp[0].disp.w>>1);
+pos_y = ONE*(disp[0].disp.h>>1);
+
+ +

Then, define a new variable for the player's angle and set the initial +value to zero.

+ +
int angle;
+
+angle = 0;
+
+ +

The player will be represented as a rotating triangle in this chaper, so +a simple array of vector coordinates will define the shape of the triangle. +The triangle will be rotated with, you guessed it, fixed point math as well. +

+ +
SVECTOR player_tri[] =
+{
+    {   0, -20,  0  },
+    {  10,  20,  0  },
+    { -10,  20,  0  }
+};
+
+ +

Then ditch the code for sorting TILE and SPRT primitives +and replace it with the following routine that sorts a rotating triangle.

+
POLY_F3 *tri;
+
+...
+
+// Rotate the triangle coordinates based on the player's angle
+// as well as apply the position
+for( i=0; i<3; i++ )
+{
+    v[i].vx = (((player_tri[i].vx*ccos( angle ))
+        -(player_tri[i].vy*csin( angle )))>>12)+(pos_x>>12);
+    v[i].vy = (((player_tri[i].vy*ccos( angle ))
+        +(player_tri[i].vx*csin( angle )))>>12)+(pos_y>>12);
+}
+
+// Sort the player triangle
+tri = (POLY_F3*)nextpri;
+setPolyF3( tri );
+setRGB0( tri, 255, 255, 0 );
+setXY3( tri,
+    v[0].vx, v[0].vy,
+    v[1].vx, v[1].vy,
+    v[2].vx, v[2].vy );
+    
+addPrim( ot[db], tri );
+nextpri += sizeof(POLY_F3);
+
+ +

And then replace the input code with the following. If you've written +something that played like Asteroids in the past, this may look pretty +familiar.

+
if( !(pad->btn&PAD_UP) )            // test UP
+{
+    pos_x += csin( angle );
+    pos_y -= ccos( angle );
+}
+else if( !(pad->btn&PAD_DOWN) )     // test DOWN
+{
+    pos_x -= csin( angle );
+    pos_y += ccos( angle );
+}
+if( !(pad->btn&PAD_LEFT) )          // test LEFT
+{
+    // Turns counter-clockwise
+    angle -= 16;
+}
+else if( !(pad->btn&PAD_RIGHT) )    // test RIGHT
+{
+    // Turns clockwise
+    angle += 16;
+}
+
+ +

Next is to finally add some text drawing so the player coordinates can be +displayed on screen, so you can see how fixed point numbers work while +interacting with the sample program more easily. This can be done with the +debug font functions provided by libetc or psxetc in both +PsyQ / Programmer's Tool and PSn00bSDK respectively. These font functions are +intended for debugging purposes, so they're not fit for drawing things like +player status with custom fonts and lower case letters.

+ +

Start by loading the debug font texture to VRAM using FntLoad(), +then, initialize a font window using FntOpen(). Ideally, you should +put these calls inside the init() function.

+ +
// Load the font texture on the upper-right corner of the VRAM
+FntLoad( 960, 0 );
+
+// Define a font window of 100 characters covering the whole screen
+FntOpen( 0, 8, 320, 224, 0, 100 );
+
+ +

Text can be printed using FntPrint() which works more or less like +printf(), only text output is directed to the specified font window. +The first argument specifies which font window the text should go to, the +value of which is obtained through the return value of FntOpen(). +Specifying -1 directs text to the last opened font window. The debug font +routines can only draw uppercase text, and text color and font cannot be +customized.

+ +

In PsyQ / Programmers tool the first argument can be omitted, but modern +GNU GCC does not support this convention anymore.

+ +
// Print player coordinates
+FntPrint( -1, "POS_X=%d (%d.%d)\n", pos_x, (pos_x>>12), (pos_x&0xfff) );
+FntPrint( -1, "POS_Y=%d (%d.%d)\n", pos_y, (pos_y>>12), (pos_y&0xfff) );
+FntPrint( -1, "ANGLE=%d\n", angle );
+
+ +

Then to make the text actually appear, call FntFlush() to draw the +characters 'printed' by FntPrint() and flush the character buffer. +This should be called immediately before the display() call in the +sample code.

+ +
// Draw and flush the character buffer
+FntFlush( -1 );
+
+ +

The finished code should look like the following (the texture stuff +remains for future samples):

+
#include <sys/types.h>	// This provides typedefs needed by libgte.h and libgpu.h
+#include <stdio.h>	// Not necessary but include it anyway
+#include <psxetc.h>	// Includes some functions that controls the display
+#include <psxgte.h>	// GTE header, not really used but libgpu.h depends on it
+#include <psxgpu.h>	// GPU library header
+#include <psxapi.h>
+
+#define OTLEN 8         // Ordering table length (recommended to set as a define
+                        // so it can be changed easily)
+
+DISPENV disp[2];        // Display/drawing buffer parameters
+DRAWENV draw[2];
+int db = 0;
+
+// PSn00bSDK requires having all u_long types replaced with
+// u_int, as u_long in modern GCC that PSn00bSDK uses defines it as a 64-bit integer.
+
+u_int ot[2][OTLEN];    // Ordering table length
+char pribuff[2][32768]; // Primitive buffer
+char *nextpri;          // Next primitive pointer
+
+int tim_mode;           // TIM image parameters
+RECT tim_prect,tim_crect;
+int tim_uoffs,tim_voffs;
+
+// Pad stuff
+#define PAD_SELECT      1
+#define PAD_L3          2
+#define PAD_R3          4
+#define PAD_START       8
+#define PAD_UP          16
+#define PAD_RIGHT       32
+#define PAD_DOWN        64
+#define PAD_LEFT        128
+#define PAD_L2          256
+#define PAD_R2          512
+#define PAD_L1          1024
+#define PAD_R1          2048
+#define PAD_TRIANGLE    4096
+#define PAD_CIRCLE      8192
+#define PAD_CROSS       16384
+#define PAD_SQUARE      32768
+
+typedef struct _PADTYPE
+{
+    unsigned char	stat;
+    unsigned char	len:4;
+    unsigned char	type:4;
+    unsigned short	btn;
+    unsigned char	rs_x,rs_y;
+    unsigned char	ls_x,ls_y;
+} PADTYPE;
+
+u_char padbuff[2][34];
+
+// For the player triangle
+SVECTOR player_tri[] = {
+    {   0, -20,  0  },
+    {  10,  20,  0  },
+    { -10,  20,  0  }
+};
+
+void display() {
+    
+    DrawSync(0);                // Wait for any graphics processing to finish
+    
+    VSync(0);                   // Wait for vertical retrace
+
+    PutDispEnv(&disp[db]);      // Apply the DISPENV/DRAWENVs
+    PutDrawEnv(&draw[db]);
+
+    SetDispMask(1);             // Enable the display
+
+    DrawOTag(ot[db]+OTLEN-1);   // Draw the ordering table
+    
+    db = !db;                   // Swap buffers on every pass (alternates between 1 and 0)
+    nextpri = pribuff[db];      // Reset next primitive pointer
+    
+}
+
+// Texture upload function
+void LoadTexture(u_int *tim, TIM_IMAGE *tparam) {
+
+    // Read TIM parameters (PsyQ)
+    //OpenTIM(tim);
+    //ReadTIM(tparam);
+
+    // Read TIM parameters (PSn00bSDK)
+    GetTimInfo(tim, tparam);
+
+    // Upload pixel data to framebuffer
+    LoadImage(tparam->prect, tparam->paddr);
+    DrawSync(0);
+
+    // Upload CLUT to framebuffer if present
+    if( tparam->mode & 0x8 ) {
+
+        LoadImage(tparam->crect, tparam->caddr);
+        DrawSync(0);
+
+    }
+
+}
+
+void loadstuff(void) {
+
+    TIM_IMAGE my_image;         // TIM image parameters
+
+    extern u_int tim_my_image[];
+
+    // Load the texture
+    LoadTexture(tim_my_image, &my_image);
+
+    // Copy the TIM coordinates
+    tim_prect   = *my_image.prect;
+    tim_crect   = *my_image.crect;
+    tim_mode    = my_image.mode;
+
+    // Calculate U,V offset for TIMs that are not page aligned
+    tim_uoffs = (tim_prect.x%64)<<(2-(tim_mode&0x3));
+    tim_voffs = (tim_prect.y&0xff);
+
+}
+
+// To make main look tidy, init stuff has to be moved here
+void init(void) {
+    
+    // Reset graphics
+    ResetGraph(0);
+
+    // First buffer
+    SetDefDispEnv(&disp[0], 0, 0, 320, 240);
+    SetDefDrawEnv(&draw[0], 0, 240, 320, 240);
+    // Second buffer
+    SetDefDispEnv(&disp[1], 0, 240, 320, 240);
+    SetDefDrawEnv(&draw[1], 0, 0, 320, 240);
+
+    draw[0].isbg = 1;               // Enable clear
+    setRGB0(&draw[0], 63, 0, 127);  // Set clear color (dark purple)
+    draw[1].isbg = 1;
+    setRGB0(&draw[1], 63, 0, 127);
+
+    nextpri = pribuff[0];           // Set initial primitive pointer address
+ 
+    // load textures and possibly other stuff
+    loadstuff();
+
+    // set tpage of lone texture as initial tpage
+    draw[0].tpage = getTPage( tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+    draw[1].tpage = getTPage( tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+
+    // apply initial drawing environment
+    PutDrawEnv(&draw[!db]);
+    
+    // Initialize the pads
+    InitPAD( padbuff[0], 34, padbuff[1], 34 );
+    
+    // Begin polling
+    StartPAD();
+    
+    // To avoid VSync Timeout error, may not be defined in PsyQ
+    ChangeClearPAD( 1 );
+    
+    // Load the font texture on the upper-right corner of the VRAM
+    FntLoad( 960, 0 );
+
+    // Define a font window of 100 characters covering the whole screen
+    FntOpen( 0, 8, 320, 224, 0, 100 );
+ 
+}
+
+int main() {
+    
+    int i;
+    int pos_x,pos_y,angle;
+    PADTYPE *pad;
+    POLY_F3 *tri;
+    SVECTOR v[3];
+    
+    TILE *tile;                         // Pointer for TILE
+    SPRT *sprt;                         // Pointer for SPRT
+
+    // Init stuff
+    init();
+    
+    pos_x = ONE*(disp[0].disp.w>>1);
+    pos_y = ONE*(disp[0].disp.h>>1);
+    angle = 0;
+    
+    while(1) {
+    
+        // Parse controller input
+        pad = (PADTYPE*)padbuff[0];
+
+        // Only parse inputs when a controller is connected
+        if( pad->stat == 0 )
+        {
+            // Only parse when a digital pad, 
+            // dual-analog and dual-shock is connected
+            if( ( pad->type == 0x4 ) || 
+                ( pad->type == 0x5 ) || 
+                ( pad->type == 0x7 ) )
+            {
+                if( !(pad->btn&PAD_UP) )            // test UP
+                {
+                    pos_x += csin( angle );
+                    pos_y -= ccos( angle );
+                }
+                else if( !(pad->btn&PAD_DOWN) )     // test DOWN
+                {
+                    pos_x -= csin( angle );
+                    pos_y += ccos( angle );
+                }
+                if( !(pad->btn&PAD_LEFT) )          // test LEFT
+                {
+                    angle -= 16;
+                }
+                else if( !(pad->btn&PAD_RIGHT) )    // test RIGHT
+                {
+                    angle += 16;
+                }
+            }
+        }
+
+        ClearOTagR(ot[db], OTLEN);      // Clear ordering table
+        
+        // Rotate the triangle coordinates based on the player's angle
+        // as well as apply the position
+        for( i=0; i<3; i++ )
+        {
+            v[i].vx = (((player_tri[i].vx*icos( angle ))
+                -(player_tri[i].vy*csin( angle )))>>12)+(pos_x>>12);
+            v[i].vy = (((player_tri[i].vy*icos( angle ))
+                +(player_tri[i].vx*csin( angle )))>>12)+(pos_y>>12);
+        }
+        
+        // Sort the player triangle
+        tri = (POLY_F3*)nextpri;
+        setPolyF3( tri );
+        setRGB0( tri, 255, 255, 0 );
+        setXY3( tri,
+            v[0].vx, v[0].vy,
+            v[1].vx, v[1].vy,
+            v[2].vx, v[2].vy );
+        addPrim( ot[db], tri );
+        nextpri += sizeof(POLY_F3);
+        
+        // Print player coordinates
+        FntPrint( -1, "POS_X=%d (%d.%d)\n", pos_x, (pos_x>>12), (pos_x&0xfff) );
+        FntPrint( -1, "POS_Y=%d (%d.%d)\n", pos_y, (pos_y>>12), (pos_y&0xfff) );
+        FntPrint( -1, "ANGLE=%d\n", angle );
+
+        // Draw and flush the character buffer
+        FntFlush( -1 );
+        
+        // Update the display
+        display();
+        
+    }
+    
+    return 0;
+}
+
+ +

Compile and execute the code and you should get a triangle that controls +more or less like a tank. Press the left and right directional buttons to +turn the triangle while pressing up and down moves the triangle forwards and +backward perpendicular to where the triangle is pointing.

+ +
+ +
+ + +

Asteroids Style Physics with Fixed Point

+ +

Now to make the tank controls sample a little more interesting by making +it control like an Asteroids or Spacewar game. Basically, instead of +accumulating the player coordinates directly with values based on the +player's angle you accumulate them to a velocity vector, which in turn +accumulates on the player's coordinates. This way, simple momentum based +physics are archieved.

+ +

This can be done by implementing some changes to the last sample. Start +by adding variables in main() that'll be used to store the player's +velocity coordinates.

+ +
int vel_x,vel_y;
+
+...
+
+// just to make sure they don't contain garbage
+vel_x = 0;
+vel_y = 0;
+
+ +

Next, modify some of the pad code to accumulate player movement +towards the velocity variables instead of the player's coordinates. +Put some bit shifts that divides the sin/cos values by 8 otherwise +the 'ship' will accelerate too quickly.

+ +
if( !(pad->btn&PAD_UP) )            // test UP
+{
+    vel_x += csin( angle )>>3;
+    vel_y -= ccos( angle )>>3;
+}
+else if( !(pad->btn&PAD_DOWN) )     // test DOWN
+{
+    vel_x -= csin( angle )>>3;
+    vel_y += ccos( angle )>>3;
+}
+
+ +

Immediately after the pad code add a few lines that accumulates the +velocity coordinates to the player's coordinates.

+ +
// accumulate player coordinates by its velocity
+pos_x += vel_x;
+pos_y += vel_y;
+
+ +

And to keep the player from going off-screen, place the following lines +immediately after the above code to wrap the player's coordinates when they +go off-screen.

+ +
// wrap player coordinates from going off-screen
+if( (pos_x>>12) < 0 )
+{
+    pos_x += (320<<12);
+}
+if( (pos_x>>12) > 320 )
+{
+    pos_x -= (320<<12);
+}
+if( (pos_y>>12) < 0 )
+{
+    pos_y += (240<<12);
+}
+if( (pos_y>>12) > 240 )
+{
+    pos_y -= (240<<12);
+}
+
+ +

Then place some additional FntPrint() calls that displays the +values from the velocity variables. You'll also need to increase the +character buffer size of the FntOpen() call (the last argument) +from 100 to 150.

+ +
FntPrint( -1, "VEL_X=%d (%d.%d)\n", vel_x, (vel_x>>12), (vel_x&0xfff) );
+FntPrint( -1, "VEL_Y=%d (%d.%d)\n", vel_y, (vel_y>>12), (vel_y&0xfff) );
+
+ +

Compile the sample demo and the triangle should behave a lot like an +Asteroids ship.

+ +
+ +
+ +

If you want velocity to slowly diminish overtime, add the following +lines just before the velocity vectors are accumulated to the player +coordinates. It also acts as a velocity constraint as well.

+ +
// equivalent to multiplying each axis by 0.9765625
+vel_x = (vel_x*4000)>>12;
+vel_y = (vel_y*4000)>>12;
+
+ + +

Bonus: Fixed Point Sprite Rotation

+ +

Since it is something new programmers would find incredibly handy and to +show off some of what the 32-bit console can do, especially for PSn00bSDK folk +as it does not have an equivalent to libgs, here's a fixed point based sprite +rotation and scaling routine that draws a rotated and scaled sprite with a +single quad. The math for rotation is more or less the same as how the player +triangle is rotated.

+ +
void sortRotSprite( int x, int y, int pw, int ph, int angle, int scale )
+{
+    POLY_FT4 *quad;
+    SVECTOR	s[4];
+    SVECTOR	v[4];
+
+    int i,cx,cy;
+
+    // calculate the pivot point (center) of the sprite
+    cx = pw>>1;
+    cy = ph>>1;
+
+    // increment by 0.5 on the bottom and right coords so scaling
+    // would increment a bit smoother
+    s[0].vx = -(((pw*scale)>>12)-cx);
+    s[0].vy = -(((ph*scale)>>12)-cy);
+
+    s[1].vx = (((pw*scale)+2048)>>12)-cx;
+    s[1].vy = s[0].vy;
+
+    s[2].vx = -(((pw*scale)>>12)-cx);
+    s[2].vy = (((ph*scale)+2048)>>12)-cy;
+
+    s[3].vx = (((pw*scale)+2048)>>12)-cx;
+    s[3].vy = s[2].vy;
+    
+    // a simple but pretty effective optimization trick
+    cx = ccos( angle );
+    cy = csin( angle );
+    
+    // calculate rotated sprite coordinates
+    for( i=0; i<4; i++ )
+    {
+        v[i].vx = (((s[i].vx*cx)
+            -(s[i].vy*cy))>>12)+x;
+        v[i].vy = (((s[i].vy*cx)
+            +(s[i].vx*cy))>>12)+y;
+    }
+
+    // initialize the quad primitive for the sprite
+    quad = (POLY_FT4*)nextpri;
+    setPolyFT4( quad );
+
+    // set CLUT and tpage to the primitive
+    setTPage( quad, tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+    setClut( quad, tim_crect.x, tim_crect.y );
+
+    // set color, screen coordinates and texture coordinates of primitive
+    setRGB0( quad, 128, 128, 128 );
+    setXY4( quad,
+        v[0].vx, v[0].vy,
+        v[1].vx, v[1].vy,
+        v[2].vx, v[2].vy,
+        v[3].vx, v[3].vy );
+    setUVWH( quad, tim_uoffs, tim_voffs, pw, ph );
+
+    // add it to the ordering table
+    addPrim( ot[db], quad );
+    nextpri += sizeof(POLY_FT4);
+
+}
+
+ +

By this point, it should be easy to figure out how to use this function +in the sample above. The angle and scale arguments are of a +fixed point notation, where 4096 is 360 degrees on the former and 4096 is +1.0 on the latter.

+ +
+ +
+ +

Limitations of Fixed Point Math

+ +

One limitation that becomes apparent when performing 32-bit fixed point +math arithmetic is when performing fractional multiplication operations with +large fixed point values due to the C compiler usually always performing +multiplication and bit shifting operations with 32-bit registers, as +multiplying a large fixed point value by a large fixed point multiplicand +will likely exceed the capacity of a 32-bit word, yielding a faulty +result.

+ +

The MIPS R3000 CPU of the PlayStation can actually return a 64-bit +multiplication result, but the C compiler doesn't really make use of this +trait when performing multiplication operations with 32-bit integers. So the +only way to effectively take advantage of this is to use some in-line +assembly code. Should be pretty self explanatory on how and where it should +be used.

+ +
/* in-line assembly macro for performing multiplication        */
+/* operations with 12-bit fractions. Uses what is effectively  */
+/* 64-bit maths with both hi and lo result registers to avoid  */
+/* overflow bugs when using 32-bit maths.                      */
+/*                                                             */
+/* Performs r2 = ( r0 * r1 )>>12 with 64-bit arithmetic        */
+/*                                                             */
+#define mult12( r0, r1, r2 ) __asm__ volatile ( \
+    "mult   %1, %0;"        /* multiply values (small * large is faster) */\ 
+    "mflo   $t0;"           /* retrieve the 64-bit result in two regs    */\
+    "mfhi   $t1;"                                                          \
+    "srl    $t0, 12;"       /* equivalent to dividing LO by 4096         */\
+    "and    $t1, 0x0fff;"   /* mask HI result to fit in upper 12 bits of */\
+    "sll    $t1, 20;"       /* LO result, then shift bits to position    */\
+    "or	    $t0, $t1;"      /* combine the bits                          */\
+    "sw	    $t0, ( %2 );"   /* store the result to r2                    */\
+    :																	   \
+    : "r"( r0 ), "r"( r1 ), "r"( r2 ) \
+    : "lo", "hi", "t0", "t1", "memory" )
+
+ +

Though naturally, fixed point math can't really be as precise as floating +point math in certain operations. You can try increasing precision by +increasing the base value, alloting more bits for the fractional part of a +fixed point value, but there will still be something rough about it.

+ + +

Conclusion and Further Reading

+ +

This chapter only really covers some pretty basic but highly essential math +operations with fixed point math, but it should be enough to get you started +in learning the practice. Interestingly fixed point math is still somewhat +talked about around the modern Internet, so you may want to look around for +those for further reading if need-be.

+ +
+ + + + + + +
PreviousBack to IndexNext
+ + + + \ No newline at end of file diff --git a/Docs/Chapter 1.5 Fixed point Math_files/style.css b/Docs/Chapter 1.5 Fixed point Math_files/style.css new file mode 100644 index 0000000..50d70a8 --- /dev/null +++ b/Docs/Chapter 1.5 Fixed point Math_files/style.css @@ -0,0 +1,49 @@ +body { + max-width: 900px; + margin: auto; + padding: 8px; + font-family: sans-serif; + font-size: 14px; + //color: white; + //background: black; +} + +h { + background-color: #e0e0e0; + padding: 2px; +} + +h2 { + border-bottom: 1px solid; + //padding-left: 8px; +} + +img { + display: block; +} + +.footer-table { + font-size: 14px; +} + +.bordered-table { + border-collapse: collapse; + font-size: 11px; +} + +.bordered-table th, .bordered-table td { + border: 1px solid; + padding: 4px; +} + +hr { + border: none; + border-bottom: 1px solid black; +} + +pre { + padding: 8px; + font-size: 12px; + color: black; + background-color: LightGray; +} \ No newline at end of file diff --git a/Docs/Chapter 1.6 Using the CD-ROM.htm b/Docs/Chapter 1.6 Using the CD-ROM.htm new file mode 100644 index 0000000..f71f269 --- /dev/null +++ b/Docs/Chapter 1.6 Using the CD-ROM.htm @@ -0,0 +1,807 @@ + + + +Chapter 1.6: Using the CD-ROM + + + + +

Chapter 1.6: Using the CD-ROM

+ +

So you've managed to make it this far in this tutorial series and have +wrapped your head around uploading textures to VRAM, drawing sprite +primitives with the GPU, handling controller input and rotating sprites +using fixed-point integer math, you should be good to go at making a simple +game with the knowledge you've gained so far. However, there's one more thing +to learn that's very important to know in this endeavor before going forward +and that is using the CD-ROM.

+ +

The most obvious use of the CD-ROM drive on the PlayStation is, well, to +load data files from of course. Such files range from texture images, to +level data and even your program executable that the console loads during +the boot process. You can only go so far by including resources into your +PS-EXE as the console only has 2 megabytes worth of RAM, and more +importantly, they take up memory space that cannot be reclaimed even when +they are no longer needed (ie. texture images).

+ +

This chapter goes over the basic usage and operation of the CD-ROM library +for reading files from the CD-ROM.

+ +

Compatible with PSn00bSDK: Yes

+ +

Tutorial Index

+ + +

Workings of the CD-ROM

+ +

Before going into the know-abouts on using the CD-ROM we shall first +look into a brief explanation of how the CD-ROM format works, as +understanding some of the inner workings of the format will aid you +greatly in understanding the CD-ROM drive as you develop software for +the PlayStation.

+ +

CD-ROM Structure

+ +

A CD-ROM typically consists of a Table-of-Contents or TOC +and a huge spiral track that spans the entire surface of the disc containing +sectors of binary data running along the track. The TOC contains information +about the location of tracks written on the disc, their pregap and their +type of track, a track in this case being the track number to your favorite +song in a music CD. The TOC would also contain information of the next +writable location in multi-session discs, which would in turn contain +another TOC of the next session but this only really applies to CD-R +discs.

+ +

PlayStation game discs typically contain only one track, with the exception +of games, usually early titles, using Red Book CD Audio tracks for music +immediately after the first data track of the disc.

+ +

CD-ROM Sectors

+ +

A CD-ROM sector is a small data block of 2352 bytes but this only +applies to plain CD audio tracks, as the usable sector size is reduced +to 2048 bytes for data storage (ie. files). The remaining space of the +CD-ROM sector is taken up by sync and address bytes used to allow for +precise logical block addressing of the disc, alongside error detection +and correcting codes to help maintain data integrity of each data sector. +This sector format is known as Mode1, with a similar format used by the +PlayStation being Mode2/Form1 from the CD-ROM XA specification as used +by the Philips CD-i.

+ +

As far as the PlayStation is concerned, the console only reads +the data part of the sector on data reads, with the sync/address +and EDC/ECC correction handled transparently by the hardware +unless instructed to ignore EDC/ECC correction on data reads or +to read whole sectors including their EDC/ECC data.

+ +

CD-ROM XA Extensions

+ +

As the PlayStation inherits the CD-ROM XA features from the CD-i as Sony +co-developed the Green Book standard with Philips, the console supports +playing back of special ADPCOM compressed audio tracks, most commonly known +as XA audio.

+ +

XA audio are basically special audio tracks compressed using ADPCM, with +a maximum sample rate of 37.8KHz mono or stereo. Unlike regular Red Book CD +Audio tracks XA audio tracks are interleaved with eight different audio +tracks at once (the interleave can be doubled, tripled and quadrupled by +using mono and/or 18.9KHz sample rate) and is played at double the speed of +plain CD Audio. However, the hardware only supports playing one audio +channel at a time.

+ +

This has some advantages, for one the drive does not need to change speed +when going from audio playback to data reading which can help improve load +times. Secondly, XA audio tracks take up less space overall especially when +the XA audio data is laid out properly (ie. all audio channels are of roughly +the same length to one another). Thirdly, XA audio data can be interleaved +with data sectors, and is used for video playback. The Data/XA Audio interleave +also explains why some files on a PlayStation game disc (usually .STR video +files) cannot be accessed directly under most computer operating systems, +usually resulting in read errors.

+ +

However, XA audio has one downside and that is it tends to skip during +normal playback more than when playing back regular CD Audio tracks.

+ +

There is one more feature of XA audio that's seldom used and that is +channel switching during playback. This would be useful for adding dynamic +music to a game by switching to different channels of different tangents +of a level theme depending on the area the player is currently at. One game +that makes use of this feature is Klonoa: Door to Phantomile.

+ +

The 650MB Limit

+ +

Even though the PlayStation can read 700MB discs it cannot read more +than 650MB of the disc as the console's CD-ROM controller does not take +larger discs into account, as the console was designed before such discs +ever existed and the original CD-ROM specification specifies 650MB as the +standard capacity.

+ +

Ways of Accessing the CD-ROM

+ +

There are two possible methods for accessing the CD-ROM of the PlayStation +that will work on both PsyQ/Programmer's Tool and PSn00bSDK. The first method +and one that is seldom used is the CD-ROM functions included in the console's +BIOS, which consists of calling _96_init() to initialize the BIOS +CD-ROM subsystem and using the BIOS file I/O functions such as open() +and read() with the cdrom: device name. Whilst this method is +technically the most efficient option as it does not introduce any code +overhead to your PlayStation project as the functions already reside in the +console itself, the BIOS CD-ROM functions are rather limited and in a good +number of cases, unstable.

+ +

For one, calling _96_init() clears all but the DMA channel for the +CD-ROM controller, breaking the GPU library unless you call the function before +ResetGraph(). The BIOS functions are also quite slow and does not +support asynchronous reads, even though the hardware itself clearly supports +such operations. It does not even support playing CD Audio nor XA audio tracks +directly, so a different method is often most desired.

+ +

The other, more preferable method is to use the CD-ROM library called +libcd in PsyQ/Programmer's Tool and psxcd in PSn00bSDK +respectively. Not only is it faster and more stable than the BIOS CD-ROM +functions at the cost of some overhead, but it also offers greater control +of the CD-ROM hardware as well. Playing CD Audio and XA audio included.

+ +

Using the CD-ROM Library

+ +

Using the CD-ROM library is quite simple in principle. The first thing +to be done is to initialize the CD-ROM library by calling the function +CdInit(). This function not only initializes the CD-ROM hardware +but also the CD-ROM library itself.

+ +

Initializing the CD-ROM

+ +

After calling ResetGraph() in your init routine you can then call +CdInit() to initialize the CD-ROM library.

+ +
int CdInit(void)
+
+ +

The behavior of this function is very identical in both SDKs, but the +PsyQ/Programmers Tool implementation insists that a CD must be inserted +otherwise the function will output a lot of error messages to stdout and +fail to initialize. PSn00bSDK's implementation does not throw errors +when no disc is inserted, as it is written with utility style programs +that don't always need to read the disc in mind.

+ +

After calling this function, all CD-ROM functions exposed by the library +should be usable.

+ +

Locating a File

+ +

Now that the CD-ROM library is initialized the next step is to locate a +file on the disc to be read. Unlike the BIOS CD-ROM functions, the CD-ROM +library does not have a concept of file handles and instead, files are +read directly from their logical position on the disc. Conveniently, no +files on a CD-ROM are fragmented so file read operations from the CD-ROM +are quite simple and pretty straight forward.

+ +

Locating a file on the disc is done by using CdSearchFile().

+ +
CdlFILE* CdSearchFile(const char *filename, CdlFILE *loc)
+
+ +

This function will search the CD-ROM file system for the file specified +by filename and stores information about the file, such as it's +logical position and file size, to a CdlFILE struct specified by +loc. This information is all we need to read a file from the disc. +The file name must contain an absolute path from the root directory of +the disc as the CD-ROM library has no concept of current directories. The +file path must additionally end with a file version identifier, usually +;1.

+ +

The return value is just a pointer to the struct specified by loc, +but NULL is returned if the file name specified does not exist.

+ +

Reading a File

+ +

Now that the file we want to read has been located, the next logical step +is to read it's contents. This is done by using two CD-ROM functions; +CdControl() and CdRead().

+ +

CdControl() is kind of a multi-purpose function as it is used +to issue raw commands directly to the console's CD-ROM controller and +can be used to make the controller do all kinds of things including +CD audio playback, but this will be covered in greater detail at a later +chapter.

+ +

For this instance, we'll be using CdControl() to issue a +CdlSetloc command to the CD-ROM controller with the location of the +file we just located.

+ +
int CdControl(u_char com, u_char *param, u_char *result);
+
+ +

com specifies the command to be issued (CdlSetloc in this +case) while param should be a pointer to the loc element in +the CdlFILE struct we obtained from the CdSearchFile() call +earlier. result can be ignored in this instance so NULL can be +specified for that argument. result is where return data from the +CD-ROM controller would be stored to if a small buffer is specified.

+ +

The reason we must issue a CdlSetloc command is it sets the +target location for a read, seek or play operation. The CD-ROM hardware +does not yet move it's optical pickup when CdlSetloc is issued +alone, seeking only occurs when either of the aforementioned disc +operations have been issued and that a target location set by issuing +CdlSetloc was set prior.

+ +

And finally, we can now start a read operation by calling the +CdRead() function.

+ +
int CdRead(int sectors, unsigned int *buf, int mode)
+
+ +

As the name says it all, this function starts a data read operation from +the disc starting from the logical position specified by a previously issued +CdlSetloc command. sectors specifies the number of sectors to +read from the disc, the exact number can be determined by taking the +size field in the CdlFILE struct, adding it by 2047 then +divide by 2048. More will be explained why it had to be computed that way +later. The sectors read are then stored to buf, which +must point to a buffer large enough to contain all the sectors to be read. +mode specifies the CD-ROM mode to use for the read operation, usually +CdlModeSpeed is needed for all file read operations so data is read +at full speed.

+ +

If you haven't guessed from the brief explanation of the operation of +CD-ROMs earlier in this chapter, each sector is 2048 bytes long. And because +CdRead() only reads in sector units you can only read data in +multiples of 2048 bytes. The logical position of files stored on the CD-ROM +are also addressed in multiples of 2048 bytes.

+ +

The BIOS CD-ROM functions are also limited to reading files in units of +2048 bytes and file seeks are limited to multiples of 2048 bytes as well. +Because of this, it is much faster to just load the entirety of a file into +memory and parse the file from there, especially as performing several small +seeks and read operations would be quite slow, even moreso as the +PlayStation's CD-ROM hardware doesn't have very fast access times.

+ +

Once CdRead() has been called and the PlayStation's optical pickup +seeks to the file's location and begins reading data, the memory buffer +specified for buf should start filling with data from the file being +read. However, the CdRead() function finishes almost immediately and +the buffer may not yet contain the file you're reading yet, so another step +is required to make sure the buffer is filled with all the contents of the +file you want to load.

+ +
int CdReadSync(int mode, unsigned char *result)
+
+ +

This function will wait until the CdRead() operation is actually +completed if mode is set to zero. If it is non-zero the function +returns the number of sectors remaining in the read operation. This is +useful if you want to have a animated loading screen or some such. +If a buffer is specified in result the most recent CD-ROM status +is written to that buffer, but it can be left NULL if not needed.

+ +

The asynchronous nature of the CdRead() function may be utilized +for implemented animated loading screens and such.

+ +

Finished Routine

+ +

With all that taken in, a simple CD-ROM read routine should like this.

+ +
CdlFILE filePos;
+int     numsecs;
+char    *buff;
+
+/* locate the file on the CD */
+if( CdSearchFile( &filePos, "\\TEXTURE.TIM;1" ) == NULL )
+{
+    /* print error message if file not found */
+    printf( "File was not found." );
+}
+else
+{
+    /* calculate number of sectors to read for the file */
+    numsecs = (filePos.size+2047)/2048;
+    
+    /* allocate buffer for the file */
+    buff = (char*)malloc( 2048*numsecs );
+    
+    /* set read target to the file */
+    CdControl( CdlSetloc, (u_char*)&filePos.loc, 0 );
+    
+    /* start read operation */
+    CdRead( numsecs, (u_long*)buff, CdlModeSpeed );
+    
+    /* wait until the read operation is complete */
+    CdReadSync( 0, 0 );
+}
+
+ +

You may notice that the file size has to be incremented by 2047 +then divided by 2048. This is to make sure that the sector count calculated +would cover the entirety of a file that is not a perfect multiple of 2048 +bytes. If the file to be read were like 1536 bytes, the whole file would be +read as one whole sector with the excess bytes being nothing more but +padding.

+ +

You also have to remember that data reads from the CD are still multiples +of 2048 bytes, so the read buffer must be allocated in multiples of 2048 bytes +to avoid buffer overflow bugs, which would in turn trash the memory heap.

+ +

Implementation

+ +

To keep things simple we'll just implement it on top of the exisitng +sample program from the last chapter. Basically instead of reading the +sample texture from an array we'll load the texture file from the CD-ROM. +This can be quickly implemented by implementing our CD-ROM file read routine +as a nice little function.

+ +
char *loadfile( const char *filename )
+{
+    CdlFILE filePos;
+    int     numsecs;
+    char    *buff;
+    
+    buff = NULL;
+    
+    /* locate the file on the CD */
+    if( CdSearchFile( filename, &filePos ) == NULL )
+    {
+        /* print error message if file not found */
+        printf( "%s not found.", filename );
+    }
+    else
+    {
+        /* calculate number of sectors to read for the file */
+        numsecs = (filePos.size+2047)/2048;
+        
+        /* allocate buffer for the file (replace with malloc3() for PsyQ) */
+        buff = (char*)malloc( 2048*numsecs );
+        
+        /* set read target to the file */
+        CdControl( CdlSetloc, (u_char*)&filePos.loc, 0 );
+        
+        /* start read operation */
+        CdRead( numsecs, (u_long*)buff, CdlModeSpeed );
+        
+        /* wait until the read operation is complete */
+        CdReadSync( 0, 0 );
+    }
+    
+    return( buff );
+    
+} /* loadfile */
+
+ +

The sample program from the last chapter will be used to demonstrate the +usage of the function, to load the texture image from CD rather than loading +from an array. The ever growing sample program should be like this. Tweak +the code as you see fit to make it work with the SDK you're using.

+ +
#include <sys/types.h>	// This provides typedefs needed by libgte.h and libgpu.h
+#include <stdio.h>	// Not necessary but include it anyway
+#include <psxetc.h>	// Includes some functions that controls the display
+#include <psxgte.h>	// GTE header, not really used but libgpu.h depends on it
+#include <psxgpu.h>	// GPU library header
+#include <psxapi.h>
+
+#define OTLEN 8         // Ordering table length (recommended to set as a define
+                        // so it can be changed easily)
+
+DISPENV disp[2];        // Display/drawing buffer parameters
+DRAWENV draw[2];
+int db = 0;
+
+// PSn00bSDK requires having all u_long types replaced with
+// u_int, as u_long in modern GCC that PSn00bSDK uses defines it as a 64-bit integer.
+
+u_int ot[2][OTLEN];    // Ordering table length
+char pribuff[2][32768]; // Primitive buffer
+char *nextpri;          // Next primitive pointer
+
+int tim_mode;           // TIM image parameters
+RECT tim_prect,tim_crect;
+int tim_uoffs,tim_voffs;
+
+// Pad stuff
+#define PAD_SELECT      1
+#define PAD_L3          2
+#define PAD_R3          4
+#define PAD_START       8
+#define PAD_UP          16
+#define PAD_RIGHT       32
+#define PAD_DOWN        64
+#define PAD_LEFT        128
+#define PAD_L2          256
+#define PAD_R2          512
+#define PAD_L1          1024
+#define PAD_R1          2048
+#define PAD_TRIANGLE    4096
+#define PAD_CIRCLE      8192
+#define PAD_CROSS       16384
+#define PAD_SQUARE      32768
+
+typedef struct _PADTYPE
+{
+    unsigned char	stat;
+    unsigned char	len:4;
+    unsigned char	type:4;
+    unsigned short	btn;
+    unsigned char	rs_x,rs_y;
+    unsigned char	ls_x,ls_y;
+} PADTYPE;
+
+u_char padbuff[2][34];
+
+// For the player triangle
+SVECTOR player_tri[] = {
+    {   0, -20,  0  },
+    {  10,  20,  0  },
+    { -10,  20,  0  }
+};
+
+void display() {
+    
+    DrawSync(0);                // Wait for any graphics processing to finish
+    
+    VSync(0);                   // Wait for vertical retrace
+
+    PutDispEnv(&disp[db]);      // Apply the DISPENV/DRAWENVs
+    PutDrawEnv(&draw[db]);
+
+    SetDispMask(1);             // Enable the display
+
+    DrawOTag(ot[db]+OTLEN-1);   // Draw the ordering table
+    
+    db = !db;                   // Swap buffers on every pass (alternates between 1 and 0)
+    nextpri = pribuff[db];      // Reset next primitive pointer
+    
+}
+
+// CD loading function
+char *loadfile( const char *filename )
+{
+    CdlFILE filePos;
+    int     numsecs;
+    char    *buff;
+    
+    buff = NULL;
+    
+    /* locate the file on the CD */
+    if( CdSearchFile( filename, &filePos ) == NULL )
+    {
+        /* print error message if file not found */
+        printf( "%s not found.", filename );
+    }
+    else
+    {
+        /* calculate number of sectors to read for the file */
+        numsecs = (filePos.size+2047)/2048;
+        
+        /* allocate buffer for the file (replace with malloc3() for PsyQ) */
+        buff = (char*)malloc( 2048*numsecs );
+        
+        /* set read target to the file */
+        CdControl( CdlSetloc, (u_char*)&filePos.loc, 0 );
+        
+        /* start read operation */
+        CdRead( numsecs, (u_long*)buff, CdlModeSpeed );
+        
+        /* wait until the read operation is complete */
+        CdReadSync( 0, 0 );
+    }
+    
+    return( buff );
+    
+} /* loadfile */
+
+// Texture upload function
+void LoadTexture(u_int *tim, TIM_IMAGE *tparam) {
+
+    // Read TIM parameters (PsyQ)
+    //OpenTIM(tim);
+    //ReadTIM(tparam);
+
+    // Read TIM parameters (PSn00bSDK)
+    GetTimInfo(tim, tparam);
+
+    // Upload pixel data to framebuffer
+    LoadImage(tparam->prect, tparam->paddr);
+    DrawSync(0);
+
+    // Upload CLUT to framebuffer if present
+    if( tparam->mode & 0x8 ) {
+
+        LoadImage(tparam->crect, tparam->caddr);
+        DrawSync(0);
+
+    }
+
+}
+
+void loadstuff(void) {
+
+    TIM_IMAGE   my_image;       // TIM image parameters
+    u_int       *filebuff;      // Pointer for the file loaded from the disc
+
+    if( filebuff = (u_int*)loadfile( "\\TEXTURE.TIM;1" ) )
+    {    
+        // On successful file read, load the texture to VRAM
+        LoadTexture(tim_my_image, &my_image);
+
+        // Copy the TIM coordinates
+        tim_prect   = *my_image.prect;
+        tim_crect   = *my_image.crect;
+        tim_mode    = my_image.mode;
+
+        // Calculate U,V offset for TIMs that are not page aligned
+        tim_uoffs = (tim_prect.x%64)<<(2-(tim_mode&0x3));
+        tim_voffs = (tim_prect.y&0xff);
+        
+        // Free the file buffer
+        free( filebuff );
+    }
+    else
+    {
+        // Output error text that the image failed to load
+        printf( "Error: TEXTURE.TIM file not found.\n" );
+    }
+}
+
+// To make main look tidy, init stuff has to be moved here
+void init(void) {
+    
+    // Reset graphics
+    ResetGraph(0);
+    
+    // Initialize the CD-ROM library
+    CdInit();
+
+    // First buffer
+    SetDefDispEnv(&disp[0], 0, 0, 320, 240);
+    SetDefDrawEnv(&draw[0], 0, 240, 320, 240);
+    // Second buffer
+    SetDefDispEnv(&disp[1], 0, 240, 320, 240);
+    SetDefDrawEnv(&draw[1], 0, 0, 320, 240);
+
+    draw[0].isbg = 1;               // Enable clear
+    setRGB0(&draw[0], 63, 0, 127);  // Set clear color (dark purple)
+    draw[1].isbg = 1;
+    setRGB0(&draw[1], 63, 0, 127);
+
+    nextpri = pribuff[0];           // Set initial primitive pointer address
+ 
+    // load textures and possibly other stuff
+    loadstuff();
+
+    // set tpage of lone texture as initial tpage
+    draw[0].tpage = getTPage( tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+    draw[1].tpage = getTPage( tim_mode&0x3, 0, tim_prect.x, tim_prect.y );
+
+    // apply initial drawing environment
+    PutDrawEnv(&draw[!db]);
+    
+    // Initialize the pads
+    InitPAD( padbuff[0], 34, padbuff[1], 34 );
+    
+    // Begin polling
+    StartPAD();
+    
+    // To avoid VSync Timeout error, may not be defined in PsyQ
+    ChangeClearPAD( 1 );
+    
+    // Load the font texture on the upper-right corner of the VRAM
+    FntLoad( 960, 0 );
+
+    // Define a font window of 100 characters covering the whole screen
+    FntOpen( 0, 8, 320, 224, 0, 100 );
+ 
+}
+
+int main() {
+    
+    int i;
+    int pos_x,pos_y,angle;
+    PADTYPE *pad;
+    POLY_F3 *tri;
+    SVECTOR v[3];
+    
+    TILE *tile;                         // Pointer for TILE
+    SPRT *sprt;                         // Pointer for SPRT
+
+    // Init stuff
+    init();
+    
+    pos_x = ONE*(disp[0].disp.w>>1);
+    pos_y = ONE*(disp[0].disp.h>>1);
+    angle = 0;
+    
+    while(1) {
+    
+        // Parse controller input
+        pad = (PADTYPE*)padbuff[0];
+
+        // Only parse inputs when a controller is connected
+        if( pad->stat == 0 )
+        {
+            // Only parse when a digital pad, 
+            // dual-analog and dual-shock is connected
+            if( ( pad->type == 0x4 ) || 
+                ( pad->type == 0x5 ) || 
+                ( pad->type == 0x7 ) )
+            {
+                if( !(pad->btn&PAD_UP) )            // test UP
+                {
+                    pos_x += csin( angle );
+                    pos_y -= ccos( angle );
+                }
+                else if( !(pad->btn&PAD_DOWN) )     // test DOWN
+                {
+                    pos_x -= csin( angle );
+                    pos_y += ccos( angle );
+                }
+                if( !(pad->btn&PAD_LEFT) )          // test LEFT
+                {
+                    angle -= 16;
+                }
+                else if( !(pad->btn&PAD_RIGHT) )    // test RIGHT
+                {
+                    angle += 16;
+                }
+            }
+        }
+
+        ClearOTagR(ot[db], OTLEN);      // Clear ordering table
+        
+        // Rotate the triangle coordinates based on the player's angle
+        // as well as apply the position
+        for( i=0; i<3; i++ )
+        {
+            v[i].vx = (((player_tri[i].vx*icos( angle ))
+                -(player_tri[i].vy*csin( angle )))>>12)+(pos_x>>12);
+            v[i].vy = (((player_tri[i].vy*icos( angle ))
+                +(player_tri[i].vx*csin( angle )))>>12)+(pos_y>>12);
+        }
+        
+        // Sort the player triangle
+        tri = (POLY_F3*)nextpri;
+        setPolyF3( tri );
+        setRGB0( tri, 255, 255, 0 );
+        setXY3( tri,
+            v[0].vx, v[0].vy,
+            v[1].vx, v[1].vy,
+            v[2].vx, v[2].vy );
+        addPrim( ot[db], tri );
+        nextpri += sizeof(POLY_F3);
+        
+        // Print player coordinates
+        FntPrint( -1, "POS_X=%d (%d.%d)\n", pos_x, (pos_x>>12), (pos_x&0xfff) );
+        FntPrint( -1, "POS_Y=%d (%d.%d)\n", pos_y, (pos_y>>12), (pos_y&0xfff) );
+        FntPrint( -1, "ANGLE=%d\n", angle );
+
+        // Draw and flush the character buffer
+        FntFlush( -1 );
+        
+        // Update the display
+        display();
+        
+    }
+    
+    return 0;
+}
+
+ +

Creating the CD Image

+ +

Once you've got the code above compiled it won't do jack for now as it +doesn't yet have a CD to read the texture file from. This is where disc +image creation comes to play in this chapter.

+ +

In the old days, the only preferred way to create PlayStation CD images +was with the old, MS-DOS based BUILDCD tool from the old leaked PsyQ SDK +dump. This tool is quite difficult to use on modern computers these days +largely due to being a 16-bit MS-DOS program, and while Dosbox can be used +to get it going on a modern machine it is not exactly ideal, not to mention +is very slow.

+ +

To make image creation even more tedious with the old BUILDCD method +the resulting image file is of a special format intended for early CD +burners and special disc cutters, so another tool called STRIPISO is +used to convert the image file to that of a usable file format. However, +the conversion process does not convert the Table-of-Contents data +produced by BUILDCD as well, so having multiple tracks in the disc image +was not possible with this method.

+ +

While other, more conventional means of disc image creation like +MKISOFS would work, it is not exactly ideal for projects that use XA +audio or streaming data which require support for mixed Mode2/Form1 +and Mode2/Form2 not supported by MKISOFS so you'd be stuck with having +to use BUILDCD in the old days. Well... That is until +MKPSXISO by +yours truly came about, solving this disc image creation dilemma in the +PlayStation homebrew scene once and for all. Said tool was so useful that +it got used quite extensively around ROM hacking and game translation +groups... Or so I heard.

+ +

Creating a MKPSXISO Script

+ +

Kind of like BUILDCD, MKPSXISO uses a simple script system to define +the contents and layout of a CD image. However, it uses a XML based +format similar to that you'd find in HTML webpage files, of which, in +of itself is quite simple especially if you use a good text editor +such as Notepad++ or nedit.

+ +

The following is a link to a sample XML script for this tutorial. +You must save the link as a file as otherwise your browser's going to +treat it as a web page. The file also contains comments that explains +the usage of the XML file.

+ +MKPSXISO Sample Script + +

The script file assumes that the above C program is compiled as +cdread.exe.

+ +

Creating the SYSTEM.CNF File

+ +

Before the ISO image can be created, a SYSTEM.CNF file must be +created and is a standard requirement for PlayStation game discs to include. +The SYSTEM.CNF file is a simple text file that defines a few +parameters. The most important being the BOOT variable.

+ +
BOOT=cdrom:\cdread.exe;1
+TCB=4
+EVENT=10
+STACK=801FFFF0
+
+ +

The parameters that immediately follow it TCB, EVENT and +STACK are special parameters that change the way how the kernel +is set up for the game. The parameters in the sample script are typical +values used in most games, so they can be left alone.

+ +

Save the text file as SYSTEM.TXT as the script provided will +rename it as SYSTEM.CNF as the disc image gets created. This is +done so that editing the CNF file is made easier when need-be, such as +changing the executable name.

+ +

Creating the disc image

+ +

Building the disc image with MKPSXISO is just a matter of simply +invoking it from the command line with the XML script as the argument. + +

mkpsxiso mkpsxiso-sample.xml
+
+ +

If things go accordingly you should end up with a BIN/CUE image pair +named cdtutorial. Run the disc image in your preferred emulator +and the program from the last tutorial should work now, only there's now +a slight delay from loading data from the disc.

+ +
+ +
+ +

Conclusion

+ +

Hopefully this chapter has cleared up a lot of things in regards to +reading data from the CD, something I feel is still not explained very +well. But then I haven't really kept up with the PlayStation homebrew +scene in a very long while. In the future, stuff like CD Audio and XA +audio playback will be covered.

+ +

And this concludes the basics chapter of this tutorial series, and +if you've managed to reach this far after reading the first few chapters +you should be able to do quite a bit with 2D stuff on the console now... +Provided you managed to absorb it all.

+ +
+ + + + + + +
PreviousBack to Index
+ + + \ No newline at end of file diff --git a/Docs/Chapter 1.6 Using the CD-ROM_files/style.css b/Docs/Chapter 1.6 Using the CD-ROM_files/style.css new file mode 100644 index 0000000..50d70a8 --- /dev/null +++ b/Docs/Chapter 1.6 Using the CD-ROM_files/style.css @@ -0,0 +1,49 @@ +body { + max-width: 900px; + margin: auto; + padding: 8px; + font-family: sans-serif; + font-size: 14px; + //color: white; + //background: black; +} + +h { + background-color: #e0e0e0; + padding: 2px; +} + +h2 { + border-bottom: 1px solid; + //padding-left: 8px; +} + +img { + display: block; +} + +.footer-table { + font-size: 14px; +} + +.bordered-table { + border-collapse: collapse; + font-size: 11px; +} + +.bordered-table th, .bordered-table td { + border: 1px solid; + padding: 4px; +} + +hr { + border: none; + border-bottom: 1px solid black; +} + +pre { + padding: 8px; + font-size: 12px; + color: black; + background-color: LightGray; +} \ No newline at end of file diff --git a/Docs/Chapter 2.2 Reading a file from CD-ROM.htm b/Docs/Chapter 2.2 Reading a file from CD-ROM.htm new file mode 100644 index 0000000..f7db53b --- /dev/null +++ b/Docs/Chapter 2.2 Reading a file from CD-ROM.htm @@ -0,0 +1,508 @@ + + + + + + + + + + + +Chapter 2.2: Reading a file from CD-ROM + + + + + +
+
The Wayback Machine - +http://web.archive.org/web/20220827033533/http://lameguy64.net/tutorials/pstutorials/chapter2-old/2-readfile.html
+ + + +
+

Chapter 2.2: Reading a file from CD-ROM

+
+

This chapter details how to read a file from the CD-ROM, loading the contents +into system RAM using the CD-ROM library.

+

PSn00bSDK Compatible: Yes

+ +

Tutorial Index

+ + +

Initializing the CD-ROM

+

Initializing the CD-ROM library is accomplished by simply calling +CdInit(). This function must be called after calling ResetGraph() +and before any CD library related function. If you intend to use the SPU you +must call SpuInit() immediately before calling CdInit(). Once the +CD-ROM library is initialized any other CD-ROM related function can be used.

+

SDK Difference

+

In PsyQ/Programmers' Tool, CdInit() will throw a lot of CD retry +messages when no disc is inserted and may lock up. In PSn00bSDK the function +carries on like normal when no disc is inserted.

+ +

Locating a file in the CD-ROM

+

The CD-ROM library does not have a concept of file handles. Instead, files +are read by locating the start position of a file through the ISO9660 file +system, seeking to it and issuing a read operation until a set number of +sectors have been read. This method of loading files from disc should not be +a problem under any circumstances as files stored in a ISO9660 file system are +never fragmented. In fact, this method of reading files may have some +advantages.

+

Locating a file on the disc is done through the CdSearchFile() +function, which parses through the disc's file system to locate the file +and returns a CdlFILE which describes information about the file found +including it's position in the disc.

+
CdlFILE file;
+
+// Search for the file
+if( !CdSearchFile( &file;, "\\MYDIR\\MYFILE.DAT;1" ) )
+{
+    // Return value is NULL, file is not found
+    printf( "File not found.\n" );
+    return 0;
+}
+
+// When file found
+printf( "File found!\n" );
+
+

The file name must be specified as a complete path from root and must use +backlash characters as directory separators (use \\ in C code). The file name +must also end with a file version number which is always ';1'. If the file is +found, it will return the pointer to the specified CdlFILE struct, +otherwise it would simply return NULL.

+

The CdlFILE struct contains a copy of the file name, file size and +most importantly, the location.

+ +

Reading File Contents

+

Now for the interesting stuff. Reading sectors is accomplished by using +CdRead(). But before you start a read operation, you must first set +the location of where to start reading from. This can be done using +CdControl() and the CdlSetloc command. Use this to set the +target location of the file.

+
char *buffer;
+
+// Allocate a buffer for the file
+buffer = (char*)malloc( 2048*((file.size+2047)/2048) );
+
+// Set seek target (seek actually happens on CdRead())
+CdControl( CdSetloc, &file.loc;, 0 );
+
+// Read sectors
+CdRead( (file.size+2047)/2048, (unsigned int*)buffer, CdlModeSpeed );
+
+// Wait until read has completed
+CdReadSync( 0, 0 );
+
+

You may have noticed by now that read sizes in this chapter are described in +sector units rather than byte units. That's because the CD-ROM subsystem can +only read in sector units and the CD-ROM library is optimized for reading in +sector units rather than buffering sectors to allow for byte by byte reading +for performance reasons.

+

Data sectors are typically 2048 bytes in size so buffers where data read +from the CD would be loaded to must be multiples of 2048 bytes. The arithmetic +to snap byte sizes to the nearest sector unit is described in the pseudo code +described above.

+

Once a read operation has been issued, you must wait until reading has +completed using CdReadSync(). You can alternatively poll the status +asynchronously by setting the mode parameter to 1 to perform animations +while waiting for a long read to complete.

+

If you intend to read only a part of a file instead of a whole file in a +single read operation, be aware that you can't simply call CdRead() +again to read the following sectors. Instead, you must retrieve the current +location using CdlGetloc, set it as the seek target with CdlSetloc +then call CdRead().

+ + +

Simple File Read Function

+

The examples described above can be consolidated into a single function, +which can be useful for quickly implementing a file read function for testing +purposes:

+
u_long *load_file(const char* filename)
+{
+    CdlFILE	file;
+    u_long	*buffer;
+    
+    
+    printf( "Reading file %s... ", filename );
+
+    // Search for the file
+    if( !CdSearchFile( &file;, (char*)filename ) )
+    {
+        // Return value is NULL, file is not found
+        printf( "Not found!\n" );
+        return NULL;
+    }
+    
+    // Allocate a buffer for the file
+    buffer = (u_long*)malloc( 2048*((file.size+2047)/2048) );
+
+    // Set seek target (seek actually happens on CdRead())
+    CdControl( CdlSetloc, (u_char*)&file.pos;, 0 );
+
+    // Read sectors
+    CdRead( (file.size+2047)/2048, buffer, CdlModeSpeed );
+
+    // Wait until read has completed
+    CdReadSync( 0, 0 );
+    
+    printf( "Done.\n" );
+
+    return buffer;
+}
+
+

If you want to do asynchronous loading to do background animations, you'll +have to use the CD functions more directly.

+ + +

Image Loader Example

+

For completedness, this example demonstrates loading a high resolution +24-bit TIM from CD and displaying it into the framebuffer in 24-bit color mode. +Take any image file you wish to use, scale it down to 640x480 and convert it +into a 24-bit TIM with the load position set to (0,0). Name that TIM file +myimage.tim for this example.

+

PsyQ/Programmers' Tool Version

+
#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <libgte.h>
+#include <libgpu.h>
+#include <libetc.h>
+#include <libcd.h>
+
+// Display environment struct
+DISPENV disp;
+
+u_long *load_file(const char* filename)
+{
+    CdlFILE file;
+    u_long  *buffer;
+    
+    
+    printf( "Reading file %s... ", filename );
+
+    // Search for the file
+    if( !CdSearchFile( &file;, (char*)filename ) )
+    {
+        // Return value is NULL, file is not found
+        printf( "Not found!\n" );
+        return NULL;
+    }
+    
+    // Allocate a buffer for the file
+    buffer = (u_long*)malloc( 2048*((file.size+2047)/2048) );
+
+    // Set seek target (seek actually happens on CdRead())
+    CdControl( CdlSetloc, (u_char*)&file.pos;, 0 );
+
+    // Read sectors
+    CdRead( (file.size+2047)/2048, buffer, CdlModeSpeed );
+
+    // Wait until read has completed
+    CdReadSync( 0, 0 );
+    
+    printf( "Done.\n" );
+
+    return buffer;
+}
+
+void display_picture()
+{
+    u_long      *image;
+    TIM_IMAGE   tim;
+
+    // Load the image file
+    if( !(image = load_file( "\\MYIMAGE.TIM;1" )) )
+    {
+        printf( "Could not load image file.\n " );
+        return;
+    }
+
+    // Read TIM header
+    OpenTIM( image );
+    ReadTIM( &tim; );
+
+    // Load image to VRAM
+    LoadImage( tim.prect, tim.paddr );
+    DrawSync( 0 );
+
+    // Enable video display
+    VSync( 0 );
+    SetDispMask( 1 );
+}
+
+void init()
+{
+    // Reset GPU (also installs IRQ handlers which are mandatory)
+    ResetGraph(0);
+
+    // Init CD-ROM library
+    CdInit();
+
+    // Set DISPENV for 640x480 24-bit color mode
+    SetDefDispEnv( &disp;, 0, 0, 640, 480 );
+    disp.isrgb24 = 1;   // Enables 24-bit (cannot be used for GPU graphics)
+    disp.isinter = 1;   // Enable interlace so hi-res will display properly
+
+    // Set display environment
+    PutDispEnv( &disp; );
+}
+
+int main(int argc, const char *argv[])
+{
+    // Init stuff
+    init();
+
+    // Load and display picture
+    display_picture();
+
+    // Loop for safe idling
+    while( 1 )
+    {
+        VSync( 0 );
+    }
+
+    return 0;
+}
+
+ +

PSn00bSDK Version

+
#include <stdio.h>
+#include <malloc.h>
+#include <psxgpu.h>
+#include <psxcd.h>
+
+// Display environment struct
+DISPENV disp;
+
+
+unsigned int *load_file(const char* filename)
+{
+    CdlFILE	file;
+    unsigned int *buffer;
+    
+    
+    printf( "Reading file %s... ", filename );
+
+    // Search for the file
+    if( !CdSearchFile( &file;, (char*)filename ) )
+    {
+        // Return value is NULL, file is not found
+        printf( "Not found!\n" );
+        return NULL;
+    }
+    
+    // Allocate a buffer for the file
+    buffer = (unsigned int*)malloc( 2048*((file.size+2047)/2048) );
+
+    // Set seek target (seek actually happens on CdRead())
+    CdControl( CdlSetloc, (unsigned char*)&file.pos;, 0 );
+
+    // Read sectors
+    CdRead( (file.size+2047)/2048, buffer, CdlModeSpeed );
+
+    // Wait until read has completed
+    CdReadSync( 0, 0 );
+    
+    printf( "Done.\n" );
+
+    return buffer;
+}
+
+void display_picture()
+{
+    unsigned int    *image;
+    TIM_IMAGE       tim;
+
+    // Load the image file
+    if( !(image = load_file( "\\MYIMAGE.TIM;1" )) )
+    {
+        printf( "Could not load image file.\n " );
+        return;
+    }
+
+    // Read TIM header
+    GetTimInfo( image, &tim; );
+
+    // Load image to VRAM
+    LoadImage( tim.prect, tim.paddr );
+    DrawSync( 0 );
+	
+    // Enable video display
+    VSync( 0 );
+    SetDispMask( 1 );
+}
+
+void init()
+{
+    // Reset GPU (also installs IRQ handlers which are mandatory)
+    ResetGraph(0);
+
+    // Init CD-ROM library
+    CdInit( 0 );
+
+    // Set DISPENV for 640x480 24-bit color mode
+    SetDefDispEnv( &disp;, 0, 0, 640, 480 );
+    disp.isrgb24 = 1;   // Enables 24-bit (cannot be used for GPU graphics)
+    disp.isinter = 1;   // Enable interlace so hi-res will display properly
+
+    // Set display environment
+    PutDispEnv( &disp; );
+}
+
+int main(int argc, const char *argv[])
+{
+    // Init stuff
+    init();
+
+    // Load and display picture
+    display_picture();
+    
+    // Loop for safe idling
+    while( 1 )
+    {
+        VSync( 0 );
+    }
+
+    return 0;
+}
+
+

Most notable differences between the PsyQ/Programmers' Tool and PSn00bSDK +versions is the latter uses type unsigned int instead of u_long +or unsigned long and for good reason. Modern compilers such as GCC +7.4.0 tend to assume long to be a 64-bit integer and may cause problems when +using unsigned long. There's no OpenTIM() and ReadTIM() +equivalent. Instead, there's GetTimInfo() but this may change in the +future.

+

Make sure you've compiled the example as readfile.exe for coherency with +the rest of this chapter.

+ +

Building the ISO image

+

In the past, the only way to create proper ISO images for PS1 games is to +use a tool called BUILDCD included in leaked copies of the PsyQ SDK. The +biggest problem of using BUILDCD is it generates an image file of a special +format not supported by any burner program, so another tool has to be used +(stripiso) to convert the image file it generates into a usable ISO image. +Not only that, BUILDCD is a 16-bit DOS executable and is difficult and very +slow to use on a modern system.

+

Instead of using BUILDCD, use +MKPSXISO instead. It +offers about the same functionality as BUILDCD but better, and is built for +modern Windows and Linux platforms.

+

MKPSXISO Project XML

+
<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- Defines the ISO project -->
+<iso_project image_name="readfile.iso">
+
+    <!-- Defines the data track for this tutorial -->
+    <track type="data">
+
+        <!-- Specifies identifier strings such as volume label -->
+        <!-- System and application identifiers must be PLAYSTATION -->
+        <identifiers
+            system      ="PLAYSTATION"
+            application ="PLAYSTATION"
+            volume      ="PSXTUTORIAL"
+            volume_set  ="PSXTUTORIAL"
+            publisher   ="MEIDOTEK"
+        />
+
+        <!-- Defines the directory tree of the data track -->
+        <directory_tree>
+
+            <!-- Specify files in the directory tree -->
+            <file name="system.cnf"      type="data" source="system.cnf"/>
+            <file name="readfile.exe"    type="data" source="readfile.exe"/>
+            <file name="myimage.tim"     type="data" source="myimage.tim"/>
+
+            <!-- Place dummy sectors at the end -->
+            <dummy sectors="1024"/>
+
+        </directory_tree>
+
+    </track>
+
+</iso_project>
+
+

While on the subject of ISO image creation, you'll also need to create a +special SYSTEM.CNF file in order to make your disc image bootable. A +SYSTEM.CNF file is simply a text file that specifies the file name of the +executable, stack address, number of task and event blocks. The latter three +wouldn't be discussed in this chapter and the typical values are generally +good enough.

+

SYSTEM.CNF Contents

+
BOOT=cdrom:\readfile.exe;1
+TCB=4
+EVENT=10
+STACK=801FFFF0
+
+

Once your MKPSXISO project and SYSTEM.CNF files are set, execute MKPSXISO +like so to create the ISO image:

+
mkpsxiso readfile.xml
+
+

Run the ISO image in an emulator and you should see your 24-bit TIM image +displayed. It may take awhile for the image to appear as the 24-bit TIM image +is a pretty big file to load for the PS1.

+

+ +

Conclusion

+

This chapter should cover about everything you need to know to load a file +from CD-ROM. The next chapter will cover common ways to optimize CD-ROM +accesses to speed up load times in your homebrew.

+ +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/Docs/Chapter 2.2 Reading a file from CD-ROM_files/analytics.js b/Docs/Chapter 2.2 Reading a file from CD-ROM_files/analytics.js new file mode 100644 index 0000000..10400f0 --- /dev/null +++ b/Docs/Chapter 2.2 Reading a file from CD-ROM_files/analytics.js @@ -0,0 +1,474 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3.0 +/* eslint-disable no-var, semi, prefer-arrow-callback, prefer-template */ + +/** + * Collection of methods for sending analytics events to Archive.org's analytics server. + * + * These events are used for internal stats and sent (in anonymized form) to Google Analytics. + * + * @see analytics.md + * + * @type {Object} + */ +window.archive_analytics = (function defineArchiveAnalytics() { + // keep orignal Date object so as not to be affected by wayback's + // hijacking global Date object + var Date = window.Date; + var ARCHIVE_ANALYTICS_VERSION = 2; + var DEFAULT_SERVICE = 'ao_2'; + var NO_SAMPLING_SERVICE = 'ao_no_sampling'; // sends every event instead of a percentage + + var startTime = new Date(); + + /** + * @return {Boolean} + */ + function isPerformanceTimingApiSupported() { + return 'performance' in window && 'timing' in window.performance; + } + + /** + * Determines how many milliseconds elapsed between the browser starting to parse the DOM and + * the current time. + * + * Uses the Performance API or a fallback value if it's not available. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API + * + * @return {Number} + */ + function getLoadTime() { + var start; + + if (isPerformanceTimingApiSupported()) + start = window.performance.timing.domLoading; + else + start = startTime.getTime(); + + return new Date().getTime() - start; + } + + /** + * Determines how many milliseconds elapsed between the user navigating to the page and + * the current time. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Performance_API + * + * @return {Number|null} null if the browser doesn't support the Performance API + */ + function getNavToDoneTime() { + if (!isPerformanceTimingApiSupported()) + return null; + + return new Date().getTime() - window.performance.timing.navigationStart; + } + + /** + * Performs an arithmetic calculation on a string with a number and unit, while maintaining + * the unit. + * + * @param {String} original value to modify, with a unit + * @param {Function} doOperation accepts one Number parameter, returns a Number + * @returns {String} + */ + function computeWithUnit(original, doOperation) { + var number = parseFloat(original, 10); + var unit = original.replace(/(\d*\.\d+)|\d+/, ''); + + return doOperation(number) + unit; + } + + /** + * Computes the default font size of the browser. + * + * @returns {String|null} computed font-size with units (typically pixels), null if it cannot be computed + */ + function getDefaultFontSize() { + var fontSizeStr; + + if (!('getComputedStyle' in window)) + return null; + + var style = window.getComputedStyle(document.documentElement); + if (!style) + return null; + + fontSizeStr = style.fontSize; + + // Don't modify the value if tracking book reader. + if (document.querySelector('#BookReader')) + return fontSizeStr; + + return computeWithUnit(fontSizeStr, function reverseBootstrapFontSize(number) { + // Undo the 62.5% size applied in the Bootstrap CSS. + return number * 1.6; + }); + } + + /** + * Get the URL parameters for a given Location + * @param {Location} + * @return {Object} The URL parameters + */ + function getParams(location) { + if (!location) location = window.location; + var vars; + var i; + var pair; + var params = {}; + var query = location.search; + if (!query) return params; + vars = query.substring(1).split('&'); + for (i = 0; i < vars.length; i++) { + pair = vars[i].split('='); + params[pair[0]] = decodeURIComponent(pair[1]); + } + return params; + } + + function getMetaProp(name) { + var metaTag = document.querySelector('meta[property=' + name + ']'); + return metaTag ? metaTag.getAttribute('content') || null : null; + } + + var ArchiveAnalytics = { + /** + * @type {String|null} + */ + service: getMetaProp('service'), + mediaType: getMetaProp('mediatype'), + primaryCollection: getMetaProp('primary_collection'), + + /** + * Key-value pairs to send in pageviews (you can read this after a pageview to see what was + * sent). + * + * @type {Object} + */ + values: {}, + + /** + * Sends an analytics ping, preferably using navigator.sendBeacon() + * @param {Object} values + * @param {Function} [onload_callback] (deprecated) callback to invoke once ping to analytics server is done + * @param {Boolean} [augment_for_ao_site] (deprecated) if true, add some archive.org site-specific values + */ + send_ping: function send_ping(values, onload_callback, augment_for_ao_site) { + if (typeof window.navigator !== 'undefined' && typeof window.navigator.sendBeacon !== 'undefined') + this.send_ping_via_beacon(values); + else + this.send_ping_via_image(values); + }, + + /** + * Sends a ping via Beacon API + * NOTE: Assumes window.navigator.sendBeacon exists + * @param {Object} values Tracking parameters to pass + */ + send_ping_via_beacon: function send_ping_via_beacon(values) { + var url = this.generate_tracking_url(values || {}); + window.navigator.sendBeacon(url); + }, + + /** + * Sends a ping via Image object + * @param {Object} values Tracking parameters to pass + */ + send_ping_via_image: function send_ping_via_image(values) { + var url = this.generate_tracking_url(values || {}); + var loadtime_img = new Image(1, 1); + loadtime_img.src = url; + loadtime_img.alt = ''; + }, + + /** + * Construct complete tracking URL containing payload + * @param {Object} params Tracking parameters to pass + * @return {String} URL to use for tracking call + */ + generate_tracking_url: function generate_tracking_url(params) { + var baseUrl = '//analytics.archive.org/0.gif'; + var keys; + var outputParams = params; + var outputParamsArray = []; + + outputParams.service = outputParams.service || this.service || DEFAULT_SERVICE; + + // Build array of querystring parameters + keys = Object.keys(outputParams); + keys.forEach(function keyIteration(key) { + outputParamsArray.push(encodeURIComponent(key) + '=' + encodeURIComponent(outputParams[key])); + }); + outputParamsArray.push('version=' + ARCHIVE_ANALYTICS_VERSION); + outputParamsArray.push('count=' + (keys.length + 2)); // Include `version` and `count` in count + + return baseUrl + '?' + outputParamsArray.join('&'); + }, + + /** + * @param {int} page Page number + */ + send_scroll_fetch_event: function send_scroll_fetch_event(page) { + var additionalValues = { ev: page }; + var loadTime = getLoadTime(); + var navToDoneTime = getNavToDoneTime(); + if (loadTime) additionalValues.loadtime = loadTime; + if (navToDoneTime) additionalValues.nav_to_done_ms = navToDoneTime; + this.send_event('page_action', 'scroll_fetch', location.pathname, additionalValues); + }, + + send_scroll_fetch_base_event: function send_scroll_fetch_base_event() { + var additionalValues = {}; + var loadTime = getLoadTime(); + var navToDoneTime = getNavToDoneTime(); + if (loadTime) additionalValues.loadtime = loadTime; + if (navToDoneTime) additionalValues.nav_to_done_ms = navToDoneTime; + this.send_event('page_action', 'scroll_fetch_base', location.pathname, additionalValues); + }, + + /** + * @param {Object} [options] + * @param {String} [options.mediaType] + * @param {String} [options.mediaLanguage] + * @param {String} [options.page] The path portion of the page URL + */ + send_pageview: function send_pageview(options) { + var settings = options || {}; + + var defaultFontSize; + var loadTime = getLoadTime(); + var mediaType = settings.mediaType; + var primaryCollection = settings.primaryCollection; + var page = settings.page; + var navToDoneTime = getNavToDoneTime(); + + /** + * @return {String} + */ + function get_locale() { + if (navigator) { + if (navigator.language) + return navigator.language; + + else if (navigator.browserLanguage) + return navigator.browserLanguage; + + else if (navigator.systemLanguage) + return navigator.systemLanguage; + + else if (navigator.userLanguage) + return navigator.userLanguage; + } + return ''; + } + + defaultFontSize = getDefaultFontSize(); + + // Set field values + this.values.kind = 'pageview'; + this.values.timediff = (new Date().getTimezoneOffset()/60)*(-1); // *timezone* diff from UTC + this.values.locale = get_locale(); + this.values.referrer = (document.referrer == '' ? '-' : document.referrer); + + if (loadTime) + this.values.loadtime = loadTime; + + if (navToDoneTime) + this.values.nav_to_done_ms = navToDoneTime; + + if (settings.trackingId) { + this.values.ga_tid = settings.trackingId; + } + + /* START CUSTOM DIMENSIONS */ + if (defaultFontSize) + this.values.ga_cd1 = defaultFontSize; + + if ('devicePixelRatio' in window) + this.values.ga_cd2 = window.devicePixelRatio; + + if (mediaType) + this.values.ga_cd3 = mediaType; + + if (settings.mediaLanguage) { + this.values.ga_cd4 = settings.mediaLanguage; + } + + if (primaryCollection) { + this.values.ga_cd5 = primaryCollection; + } + /* END CUSTOM DIMENSIONS */ + + if (page) + this.values.page = page; + + this.send_ping(this.values); + }, + + /** + * Sends a tracking "Event". + * @param {string} category + * @param {string} action + * @param {string} label + * @param {Object} additionalEventParams + */ + send_event: function send_event( + category, + action, + label, + additionalEventParams + ) { + if (!label) label = window.location.pathname; + if (!additionalEventParams) additionalEventParams = {}; + if (additionalEventParams.mediaLanguage) { + additionalEventParams.ga_cd4 = additionalEventParams.mediaLanguage; + delete additionalEventParams.mediaLanguage; + } + var eventParams = Object.assign( + { + kind: 'event', + ec: category, + ea: action, + el: label, + cache_bust: Math.random(), + }, + additionalEventParams + ); + this.send_ping(eventParams); + }, + + /** + * Sends every event instead of a small percentage. + * + * Use this sparingly as it can generate a lot of events. + * + * @param {string} category + * @param {string} action + * @param {string} label + * @param {Object} additionalEventParams + */ + send_event_no_sampling: function send_event_no_sampling( + category, + action, + label, + additionalEventParams + ) { + var extraParams = additionalEventParams || {}; + extraParams.service = NO_SAMPLING_SERVICE; + this.send_event(category, action, label, extraParams); + }, + + /** + * @param {Object} options see this.send_pageview options + */ + send_pageview_on_load: function send_pageview_on_load(options) { + var self = this; + window.addEventListener('load', function send_pageview_with_options() { + self.send_pageview(options); + }); + }, + + /** + * Handles tracking events passed in URL. + * Assumes category and action values are separated by a "|" character. + * NOTE: Uses the unsampled analytics property. Watch out for future high click links! + * @param {Location} + */ + process_url_events: function process_url_events(location) { + var eventValues; + var actionValue; + var eventValue = getParams(location).iax; + if (!eventValue) return; + eventValues = eventValue.split('|'); + actionValue = eventValues.length >= 1 ? eventValues[1] : ''; + this.send_event_no_sampling( + eventValues[0], + actionValue, + window.location.pathname + ); + }, + + /** + * Attaches handlers for event tracking. + * + * To enable click tracking for a link, add a `data-event-click-tracking` + * attribute containing the Google Analytics Event Category and Action, separated + * by a vertical pipe (|). + * e.g. `` + * + * To enable form submit tracking, add a `data-event-form-tracking` attribute + * to the `form` tag. + * e.g. `` + * + * Additional tracking options can be added via a `data-event-tracking-options` + * parameter. This parameter, if included, should be a JSON string of the parameters. + * Valid parameters are: + * - service {string}: Corresponds to the Google Analytics property data values flow into + */ + set_up_event_tracking: function set_up_event_tracking() { + var self = this; + var clickTrackingAttributeName = 'event-click-tracking'; + var formTrackingAttributeName = 'event-form-tracking'; + var trackingOptionsAttributeName = 'event-tracking-options'; + + function handleAction(event, attributeName) { + var selector = '[data-' + attributeName + ']'; + var eventTarget = event.target; + if (!eventTarget) return; + var target = eventTarget.closest(selector); + if (!target) return; + var categoryAction; + var categoryActionParts; + var options; + categoryAction = target.dataset[toCamelCase(attributeName)]; + if (!categoryAction) return; + categoryActionParts = categoryAction.split('|'); + options = target.dataset[toCamelCase(trackingOptionsAttributeName)]; + options = options ? JSON.parse(options) : {}; + self.send_event( + categoryActionParts[0], + categoryActionParts[1], + categoryActionParts[2] || window.location.pathname, + options.service ? { service: options.service } : {} + ); + } + + function toCamelCase(str) { + return str.replace(/\W+(.)/g, function (match, chr) { + return chr.toUpperCase(); + }); + }; + + document.addEventListener('click', function(e) { + handleAction(e, clickTrackingAttributeName); + }); + + document.addEventListener('submit', function(e) { + handleAction(e, formTrackingAttributeName); + }); + }, + + /** + * @returns {Object[]} + */ + get_data_packets: function get_data_packets() { + return [this.values]; + }, + + /** + * Creates a tracking image for tracking JS compatibility. + * + * @param {string} type The type value for track_js_case in query params for 0.gif + */ + create_tracking_image: function create_tracking_image(type) { + this.send_ping_via_image({ + cache_bust: Math.random(), + kind: 'track_js', + track_js_case: type, + }); + } + }; + + return ArchiveAnalytics; +}()); +// @license-end diff --git a/Docs/Chapter 2.2 Reading a file from CD-ROM_files/banner-styles.css b/Docs/Chapter 2.2 Reading a file from CD-ROM_files/banner-styles.css new file mode 100644 index 0000000..8d39621 --- /dev/null +++ b/Docs/Chapter 2.2 Reading a file from CD-ROM_files/banner-styles.css @@ -0,0 +1,500 @@ +@import 'record.css'; /* for SPN1 */ + +#wm-ipp-base { + height:65px;/* initial height just in case js code fails */ + padding:0; + margin:0; + border:none; + background:none transparent; +} +#wm-ipp { + z-index: 2147483647; +} +#wm-ipp, #wm-ipp * { + font-family:Lucida Grande, Helvetica, Arial, sans-serif; + font-size:12px; + line-height:1.2; + letter-spacing:0; + width:auto; + height:auto; + max-width:none; + max-height:none; + min-width:0 !important; + min-height:0; + outline:none; + float:none; + text-align:left; + border:none; + color: #000; + text-indent: 0; + position: initial; + background: none; +} +#wm-ipp div, #wm-ipp canvas { + display: block; +} +#wm-ipp div, #wm-ipp tr, #wm-ipp td, #wm-ipp a, #wm-ipp form { + padding:0; + margin:0; + border:none; + border-radius:0; + background-color:transparent; + background-image:none; + /*z-index:2147483640;*/ + height:auto; +} +#wm-ipp table { + border:none; + border-collapse:collapse; + margin:0; + padding:0; + width:auto; + font-size:inherit; +} +#wm-ipp form input { + padding:1px !important; + height:auto; + display:inline; + margin:0; + color: #000; + background: none #fff; + border: 1px solid #666; +} +#wm-ipp form input[type=submit] { + padding:0 8px !important; + margin:1px 0 1px 5px !important; + width:auto !important; + border: 1px solid #000 !important; + background: #fff !important; + color: #000 !important; +} +#wm-ipp a { + display: inline; +} +#wm-ipp a:hover{ + text-decoration:underline; +} +#wm-ipp a.wm-btn:hover { + text-decoration:none; + color:#ff0 !important; +} +#wm-ipp a.wm-btn:hover span { + color:#ff0 !important; +} +#wm-ipp #wm-ipp-inside { + margin: 0 6px; + border:5px solid #000; + border-top:none; + background-color:rgba(255,255,255,0.9); + -moz-box-shadow:1px 1px 4px #333; + -webkit-box-shadow:1px 1px 4px #333; + box-shadow:1px 1px 4px #333; + border-radius:0 0 8px 8px; +} +/* selectors are intentionally verbose to ensure priority */ +#wm-ipp #wm-logo { + padding:0 10px; + vertical-align:middle; + min-width:100px; + flex: 0 0 100px; +} +#wm-ipp .c { + padding-left: 4px; +} +#wm-ipp .c .u { + margin-top: 4px !important; +} +#wm-ipp .n { + padding:0 0 0 5px !important; + vertical-align: bottom; +} +#wm-ipp .n a { + text-decoration:none; + color:#33f; + font-weight:bold; +} +#wm-ipp .n .b { + padding:0 6px 0 0 !important; + text-align:right !important; + overflow:visible; + white-space:nowrap; + color:#99a; + vertical-align:middle; +} +#wm-ipp .n .y .b { + padding:0 6px 2px 0 !important; +} +#wm-ipp .n .c { + background:#000; + color:#ff0; + font-weight:bold; + padding:0 !important; + text-align:center; +} +#wm-ipp.hi .n td.c { + color:#ec008c; +} +#wm-ipp .n td.f { + padding:0 0 0 6px !important; + text-align:left !important; + overflow:visible; + white-space:nowrap; + color:#99a; + vertical-align:middle; +} +#wm-ipp .n tr.m td { + text-transform:uppercase; + white-space:nowrap; + padding:2px 0; +} +#wm-ipp .c .s { + padding:0 5px 0 0 !important; + vertical-align:bottom; +} +#wm-ipp #wm-nav-captures { + white-space: nowrap; +} +#wm-ipp .c .s a.t { + color:#33f; + font-weight:bold; + line-height: 1.8; +} +#wm-ipp .c .s div.r { + color: #666; + font-size:9px; + white-space:nowrap; +} +#wm-ipp .c .k { + padding-bottom:1px; +} +#wm-ipp .c .s { + padding:0 5px 2px 0 !important; +} +#wm-ipp td#displayMonthEl { + padding: 2px 0 !important; +} +#wm-ipp td#displayYearEl { + padding: 0 0 2px 0 !important; +} + +div#wm-ipp-sparkline { + position:relative;/* for positioning markers */ + white-space:nowrap; + background-color:#fff; + cursor:pointer; + line-height:0.9; +} +#sparklineImgId, #wm-sparkline-canvas { + position:relative; + z-index:9012; + max-width:none; +} +#wm-ipp-sparkline div.yt { + position:absolute; + z-index:9010 !important; + background-color:#ff0 !important; + top: 0; +} +#wm-ipp-sparkline div.mt { + position:absolute; + z-index:9013 !important; + background-color:#ec008c !important; + top: 0; +} +#wm-ipp .r { + margin-left: 4px; +} +#wm-ipp .r a { + color:#33f; + border:none; + position:relative; + background-color:transparent; + background-repeat:no-repeat !important; + background-position:100% 100% !important; + text-decoration: none; +} +#wm-ipp #wm-capinfo { + /* prevents notice div background from sticking into round corners of + #wm-ipp-inside */ + border-radius: 0 0 4px 4px; +} +#wm-ipp #wm-capinfo .c-logo { + display:block; + float:left; + margin-right:3px; + width:90px; + min-height:90px; + max-height: 290px; + border-radius:45px; + overflow:hidden; + background-position:50%; + background-size:auto 90px; + box-shadow: 0 0 2px 2px rgba(208,208,208,128) inset; +} +#wm-ipp #wm-capinfo .c-logo span { + display:inline-block; +} +#wm-ipp #wm-capinfo .c-logo img { + height:90px; + position:relative; + left:-50%; +} +#wm-ipp #wm-capinfo .wm-title { + font-size:130%; +} +#wm-ipp #wm-capinfo a.wm-selector { + display:inline-block; + color: #aaa; + text-decoration:none !important; + padding: 2px 8px; +} +#wm-ipp #wm-capinfo a.wm-selector.selected { + background-color:#666; +} +#wm-ipp #wm-capinfo a.wm-selector:hover { + color: #fff; +} +#wm-ipp #wm-capinfo.notice-only #wm-capinfo-collected-by, +#wm-ipp #wm-capinfo.notice-only #wm-capinfo-timestamps { + display: none; +} +#wm-ipp #wm-capinfo #wm-capinfo-notice .wm-capinfo-content { + background-color:#ff0; + padding:5px; + font-size:14px; + text-align:center; +} +#wm-ipp #wm-capinfo #wm-capinfo-notice .wm-capinfo-content * { + font-size:14px; + text-align:center; +} +#wm-ipp #wm-expand { + right: 1px; + bottom: -1px; + color: #ffffff; + background-color: #666 !important; + padding:0 5px 0 3px !important; + border-radius: 3px 3px 0 0 !important; +} +#wm-ipp #wm-expand span { + color: #ffffff; +} +#wm-ipp #wm-expand #wm-expand-icon { + display: inline-block; + transition: transform 0.5s; + transform-origin: 50% 45%; +} +#wm-ipp #wm-expand.wm-open #wm-expand-icon { + transform: rotate(180deg); +} +#wm-ipp #wmtb { + text-align:right; +} +#wm-ipp #wmtb #wmtbURL { + width: calc(100% - 45px); +} +#wm-ipp #wm-graph-anchor { + border-right:1px solid #ccc; +} +/* time coherence */ +html.wb-highlight { + box-shadow: inset 0 0 0 3px #a50e3a !important; +} +.wb-highlight { + outline: 3px solid #a50e3a !important; +} +#wm-ipp-print { + display:none !important; +} +@media print { +#wm-ipp-base { + display:none !important; +} +#wm-ipp-print { + display:block !important; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +} +@media (max-width:414px) { + #wm-ipp .xxs { + display:none !important; + } +} +@media (min-width:1055px) { +#wm-ipp #wm-graph-anchor { + display:block !important; +} +} +@media (max-width:1054px) { +#wm-ipp #wm-graph-anchor { + display:none !important; +} +} +@media (max-width:1163px) { +#wm-logo { + display:none !important; +} +} + +#wm-btns { + white-space: nowrap; + margin-top: -2px; +} + +#wm-btns #wm-save-snapshot-open { + margin-right: 7px; + top: -6px; +} + +#wm-btns #wm-sign-in { + box-sizing: content-box; + display: none; + margin-right: 7px; + top: -8px; + + /* + round border around sign in button + */ + border: 2px #000 solid; + border-radius: 14px; + padding-right: 2px; + padding-bottom: 2px; + width: 11px; + height: 11px; +} + +#wm-btns #wm-sign-in>.iconochive-person { + font-size: 12.5px; +} + +#wm-save-snapshot-open > .iconochive-web { + color:#000; + font-size:160%; +} + +#wm-ipp #wm-share { + display: flex; + align-items: flex-end; + justify-content: space-between; +} + +#wm-share > #wm-screenshot { + display: inline-block; + margin-right: 3px; + visibility: hidden; +} + +#wm-screenshot > .iconochive-image { + color:#000; + font-size:160%; +} + +#wm-share > #wm-video { + display: inline-block; + margin-right: 3px; + visibility: hidden; +} + +#wm-video > .iconochive-movies { + color: #000; + display: inline-block; + font-size: 150%; + margin-bottom: 2px; +} + +#wm-btns #wm-save-snapshot-in-progress { + display: none; + font-size:160%; + opacity: 0.5; + position: relative; + margin-right: 7px; + top: -5px; +} + +#wm-btns #wm-save-snapshot-success { + display: none; + color: green; + position: relative; + top: -7px; +} + +#wm-btns #wm-save-snapshot-fail { + display: none; + color: red; + position: relative; + top: -7px; +} + +.wm-icon-screen-shot { + background: url("../images/web-screenshot.svg") no-repeat !important; + background-size: contain !important; + width: 22px !important; + height: 19px !important; + + display: inline-block; +} +#donato { + /* transition effect is disable so as to simplify height adjustment */ + /*transition: height 0.5s;*/ + height: 0; + margin: 0; + padding: 0; + border-bottom: 1px solid #999 !important; +} +body.wm-modal { + height: auto !important; + overflow: hidden !important; +} +#donato #donato-base { + width: 100%; + height: 100%; + /*bottom: 0;*/ + margin: 0; + padding: 0; + position: absolute; + z-index: 2147483639; +} +body.wm-modal #donato #donato-base { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 2147483640; +} + +.wb-autocomplete-suggestions { + font-family: Lucida Grande, Helvetica, Arial, sans-serif; + font-size: 12px; + text-align: left; + cursor: default; + border: 1px solid #ccc; + border-top: 0; + background: #fff; + box-shadow: -1px 1px 3px rgba(0,0,0,.1); + position: absolute; + display: none; + z-index: 2147483647; + max-height: 254px; + overflow: hidden; + overflow-y: auto; + box-sizing: border-box; +} +.wb-autocomplete-suggestion { + position: relative; + padding: 0 .6em; + line-height: 23px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-size: 1.02em; + color: #333; +} +.wb-autocomplete-suggestion b { + font-weight: bold; +} +.wb-autocomplete-suggestion.selected { + background: #f0f0f0; +} diff --git a/Docs/Chapter 2.2 Reading a file from CD-ROM_files/bundle-playback.js b/Docs/Chapter 2.2 Reading a file from CD-ROM_files/bundle-playback.js new file mode 100644 index 0000000..390894d --- /dev/null +++ b/Docs/Chapter 2.2 Reading a file from CD-ROM_files/bundle-playback.js @@ -0,0 +1,3 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0 +!function(e){var t={};function n(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(o,i,function(t){return e[t]}.bind(null,i));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=9)}([function(e,t,n){"use strict";function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function s(e){var t="function"==typeof Map?new Map:void 0;return(s=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,o)}function o(){return a(e,arguments,u(this).constructor)}return o.prototype=Object.create(e.prototype,{constructor:{value:o,enumerable:!1,writable:!0,configurable:!0}}),l(o,e)})(e)}function a(e,t,n){return(a=c()?Reflect.construct:function(e,t,n){var o=[null];o.push.apply(o,t);var i=new(Function.bind.apply(e,o));return n&&l(i,n.prototype),i}).apply(null,arguments)}function c(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function l(e,t){return(l=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function u(e){return(u=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}if(n.d(t,"a",(function(){return f})),n.d(t,"d",(function(){return p})),n.d(t,"c",(function(){return d})),n.d(t,"b",(function(){return v})),"undefiend"!=typeof window.XMLHttpRequest){var h=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&l(e,t)}(o,e);var t,n=(t=o,function(){var e,n=u(t);if(c()){var o=u(this).constructor;e=Reflect.construct(n,arguments,o)}else e=n.apply(this,arguments);return r(this,e)});function o(){return i(this,o),n.apply(this,arguments)}return o}(s(XMLHttpRequest));Object.defineProperty(h.prototype,"responseURL",Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype,"responseURL"))}function f(e,t,n,o,i){var r;if((r=window.XMLHttpRequest?new h:new ActiveXObject("Microsoft.XMLHTTP")).onreadystatechange=function(){4==this.readyState&&n(r)},r.open(e,t,!0),o)for(var s in o)o.hasOwnProperty(s)&&r.setRequestHeader(s,o[s]);r.withCredentials=!0,r.send(i)}function p(e){return void 0!==e&&e&&e.constructor===Array}function d(e){return document.cookie.search(e)>=0}function m(e,t){var n=window["HTML".concat(e,"Element")];if(void 0!==n){var o=Object.getOwnPropertyDescriptor(n.prototype,t);void 0!==o&&Object.defineProperty(n.prototype,"_wm_".concat(t),o)}}function v(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"src",n="_wm_".concat(t);return n in e.__proto__?e[n]:e[t]}m("Image","src"),m("Media","src"),m("Embed","src"),m("IFrame","src"),m("Script","src"),m("Link","href"),m("Anchor","href")},function(e,t,n){"use strict";n.d(t,"c",(function(){return s})),n.d(t,"b",(function(){return a})),n.d(t,"a",(function(){return c}));var o=["January","February","March","April","May","June","July","August","September","October","November","December"],i=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],r={Y:function(e){return e.getUTCFullYear()},m:function(e){return e.getUTCMonth()+1},b:function(e){return i[e.getUTCMonth()]},B:function(e){return o[e.getUTCMonth()]},d:function(e){return e.getUTCDate()},H:function(e){return("0"+e.getUTCHours()).slice(-2)},M:function(e){return("0"+e.getUTCMinutes()).slice(-2)},S:function(e){return("0"+e.getUTCSeconds()).slice(-2)},"%":function(){return"%"}};function s(e){var t=function(e){return"number"==typeof e&&(e=e.toString()),[e.slice(-14,-10),e.slice(-10,-8),e.slice(-8,-6),e.slice(-6,-4),e.slice(-4,-2),e.slice(-2)]}(e);return new Date(Date.UTC(t[0],t[1]-1,t[2],t[3],t[4],t[5]))}function a(e){return i[e]}function c(e,t){return t.replace(/%./g,(function(t){var n=r[t[1]];return n?n(s(e)):t}))}},function(e,t,n){"use strict";n.d(t,"b",(function(){return s})),n.d(t,"a",(function(){return a}));var o=n(0);function i(e,t){for(var n=0;n=400?i.failure&&i.failure(e):i.success&&i.success(e)}),{"Content-Type":"application/json"},r.stringify({url:e,snapshot:t,tags:n||[]})),!1}var a=function(){function e(t,n,i){var r=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.el=t,this.url=n,this.timestamp=i,t.onclick=this.save.bind(this),document.addEventListener("DOMContentLoaded",(function(){Object(o.c)("logged-in-user")&&Object(o.c)("logged-in-sig")?r.userIsLoggedIn():r.userIsNotLoggedIn()}))}var t,n,r;return t=e,(n=[{key:"save",value:function(e){this.start(),s(this.url,this.timestamp,[],{failure:this.failure.bind(this),success:this.success.bind(this)})}},{key:"start",value:function(){this.hide(["wm-save-snapshot-fail","wm-save-snapshot-open","wm-save-snapshot-success"]),this.show(["wm-save-snapshot-in-progress"])}},{key:"failure",value:function(e){401==e.status?this.userNotLoggedIn(e):(this.hide(["wm-save-snapshot-in-progress","wm-save-snapshot-success"]),this.show(["wm-save-snapshot-fail","wm-save-snapshot-open"]),console.log("You have got an error."),console.log("If you think something wrong here please send it to support."),console.log('Response: "'+e.responseText+'"'),console.log('status: "'+e.status+'"'))}},{key:"success",value:function(e){this.hide(["wm-save-snapshot-fail","wm-save-snapshot-in-progress"]),this.show(["wm-save-snapshot-open","wm-save-snapshot-success"])}},{key:"userIsLoggedIn",value:function(){this.show("wm-save-snapshot-open"),this.hide("wm-sign-in")}},{key:"userIsNotLoggedIn",value:function(){this.hide(["wm-save-snapshot-open","wm-save-snapshot-in-progress"]),this.show("wm-sign-in")}},{key:"show",value:function(e){this.setDisplayStyle(e,"inline-block")}},{key:"hide",value:function(e){this.setDisplayStyle(e,"none")}},{key:"setDisplayStyle",value:function(e,t){var n=this;(Object(o.d)(e)?e:[e]).forEach((function(e){var o=n.el.getRootNode().getElementById(e);o&&(o.style.display=t)}))}}])&&i(t.prototype,n),r&&i(t,r),e}()},,,,,,,function(e,t,n){"use strict";var o;n.r(t);var i,r={createElementNS:document.createElementNS};var s=!0;function a(e){!function(e,t,n){if(n){var o=new Date;o.setTime(o.getTime()+24*n*60*60*1e3);var i="; expires="+o.toGMTString()}else i="";document.cookie=e+"="+t+i+"; path=/"}(e,"",-1)}var c=n(0),l=n(1),u=window.Date;function h(e,t){return(e=e.toString()).length>=t?e:"00000000".substring(0,t-e.length)+e}function f(e){for(var t=0,n=0;n3}(e)){var o=[];for(n=0;n=e.length?{done:!0}:{done:!1,value:e[t++]}},e:function(e){throw e},f:n}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,i,r=!0,s=!1;return{s:function(){o=e[Symbol.iterator]()},n:function(){var e=o.next();return r=e.done,e},e:function(e){s=!0,i=e},f:function(){try{r||null==o.return||o.return()}finally{if(s)throw i}}}}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n2&&void 0!==arguments[2]?arguments[2]:"src",r=window.location.origin,s=b(window,e),l=p(s);try{for(l.s();!(o=l.n()).done;){var u=o.value;if(!n||n(u)){var h=Object(c.b)(u,i);h&&!h.startsWith(t)&&h.startsWith(r)&&(h.startsWith("data:")||a.push(h))}}}catch(e){l.e(e)}finally{l.f()}}u("img"),u("frame"),u("iframe",(function(e){return"playback"!==e.id})),u("script"),u("link",(function(e){return"stylesheet"===e.rel}),"href");var h=a.filter((function(e,t,n){return n.indexOf(e)===t}));h.length>0?(s=0,h.map((function(e){e.match("^https?://")&&(s++,Object(c.a)("HEAD",e,(function(e){if(200==e.status){var t=e.getResponseHeader("Memento-Datetime");if(null==t)console.log("%s: no Memento-Datetime",u);else{var n=document.createElement("span"),a=function(e,t){var n=new Date(e).getTime()-t,o="";n<0?(o+="-",n=Math.abs(n)):o+="+";var i=!1;if(n<1e3)return{delta:n,text:"",highlight:i};var r=n,s=Math.floor(n/1e3/60/60/24/30/12);n-=1e3*s*60*60*24*30*12;var a=Math.floor(n/1e3/60/60/24/30);n-=1e3*a*60*60*24*30;var c=Math.floor(n/1e3/60/60/24);n-=1e3*c*60*60*24;var l=Math.floor(n/1e3/60/60);n-=1e3*l*60*60;var u=Math.floor(n/1e3/60);n-=1e3*u*60;var h=Math.floor(n/1e3),f=[];s>1?(f.push(s+" years"),i=!0):1==s&&(f.push(s+" year"),i=!0);a>1?(f.push(a+" months"),i=!0):1==a&&(f.push(a+" month"),i=!0);c>1?f.push(c+" days"):1==c&&f.push(c+" day");l>1?f.push(l+" hours"):1==l&&f.push(l+" hour");u>1?f.push(u+" minutes"):1==u&&f.push(u+" minute");h>1?f.push(h+" seconds"):1==h&&f.push(h+" second");f.length>2&&(f=f.slice(0,2));return{delta:r,text:o+f.join(" "),highlight:i}}(t,r),c=a.highlight?"color:red;":"";n.innerHTML=" "+a.text,n.title=t,n.setAttribute("style",c);var l=e.getResponseHeader("Content-Type"),u=e.responseURL.replace(window.location.origin,""),h=document.createElement("a");h.innerHTML=u.split("/").splice(3).join("/"),h._wm_href=u,h.title=l,h.onmouseover=y,h.onmouseout=w;var f=document.createElement("div");f.setAttribute("data-delta",a.delta),f.appendChild(h),f.append(n),o.appendChild(f);var p=Array.prototype.slice.call(o.childNodes,0);p.sort((function(e,t){return t.getAttribute("data-delta")-e.getAttribute("data-delta")})),o.innerHTML="";for(var d=0,m=p.length;d0)for(var n=0;n0)for(var n=0;n0?this.sc.scrollTop=i+this.sc.suggestionHeight+o-this.sc.maxHeight:i<0&&(this.sc.scrollTop=i+o)}}},{key:"blurHandler",value:function(){var e=this;try{var t=this.root.querySelector(".wb-autocomplete-suggestions:hover")}catch(e){t=null}t?this.input!==document.activeElement&&setTimeout((function(){return e.focus()}),20):(this.last_val=this.input.value,this.sc.style.display="none",setTimeout((function(){return e.sc.style.display="none"}),350))}},{key:"suggest",value:function(e){var t=this.input.value;if(this.cache[t]=e,e.length&&t.length>=this.minChars){for(var n="",o=0;o40)&&13!=n&&27!=n){var o=this.input.value;if(o.length>=this.minChars){if(o!=this.last_val){if(this.last_val=o,clearTimeout(this.timer),this.cache){if(o in this.cache)return void this.suggest(this.cache[o]);for(var i=1;i'+e.replace(n,"$1")+""}},{key:"onSelect",value:function(e,t,n){}}]),e}(),j=function(){function e(t,n){S(this,e);var o=t.getRootNode();if(o.querySelector){var i="object"==_(t)?[t]:o.querySelectorAll(t);this.elems=i.map((function(e){return new E(e,n)}))}}return T(e,[{key:"destroy",value:function(){for(;this.elems.length>0;)this.elems.pop().unload()}}]),e}(),R=n(2),A=window.JSON,N=window.open,U=window.Date,I=document,D=document,P=function(e){return D.getElementById(e)};var q,F="/static/";function B(e){L.classList.contains("wm-closed")?(e&&O.classList.add("notice-only"),L.classList.replace("wm-closed","wm-open"),O.style.display="block",m(q,F,P)):(L.classList.replace("wm-open","wm-closed"),O.style.display="none",O.classList.remove("notice-only"))}function W(e,t){var n=P(e);n&&(n.style.visibility=t?"visible":"hidden")}function X(e,t){Object(c.d)(e)||(e=[e]);for(var n=0;n0&&r<60,r)}))}window.__wm={init:function(e){!function(){var e=document.cookie.split(";");if(e.length>40)for(var t=0;t1?t-1:0),o=1;o0;)x.appendChild(C.children[0]);if(d)for(var H=0;H'+((""+n).replace(/\B(?=(\d{3})+$)/g,",")+" ")+(n>1?"captures":"capture")+"",f=l.a(i,"%d %b %Y");s!=i&&(f+=" - "+l.a(s,"%d %b %Y")),h+='
'+f+"
",t.innerHTML=h}(o),function(e,t,n,o,i,r,s){var a=o.getContext("2d");if(a){a.fillStyle="#FFF";var c=(new u).getUTCFullYear(),l=t/(c-i+1),h=f(e.years),p=h[0],d=n/h[1];if(r>=i){var m=T(r);a.fillStyle="#FFFFA5",a.fillRect(m,0,l,n)}for(var v=i;v<=c;v++){m=T(v);a.beginPath(),a.moveTo(m,0),a.lineTo(m,n),a.lineWidth=1,a.strokeStyle="#CCC",a.stroke()}s=parseInt(s)-1;for(var g=(l-1)/12,y=0;y0){var M=Math.ceil(S*d);a.fillStyle=v==r&&_==s?"#EC008C":"#000",a.fillRect(Math.round(b),Math.ceil(n-M),Math.ceil(g),Math.round(M))}b+=g}}}function T(e){return Math.ceil((e-i)*l)+.5}}(o,e,t,Z,a,_,S)}}))}else{var te=new Image;te.src="/__wb/sparkline?url="+encodeURIComponent(r)+"&width="+e+"&height="+t+"&selected_year="+_+"&selected_month="+S+(i&&"&collection="+i||""),te.alt="sparkline",te.width=e,te.height=t,te.id="sparklineImgId",te.border="0",Q.parentNode.replaceChild(te,Q)}function ne(e){for(var t=[],n=e.length,o=0;o. + */ +(function(){function FuncMap(){this._map=[]}function ensureNumber(maybeNumber){try{switch(typeof maybeNumber){case"number":case"bigint":return maybeNumber;}var converted=Number(maybeNumber);return isNaN(converted)?null:converted}catch(e){}return null}function addToStringTagToClass(clazz,tag){typeof self.Symbol!=="undefined"&&typeof self.Symbol.toStringTag!=="undefined"&&Object.defineProperty(clazz.prototype,self.Symbol.toStringTag,{value:tag,enumerable:false})}function autobind(clazz){for(var prop,propValue,proto=clazz.__proto__||clazz.constructor.prototype||clazz.prototype,clazzProps=Object.getOwnPropertyNames(proto),len=clazzProps.length,i=0;i=0){var fnMapping=this._map.splice(idx,1);return fnMapping[0][1]}return null},FuncMap.prototype.map=function(param){for(var i=0;i0&&afw.preserveMedia(media)})},AutoFetcher.prototype.terminate=function(){this.worker.terminate()},AutoFetcher.prototype.justFetch=function(urls){this.worker.postMessage({type:"fetch-all",values:urls})},AutoFetcher.prototype.fetchAsPage=function(url,originalUrl,title){if(url){var headers={"X-Wombat-History-Page":originalUrl};if(title){var encodedTitle=encodeURIComponent(title.trim());title&&(headers["X-Wombat-History-Title"]=encodedTitle)}var fetchData={url:url,options:{headers:headers,cache:"no-store"}};this.justFetch([fetchData])}},AutoFetcher.prototype.postMessage=function(msg,deferred){if(deferred){var afWorker=this;return void Promise.resolve().then(function(){afWorker.worker.postMessage(msg)})}this.worker.postMessage(msg)},AutoFetcher.prototype.preserveSrcset=function(srcset,mod){this.postMessage({type:"values",srcset:{value:srcset,mod:mod,presplit:true}},true)},AutoFetcher.prototype.preserveDataSrcset=function(elem){this.postMessage({type:"values",srcset:{value:elem.dataset.srcset,mod:this.rwMod(elem),presplit:false}},true)},AutoFetcher.prototype.preserveMedia=function(media){this.postMessage({type:"values",media:media},true)},AutoFetcher.prototype.getSrcset=function(elem){return this.wombat.wb_getAttribute?this.wombat.wb_getAttribute.call(elem,"srcset"):elem.getAttribute("srcset")},AutoFetcher.prototype.rwMod=function(elem){switch(elem.tagName){case"SOURCE":return elem.parentElement&&elem.parentElement.tagName==="PICTURE"?"im_":"oe_";case"IMG":return"im_";}return"oe_"},AutoFetcher.prototype.extractFromLocalDoc=function(){var afw=this;Promise.resolve().then(function(){for(var msg={type:"values",context:{docBaseURI:document.baseURI}},media=[],i=0,sheets=document.styleSheets;i=0)||scriptType.indexOf("text/template")>=0)},Wombat.prototype.skipWrapScriptTextBasedOnText=function(text){if(!text||text.indexOf(this.WB_ASSIGN_FUNC)>=0||text.indexOf("<")===0)return true;for(var override_props=["window","self","document","location","top","parent","frames","opener"],i=0;i=0)return false;return true},Wombat.prototype.nodeHasChildren=function(node){if(!node)return false;if(typeof node.hasChildNodes==="function")return node.hasChildNodes();var kids=node.children||node.childNodes;return!!kids&&kids.length>0},Wombat.prototype.rwModForElement=function(elem,attrName){if(!elem)return undefined;var mod="mp_";if(!(elem.tagName==="LINK"&&attrName==="href")){var maybeMod=this.tagToMod[elem.tagName];maybeMod!=null&&(mod=maybeMod[attrName])}else if(elem.rel){var relV=elem.rel.trim().toLowerCase(),asV=this.wb_getAttribute.call(elem,"as");if(asV&&this.linkTagMods.linkRelToAs[relV]!=null){var asMods=this.linkTagMods.linkRelToAs[relV];mod=asMods[asV.toLowerCase()]}else this.linkTagMods[relV]!=null&&(mod=this.linkTagMods[relV])}return mod},Wombat.prototype.removeWBOSRC=function(elem){elem.tagName!=="SCRIPT"||elem.__$removedWBOSRC$__||(elem.hasAttribute("__wb_orig_src")&&elem.removeAttribute("__wb_orig_src"),elem.__$removedWBOSRC$__=true)},Wombat.prototype.retrieveWBOSRC=function(elem){if(elem.tagName==="SCRIPT"&&!elem.__$removedWBOSRC$__){var maybeWBOSRC;return maybeWBOSRC=this.wb_getAttribute?this.wb_getAttribute.call(elem,"__wb_orig_src"):elem.getAttribute("__wb_orig_src"),maybeWBOSRC==null&&(elem.__$removedWBOSRC$__=true),maybeWBOSRC}return undefined},Wombat.prototype.wrapScriptTextJsProxy=function(scriptText){return"var _____WB$wombat$assign$function_____ = function(name) {return (self._wb_wombat && self._wb_wombat.local_init && self._wb_wombat.local_init(name)) || self[name]; };\nif (!self.__WB_pmw) { self.__WB_pmw = function(obj) { this.__WB_source = obj; return this; } }\n{\nlet window = _____WB$wombat$assign$function_____(\"window\");\nlet self = _____WB$wombat$assign$function_____(\"self\");\nlet document = _____WB$wombat$assign$function_____(\"document\");\nlet location = _____WB$wombat$assign$function_____(\"location\");\nlet top = _____WB$wombat$assign$function_____(\"top\");\nlet parent = _____WB$wombat$assign$function_____(\"parent\");\nlet frames = _____WB$wombat$assign$function_____(\"frames\");\nlet opener = _____WB$wombat$assign$function_____(\"opener\");\n"+scriptText.replace(this.DotPostMessageRe,".__WB_pmw(self.window)$1")+"\n\n}"},Wombat.prototype.watchElem=function(elem,func){if(!this.$wbwindow.MutationObserver)return false;var m=new this.$wbwindow.MutationObserver(function(records,observer){for(var r,i=0;i"},Wombat.prototype.getFinalUrl=function(useRel,mod,url){var prefix=useRel?this.wb_rel_prefix:this.wb_abs_prefix;return mod==null&&(mod=this.wb_info.mod),this.wb_info.is_live||(prefix+=this.wb_info.wombat_ts),prefix+=mod,prefix[prefix.length-1]!=="/"&&(prefix+="/"),prefix+url},Wombat.prototype.resolveRelUrl=function(url,doc){var docObj=doc||this.$wbwindow.document,parser=this.makeParser(docObj.baseURI,docObj),hash=parser.href.lastIndexOf("#"),href=hash>=0?parser.href.substring(0,hash):parser.href,lastslash=href.lastIndexOf("/");return parser.href=lastslash>=0&&lastslash!==href.length-1?href.substring(0,lastslash+1)+url:href+url,parser.href},Wombat.prototype.extractOriginalURL=function(rewrittenUrl){if(!rewrittenUrl)return"";if(this.wb_is_proxy)return rewrittenUrl;var rwURLString=rewrittenUrl.toString(),url=rwURLString;if(this.startsWithOneOf(url,this.IGNORE_PREFIXES))return url;var start;start=this.startsWith(url,this.wb_abs_prefix)?this.wb_abs_prefix.length:this.wb_rel_prefix&&this.startsWith(url,this.wb_rel_prefix)?this.wb_rel_prefix.length:this.wb_rel_prefix?1:0;var index=url.indexOf("/http",start);return index<0&&(index=url.indexOf("///",start)),index<0&&(index=url.indexOf("/blob:",start)),index<0&&(index=url.indexOf("/about:blank",start)),index>=0?url=url.substr(index+1):(index=url.indexOf(this.wb_replay_prefix),index>=0&&(url=url.substr(index+this.wb_replay_prefix.length)),url.length>4&&url.charAt(2)==="_"&&url.charAt(3)==="/"&&(url=url.substr(4)),url!==rwURLString&&!this.startsWithOneOf(url,this.VALID_PREFIXES)&&!this.startsWith(url,"blob:")&&(url=this.wb_orig_scheme+url)),rwURLString.charAt(0)==="/"&&rwURLString.charAt(1)!=="/"&&this.startsWith(url,this.wb_orig_origin)&&(url=url.substr(this.wb_orig_origin.length)),this.startsWith(url,this.REL_PREFIX)?this.wb_info.wombat_scheme+":"+url:url},Wombat.prototype.makeParser=function(maybeRewrittenURL,doc){var originalURL=this.extractOriginalURL(maybeRewrittenURL),docElem=doc;return doc||(this.$wbwindow.location.href==="about:blank"&&this.$wbwindow.opener?docElem=this.$wbwindow.opener.document:docElem=this.$wbwindow.document),this._makeURLParser(originalURL,docElem)},Wombat.prototype._makeURLParser=function(url,docElem){try{return new this.$wbwindow.URL(url,docElem.baseURI)}catch(e){}var p=docElem.createElement("a");return p._no_rewrite=true,p.href=url,p},Wombat.prototype.defProp=function(obj,prop,setFunc,getFunc,enumerable){var existingDescriptor=Object.getOwnPropertyDescriptor(obj,prop);if(existingDescriptor&&!existingDescriptor.configurable)return false;if(!getFunc)return false;var descriptor={configurable:true,enumerable:enumerable||false,get:getFunc};setFunc&&(descriptor.set=setFunc);try{return Object.defineProperty(obj,prop,descriptor),true}catch(e){return console.warn("Failed to redefine property %s",prop,e.message),false}},Wombat.prototype.defGetterProp=function(obj,prop,getFunc,enumerable){var existingDescriptor=Object.getOwnPropertyDescriptor(obj,prop);if(existingDescriptor&&!existingDescriptor.configurable)return false;if(!getFunc)return false;try{return Object.defineProperty(obj,prop,{configurable:true,enumerable:enumerable||false,get:getFunc}),true}catch(e){return console.warn("Failed to redefine property %s",prop,e.message),false}},Wombat.prototype.getOrigGetter=function(obj,prop){var orig_getter;if(obj.__lookupGetter__&&(orig_getter=obj.__lookupGetter__(prop)),!orig_getter&&Object.getOwnPropertyDescriptor){var props=Object.getOwnPropertyDescriptor(obj,prop);props&&(orig_getter=props.get)}return orig_getter},Wombat.prototype.getOrigSetter=function(obj,prop){var orig_setter;if(obj.__lookupSetter__&&(orig_setter=obj.__lookupSetter__(prop)),!orig_setter&&Object.getOwnPropertyDescriptor){var props=Object.getOwnPropertyDescriptor(obj,prop);props&&(orig_setter=props.set)}return orig_setter},Wombat.prototype.getAllOwnProps=function(obj){for(var ownProps=[],props=Object.getOwnPropertyNames(obj),i=0;i "+final_href),actualLocation.href=final_href}}},Wombat.prototype.checkLocationChange=function(wombatLoc,isTop){var locType=typeof wombatLoc,actual_location=isTop?this.$wbwindow.__WB_replay_top.location:this.$wbwindow.location;locType==="string"?this.updateLocation(wombatLoc,actual_location.href,actual_location):locType==="object"&&this.updateLocation(wombatLoc.href,wombatLoc._orig_href,actual_location)},Wombat.prototype.checkAllLocations=function(){return!this.wb_wombat_updating&&void(this.wb_wombat_updating=true,this.checkLocationChange(this.$wbwindow.WB_wombat_location,false),this.$wbwindow.WB_wombat_location!=this.$wbwindow.__WB_replay_top.WB_wombat_location&&this.checkLocationChange(this.$wbwindow.__WB_replay_top.WB_wombat_location,true),this.wb_wombat_updating=false)},Wombat.prototype.proxyToObj=function(source){if(source)try{var proxyRealObj=source.__WBProxyRealObj__;if(proxyRealObj)return proxyRealObj}catch(e){}return source},Wombat.prototype.objToProxy=function(obj){if(obj)try{var maybeWbProxy=obj._WB_wombat_obj_proxy;if(maybeWbProxy)return maybeWbProxy}catch(e){}return obj},Wombat.prototype.defaultProxyGet=function(obj,prop,ownProps,fnCache){switch(prop){case"__WBProxyRealObj__":return obj;case"location":case"WB_wombat_location":return obj.WB_wombat_location;case"_WB_wombat_obj_proxy":return obj._WB_wombat_obj_proxy;case"__WB_pmw":case"WB_wombat_eval":case this.WB_ASSIGN_FUNC:case this.WB_CHECK_THIS_FUNC:return obj[prop];case"origin":return obj.WB_wombat_location.origin;case"constructor":if(obj.constructor===Window)return obj.constructor;}var retVal=obj[prop],type=typeof retVal;if(type==="function"&&ownProps.indexOf(prop)!==-1){switch(prop){case"requestAnimationFrame":case"cancelAnimationFrame":{if(!this.isNativeFunction(retVal))return retVal;break}}var cachedFN=fnCache[prop];return cachedFN&&cachedFN.original===retVal||(cachedFN={original:retVal,boundFn:retVal.bind(obj)},fnCache[prop]=cachedFN),cachedFN.boundFn}return type==="object"&&retVal&&retVal._WB_wombat_obj_proxy?(retVal instanceof Window&&this.initNewWindowWombat(retVal),retVal._WB_wombat_obj_proxy):retVal},Wombat.prototype.setLoc=function(loc,originalURL){var parser=this.makeParser(originalURL,loc.ownerDocument);loc._orig_href=originalURL,loc._parser=parser;var href=parser.href;loc._hash=parser.hash,loc._href=href,loc._host=parser.host,loc._hostname=parser.hostname,loc._origin=parser.origin?parser.host?parser.origin:"null":parser.protocol+"//"+parser.hostname+(parser.port?":"+parser.port:""),loc._pathname=parser.pathname,loc._port=parser.port,loc._protocol=parser.protocol,loc._search=parser.search,Object.defineProperty||(loc.href=href,loc.hash=parser.hash,loc.host=loc._host,loc.hostname=loc._hostname,loc.origin=loc._origin,loc.pathname=loc._pathname,loc.port=loc._port,loc.protocol=loc._protocol,loc.search=loc._search)},Wombat.prototype.makeGetLocProp=function(prop,origGetter){var wombat=this;return function newGetLocProp(){if(this._no_rewrite)return origGetter.call(this,prop);var curr_orig_href=origGetter.call(this,"href");return prop==="href"?wombat.extractOriginalURL(curr_orig_href):prop==="ancestorOrigins"?[]:(this._orig_href!==curr_orig_href&&wombat.setLoc(this,curr_orig_href),this["_"+prop])}},Wombat.prototype.makeSetLocProp=function(prop,origSetter,origGetter){var wombat=this;return function newSetLocProp(value){if(this._no_rewrite)return origSetter.call(this,prop,value);if(this["_"+prop]!==value){if(this["_"+prop]=value,!this._parser){var href=origGetter.call(this);this._parser=wombat.makeParser(href,this.ownerDocument)}var rel=false;prop==="href"&&typeof value==="string"&&value&&(value[0]==="."?value=wombat.resolveRelUrl(value,this.ownerDocument):value[0]==="/"&&(value.length<=1||value[1]!=="/")&&(rel=true,value=WB_wombat_location.origin+value));try{this._parser[prop]=value}catch(e){console.log("Error setting "+prop+" = "+value)}prop==="hash"?(value=this._parser[prop],origSetter.call(this,"hash",value)):(rel=rel||value===this._parser.pathname,value=wombat.rewriteUrl(this._parser.href,rel),origSetter.call(this,"href",value))}}},Wombat.prototype.styleReplacer=function(match,n1,n2,n3,offset,string){return n1+this.rewriteUrl(n2)+n3},Wombat.prototype.domConstructorErrorChecker=function(thisObj,what,args,numRequiredArgs){var errorMsg,needArgs=typeof numRequiredArgs==="number"?numRequiredArgs:1;if(thisObj instanceof Window?errorMsg="Failed to construct '"+what+"': Please use the 'new' operator, this DOM object constructor cannot be called as a function.":args&&args.length=0)return url;if(url.indexOf(this.wb_rel_prefix)===0&&url.indexOf("http")>1){var scheme_sep=url.indexOf(":/");return scheme_sep>0&&url[scheme_sep+2]!=="/"?url.substring(0,scheme_sep+2)+"/"+url.substring(scheme_sep+2):url}return this.getFinalUrl(true,mod,this.wb_orig_origin+url)}url.charAt(0)==="."&&(url=this.resolveRelUrl(url,doc));var prefix=this.startsWithOneOf(url.toLowerCase(),this.VALID_PREFIXES);if(prefix){var orig_host=this.$wbwindow.__WB_replay_top.location.host,orig_protocol=this.$wbwindow.__WB_replay_top.location.protocol,prefix_host=prefix+orig_host+"/";if(this.startsWith(url,prefix_host)){if(this.startsWith(url,this.wb_replay_prefix))return url;var curr_scheme=orig_protocol+"//",path=url.substring(prefix_host.length),rebuild=false;return path.indexOf(this.wb_rel_prefix)<0&&url.indexOf("/static/")<0&&(path=this.getFinalUrl(true,mod,WB_wombat_location.origin+"/"+path),rebuild=true),prefix!==curr_scheme&&prefix!==this.REL_PREFIX&&(rebuild=true),rebuild&&(url=useRel?"":curr_scheme+orig_host,path&&path[0]!=="/"&&(url+="/"),url+=path),url}return this.getFinalUrl(useRel,mod,url)}return prefix=this.startsWithOneOf(url,this.BAD_PREFIXES),prefix?this.getFinalUrl(useRel,mod,this.extractOriginalURL(url)):this.isHostUrl(url)&&!this.startsWith(url,originalLoc.host+"/")?this.getFinalUrl(useRel,mod,this.wb_orig_scheme+url):url},Wombat.prototype.rewriteUrl=function(url,useRel,mod,doc){var rewritten=this.rewriteUrl_(url,useRel,mod,doc);return this.debug_rw&&(url===rewritten?console.log("NOT REWRITTEN "+url):console.log("REWRITE: "+url+" -> "+rewritten)),rewritten},Wombat.prototype.performAttributeRewrite=function(elem,name,value,absUrlOnly){switch(name){case"innerHTML":case"outerHTML":return this.rewriteHtml(value);case"filter":return this.rewriteInlineStyle(value);case"style":return this.rewriteStyle(value);case"srcset":return this.rewriteSrcset(value,elem);}if(absUrlOnly&&!this.startsWithOneOf(value,this.VALID_PREFIXES))return value;var mod=this.rwModForElement(elem,name);return this.wbUseAFWorker&&this.WBAutoFetchWorker&&this.isSavedDataSrcSrcset(elem)&&this.WBAutoFetchWorker.preserveDataSrcset(elem),this.rewriteUrl(value,false,mod,elem.ownerDocument)},Wombat.prototype.rewriteAttr=function(elem,name,absUrlOnly){var changed=false;if(!elem||!elem.getAttribute||elem._no_rewrite||elem["_"+name])return changed;var value=this.wb_getAttribute.call(elem,name);if(!value||this.startsWith(value,"javascript:"))return changed;var new_value=this.performAttributeRewrite(elem,name,value,absUrlOnly);return new_value!==value&&(this.removeWBOSRC(elem),this.wb_setAttribute.call(elem,name,new_value),changed=true),changed},Wombat.prototype.noExceptRewriteStyle=function(style){try{return this.rewriteStyle(style)}catch(e){return style}},Wombat.prototype.rewriteStyle=function(style){if(!style)return style;var value=style;return typeof style==="object"&&(value=style.toString()),typeof value==="string"?value.replace(this.STYLE_REGEX,this.styleReplacer).replace(this.IMPORT_REGEX,this.styleReplacer).replace(this.no_wombatRe,""):value},Wombat.prototype.rewriteSrcset=function(value,elem){if(!value)return"";for(var split=value.split(this.srcsetRe),values=[],mod=this.rwModForElement(elem,"srcset"),i=0;i=0){var JS="javascript:";new_value="javascript:window.parent._wb_wombat.initNewWindowWombat(window);"+value.substr(11)}return new_value||(new_value=this.rewriteUrl(value,false,this.rwModForElement(elem,attrName))),new_value!==value&&(this.wb_setAttribute.call(elem,attrName,new_value),true)},Wombat.prototype.rewriteScript=function(elem){if(elem.hasAttribute("src")||!elem.textContent||!this.$wbwindow.Proxy)return this.rewriteAttr(elem,"src");if(this.skipWrapScriptBasedOnType(elem.type))return false;var text=elem.textContent.trim();return!this.skipWrapScriptTextBasedOnText(text)&&(elem.textContent=this.wrapScriptTextJsProxy(text),true)},Wombat.prototype.rewriteSVGElem=function(elem){var changed=this.rewriteAttr(elem,"filter");return changed=this.rewriteAttr(elem,"style")||changed,changed=this.rewriteAttr(elem,"xlink:href")||changed,changed=this.rewriteAttr(elem,"href")||changed,changed=this.rewriteAttr(elem,"src")||changed,changed},Wombat.prototype.rewriteElem=function(elem){var changed=false;if(!elem)return changed;if(elem instanceof SVGElement)changed=this.rewriteSVGElem(elem);else switch(elem.tagName){case"META":var maybeCSP=this.wb_getAttribute.call(elem,"http-equiv");maybeCSP&&maybeCSP.toLowerCase()==="content-security-policy"&&(this.wb_setAttribute.call(elem,"http-equiv","_"+maybeCSP),changed=true);break;case"STYLE":var new_content=this.rewriteStyle(elem.textContent);elem.textContent!==new_content&&(elem.textContent=new_content,changed=true,this.wbUseAFWorker&&this.WBAutoFetchWorker&&elem.sheet!=null&&this.WBAutoFetchWorker.deferredSheetExtraction(elem.sheet));break;case"LINK":changed=this.rewriteAttr(elem,"href"),this.wbUseAFWorker&&elem.rel==="stylesheet"&&this._addEventListener(elem,"load",this.utilFns.wbSheetMediaQChecker);break;case"IMG":changed=this.rewriteAttr(elem,"src"),changed=this.rewriteAttr(elem,"srcset")||changed,changed=this.rewriteAttr(elem,"style")||changed,this.wbUseAFWorker&&this.WBAutoFetchWorker&&elem.dataset.srcset&&this.WBAutoFetchWorker.preserveDataSrcset(elem);break;case"OBJECT":if(this.wb_info.isSW&&elem.parentElement&&elem.getAttribute("type")==="application/pdf"){for(var iframe=this.$wbwindow.document.createElement("IFRAME"),i=0;i0;)for(var child,children=rewriteQ.shift(),i=0;i"+rwString+"","text/html");if(!inner_doc||!this.nodeHasChildren(inner_doc.head)||!inner_doc.head.children[0].content)return rwString;var template=inner_doc.head.children[0];if(template._no_rewrite=true,this.recurseRewriteElem(template.content)){var new_html=template.innerHTML;if(checkEndTag){var first_elem=template.content.children&&template.content.children[0];if(first_elem){var end_tag="";this.endsWith(new_html,end_tag)&&!this.endsWith(rwString.toLowerCase(),end_tag)&&(new_html=new_html.substring(0,new_html.length-end_tag.length))}else if(rwString[0]!=="<"||rwString[rwString.length-1]!==">")return this.write_buff+=rwString,undefined}return new_html}return rwString},Wombat.prototype.rewriteHtmlFull=function(string,checkEndTag){var inner_doc=new DOMParser().parseFromString(string,"text/html");if(!inner_doc)return string;for(var changed=false,i=0;i=0)inner_doc.documentElement._no_rewrite=true,new_html=this.reconstructDocType(inner_doc.doctype)+inner_doc.documentElement.outerHTML;else{inner_doc.head._no_rewrite=true,inner_doc.body._no_rewrite=true;var headHasKids=this.nodeHasChildren(inner_doc.head),bodyHasKids=this.nodeHasChildren(inner_doc.body);if(new_html=(headHasKids?inner_doc.head.outerHTML:"")+(bodyHasKids?inner_doc.body.outerHTML:""),checkEndTag)if(inner_doc.all.length>3){var end_tag="";this.endsWith(new_html,end_tag)&&!this.endsWith(string.toLowerCase(),end_tag)&&(new_html=new_html.substring(0,new_html.length-end_tag.length))}else if(string[0]!=="<"||string[string.length-1]!==">")return void(this.write_buff+=string);new_html=this.reconstructDocType(inner_doc.doctype)+new_html}return new_html}return string},Wombat.prototype.rewriteInlineStyle=function(orig){var decoded;try{decoded=decodeURIComponent(orig)}catch(e){decoded=orig}if(decoded!==orig){var parts=this.rewriteStyle(decoded).split(",",2);return parts[0]+","+encodeURIComponent(parts[1])}return this.rewriteStyle(orig)},Wombat.prototype.rewriteCookie=function(cookie){var wombat=this,rwCookie=cookie.replace(this.wb_abs_prefix,"").replace(this.wb_rel_prefix,"");return rwCookie=rwCookie.replace(this.cookie_domain_regex,function(m,m1){var message={domain:m1,cookie:rwCookie,wb_type:"cookie"};return wombat.sendTopMessage(message,true),wombat.$wbwindow.location.hostname.indexOf(".")>=0&&!wombat.IP_RX.test(wombat.$wbwindow.location.hostname)?"Domain=."+wombat.$wbwindow.location.hostname:""}).replace(this.cookie_path_regex,function(m,m1){var rewritten=wombat.rewriteUrl(m1);return rewritten.indexOf(wombat.wb_curr_host)===0&&(rewritten=rewritten.substring(wombat.wb_curr_host.length)),"Path="+rewritten}),wombat.$wbwindow.location.protocol!=="https:"&&(rwCookie=rwCookie.replace("secure","")),rwCookie.replace(",|",",")},Wombat.prototype.rewriteWorker=function(workerUrl){if(!workerUrl)return workerUrl;var isBlob=workerUrl.indexOf("blob:")===0,isJS=workerUrl.indexOf("javascript:")===0;if(!isBlob&&!isJS){if(!this.startsWithOneOf(workerUrl,this.VALID_PREFIXES)&&!this.startsWith(workerUrl,"/")&&!this.startsWithOneOf(workerUrl,this.BAD_PREFIXES)){var rurl=this.resolveRelUrl(workerUrl,this.$wbwindow.document);return this.rewriteUrl(rurl,false,"wkr_",this.$wbwindow.document)}return this.rewriteUrl(workerUrl,false,"wkr_",this.$wbwindow.document)}var workerCode=isJS?workerUrl.replace("javascript:",""):null;if(isBlob){var x=new XMLHttpRequest;this.utilFns.XHRopen.call(x,"GET",workerUrl,false),this.utilFns.XHRsend.call(x),workerCode=x.responseText.replace(this.workerBlobRe,"").replace(this.rmCheckThisInjectRe,"this")}if(this.wb_info.static_prefix||this.wb_info.ww_rw_script){var originalURL=this.$wbwindow.document.baseURI,ww_rw=this.wb_info.ww_rw_script||this.wb_info.static_prefix+"wombatWorkers.js",rw="(function() { self.importScripts('"+ww_rw+"'); new WBWombat({'prefix': '"+this.wb_abs_prefix+"', 'prefixMod': '"+this.wb_abs_prefix+"wkrf_/', 'originalURL': '"+originalURL+"'}); })();";workerCode=rw+workerCode}var blob=new Blob([workerCode],{type:"application/javascript"});return URL.createObjectURL(blob)},Wombat.prototype.rewriteTextNodeFn=function(fnThis,originalFn,argsObj){var args,deproxiedThis=this.proxyToObj(fnThis);if(argsObj.length>0&&deproxiedThis.parentElement&&deproxiedThis.parentElement.tagName==="STYLE"){args=new Array(argsObj.length);var dataIndex=argsObj.length-1;dataIndex===2?(args[0]=argsObj[0],args[1]=argsObj[1]):dataIndex===1&&(args[0]=argsObj[0]),args[dataIndex]=this.rewriteStyle(argsObj[dataIndex])}else args=argsObj;return originalFn.__WB_orig_apply?originalFn.__WB_orig_apply(deproxiedThis,args):originalFn.apply(deproxiedThis,args)},Wombat.prototype.rewriteDocWriteWriteln=function(fnThis,originalFn,argsObj){var string,thisObj=this.proxyToObj(fnThis),argLen=argsObj.length;if(argLen===0)return originalFn.call(thisObj);string=argLen===1?argsObj[0]:Array.prototype.join.call(argsObj,"");var new_buff=this.rewriteHtml(string,true),res=originalFn.call(thisObj,new_buff);return this.initNewWindowWombat(thisObj.defaultView),res},Wombat.prototype.rewriteChildNodeFn=function(fnThis,originalFn,argsObj){var thisObj=this.proxyToObj(fnThis);if(argsObj.length===0)return originalFn.call(thisObj);var newArgs=this.rewriteElementsInArguments(argsObj);return originalFn.__WB_orig_apply?originalFn.__WB_orig_apply(thisObj,newArgs):originalFn.apply(thisObj,newArgs)},Wombat.prototype.rewriteInsertAdjHTMLOrElemArgs=function(fnThis,originalFn,position,textOrElem,rwHTML){var fnThisObj=this.proxyToObj(fnThis);return fnThisObj._no_rewrite?originalFn.call(fnThisObj,position,textOrElem):rwHTML?originalFn.call(fnThisObj,position,this.rewriteHtml(textOrElem)):(this.rewriteElemComplete(textOrElem),originalFn.call(fnThisObj,position,textOrElem))},Wombat.prototype.rewriteSetTimeoutInterval=function(fnThis,originalFn,argsObj){var rw=this.isString(argsObj[0]),args=rw?new Array(argsObj.length):argsObj;if(rw){args[0]=this.$wbwindow.Proxy?this.wrapScriptTextJsProxy(argsObj[0]):argsObj[0].replace(/\blocation\b/g,"WB_wombat_$&");for(var i=1;i0&&cssStyleValueOverride(this.$wbwindow.CSSStyleValue,"parse"),this.$wbwindow.CSSStyleValue.parseAll&&this.$wbwindow.CSSStyleValue.parseAll.toString().indexOf("[native code]")>0&&cssStyleValueOverride(this.$wbwindow.CSSStyleValue,"parseAll")}if(this.$wbwindow.CSSKeywordValue&&this.$wbwindow.CSSKeywordValue.prototype){var oCSSKV=this.$wbwindow.CSSKeywordValue;this.$wbwindow.CSSKeywordValue=function(CSSKeywordValue_){return function CSSKeywordValue(cssValue){return wombat.domConstructorErrorChecker(this,"CSSKeywordValue",arguments),new CSSKeywordValue_(wombat.rewriteStyle(cssValue))}}(this.$wbwindow.CSSKeywordValue),this.$wbwindow.CSSKeywordValue.prototype=oCSSKV.prototype,Object.defineProperty(this.$wbwindow.CSSKeywordValue.prototype,"constructor",{value:this.$wbwindow.CSSKeywordValue}),addToStringTagToClass(this.$wbwindow.CSSKeywordValue,"CSSKeywordValue")}if(this.$wbwindow.StylePropertyMap&&this.$wbwindow.StylePropertyMap.prototype){var originalSet=this.$wbwindow.StylePropertyMap.prototype.set;this.$wbwindow.StylePropertyMap.prototype.set=function set(){if(arguments.length<=1)return originalSet.__WB_orig_apply?originalSet.__WB_orig_apply(this,arguments):originalSet.apply(this,arguments);var newArgs=new Array(arguments.length);newArgs[0]=arguments[0];for(var i=1;i")&&(array[0]=wombat.rewriteHtml(array[0]),options.type="text/html"),new Blob_(array,options)}}(this.$wbwindow.Blob),this.$wbwindow.Blob.prototype=orig_blob.prototype}},Wombat.prototype.initDocTitleOverride=function(){var orig_get_title=this.getOrigGetter(this.$wbwindow.document,"title"),orig_set_title=this.getOrigSetter(this.$wbwindow.document,"title"),wombat=this,set_title=function title(value){var res=orig_set_title.call(this,value),message={wb_type:"title",title:value};return wombat.sendTopMessage(message),res};this.defProp(this.$wbwindow.document,"title",set_title,orig_get_title)},Wombat.prototype.initFontFaceOverride=function(){if(this.$wbwindow.FontFace){var wombat=this,origFontFace=this.$wbwindow.FontFace;this.$wbwindow.FontFace=function(FontFace_){return function FontFace(family,source,descriptors){wombat.domConstructorErrorChecker(this,"FontFace",arguments,2);var rwSource=source;return source!=null&&(typeof source==="string"?rwSource=wombat.rewriteInlineStyle(source):rwSource=wombat.rewriteInlineStyle(source.toString())),new FontFace_(family,rwSource,descriptors)}}(this.$wbwindow.FontFace),this.$wbwindow.FontFace.prototype=origFontFace.prototype,Object.defineProperty(this.$wbwindow.FontFace.prototype,"constructor",{value:this.$wbwindow.FontFace}),addToStringTagToClass(this.$wbwindow.FontFace,"FontFace")}},Wombat.prototype.initFixedRatio=function(){try{this.$wbwindow.devicePixelRatio=1}catch(e){}if(Object.defineProperty)try{Object.defineProperty(this.$wbwindow,"devicePixelRatio",{value:1,writable:false})}catch(e){}},Wombat.prototype.initPaths=function(wbinfo){wbinfo.wombat_opts=wbinfo.wombat_opts||{},Object.assign(this.wb_info,wbinfo),this.wb_opts=wbinfo.wombat_opts,this.wb_replay_prefix=wbinfo.prefix,this.wb_is_proxy=wbinfo.proxy_magic||!this.wb_replay_prefix,this.wb_info.top_host=this.wb_info.top_host||"*",this.wb_curr_host=this.$wbwindow.location.protocol+"//"+this.$wbwindow.location.host,this.wb_info.wombat_opts=this.wb_info.wombat_opts||{},this.wb_orig_scheme=wbinfo.wombat_scheme+"://",this.wb_orig_origin=this.wb_orig_scheme+wbinfo.wombat_host,this.wb_abs_prefix=this.wb_replay_prefix,this.wb_capture_date_part=!wbinfo.is_live&&wbinfo.wombat_ts?"/"+wbinfo.wombat_ts+"/":"",this.initBadPrefixes(this.wb_replay_prefix),this.initCookiePreset()},Wombat.prototype.initSeededRandom=function(seed){this.$wbwindow.Math.seed=parseInt(seed);var wombat=this;this.$wbwindow.Math.random=function random(){return wombat.$wbwindow.Math.seed=(wombat.$wbwindow.Math.seed*9301+49297)%233280,wombat.$wbwindow.Math.seed/233280}},Wombat.prototype.initHistoryOverrides=function(){this.overrideHistoryFunc("pushState"),this.overrideHistoryFunc("replaceState");var wombat=this;this.$wbwindow.addEventListener("popstate",function(event){wombat.sendHistoryUpdate(wombat.$wbwindow.WB_wombat_location.href,wombat.$wbwindow.document.title)})},Wombat.prototype.initCookiePreset=function(){if(this.wb_info.presetCookie)for(var splitCookies=this.wb_info.presetCookie.split(";"),i=0;i0?"&":"?")+value.toString(),value=null):contentType==="application/json"||contentType==="text/plain"?(this.__WB_xhr_open_arguments[0]="GET",this.__WB_xhr_open_arguments[1]+=(this.__WB_xhr_open_arguments[1].indexOf("?")>0?"&":"?")+jsonToQueryString(value),value=null):wombat.startsWith(contentType,"multipart/form-data")&&(this.__WB_xhr_open_arguments[0]="GET",this.__WB_xhr_open_arguments[1]+=(this.__WB_xhr_open_arguments[1].indexOf("?")>0?"&":"?")+mfdToQueryString(value,contentType))}if(this.__WB_xhr_open_arguments.length>2&&(this.__WB_xhr_open_arguments[2]=true),this._no_rewrite||(this.__WB_xhr_open_arguments[1]=wombat.rewriteUrl(this.__WB_xhr_open_arguments[1])),origOpen.apply(this,this.__WB_xhr_open_arguments),!wombat.startsWith(this.__WB_xhr_open_arguments[1],"data:")){for(const[name,value]of this.__WB_xhr_headers.entries())origSetRequestHeader.call(this,name,value);origSetRequestHeader.call(this,"X-Pywb-Requested-With","XMLHttpRequest")}origSend.call(this,value)}}if(this.$wbwindow.fetch){var orig_fetch=this.$wbwindow.fetch;this.$wbwindow.fetch=function fetch(input,init_opts){var rwInput=input,inputType=typeof input;if(inputType==="string")rwInput=wombat.rewriteUrl(input);else if(inputType==="object"&&input.url){var new_url=wombat.rewriteUrl(input.url);new_url!==input.url&&(rwInput=new Request(new_url,init_opts))}else inputType==="object"&&input.href&&(rwInput=wombat.rewriteUrl(input.href));if(init_opts||(init_opts={}),init_opts.credentials===undefined)try{init_opts.credentials="include"}catch(e){}return orig_fetch.call(wombat.proxyToObj(this),rwInput,init_opts)}}if(this.$wbwindow.Request&&this.$wbwindow.Request.prototype){var orig_request=this.$wbwindow.Request;this.$wbwindow.Request=function(Request_){return function Request(input,init_opts){wombat.domConstructorErrorChecker(this,"Request",arguments);var newInitOpts=init_opts||{},newInput=input,inputType=typeof input;switch(inputType){case"string":newInput=wombat.rewriteUrl(input);break;case"object":if(newInput=input,input.url){var new_url=wombat.rewriteUrl(input.url);new_url!==input.url&&(newInput=new Request_(new_url,input))}else input.href&&(newInput=wombat.rewriteUrl(input.toString(),true));}return newInitOpts.credentials="include",new Request_(newInput,newInitOpts)}}(this.$wbwindow.Request),this.$wbwindow.Request.prototype=orig_request.prototype,Object.defineProperty(this.$wbwindow.Request.prototype,"constructor",{value:this.$wbwindow.Request})}if(this.$wbwindow.Response&&this.$wbwindow.Response.prototype){var originalRedirect=this.$wbwindow.Response.prototype.redirect;this.$wbwindow.Response.prototype.redirect=function redirect(url,status){var rwURL=wombat.rewriteUrl(url,true,null,wombat.$wbwindow.document);return originalRedirect.call(this,rwURL,status)}}if(this.$wbwindow.EventSource&&this.$wbwindow.EventSource.prototype){var origEventSource=this.$wbwindow.EventSource;this.$wbwindow.EventSource=function(EventSource_){return function EventSource(url,configuration){wombat.domConstructorErrorChecker(this,"EventSource",arguments);var rwURL=url;return url!=null&&(rwURL=wombat.rewriteUrl(url)),new EventSource_(rwURL,configuration)}}(this.$wbwindow.EventSource),this.$wbwindow.EventSource.prototype=origEventSource.prototype,Object.defineProperty(this.$wbwindow.EventSource.prototype,"constructor",{value:this.$wbwindow.EventSource}),addToStringTagToClass(this.$wbwindow.EventSource,"EventSource")}if(this.$wbwindow.WebSocket&&this.$wbwindow.WebSocket.prototype){var origWebSocket=this.$wbwindow.WebSocket;this.$wbwindow.WebSocket=function(WebSocket_){return function WebSocket(url,configuration){wombat.domConstructorErrorChecker(this,"WebSocket",arguments);var rwURL=url;return url!=null&&(rwURL=wombat.rewriteWSURL(url)),new WebSocket_(rwURL,configuration)}}(this.$wbwindow.WebSocket),this.$wbwindow.WebSocket.prototype=origWebSocket.prototype,Object.defineProperty(this.$wbwindow.WebSocket.prototype,"constructor",{value:this.$wbwindow.WebSocket}),addToStringTagToClass(this.$wbwindow.WebSocket,"WebSocket")}},Wombat.prototype.initElementGetSetAttributeOverride=function(){if(!this.wb_opts.skip_setAttribute&&this.$wbwindow.Element&&this.$wbwindow.Element.prototype){var wombat=this,ElementProto=this.$wbwindow.Element.prototype;if(ElementProto.setAttribute){var orig_setAttribute=ElementProto.setAttribute;ElementProto._orig_setAttribute=orig_setAttribute,ElementProto.setAttribute=function setAttribute(name,value){var rwValue=value;if(name&&typeof rwValue==="string"){var lowername=name.toLowerCase();if(this.tagName==="LINK"&&lowername==="href"&&rwValue.indexOf("data:text/css")===0)rwValue=wombat.rewriteInlineStyle(value);else if(lowername==="style")rwValue=wombat.rewriteStyle(value);else if(lowername==="srcset")rwValue=wombat.rewriteSrcset(value,this);else{var shouldRW=wombat.shouldRewriteAttr(this.tagName,lowername);shouldRW&&(wombat.removeWBOSRC(this),!this._no_rewrite&&(rwValue=wombat.rewriteUrl(value,false,wombat.rwModForElement(this,lowername))))}}return orig_setAttribute.call(this,name,rwValue)}}if(ElementProto.getAttribute){var orig_getAttribute=ElementProto.getAttribute;this.wb_getAttribute=orig_getAttribute,ElementProto.getAttribute=function getAttribute(name){var result=orig_getAttribute.call(this,name);if(result===null)return result;var lowerName=name;if(name&&(lowerName=name.toLowerCase()),wombat.shouldRewriteAttr(this.tagName,lowerName)){var maybeWBOSRC=wombat.retrieveWBOSRC(this);return maybeWBOSRC?maybeWBOSRC:wombat.extractOriginalURL(result)}return wombat.startsWith(lowerName,"data-")&&wombat.startsWithOneOf(result,wombat.wb_prefixes)?wombat.extractOriginalURL(result):result}}}},Wombat.prototype.initSvgImageOverrides=function(){if(this.$wbwindow.SVGImageElement){var svgImgProto=this.$wbwindow.SVGImageElement.prototype,orig_getAttr=svgImgProto.getAttribute,orig_getAttrNS=svgImgProto.getAttributeNS,orig_setAttr=svgImgProto.setAttribute,orig_setAttrNS=svgImgProto.setAttributeNS,wombat=this;svgImgProto.getAttribute=function getAttribute(name){var value=orig_getAttr.call(this,name);return name.indexOf("xlink:href")>=0||name==="href"?wombat.extractOriginalURL(value):value},svgImgProto.getAttributeNS=function getAttributeNS(ns,name){var value=orig_getAttrNS.call(this,ns,name);return name.indexOf("xlink:href")>=0||name==="href"?wombat.extractOriginalURL(value):value},svgImgProto.setAttribute=function setAttribute(name,value){var rwValue=value;return(name.indexOf("xlink:href")>=0||name==="href")&&(rwValue=wombat.rewriteUrl(value)),orig_setAttr.call(this,name,rwValue)},svgImgProto.setAttributeNS=function setAttributeNS(ns,name,value){var rwValue=value;return(name.indexOf("xlink:href")>=0||name==="href")&&(rwValue=wombat.rewriteUrl(value)),orig_setAttrNS.call(this,ns,name,rwValue)}}},Wombat.prototype.initCreateElementNSFix=function(){if(this.$wbwindow.document.createElementNS&&this.$wbwindow.Document.prototype.createElementNS){var orig_createElementNS=this.$wbwindow.document.createElementNS,wombat=this,createElementNS=function createElementNS(namespaceURI,qualifiedName){return orig_createElementNS.call(wombat.proxyToObj(this),wombat.extractOriginalURL(namespaceURI),qualifiedName)};this.$wbwindow.Document.prototype.createElementNS=createElementNS,this.$wbwindow.document.createElementNS=createElementNS}},Wombat.prototype.initInsertAdjacentElementHTMLOverrides=function(){var Element=this.$wbwindow.Element;if(Element&&Element.prototype){var elementProto=Element.prototype,rewriteFn=this.rewriteInsertAdjHTMLOrElemArgs;if(elementProto.insertAdjacentHTML){var origInsertAdjacentHTML=elementProto.insertAdjacentHTML;elementProto.insertAdjacentHTML=function insertAdjacentHTML(position,text){return rewriteFn(this,origInsertAdjacentHTML,position,text,true)}}if(elementProto.insertAdjacentElement){var origIAdjElem=elementProto.insertAdjacentElement;elementProto.insertAdjacentElement=function insertAdjacentElement(position,element){return rewriteFn(this,origIAdjElem,position,element,false)}}}},Wombat.prototype.initDomOverride=function(){var Node=this.$wbwindow.Node;if(Node&&Node.prototype){var rewriteFn=this.rewriteNodeFuncArgs;if(Node.prototype.appendChild){var originalAppendChild=Node.prototype.appendChild;Node.prototype.appendChild=function appendChild(newNode,oldNode){return rewriteFn(this,originalAppendChild,newNode,oldNode)}}if(Node.prototype.insertBefore){var originalInsertBefore=Node.prototype.insertBefore;Node.prototype.insertBefore=function insertBefore(newNode,oldNode){return rewriteFn(this,originalInsertBefore,newNode,oldNode)}}if(Node.prototype.replaceChild){var originalReplaceChild=Node.prototype.replaceChild;Node.prototype.replaceChild=function replaceChild(newNode,oldNode){return rewriteFn(this,originalReplaceChild,newNode,oldNode)}}this.overridePropToProxy(Node.prototype,"ownerDocument"),this.overridePropToProxy(this.$wbwindow.HTMLHtmlElement.prototype,"parentNode"),this.overridePropToProxy(this.$wbwindow.Event.prototype,"target")}this.$wbwindow.Element&&this.$wbwindow.Element.prototype&&(this.overrideParentNodeAppendPrepend(this.$wbwindow.Element),this.overrideChildNodeInterface(this.$wbwindow.Element,false)),this.$wbwindow.DocumentFragment&&this.$wbwindow.DocumentFragment.prototype&&this.overrideParentNodeAppendPrepend(this.$wbwindow.DocumentFragment)},Wombat.prototype.initDocOverrides=function($document){if(Object.defineProperty){this.overrideReferrer($document),this.defGetterProp($document,"origin",function origin(){return this.WB_wombat_location.origin}),this.defGetterProp(this.$wbwindow,"origin",function origin(){return this.WB_wombat_location.origin});var wombat=this,domain_setter=function domain(val){var loc=this.WB_wombat_location;loc&&wombat.endsWith(loc.hostname,val)&&(this.__wb_domain=val)},domain_getter=function domain(){return this.__wb_domain||this.WB_wombat_location.hostname};this.defProp($document,"domain",domain_setter,domain_getter)}},Wombat.prototype.initDocWriteOpenCloseOverride=function(){if(this.$wbwindow.DOMParser){var DocumentProto=this.$wbwindow.Document.prototype,$wbDocument=this.$wbwindow.document,docWriteWritelnRWFn=this.rewriteDocWriteWriteln,orig_doc_write=$wbDocument.write,new_write=function write(){return docWriteWritelnRWFn(this,orig_doc_write,arguments)};$wbDocument.write=new_write,DocumentProto.write=new_write;var orig_doc_writeln=$wbDocument.writeln,new_writeln=function writeln(){return docWriteWritelnRWFn(this,orig_doc_writeln,arguments)};$wbDocument.writeln=new_writeln,DocumentProto.writeln=new_writeln;var wombat=this,orig_doc_open=$wbDocument.open,new_open=function open(){var res,thisObj=wombat.proxyToObj(this);if(arguments.length===3){var rwUrl=wombat.rewriteUrl(arguments[0],false,"mp_");res=orig_doc_open.call(thisObj,rwUrl,arguments[1],arguments[2]),wombat.initNewWindowWombat(res,arguments[0])}else res=orig_doc_open.call(thisObj),wombat.initNewWindowWombat(thisObj.defaultView);return res};$wbDocument.open=new_open,DocumentProto.open=new_open;var originalClose=$wbDocument.close,newClose=function close(){var thisObj=wombat.proxyToObj(this);return wombat.initNewWindowWombat(thisObj.defaultView),originalClose.__WB_orig_apply?originalClose.__WB_orig_apply(thisObj,arguments):originalClose.apply(thisObj,arguments)};$wbDocument.close=newClose,DocumentProto.close=newClose;var oBodyGetter=this.getOrigGetter(DocumentProto,"body"),oBodySetter=this.getOrigSetter(DocumentProto,"body");oBodyGetter&&oBodySetter&&this.defProp(DocumentProto,"body",function body(newBody){return newBody&&(newBody instanceof HTMLBodyElement||newBody instanceof HTMLFrameSetElement)&&wombat.rewriteElemComplete(newBody),oBodySetter.call(wombat.proxyToObj(this),newBody)},oBodyGetter)}},Wombat.prototype.initIframeWombat=function(iframe){var win;win=iframe._get_contentWindow?iframe._get_contentWindow.call(iframe):iframe.contentWindow;try{if(!win||win===this.$wbwindow||win._skip_wombat||win._wb_wombat)return}catch(e){return}var src=iframe.src;this.initNewWindowWombat(win,src)},Wombat.prototype.initNewWindowWombat=function(win,src){var fullWombat=false;if(win&&!win._wb_wombat){if((!src||src===""||this.startsWithOneOf(src,["about:blank","javascript:"]))&&(fullWombat=true),!fullWombat&&this.wb_info.isSW){var origURL=this.extractOriginalURL(src);(origURL==="about:blank"||origURL.startsWith("srcdoc:")||origURL.startsWith("blob:"))&&(fullWombat=true)}if(fullWombat){var newInfo={};Object.assign(newInfo,this.wb_info);var wombat=new Wombat(win,newInfo);win._wb_wombat=wombat.wombatInit()}else this.initProtoPmOrigin(win),this.initPostMessageOverride(win),this.initMessageEventOverride(win),this.initCheckThisFunc(win)}},Wombat.prototype.initTimeoutIntervalOverrides=function(){var rewriteFn=this.rewriteSetTimeoutInterval;if(this.$wbwindow.setTimeout&&!this.$wbwindow.setTimeout.__$wbpatched$__){var originalSetTimeout=this.$wbwindow.setTimeout;this.$wbwindow.setTimeout=function setTimeout(){return rewriteFn(this,originalSetTimeout,arguments)},this.$wbwindow.setTimeout.__$wbpatched$__=true}if(this.$wbwindow.setInterval&&!this.$wbwindow.setInterval.__$wbpatched$__){var originalSetInterval=this.$wbwindow.setInterval;this.$wbwindow.setInterval=function setInterval(){return rewriteFn(this,originalSetInterval,arguments)},this.$wbwindow.setInterval.__$wbpatched$__=true}},Wombat.prototype.initWorkerOverrides=function(){var wombat=this;if(this.$wbwindow.Worker&&!this.$wbwindow.Worker._wb_worker_overriden){var orig_worker=this.$wbwindow.Worker;this.$wbwindow.Worker=function(Worker_){return function Worker(url,options){return wombat.domConstructorErrorChecker(this,"Worker",arguments),new Worker_(wombat.rewriteWorker(url),options)}}(orig_worker),this.$wbwindow.Worker.prototype=orig_worker.prototype,Object.defineProperty(this.$wbwindow.Worker.prototype,"constructor",{value:this.$wbwindow.Worker}),this.$wbwindow.Worker._wb_worker_overriden=true}if(this.$wbwindow.SharedWorker&&!this.$wbwindow.SharedWorker.__wb_sharedWorker_overriden){var oSharedWorker=this.$wbwindow.SharedWorker;this.$wbwindow.SharedWorker=function(SharedWorker_){return function SharedWorker(url,options){return wombat.domConstructorErrorChecker(this,"SharedWorker",arguments),new SharedWorker_(wombat.rewriteWorker(url),options)}}(oSharedWorker),this.$wbwindow.SharedWorker.prototype=oSharedWorker.prototype,Object.defineProperty(this.$wbwindow.SharedWorker.prototype,"constructor",{value:this.$wbwindow.SharedWorker}),this.$wbwindow.SharedWorker.__wb_sharedWorker_overriden=true}if(this.$wbwindow.ServiceWorkerContainer&&this.$wbwindow.ServiceWorkerContainer.prototype&&this.$wbwindow.ServiceWorkerContainer.prototype.register){var orig_register=this.$wbwindow.ServiceWorkerContainer.prototype.register;this.$wbwindow.ServiceWorkerContainer.prototype.register=function register(scriptURL,options){var newScriptURL=new URL(scriptURL,wombat.$wbwindow.document.baseURI).href,mod=wombat.getPageUnderModifier();return options&&options.scope?options.scope=wombat.rewriteUrl(options.scope,false,mod):options={scope:wombat.rewriteUrl("/",false,mod)},orig_register.call(this,wombat.rewriteUrl(newScriptURL,false,"sw_"),options)}}if(this.$wbwindow.Worklet&&this.$wbwindow.Worklet.prototype&&this.$wbwindow.Worklet.prototype.addModule&&!this.$wbwindow.Worklet.__wb_workerlet_overriden){var oAddModule=this.$wbwindow.Worklet.prototype.addModule;this.$wbwindow.Worklet.prototype.addModule=function addModule(moduleURL,options){var rwModuleURL=wombat.rewriteUrl(moduleURL,false,"js_");return oAddModule.call(this,rwModuleURL,options)},this.$wbwindow.Worklet.__wb_workerlet_overriden=true}},Wombat.prototype.initLocOverride=function(loc,oSetter,oGetter){if(Object.defineProperty)for(var prop,i=0;i=0&&props.splice(foundInx,1);return props}})}catch(e){console.log(e)}},Wombat.prototype.initHashChange=function(){if(this.$wbwindow.__WB_top_frame){var wombat=this,receive_hash_change=function receive_hash_change(event){if(event.data&&event.data.from_top){var message=event.data.message;message.wb_type&&(message.wb_type!=="outer_hashchange"||wombat.$wbwindow.location.hash==message.hash||(wombat.$wbwindow.location.hash=message.hash))}},send_hash_change=function send_hash_change(){var message={wb_type:"hashchange",hash:wombat.$wbwindow.location.hash};wombat.sendTopMessage(message)};this.$wbwindow.addEventListener("message",receive_hash_change),this.$wbwindow.addEventListener("hashchange",send_hash_change)}},Wombat.prototype.initPostMessageOverride=function($wbwindow){if($wbwindow.postMessage&&!$wbwindow.__orig_postMessage){var orig=$wbwindow.postMessage,wombat=this;$wbwindow.__orig_postMessage=orig;var postmessage_rewritten=function postMessage(message,targetOrigin,transfer,from_top){var from,src_id,this_obj=wombat.proxyToObj(this);if(this_obj.__WB_source&&this_obj.__WB_source.WB_wombat_location){var source=this_obj.__WB_source;if(from=source.WB_wombat_location.origin,this_obj.__WB_win_id||(this_obj.__WB_win_id={},this_obj.__WB_counter=0),!source.__WB_id){var id=this_obj.__WB_counter;source.__WB_id=id+source.WB_wombat_location.href,this_obj.__WB_counter+=1}this_obj.__WB_win_id[source.__WB_id]=source,src_id=source.__WB_id,this_obj.__WB_source=undefined}else from=window.WB_wombat_location.origin;var to_origin=targetOrigin;to_origin===this_obj.location.origin&&(to_origin=from);var new_message={from:from,to_origin:to_origin,src_id:src_id,message:message,from_top:from_top};if(targetOrigin!=="*"){if(this_obj.location.origin==="null"||this_obj.location.origin==="")return;targetOrigin=this_obj.location.origin}return orig.call(this_obj,new_message,targetOrigin,transfer)};$wbwindow.postMessage=postmessage_rewritten,$wbwindow.Window.prototype.postMessage=postmessage_rewritten;var eventTarget=null;eventTarget=$wbwindow.EventTarget&&$wbwindow.EventTarget.prototype?$wbwindow.EventTarget.prototype:$wbwindow;var _oAddEventListener=eventTarget.addEventListener;eventTarget.addEventListener=function addEventListener(type,listener,useCapture){var rwListener,obj=wombat.proxyToObj(this);if(type==="message"?rwListener=wombat.message_listeners.add_or_get(listener,function(){return wrapEventListener(listener,obj,wombat)}):type==="storage"?wombat.storage_listeners.add_or_get(listener,function(){return wrapSameOriginEventListener(listener,obj)}):rwListener=listener,rwListener)return _oAddEventListener.call(obj,type,rwListener,useCapture)};var _oRemoveEventListener=eventTarget.removeEventListener;eventTarget.removeEventListener=function removeEventListener(type,listener,useCapture){var rwListener,obj=wombat.proxyToObj(this);if(type==="message"?rwListener=wombat.message_listeners.remove(listener):type==="storage"?wombat.storage_listeners.remove(listener):rwListener=listener,rwListener)return _oRemoveEventListener.call(obj,type,rwListener,useCapture)};var override_on_prop=function(onevent,wrapperFN){var orig_setter=wombat.getOrigSetter($wbwindow,onevent),setter=function(value){this["__orig_"+onevent]=value;var obj=wombat.proxyToObj(this),listener=value?wrapperFN(value,obj,wombat):value;return orig_setter.call(obj,listener)},getter=function(){return this["__orig_"+onevent]};wombat.defProp($wbwindow,onevent,setter,getter)};override_on_prop("onmessage",wrapEventListener),override_on_prop("onstorage",wrapSameOriginEventListener)}},Wombat.prototype.initMessageEventOverride=function($wbwindow){!$wbwindow.MessageEvent||$wbwindow.MessageEvent.prototype.__extended||(this.addEventOverride("target"),this.addEventOverride("srcElement"),this.addEventOverride("currentTarget"),this.addEventOverride("eventPhase"),this.addEventOverride("path"),this.overridePropToProxy($wbwindow.MessageEvent.prototype,"source"),$wbwindow.MessageEvent.prototype.__extended=true)},Wombat.prototype.initUIEventsOverrides=function(){this.overrideAnUIEvent("UIEvent"),this.overrideAnUIEvent("MouseEvent"),this.overrideAnUIEvent("TouchEvent"),this.overrideAnUIEvent("FocusEvent"),this.overrideAnUIEvent("KeyboardEvent"),this.overrideAnUIEvent("WheelEvent"),this.overrideAnUIEvent("InputEvent"),this.overrideAnUIEvent("CompositionEvent")},Wombat.prototype.initOpenOverride=function(){var orig=this.$wbwindow.open;this.$wbwindow.Window.prototype.open&&(orig=this.$wbwindow.Window.prototype.open);var wombat=this,open_rewritten=function open(strUrl,strWindowName,strWindowFeatures){var rwStrUrl=wombat.rewriteUrl(strUrl,false,""),res=orig.call(wombat.proxyToObj(this),rwStrUrl,strWindowName,strWindowFeatures);return wombat.initNewWindowWombat(res,strUrl),res};this.$wbwindow.open=open_rewritten,this.$wbwindow.Window.prototype.open&&(this.$wbwindow.Window.prototype.open=open_rewritten);for(var i=0;ifQ?9!IKXZF}BDy1b-gbQZi~Y1$X0FV& zNEJlHXc_6)ph$;GhPsDZhw`DA2p9Kv~e+Yq8GC< zbTJh%HMTb~<>P~Lc5yN_w1x7>+0l}oqv^2Sd8sRJ0dyDX0fnL4cN~qr0&5pQ6I4s( z5WABF@J{Z-&vP!XytpU$7zW;pze=Ns`h6I2@zi?Qr|-|Zn7B(hSDf9mR&Px6^|jU4 z_x*({-c8LFN5-$Jwed_;4s5!akXU|`fMD@e=z15eB zzj*f}mG!xg*Sd(mIJm|?s_y@J^7Co@F6p24)Ax(tcWTz>W9|0m>HYlU@^o*xw9P$@ z?Tx`=NVP!1iq5Fy+~ve;2>qiNdUP-U^M~K><2xVe^YMPIxcQk*9NP|E8`i}CWeVop zwg;|FRhRCL;Y{Jgg9Ek;Ex`lO;+jCW*+dMEW*zodh;svvX)_GDVed8N;Iu4R$)Y$03FtAW#@7-h@{5c_`83#pM=9q zAAK#Oy|RR1qf@yPE&|o8NP~e8`i|hpK zMxIY5IkXt!O7kqwQP4acC8$GHdN(-cap9_HXaa@*K^fCy0{x258Vg4z4xd20hYZkm zV2+wfNQy6eI%QcS#i2*egb7y7felf1$6!I7&~e%H^du0OXiar&B2+wCuBZ?SlYmbi zOGomu3Y1gJM~g_QyVdn1ly`+Hd9f0ex~lulaZz?m_lE0CVpCXm%duqzsV6lp`nl%|oHzhTbj5W=RJPJMuBq$lgtP<~=I?};pC~i7a?wCg zJlf{Uxqm#TliF)kR>Vm}t64Otz>sjyYA?KbKy&ep+V~;vA^Ja*SUOKJPexA|!ZHXV ziFem%ONv4KV}l@?3Jt+J9Ge^$Y$o)fHWWh*5HUu zN#$;4FO!?!B7cAhPCn5)2}NpaZ8oi4kFD%RAknB*GK9v3U5vD#8GekhKNCuFnBp2D zhpLmLl|k0o_5*M@Lu1W=!ydBJwQH2vJQM1m0W^$&jwhoyT(oOM08kb{;m2kc(Cju_zhMUKH!yH2wr3XF6 zoghb_7%+6TOqYbu3+*mcDkW3-J_?AJB%_pE${8NjRU0fXL(Kc*Md$48s&BSip`}(CLkv?eNRaKjC5yeju{5+&T7?RQ|1i@b90ebv7F;H9$b;Jg5 ze%t5~{3^EUL+$Ev)$y`=6_E+1fh?NxGjiWUM3iiYC{3<0#%ntXtlw9jWO4RZAtMw- z(&uWJ7)LTs9}DEPxKgE z<3099xCzmg8;7QSq3CD6vB&+R&~!EXjIUWJxZ-R6w^VJCc1E5XaFMCN(iuNXiv~x5 zsZI6{ctq=tj|J7o1z&Sc@iTy`RhJh$oMheTkZc=~2HhTt*}5;dO?A=ryv+;cmB$S( zYK>`7&KVEO@2VXS4<}mk15c~bt=$kGt z3qj$k+pu;lt=7V>A;i%+tIo)@lFP%D_lx+WT+HYuv0Zkp%rFN|v4D{^u!Fn+{1NIJ@jfr`nv7*9h8U7%V6N{x$p;UOR$#rb=`N*5OP8Z zSH`@~-26(W88Va3-QTmKtivlIPfOV)5hp^&J<`l%>XiogPm&FsAePW?NK+qUGgm8f z@N|_k_M$gGJ9HFzWRbE8Y-?OGrQL-ijyKk{jCvcZwl`;Ih zXc@&d3qEnG<#>x&e5$>9jqznRjb?|6@S98Zdbsh8W8X4vkym+Klut0T`_o8GIICp( z4DK+os%BAmS8dsZJ{np$%#5?gP#k-8|3u2L%P@=^*il}(cv?VK7>|HreP9ZhW&qLV z{hpOS=YYC|@je^Vi+P5@Mx`@&Ku})Mqh0OfoR7RFl~quWYoCFjDw6{Q2%*;=JM}uP zdv%D*(LgUGYpg$*_mOB;itz;Tb|oY4<(s}FSfrjN=(q;7N|1Z zpfl6RF|YR>Gl}~)Amvq1;u0OJLNi_S;1P>Buj%J7tf)8bi%-Z^oMY13Dhs!B8!+uOVkqCv;5iJE)O~?P zcIwbFj%gT~31)7Yl3a=+dU=B?xghz95r;#l3P$zL6b|+u88wh+T3!F#`zEr(PNSbe zUwRHu%2a-RfH=j&9xV`!T_$EY4*P94U@nI0eKY}qfGvjZCqgdgy8Fqm_$oL3qw_rQz>Med2)A^-HDc zX}FSMiYU3hR|)XYX-+Vk8DoZU-AOa39e@-!^X47t;(Wvxm;&0Wdck}4f;q@^Y#)SS{OBWX#reo%z`{7(E0 z6?&LmW1f9Hz=kJ?A{HVD?u^8N`E39RVRnv*O@1Y&C3=h)a;6k+g9Z+co{xSR={~c1 zlsa|f4@KFrTaV5F@*l>$c7OytdjRG#wdli}mjewlt!?nmjXR(#@1#Qv!`@|3g$%r> zR24m;qU1!3EODJyfuYm5#nL%+_xW-wIEd3hAa>aE+`|{GX7??6Y4X^Sw5G=h@gW~((hKX8KsPQhvcgawo-dltd4BvKV4-qy94J#elmFj|{`K^C z^9uEM&-(WRGdm;W->?7cko8|$Tekm0YdfPU8-K_K({rl+szXpgF_Hue0!9|;d}bR6 z=tbdmIaVX^ve>5|T_hpZm^)E#?x;JGat(M z_4V~KG{^7aUy3-Df9sD|dmFx+A9iyUw$$PMQ}c0uz{Rlhf#0VCBO~t4==Okqc=v!q zKj*Qr)bx5u?#*cU{`~c8=+p1Dm8ewu>CCa-%hYXUSoVfU%{8%zJESq8n1R2qE+x$JBKgpM*CVC-Xv3Dl z%Z(+H$vJ9HG7~$+-c@*_{kbR7DVmD)zmaYAHVX{^%}et{gZenej&ixjZ~dh~AW??T zMa_3iU6|c4dnwTGhRK@I%EvF6A7Z9;Dp2Zj98_fb1`1T~nL){f0(I9fFa3ptczNtO zu_)F#v_vDQNQbRyWOqeItyw1bSEV!iN2%$=;|{ z*bwez;#5QIKskzcYfcG`7g~4nAxZ&l#JgFaKxpHDk3KxKeQnbe$O!pV*`c^yPk%xf_< zXK!v}j;?3BL-hdFK#wYNSmKupS|V=qZV8H4O~2R*U!^M;aWcE6hpK@TC0jGxf*?`s z!`BlTFP9Sgs1%i_!y?$U)UMH}<7|{;;Up6{5|oogJsuMVBPD7Z%ETO-e^=)>WR_`^ z2bF;xnp=mNF14w9X(6nqnJf${aOZZ70LPBiFs2Aah@MtsPvuq-_!^bVanWX_u8U|V zAzV#xySl}N7bxq3T3FMworwmj-%xk6MNCney!RAT8MG7!E=2VaWk;eG;N)eT<{Xp! zz!_R-^hT38_;6R<{_H=W2ZtDDEKeBbuXBrCcc6MV&t=v*A3}9zLYGRS`({T;TI#L}mg62uD%%TN z|8$(aZI<7BCzh9^GsG^f4N31rQeDgq($H49mYaotfOJOKy@9JG($Lo zMd=Yb+~RdKdHz#~*IP}jzmrxUi0aL{@;q-zgKtxZXRVGqLAPe`*{D32WnIepfVka* z)Y^TLqGLcw(G2Jw-v%SWE9yKuPWN#H!Ocs>_2lHN+mfgae%7N=ta(jyF`L9fNDpW; z5c;lBY^QjsD^dy4B82AT%VzcgCQ=Op_jSrOWo!EDPLb&FvbMap{cx8BNh6$oQ^O) zqX!G*;8baL^g+6K=3b{ipm!N`=)a+kzd7M=x?p5wVE!NK;P@Bn;QT*OM@xom{1yR1 z*zFrCpSo5$CIdc_(B|-cVOuKEbNxjPz7l+DXZrUSP_S*I!S+sx7Ud-ZMjobK*g$po z&D??e7}qNEaxTbOY>*u0`_IGm-J9@BwAX82I)3=!F~hi?d(=5z*VNk0AqejH&BND5 zkxP{JpYe8Y0ci2?v{;!gaJzvJGB-HcP5*)@-5BJwiC2ha?=PTj-wq$H9QyEISOLpr z=pg;v1|SHhM#0GgA{lIaqaEuDfsFxp)K8g%Fq`aQ`C_MCaSgfQfWkP~*!#_rgfjM2 z7-^X9Z<^Q##8jyd!L=2f?u;xf*!w(9QiP8JG>wSWE*#$EkthRz@@PU=hZ?T7W?Etm z*X>E-phjE7l+mv3MlStVgPDf2(8@z86Yx%%(eqSk1C%%o^qKSAbf_^~bcyX?igd~a z5br8!xjfQ3Y6=yN0x7aNK6xpF!vcE)7sD` z$ft<7tQYT582ReiTh2UJ()2O;lkDj&=bsEzDo}KsVY)Yq-X?SPBe8djZv^y13A~zE z7r`Coh0mX2sp2_UyFwn<2NjKoQvv|P@tclP8@rk_N@;scUQE#y+{RpNW~>qUcaiq7 zw4NeZd6QnjLcP>XJ!OI>E?+!gvf{aCRm!_3gJl<-%mN-Hyy}>ZI4AY$z;g{_s;@eg z41c?zu!YXaA_jhxG(e~}$SG`fB|1S~)W9Z?hENWZQ@0)IIIO@)dSp*q1DNTb5d6sF zRc!cfqf=o^74BXy#~7qyB56pw4c=wPKQ{XhjvCc}bAfx$7qJ?$EJd z@Qtxn^`E7;$kec_q^AI4B}uL%?jZJ3?8x3p!-=RcVmIH^N$nq=+FH>ikv2iS#LTS2 z&hi>~ND_IL)?1ZsVZV7R4Ulrw&r&^Woiy#8ugb2~MhVJ7MhPld z{IeR`wb%1sAGC_fNJVephAK1SCATKWu$$!8{PO_J7(tXQ_bo(xoZNoKeQSMJ>B1cb zcW5=SRs+9a{jyOIhmOLr|20O|E1~~|Bgrg zQy5aCB^^z|4%0hVSMFTEoi=6KRbZLn2l^+?gdjXY8?T-u@QT!*zm-J0@p2&-0nN-> z$8UV`mwY^ybI8GMTOSy6Msb7V9l#i8KZ4o&&lJ5qzYpuDB=ce)eP53*-!7SdjBx#u zBOae0UawyaaK^#m8ooSR9{k~ijJZG1czi(oflocTGp8^|U?}vgXU;XG5!Q5_-6_j+ z*rBl=!+{n~z~$SoczOGm_%?fQ%IzEwjVMQ^$G5}Bizu45_!Eu=APfRL+r;gYA^01R zrcfH*92vZ3yqE?}84Sfi9te1!A3r(%ZcrZy^sNLI%0+LExZKwMyn!4IeD}}D3yExX z-1h3s@H1vMWWt{Mw3ck}LCzdC6dObJ0aMSWus=YqS(4P}9ufPBEINi|Bd~UF3EhtG zju4(KcaDE1op{b@<;!>_&{`5*dC)HyNfKwQ$MNX+xxn%w0<7ST~&x9(L8buCxljUZ)Bm#^l&RtO4hu0EWni~0FB})1pzP# zDO|?ud#q@ShaUQMQK&NtviZ1>56ZRXb5Iqdq4+|SO#?wqqM@MqXsKv>w9S#VWL_R< zKS3&vizIC*%1WY9&a33ld>!$Gin+`0s})>|Y<~1shSXY?@*u^>L7qa;P)Mj6EigLo z$CHMB$70A2IZdsxHjj16-yhhjXhDn>*dI^URPF_#j?oSbdicP+F-EkJR?d)3L`Xni zc5+%D>f+J!+)g%-SjLNvuCZ%*n{U}l@Nv1jRQ)kP^#p8o16Mo=qKP1>g@IA|S|)~1 zrJ^uPrKX_rBg%MAkS_-R0TT6=rNZuQ0#?aLHsmgVN){A01>bViB*Lldj@}hDr3kfh z5-Se-Np~n;{vu(Tr(RuoV|c6-f=vC=W#zJL1L)okyuY?`sWRyjGqn|BnM7r!-4QjN z(Hhx{XQpqH3T0EVShN*qkt#Mt7yy-Kc%Fo|azeL&T=RfOy4els#dXMRHxYzVrk)Uj zeHuQO?VLa2R5g20VKPWyjXmuS%SCU52MU;zg6x67b`&DT$=W@{x$s;7S5l7 z^pfksw{Z|4JLr(Sy&s>(^=3#Qn8Vf(ilTBA*jD_H@K0B zJa(!yb_Njbams5%)k>R=hD=p&BI4Gl_84s@okVLt%B`SJ4`E!YfTL%sng2bCY5-Re zq~4|>K7yyY8tgk`l)}vq%iRhYi5Se;7Zc^4twJ%?K%oTH)SB0)rl5#NLFnTMfATW< za%C+fTuD>YCP3*LG^e`x8%I(CDbTazeaKFpe5b;26qjSu^E^NKPvOn`Qe!n8O-1o{ z6mwC%Il`*y_LNh6JXDh7a%2IGl4kL((}noVLCv|{ol%&eCF!l=eSaxKZp;(Q?3*Wy zlqgjTrGbu#ab;B1*@dig4$O3~gM~|G`LLJ*GfVPwVEy>F-Unvu=Wxh*E~w$WCIkAa zaA$sH7w=p^C$y;T;kC^?<(}x7OBSGYenehF=s{gF_N6u2l~p^nE1mfq=W#e@sk}|w zh~Vn^jPxaA$B5S@@lj9)HH`9C#@N*N)n;L8rHqb>~WmaXowmvcQUc;*PO1|NQ;AB7mo<%l-)J1 z+%+nswL6i$X|(l8XH%?H2mCCjY>QkNaeUzk;KX_>3`+3@#$a492ff+N<;Z30>fFg9>1?+Io&?L3{xPiPJHx<39b|b`0+!Bub=|QG6W* zYm(QL+7UXX;4-sg@|XS0bMiNUtz+^}ciFB~4>*FhZR&cD0|NSPXRi@a=uifQa%07F z8bvZ!d_hF7!BaIt+K>ddEFG)f>W*5dUA(g3>bb^KHCqGKe2y)Uu3)*!n~&5d{e@dD zTj-N&rA;t(3toqgX)x&Md-?ONOG+wgumw*RlqY)L$z$HO)tWYu8i>;EV;ke5u=Dbp zk&aJ=iyDJ)`hNB(m5Kqk1Ta^RLpEsm5#I5T#6V@HQKe@7#Y)=53-t6-6M^h3tPon>bULD&C7ZQrU^5!df=6Fj$Har>F46_wxdR9*9o({>8*Z> zjcZs=c*_MgNcyQp%~j)I+nhoYh{}O9pLxFX%)qDV(TDY?>2g4EQL*XLcfb;Eb@Efa zEw{;>Wgak%a!yb6vYTuQT1pBhmhs;+lE0n2I=}nn3Tp7NZYW3J zag5rYa(_|?D0_as-}U>TnlHy~3t`1ZmZ%_`mRsk3tCUPVpR1YAAJcPXs~7MeW8{(y zpEgV%2~!1?^SV-OuO%ybUfr2mgw`rGWhsqmz`VuGJKeb zS-KNnb*1S0;`5Pb*VJYlHA(FZ@-If+gZlx{rwrEmH^St<6vyAngo%-X4p3;JJ+{2FV<(>mv%pLb{Y2h?&(`MLtW^<_fz+NI72yxj+EXwWm#fKA^C5(0?Q0`^ee{A8= zKlda+xDEIQXYXvo>=GYl+8J?>aCeW)E#*AK*wvwE{cM1F)4?J5lsKU;wWa_W4((}> zP|nKp|MIvS01Jr7?_B=S8O796`UzNc9Db|OwXcKH(Vqwx_K=rSaLDSRuB6F37}i)0 z#@fJ0-JvXjjVTHl_At#eD<7I&vrkGcUxgFHwkI)aoF%Qtvcp8_5$p2mIDNv70sW2(9g^s z9C_M%xgOBp;H)KwaolPMhNKEs#*hud$cCzhu)snv!rwGfN&9tYRs>=ZEtnnk*TjiA zu*x5XAS`cSpHh%8XBgscNU5t-Uqv=rP_KApqOTfXMa}#{H4|gjZHtOPZ6ew(W@!^~ zG;;<(_J-gZwTTF7)o&Z^|mQJQqnGEN8L zjdh>oi7*q$X<2&a9~{CSiFU}QsYAjSq zw%p$$XKcvqOV0*Y;28@fv5Xkgy;t^PTR0sGl%t_mO_hd~XEHOp%8Ej1aV~q?IbpU! zBZ&xXt2i-fb}9#uLB?#^!i?lN_H5yEX-YblX$1%$V1Y&wK|;a(q{@*Bti~`+Z5BJq&$Q?w71@7cQrby0Id8z>lPu)3>44pP~(L?gehin z99PdcPP%dY&M2-F%#B1k3l2G2pjD%OOWP3o#ze}xVRdi6jZ+r_1J>~7f2kZ~P^_Uw z%v7`+&x$p}FI3Moz)ZQU>(-mt>Cf(D`2scp`$CxQ$o*1QlmcnyL~$N84F3aQ_Eqcf z>4PcOAEggycLigg_Q7@ME>mu#*M8NGoum0-@30VehhFJ0M9rz=Ow7G{65POt!}9id zj4so1qDj&c3}f;L&``^y=8iO>Oc6po_Yyf~ifk3P2z?HepxKewgfE+ROE>;FX1=hwA4+;t-gPN8Kl&hf10|ds%1NqYb1?uRSi&} za`t6>>`}pEa~qYo*6m&Tp2l?Q$7jD>lLhP8+W`p(f6{SzDKqI#${;aIxwiMF_$@-g z-tNQhn{t_QES27?ZRbnz?i@ILE8@4?AE^M=7}?Ytewvj6teD`DI4N%VKp*##U58Gm zq^^je7G61aeC#{+kUH)Qg5UWA_-_wS(Y9|k=mBOA*;QQAKdEWhu+W6 zhXWUXPT#g2&#bSqj~e<(8hZR}=4}e_!xVKC@_qm^9dFBHmEW%IspD-BRZjjV-z~e96IJ?UDK&*b7b)WS{M!{ zYn+#e_wFYCW0v3kjJF zm6k^>m>reNdwc-sS#LL}u%Vu30%4i38fleHndK7$@5ejiF`~&dzgx%2nxTa73>{Ch zWe^F4tc5dd!hxAtC@7;KL@}pm^ja?ymL@q7nNp0d_TYW9MK!9rsBVzLr&z<1BNNo< zViW>BKfyskBTd;qY-6tWZ+^mM&l=LX#=;I3mx$3fFm(m#OzMTSj|=z!GF-U7AE2|N zNQxEXU=_JDB8f7{y_WTYn8PhhK-h#EZNz~wV(tV*MXPBi)gB)a%n>d`XF^a>JfI@&iw4p0 zv{Di=;cihde_XtKZGtqNwutF9sgAIs+mgdj;rpLe7Twb;(PiK@FD z4pe(fa$v>F6oZ85xMRbgw@VpD=n@F5sjD}$`$0=2qVT7zVhhi&qD_K`AUy*QKL8HWV*a@eg zuxIXs4UDpc#ydusBeonz$V4M}%BHdz@--_+YBv{2uIZT(!D6lB6f_UIA=A(5*G5f% z#j}Il7!(*?H8xV8aQmV1SCkqnPmW&TSi@Njx5Rc4A3tJWt6|IJ(?L&BTe5-Ck2boA z@Dav2Zd!(e)hprnv2GC8e3NWa+{}AKoHzG}g_LP}{-b02HY0AFY(=DlX>(PC(RUh0 zCq9IMuVl0z@U9x~_z%cB&;0>f-iK|kWE|PCa>W)|R9V)}Vti(vV3hiJcx}8=bpsy- zImTL@_5;#G8ly3r=+vf^^4RGfyG9MBRd&Yai!4#Zr47aw#a0}|v!sh5?@YP}?X5+z z8;&S>$);TjexU%TYO-q-&xtT=DGoTWOhYi4fJEUiP4B>;OoHFeLcsgP0FVW7X`#Nz zid<-U9n#538SpJhD2>WPD6VxvBViA5=-IAG%2KSuCw^u;z{jucQd+aw+tTCbE5%cA+>{ z*3Isd*)5>hT&v0D1SX%OB#GmrW*}>~^WxXoMcr+Gyu4P{L};^CxZ($6-w5)KiIunS zx2vVWphrDLzrtv4YraYJUB5$O+1o5i$|t`4|5!l0?EX=xcLvM~LPoB_XJDYPuS?~X zV!zWES@p9ngdT%)PA$6McPTJSyce5U;GR?0t`MU&U{hoREyN!)3AXvJugF0yQHGGp ziqkPF6|?q&YRd3_r{?ya-M#czv_8$n;eR1Gc^&rD^ zJae({u$LP?2}!rv*Ph7A?fHuWSMjnxI&o3{JI zfoCTE1)Q0TJw9qC;^i9CF(%7!*$}Q4;nrf*eW(xQwXNXavHCx<6GqPemBlkL{0ply z{cX4YCsv=)l>R%7@BJ%{?-tOJT%HmzAc&U??6Jiz2rp`L)21LTbY5HClVDtod+ zv{f;-Kq%EksL9_HrOjUK5)Hu++xz>9&|Puu-&f2;oPfTGOMh+6zA?fLv^!$i^}+4w z8qQm__wWm3*yFp&x9xO|0AN2${p7LQ|e-I-`>A- zS$AJAwzR$~=wBQ!eNJ6pZ%)(2ncX2ONU^lwHOsGYa0;CVuRiMGFQ@Ruj$(7bj_cYj z5o^VU?b1+)-O6MROu~?5NaoAr2yjx=?j+?=fk~W*D;(>@)+IP`CvUa?BDU`xi^y z5ho4r+g+Gx`PnHc{F;`8oz5e}jE%^~T;2$t!OsnQt z%&njnt#V|h(HIH67$nxbI4Y+LW8?#cvatampSb6 zd9ZLU!&pe_oF<}oL7Un(ls)Rj^G3DJ<&O)OzgJi6B@J$dHV1zCe_lt~9kp6``-=5WHQ7c|A7W<_`XcqfAh;<>8vz^+$zFY` zJ>3E)E!PK{v1^rhy_)w+_L zBBPRbre!77Fa#H=f%d9HwM+4f}N3Ei-hJSxNZecWGIAUe?w$;$@y*iC^7RjtJJIR$AKqoaBp+K3jek3vpF> zX0mwNRdTwV_ZF_z8m4!7|5t~4;yD@ zW&rq#Etz=6V&KjXEvMeFA=z!BCq3GBdnfVYV!cFzyEow}<_h~zBaac4)h4eC>z8dZ z=3?USp{eHd7u~m*(uYDK2|Z7I=n2H=u?hAwyv8akU+U+LmK3=%ZziKFmau^laQ}4U zAe76r+5K0Jz}b8ouINCsOS13v>!)d*;{qy0s1htZ!Y=LhLsuu)_#UwCQ_cDLD+WTyj~UjcqM=eoL%Ep zq%S>R6Jz_Z5mmULWpR$2J;rCA0k7dvW^Pg6z$15YN~fglkos4P>ig`_MrN)>ODQ+= zdB}#(;{k3G*HW~##TbsHt&^Vo**}2`Z&M5Z4Y~XmXZ&|s&-~Apk?9}fU;kWUV*1-K z`%mOjsxBS9Er!s0ss6OVAf?W~!T@2W#tgWZ19N2HB%Nc>9r&8mm+#fGT%3xM=5b#x zUHRRamoL={{wV*_)-d{K6_yO}i8OdZw06(`*6+>W`@)8wW6b^}yo=pn=5Xq?3BH(n zizV-2qc`UJig%JPj=Y<@(59~0#gOOVU9K}R4dD(`X6k|M`~7u&2XE)s^F-l(p?y5x z$JXm>XAAHp32Z5R5gZth8mgVc25NifK6tZ>KlS&X+d^XaujWId^$pP{2nSE&TO<=d znAke36s9s}2M(1sUnonEs;%nNG0*8r%%XzIi_`$J6&Wk2?u3yp#~D1}EQWT+B(6=>`_RwDPvy@unsD9=X>$tVD%1Z}4x!Wg<_v860~! z`#kxD>P^nXgk{Pucab}gURRLx3?iuq%*6o>;T1f7OUVRP_l=BYX~?pES=(crv>^8$ z^k|_L2s#u_cD1oOtp$39z;;ja{V79En*%n1D+^F=$Jw~Y-oVpZV;Se6FL9@~s|FPs z9PT!4?5y_KYc^wt91?0n0hdg5b}Uw%n`0nMh=e%vhehI&&UO?iH4re^COv!3de90B ze5SPJyFxD5O?Qaj7zx%Rs2xTu_vQsD9tX)msr}8z(7SU-1djZD~FmS-eO{ylk&nic7ax>}<=u+E0U*XpADdwWBu+^=}dSIt-717MF zIw13et5@kP<~*BH$HPG}2;r)&CZ6ohGw7G>>>}GZfNuO6(AUGW^?i3uC0<&*)R}U6 z-IL?GOe})?Jc?!jMj`M{(cL|$mIgf7DrQ_Z|Ce%Ljj^aOggLK#9nRMk`d<^7c#{^ zMI)>9QQHa&&*~vLAV~g8tzjI}%gwtabR&2sK(VNJw6QS3Z!q=UGrO-vMn`Npb57}HcbN1KZ=R8Xo&A4o zET(_V75y(v`rFz1kC>z}RlCK8u=7FP3}=vPFBL$z|E@~V)eP1N(P_OzG)_Bj^Zt>G zK9Wc?Ns$%3P9_Rx4mXDbXX>@}<^0;koO>RN-DzUWZ?<)u*w^>t_j)Y+vNrG}9OS?A z{_%ky4%26xo-|VTA{^7;?);&xzDf85xy9tOlClua53kRM5xW!^rVZ;oC*yxVx;@>P(A_1K5}`92xj6C|JQGGi_ecz*93xP^yYZ^@j8 z^5|v6pS|*Eoy6a*fOwnMU!K{1zCPPpm=;N44e;Id*ERr3fmL)}3wd87@T2eB4%p;F zKc#awaCz;?Jq2s*4>8>#d*>!RZz&DJJcqyBGO9Is_63q$R_bNA(cl5f82&h3Fa7|G zk2YH}A93>4C(EtQW3^q7-_9V#juOFPwspYRvtf$}&q`3#8cYc4XqEZG)OTf<>sV^@ zaMd}qnaml~*#v@^YDt5{kG7=|TttnCV9Su@=0d4>y;&cF1)G_VLWGX%V5aFS4Rq}` zi5Gg9>>+Tnr}obcHb(bo!9B)>?YW)To2p|L2}Cy#UvGT(+OGpgP*DDHcb!5Erf~#m z@^3KKz628(xu+u)2vQz9-V~gZ88!T@J|~$B25rb`5tSHdCW4DWATI#j((TM)CAQGs zGQmksqK4d*8Vp1f2a6=JJF?%0^nnp!>eJAnou0!jW0k^ZQ}~W>KO!05k5d<>xUh}h z{0OswLu6qC5?wQ-L1SOt87W3X2gd2%oKHIL$6EwvXFESd;;4c79Q$iqFjvY8KBtj; z1A4;n(ql0TmXX?upon=~CnvJ{FQZ9U*Fs+#)3#i3ly!3zIS|v1J8M}@F|bpsLV;Wf z+1)f;KS)!@%--|1fhQC%Ke-lFp+nooI z8$MaiQJ^(h7n9`2gg2S6>LeM-keUEKR-ousR-ve) zc4{aqHFEPV#6)mn1C$b^xZ>@dA{h{ZU51oV)?w1Q8d1W{F|U-;Pu>Qe}3x%LWfTrjxhHJ%^AN z8x6l399Y0|PWoU=+kHgO$Bs)dys@bA=;xQA-v!$ieKL>*D>Io>m&%CbDERL;mVSk{KZ+F#JBZ=TGQLWBraIYW#LY>b8wi^ z0tzdFGPc^$qvq$@Ol35)M(GN+hq6V=1B!qCOBveHNl5|p{#w`{xCeFD6D`{Kc_`ud zIdc^Fmet!{Ya#t*l9Y}6345E_bB#f*(IOuOLiM^yAlr{Pa>E($ZfldJYkmXn=|b`Lt2LxhLOdgyY}+d^v+1A*fvn4 zz&aI|mO(G12NKa89KesCrFaae-r?ZUu~|3$`3E#Z7L?58H@M z_WAv1>^vQQXODa#e)i|`;?~|j5A0{lZC3Kti&N9uJ9SgPYn`pkeZK5KHCZhGo6Gkb zfs_i6-Yjx`7HMQ1UPff4WI?A$6WM2TCn+3Cs@O_AM_CB2+{L7OabQ?dxJOwR<- zHCe29cpv2FRMyLvPjfAPr@)5ab*|5yzq&KI$ou>AQZ!prHza#*NOarGcVV-wC3mj( zw-1iHVG3{r{D1Y+Hr*o#i_qT^uo_zjA=FAcKj-2m;{NrPK4?B>%0Je5Wj)-p-mdzm=lsi0oUQn0>@u@S=IPx=KEYgaUm0J#pk)uGQC0`@$8T7iQ? zUgwx5)J1v_FRZ=P>Hv6HW<9@_R$$>=t)V3{Nrhu8oL5-1k|9Wj-mV#{C|&b%+QVk{ zmgmyeB)~-S!*y-S>h&bcP>z}l_(zdvnvE>TLRJgHj3kPHuRB&VDinyIl!<~>77kx_ z#Qds<%C*)pUQ8vmgM?G7G>7E3y^J9X#9lU$M;-~607R4uQ*o@UzxkQwy{NcW5u>6G z4jT>zN@0O&ouepOtps1-@iGo-pAyCPk#12IHH05m$WWdR83hGaXm0Ra+*dF0TsDQs zN`v|f8W8{~RfcBY?}i@F*tRGkdd>(D;lfO=L1xDO`q!&~m=g2zVM`FG5Y_(vqi2xc z8p`QOMi0yLXqMz-7D*{-C=PlNP(Z*E%OQJsxmy)iX&6#iH|SAj^kIAyPqX$S`?MU2M61ML-T~@mWNC4H}a*W@m7dJ-~{jn z`U)(wGE`=(`bkU&DLQDvOXW-g6Kx6Yh>`Ommng?I7w;%=qjCgs9A|`|XiuvcktK+F zGVr?-Ab;JHJ;b{p3tG79Q_JqnU1(~-4RrxQkpkWjCYv*wmi~tQEpcpMRWwYxQE(pC z6N4f{1+&5NcAVv0IPE0zTf*z@9Pv_XVVGqkKOs5eQ)J9-#)&HL+00d>p-zhxdcsnY zEZC^1D%mQ#fpGM>9WcHXD8pz9Z$CYY?~~Y_1b^~I%Wr>+oP@)31O+uAbZ^|C(CQ(L zH-)bCnZb!H(`{rJ`A{;>z8XiepLwyXZ#{l|O0K5_b@uU5ob_jAk~nfWYEYA^ZbV)T@i;&UxQC2l z*hp;p4oCE`wo~H2{m6$j@BnG96q4c5bX`AK_-Gz^V0cB9J4M2QD?mbz%?pp+_5Kk_ zn?^a`gX?I)@sz2F6&-c72UWO&(>c`;x~^F5_!luF@)Ag3b4cHNf& ztWuL~2J1_H7e-C$D1PYUGP@caG#=LU`)qan;F*^gEW^S-wB25VqT1tt-dW*Z;n-E- z@h#1GI~)DT)O9-ToGsd!0lzG+0ClGxNMQIw$BOuf=WNURP}*T(17`HSmP6Ivxa*g^k=EDmDbv^=%ogP=#nW@_T%KhUKve7DBHy3Mu_Lv1Z+ys?Ug0kQOMl?wyq`7aovCR0(9@Bl+CQ zcs3Z;*0JkWY}pkJ80Bj?&fYAv&_aj_SuxIR3V0q_;NEbYuT|1WZwn=~V@j%0xi*&e z(LTk^lbmQHnl2OENiJ%?IMgq2xR_B#Qhs(@(oKT6S3NRV{W02AL8(RaFY+Y~G10i$w?^kDVEM5)--M|ZRq?fLg+?*)1+E~IP71YzEbFrw8$ZjDO^RkFMC8RS?06*7Y8 zAXD#BCXDblpi*#`+wlYNUW*p^UuOHiNA|xLNE{6RC)Sw$3kBzY!Qc$5PevTFB5$pz zx%0@!)a0-thnzdA=({E&8zVMIks74I8MD59ZHDT)YFwLk5McZwWsoTjqQFs@MAc^?X9G+j!9h{_erce&U(Eq1UB@4-g0D{r64Fj6pEpRsX(cR)p9GU+e#P< zMkWK%h>J+GcKCSJXDO;1G@cFchoD&QCFtR64)p51zVm1M%bp3R?E3qyXlCJSa?g{` zTNAbp*!uD3$@sEJZek&K()p3h=ytyCER61WJZlk&$C3-@?u`|&$Mq2gm2W^Bw|3!g zyj+W^Q2LYpS(P*djyfWuWLY5gwupbnJ)#cW|Hm(O%RciH(!Uye&f6QQ4Vn+gS2=`l zLXZ}O4EPI#GCH_H62)VVd9KtU&?DI*W0GFHr`702RmuapefN{J1XiiVoK$G|)+!|G z!xM>=_D?56IBB!3EKx8tKHwQBA4@%~`2jVhQDSnsgh`4}4$1ZJf>y!g*hs}{iYkKJ zY6^8;M1|)}0v74;3eR`XO0|1LMo?N8Xs+N0l=4d(va)l$FF)Ftjv*6c3`^ zhZ^h_dn$Zgb0Dt!oU5A;FkHnVw<6rXS`9&ja$dU8!(g=KxOprhMdyAjxD75O<}!JGFpZ`_Us9!y$VN)z;0kSRfi*Z#~ZTQKc+0GUU`Aq5vaKq(JOV zBzreEK*SU^Q4ML*O~zJ6A@S)sW9$qp)6lmmRPe|(1|3_}G<08^jz36(K~g(<+5VW# zNGSr<$u(M)S>K#TbKfnzR#Q79+=5ckOIrq1)7v8_C1BKKRwh8BYf-zd@aQNB+b~0m zGE4u9p$Cr)wAy~(sgCpo8(nO*Jt0NUu!tX3lzF(+%K4LWrJQYHZ_!J#D9>iDzah*! zYJsXrVGdJT-h74vhYI|VV3C8@R8+@trfUX@*)XWh$UUBesjD;&O4A_b%CrIm#1xn= zLDgRx)Oe}j*PXs$0Tag;6jjY_COL{lfJ8wMrI+OIVK~k*s~Xw$O$F?QJprc?17(=$ zyfD;P9$`+zDnt$k2s_Li;*|y}QAPnlv^Bm89%rs~a2(0oRBdV!kaN!{AnbF>(Irh9 z5`z@I8i5e$lEs{&Y^%Hb*Jg3vp4}MxN=reyr%dWAOt!k3`ss?HnT=1s#Z_qyX4k#; z>Of-tn+qO_?N$VMXpb2#8aszlyJQ+(9py8!SQU*OmvMdsg^OD@v zkXynXCkl&1PEG#8{`HHckvD5B##Mi3RRe_=a~zF&otQa8u&->gWle2O%2w?06py%f z3pJp`r+xJmp9p~2CL^2O3__-{eExG$YFQMDa3P*3YwS#enXa&7?)84hoTr+QQ_wX$ zBk5|Rt7=DnDTOzJQku`mEqiqmLHge_S*$0NW!ee7YNh;92Jp6gMR9|~!D3|FvJAf} zxt|AoJu_qATy%21xxR56-A}~vtZqh?*SJ6nYv-o>mZ=^+xm zdaaOtb}y4Gyty?2IP9hDAy95N<77oEy`Xr85<+dM4tIyiT%cu*y?-}};Yqa*EqnmR6|R|>U+%wsl>I9M?9 zc>F&)C&(?Xu|$*>(dq!fTg1@M;;kjCw?yaAkKvkgC~hEzC)~jSm&F<-=0_#_e)Jxyk8FQuQmAZkZ+X)DIP+Ph@u+=%L@&j z0p?`etB5AshzwB*0#zj@&7#h@XkjMX2-!@ShCDQtXkl?FVT?CnMeMNk87WJFY15KF z#zm7CzYO$Eh(pq6Ee?tK_{m@f{wTF z5jWin4~UrUekr`|V?EuST-(}Gc&iCo#CfqlW?a*?xvXw+6`}MR_cL99U=ZAG$me-ilM{G#2w;O>YQQgAvL)S?$!l3|-@tJwZs~9I-;MYARoi{W+##wCo zEk8Ra5V;$V?P~({B6f85j#j~0`xmdNv&qkMV0$ZR8J~KR$ut3%e=>K8!ploeW}$o zP%onk5LzsO8ZWgDD>CMY-usr>9H!%$&oiq_y*2@iJdCDuQULfwzfS! ze&s3;ba@cGRiF|UWAdzPs2WdYGJU2mWJw1ylcfgfvU??pWam-m?`vZ7*`D`wlHJd~ew@g} z-o^62X2Bz(U+uMZmCIDts~43UkbSYF>a(+y<*7i$$tw}&a~Pi%pxIiJPn%nx=8}8% zChx3Vt4rlnC?iJs*_tQ|;U`E2d5=phQwIvw$kWMIX7JK59e7p5Toxxh_&X&RoXwS= z1f-KWM*1pitVY2POf<+yZ41;?$WUd1A}9b!&j6nSp0y0w`LAX>D|M_=Rh7xuU_)^) zZu5(tbbo|rjOWN+NmV2 zRG4$i6LI$Vt}6z3EwezV(iZ-)+!G!Di3SoWjy<^7i-^h07nxNNagt$T(ULxB&~$ZjDip#qH#Bw`HxBno-vik-$AUzIaSknMs*{9w@Q2VQ=4h_y_$(B+fRxffXsC z(6+^^D?yt1A_n*p|zNR<>buysMsQ>hqT8VL0`N*@Lg|wp?d()KdaC zY@X2z%NJP!m8)P6i`Uuvh8AtPMYfggbO&rv4)m$jp9j-s{DgBFKumhxQ(k)fF^z&W z-_K^3>*5PXRaH6X{8Ahu;Im4E@`4ZM2jH^Nec`_iuzwsQ2G;-ZwweBkQ~k#P`=7e# zYErR_>fAppqc+5>hnU?;gdFz8 zEMbQbF9JnaLgE3Zp4pyDY9VllKZn=;=#G_zM}{&N-PqwHUt230pxRp63-76mJ0-Aj z^mR3D-wtc%27LuG?J`2^KF9l=l>+WZ9}+S`1OK?+g|N>6H_!O)0_b_Qk526q?1Z7~ z$%Ulz$sDW73I=M7V;2o*24f$LA-zdq8>&i_?g$?7%|`97^a-eHrpb@@C^AyeOP(>} zc{h)YJe-&p+J~3lKtBEvMuyk4H){ZCk?qnz8)+(@>qDgX_M4V74!+xZt{!=s*^mLX zp&nh_&T%8TRfxvbPRP>Ayj7jV zx+3QRZ4+dL&M!k55Zmj4u~ve}j*P?uk|&-Y8KG(#r-{koQ7~>b>04ZW(x5?wh|$)| z5V*hn)^3eBmB`qC{DEoeELpV3VhksYR&*#UaKmFj!yDVaRDQojQ3qlUx`K(9hNymKdx*ab9!nF@mT+`^rP zQ&)A%U^tGE1M;%CT}nixJ71sn7)$cgFj5S#!^yd<5_Y=En>IY*j|Fd*w=7Bcz$7&b zCv0QwT=UG`4+X93n~aP|o^cBFcunyj#rL1_Sb`+ZVVUS?i6wmwr!4HE)O|a5nJqc# z@Q{o6s(QwoCE1SKv>r~E&~gHkm*(GlM);031r^g4Wh?2V&{OMnzkUWw7OL23LCUd+ z=6|;E=9AntO2)B3&!xHmXS^L?-+;{TA1mLLtaqr(>_(QFS$Bf9r1o(u$DDE)`TYPV zJ0&U7x78?Z6?U3|X)bH&3FBQR8aw|cZk%is6Z|T_fgQ6#|681s=^xwUue;6huT$$^ z%M&Q(|8G^E`G2X(PislV615`!J8|QW+%pdLH*`WY?r$dxHbyWutqUH)#_v78!#2KO zD302x)yc~)YFg?wMtJe15nkp+j4wc9; zEo%HJ?t;0rf)yev4f29hei=&dtz?0pbYXxYa{A9K^zO66pW}U0sz(zYUSG}c=Ok#e z$2pK@E;A+t_?HFEFM zW_vVY6T~H}){rE?4wm6%@51xSiP0s=mmoBLweR5hDwO~RK<(U9wh+kD0uhnHIOSbL z-xT7q+Dr#*t5|*~FF06vVfkzETnLLyl)jWTMb?2isZzJsI4X)*2K~&!N!6PQNX<3( z1qgYV2S-rffqMK!^#`Cwb5 z1_0$>@(u+?m=~z~8qo0`v;`$6=~?dF5fMfP1f=0|Owv;_HVhg}=6*YGX$80^dKVs1 zZ`_ZA_??W6DdGZyX$FjspKAfTC89KI3al@jq^(0QsLN|{zK2)hF{cf4j0ie~p5hu< zQn!A>q$nB*4rLGc2?~unw%~13G`6X5N@AMB0glCV`v~)4dpvgQiw)Iaspm zMrhRKU+rIG)9MT01+=#k+yX#Hglmr;$>%)4g)uOlj8m1q!LSI15#c8N8qnTF78|vA z)a_(fgdO~=o^I3t<&MlWYtEw8Am6K8?@wgdC6eWf=ZMI!i6l4`wbp&`eAa^ws-RaS z0vDGf=ZsSj?PgeR2MwoRv z1I{SEO0afog_=vdS>x;SbNEo6KySkFd`czcIj5YRjBQ|Yrd6%3r%25g8)Q%ckadbO z)FGefSm4Cq(Nj}NJ%DJ@fCXu?W{dl9T})!Zuk(>{@&Znc+L+r7Gd?Bat+PeyCw>HC zEIi@_$xb}A(>*TD`4xBtwFkiK)#Av7b|7R-z6={_+8D_jSPfS^`i)R@1;x$iXcmx} z{IaqyveX@(fou_gO2#)7<=s&+?$A<-NDSU!TEDxQt(X54S_BE}z*NV%y-^hHaJZaw zRmKRy!0}!wQ5E~}e`a7}4tHBik{hw4RhF+xdfdglM{d*Qw%3x`A1RhbG=pH)4dufX zWmjNI`=ChI>&KL{x7RYnd3&0$*f5l#xG^KoWs{2V3K;v6$PV>@>A>a33OkHiiD(fo zQWt80PsscEn^3?NlxZ3rb1$^bsjAHLkZV+i9T`Eu1P?RyHm9!g5IfVt=1 zHX>3by*>bks~b?3jMjV)anZwNHyf(55mXqnCr~Ox+_*gml4-^_q4NQ$ISe-#)KGQn zG@tY{CCEyP3$9P1uPrJilGg7dGb?31h!TIv2~fr)XH&(8zmc%Ah$2E7b+TO@ z1!RZ<^~as%!6=rdOkr&&(Xc4ARnV>|dpr990`GFgJSi%F8i5zZ%G*hlwOn$FQ5@2- zXAyrgn7-QBR$~~R+4r3>f$JkJ=(moVuCs>?V*~wZGuopU^#=%^OOb$Qz~XI%kMaM@ z@2GC+PDr4(5~F)I?KsT|;5>)l^Um}c8X_&N%AiR$Cq&5Pt1oXvTr4EBFU zt_~!cjIsOmsI`+7!TNR_06Wl+VXk*QBo(pEFk8%yNC6GQ6AroB&yEa2$v|D^4wK9Q zYiLER2cMR4o9O`Da`$Iz=Z1{bH5pwdBUutqCz|~PSZ_O7Jq|NYuJuY~(e~mT5Q0{N zpG4gvQ>eJVN84zLRxTlWuS^GKiDLCmK3k~rV$HAp)W^Ea$u@g61%kc>+>}6r@_|o$} z3nGpOM;R~2_rhQeBOKwI(zFopoeDkv{w682Rf1Mi^a0CYL>Nw2}u8+{Jr2AnBxkFqp(A>Fc z$s@?xsA9`hq;dWrHyMEL4hMJ%B#y@G;u3Up3ZYf>Sh`^W!AWM;Y$99+Q!sP^-%uwS zz4*|Ewm6d7^Mf3z4wBSx2$=eTDt7!J9A)z-XPy-WWwnD&>U*`}%NYCWoV z`@Zd+X5szXU6&B`0TAr6uPfnUHg4kYJf+l>H=P!a`KAPk(mu-BWkH=&b1%s<31vbf zVfg%tK2V~B3}ciRj!lIfi;j{nv808o9|alt1K4KPb?h_4U`~+|mHN{-p1~GD#Mlxq zSG_{=o{0Iko_&}PahsE;I%v#cq=P%pBw*{Srin68%_#;RIe;mKU#nJK@=~}!sEfk0 z-cHbgybXj!icFeSjSSE7h+awVVG+N#PRdyg&;CAT^^rn`c7>jtb<-8z-;JT zc`~&(ckn$#T)kW?;hn)%A{TX=wGG3U9o;xPi2`&cNm95?+mqNWeU$6B-GAR_PA|YL zkBcmzVO`o}qOd#z_YQN1dcn*ZKE0YpB+ca@PSh8>Rdpyobmr)LfgCMAyRI*ZwLD8o zMHRSBF_wp84QqOtuPz-v0up(U05yltG-CzN1BmWZ`mWcx5qD3Qp?mpVC0DrD9xZ7h zz4i!Su@kBMu|Ytm$4ys5*dyBCgQGt&DvYIGly7VgXRf=I^$OH1W_dp=1sOjD2kHb& zRaflR%a#~vU05hB`LQ5lDMP)?w?3zMgx!25FC<*-0R%D`Vl}h24%$~8vS+BOwYI+s z8KAZdjfTxQgcvJvoyj@~4PS>{$y}#{lbJv(FGjmL9q@ODmL!TL>QSba=khC8m2K}j zNlx(W0*{?gZ*%~wT7Eqn4+f9&+8LT1F+5E!sNk(Yog(~};a+$#A*dVIn&9xj zR^+ulzS#-&`CV)BH3$!_=L?IMTyr<6lG#g<{C3xRgx4p|1n7qu*<&@GJD{jEfN3(8 z`iTxXMK*MYX#<7Z%7&8Chqs~0=fEp85Y|=t*)%Rp{07>{jDg3;tgy+7hg^D6jj>I{ zk^?xKXfqw}AVyw8_K!q!I9thA z?5OLConl9<BBSnp27Y=p%?_}b6t8AT z+N}TO8xOS7HwWuf)f7Uc6eCRoL;rjwE>}VDQup=#roWZBw`kP3UK^L#Y(?wqLt)6a zQRcRYURCioUay9k0&4KES4CnlMump!H824@a??K{tv&Q2Q}}&r5Yj>xD7ZBpGX-t- z_ztG1Z_74A$k~-92=bsCBanC16{Rn~3dJ7AzQ}+Hv5bOitR@l`8q$w|I25NwFCg*h zBj2A`Dv=>42f95AgaXwi?}=YH1SsXTvWF7}x4iuuM%IGi1Cpj}%zT~w6xdq|Tba9{ zu>U3~>E_f9sRj#Rr}1GNso@Cw3pox>_-&OMYhRg0C@Z4WZH-aN7z}{KT@?U@$p0@a z1%M=^3rIe2bNZdubs@yYKe9_>zX!ia4VUj(@?;;ZrW*-Bzp$4HvODZWA1$`aqJ217 zNJfg~UQ8F_QMgSC@1lKA-9p2q)ot-U#=Gpml$}Ihig($D%7kUsYx_Ouz98lLxO&y& z_Rc(o;+=n*w?*HDlad?=f8A-WBdGh2-J&b%4Q0&nUUyrnW04ZUNT)QMExsl-_o8?| z$cJYsMtPe7y)q-iAqR_6FlXrRu720OV5{uRE{cl@q~02b2???23o59SPigCP!7DEq zHGQC1nJnl&g`a72m(6nUbv!64-u}rB?Qt`F!H}oKtyfHjKes%gajvXDty`XxvZ`&T z548U3$6lMSOD!-gooz6#<`dDj9G8%gO29!SVCAqKSkL~F6kv6<6F083^w5~nkh}S~ z6sD!j60$+dN8{SvI-?)zM$2%IBqFRViG`YkT)fMgO!7D~E{$S~Ycbx3fg5`>6vaAl z=|o8grN@*I*WL_Z%fo66l5*SkTo#SFqPTLCr>xAIYn(F$!GXbN$N3{fI%g8U8Sc!w;RHaV(VsP4Av zF;i)elk<$T8AH*nn(mIxVkoV%J(M|i+l5^;j3f1OlptH^vav@gETk^4-8#LyPVP=U zcQKHu?lKjoL~&a&hzeIhDX&i$BHRvzkl6;ag&aD6?cfc|Cqrg_hy@qYF6eRkgEj01 zQNWaLw!rHRFH)C?G_X>89;$CI7w;hZL?ZVIF$mW$Ga_Ltc8Aq9G~_`TK}^@S|`?to>8#s=GeAC@$z zVJ_KUGxL=k+&3u=d5KhPv_WYAmRO9d@i`k4Vp_PHlL{0MkO}ja6$IJzq9%fit5Ee> zYlJ!}hl^iktd1iE=QzyqK9t6a~Y-Xx=pKMdT zGVoGkITTv33hCS(*D^fK#RHksC|pB{@%FV%1&NMG!%GmDW%raIc;yuf!Ux%)FNEc{ z*j|^Pe{bLdA9~qsoAhnd^1#`j;)i(N*o1KnC9b8x z5i%+;Pr*wYIFWTK5{!&4b4_BnsJv$~WR8Q=lSXoVFfn%FK9X>{X{rvq>W)?(MDG^5 zpz~1a)h7bqPx(B()=jO=ULN^cj{Nad)`8PHa*tnOJ3d?pAlT0L6aYnT$F3vb!38~5 zlHt?nGHha1ENE4&hQ=;3%(~RZ<$9o`H>}K|4rMC!nAFCrvZT~y^V(7ZvCmnSRCL*hct|%(;e$E?pB(eczGX~fT_vnDXL@*e4|%QUCj9jTA(du)Bx8|J5-hQ1Rz0o4 zQ&|~q+X;rmVQc?ajzr=Sr>)7z{m3=IC_ZpLyP7M9rE)GJYypZm$h(e0oovKTIejXz zGDR@OKoKQ4x69?x&|NzE-s%0KY`C!jt3pn4pHKYB@mjfz*t$<49B@Mcw3)>l#n7^e z#7hv`ZMW5c&{d_O!HCSKTN~`#L%gGgS(88xcZWb-aC0)R_MMIV=Dg6+5$!Im*Z#Q& zlL^(rZT6&N!1c`G9)Dw6h8NRhf1 z^4<`Ih=CXK%qxiqfeW3WvULmb?=uDUHH?Eoq5LfHywTHX?Xzv}9vAYyTqwVWyPvIG zkZB|#6|seP@DT(Ekf4WZn_$tw0{~wDSj)wh#uXs@fOk6vZEh58T~B-iK!WBp)AGD2xxYXM_CVeG9eGSzup0T=^u z=6$)qFoqAfp z?#AOKJ+K8_jKKQ{hR>2PKvv@)Ff;-BqOsoyUjdzqkV|1P^_Nc+OnkOD0B_-l2~0;~ zOTfyU9Tr_e-503=(SKRfT@@h*{ZZj>^6dky6AM>BB^D~%Gy_7gPQzY225?s+2hc|& zN03z`e_ZkaV2$$ZH^OPQ1i%8>uv*1O&$=h~hje^pLJhMwKMl2S69lwx;}7`z%&(mp zr0l(fc4ZZACa@n#K?cJ<&0*p*Kg|CHKL%>Tt_Rb;+nSX%LYVzT4!zScM5$tlKa9Nh znKt8QOl<&>OBn8+YH-BP=%AJNDE;N3Gljv~fMo`)$U;G%z4`2>Iy(YdHNCgR^0YQd zs{2x$(YSP^{so=x>Fhqt-m?L>wb8Mic7CCrKWF=;XVFb=qIHHlc<)xxr)5 z%*mYQx))`f}~ zG0;$Vf*{Ht&*6=>lM4Z^xO)Vdr(nMoU6s6{+_9f@QzaCHr0J&b-oMr7B&Fc4a+jxY zqvMt(z?)AVfnLTLkk;5j2m$`~^9s&~@}mZ`ISh}K>-$`+%8QYzPCKjz-*=%`!qw9+4+mIT3W?juYf^5lkc`z}wJ?{FOetP40CyYK@b zwj?6{->&5UgkTuiS^tkI$NW#t;XkhA{|jiT`v28X8*Bv_>}xhb8>6ibpbflU-yjr+ zV$S^bJrRgl4C?4HcS77q8WWmHPah;uf#2c_?d4i3*F9VH@b`t7`z_G(Peo1OY5t(s z_U-E{R;X{M<^lKgVxym9<)ZwndD6zpOYUmXXI{D+-Vaxo&sezHTwfr`RY18O9%ZN? z-E$>u#v;R6Q2GjTUgI>MpE|SLE!teDh!)AvQZ8)yV|~hm=?PWX73iCwICZrDjn`G6 z)AtnjZ*gQ(2E4+n%a<3!Ynkk5cGO;RrI7<8$mU>1%$w6tOXsw-<%HPV7n|oaY=M*zfsbF!Wu+ zk%t2*XrQ0jlO>{b5X60qMaWfL7b7LY46FnlLyu!IBp$JyU2tw8z~}{gSv<&5`XP*LDS z+ib6bjWpt(lMY}$S66eLBo7=>yI&3O$b3}sK^5_U)FI|m>PkF)*tTn7!HTY(J!(i-A@ zT5euoxr@S@_F-#nX@nJ$%uCj~_UfxWXh<^L$BB>p6Jq#nZ<7hh@M#1H(BsQXs)*A`pF=()hBKPYh*g-T!wZDU-R6&Z zfFro1mk}gDo$ISG-4a#Hc1N(Rn)VA3d8F87zzzO9<>O{5MtIkCADLg(-*^hITmCgf zdN&Efda1zemXUQ@%5_HQw^C-_;GrFBR7tTdyE3NwxK4&ONW@K*HWaO| zm@?z|R2U3FCcHl4+nmtyEEDu<+YTvSEDp<6;Yy5ZJ+*N6#nc=Mts+ra#U;1b!cY~1 zP=Pv(<=j&Qaxl726RUfja@Mp7!7KFWlHQA}gXN2c0jLcu&a$nPizi*@UoK&%hD<63 zx~B*GOCVjxwpSQ1GsUk&r1cx%bDX!3Op>FbTI#+OO~<-> z@Gg15zt03}Jq(9I*ymWBL2`Z6+xQ85pV80z0#d=qU4 z=g7z?TnC*q9_KBK?bu2_DO;~AUnD^z;1iF7%XsF^@79nxY^7AY_HlqKz|9?%$b{qX z0`rLX<8;S1o&oXLu9D4lmOz5uCDP*W+`m6TPzHi|`fn5BpOgs$GaJkQv$SFP|3Z6M z{ugLZvBr1|78^qM1=YJXKhE_fSTLCAxdOmnu0mW;yw*NQ2-#nk_oft;b_vU@9y~>u z^-aCXvpKHXbL-3Pz4c$Ac#Mub7e3Lg;eU0QJ>IW`US=hpg#7>AVb&{!==DJh9I5>q zo$O&N{;Hm|IeGWLV)kB=E|l}j?eQK96Wtq%7`uun3*m(dQ(=lu3FB?kg&ta@4co?| zSnNm_l@dk+f};p4*FnJXK7*>aEt!uJ7xm|pKYKbm6ykH9fAzi0`9AgS*pRKfKASv= z#4K&>USR8B2UMC zq_=RHCrfK1;rRf<2xSThFILqA_exkCIpMr&2$aLgHea&fE+6Y$&634!hNhcH%Nj~Hi7OWcRgt9I)< z)2W_PdB75)y!^XXYNBvCZA9&VNx>&ITTppN(!o%n<%53M@h~*iECB95GN{j&F9~Gn zHVM~G5$DT0o=Rf#m1*iY(|BOLf%u#&8pN#uD2O(#V_K`SdBNe9M+A#TtLh*N6HGx@ zZ1m|j^t#}ji!h)9odfBN!LS4euL~QzZxj_?ildYimMOZWI0k?bMT$HZ%@ZmHj>8Lr zn1&pqr$9HtS1D98>=M0-enS+offIbTj|WW9Iss2rimfTB|OUfg>V;ELBu=yd2gr!@$e3O)gSWqyxd{HOofiOPyV767yKZiqDR&Pp!Dlc5z@^ z@tqosv4Fa{VR?P|>@xZfzb>_|j)I+cJ-vmNWhsMtI$FaisFr26#d)}))D%8Y0dX$7 zE-?~pvJ<1DB#C(J5jldfB4M(zFQcG>$3h;SGPSGD1^gJk015@!+jU)SxnP4@ zS{%9yy21u$MUuCGg1n&dNnGOa+q?&_+3CLO9}D`Cx}0LPfL^ujC8K>#lN3k2 zoMJW7t$sb92Jx;3%I9$*O9TViit31lY#}J`O)lD05VH#XtO*AnoAv(bXrY==t7V;> zV}es=D;NW_c)Nu+qivAq7gSOb`LnU&k&J;!QI{9v*~=R-z-r3|pF4Xv5{Ry=eF16h z2P?$3$nyRYXATmM7E(hAW`p|Tqa#V)(4=cHypXnV*4iT>hrHpSx;UfE+Dz%y@!B`c zAUo)(tqBm^^+MQwQ|*hl*j@ZIy+hn5t}d zhZ=hEh#__-m(mUmS=oDG(-skjAgOsfqe-on2K<2mWHkySNDjLhUb=>o!xFFL6evFr z7qz!V>BE`P?Mq#ry3J3HBqHSO66PCEFUhO!KSl_rGuE`MnyK(&rEqM2H2jR%J#K&i zf4Sk6hi=a8fu^8%q#2TTlJZP`OD0zphfO+Rx5i%ohQSGp8HzWR$KI5Nt#)@Ra?e7; zF1hwH89Y8_x$0AG%rIe05K$XHHUX#pq2oJHy>&rg=5_7(h`3=F^<+VMpn}WH-09Hs zxQT?k-->m2NZfh4{M*x>h&$ON_CJ7R-iFR^TSJ9Pjk8Onx5J*T<0hO;(wde*IBeWh z#QZ7$z}slrk@zn|>)*5J-(4=&|M-gs%RfDU|C2Q={|gMLT4S;Xiw)*4c*7K@Pf1}G zqYoY57iEn03bcd#U*wJdzpNoqgqI|m?xy*R-dI-WEEp>kl0;>a_RIaw7$P<$NF4{7 zstg*he*C^_U68ve;gd7et@>eWzS;5R&VUKVu!@MIjBVr=b|F0X#F7UFWX%cy@j zi(M#ngH(v1uftdD#E&p>g(-uK*cvV0SJ>H+4ME=R_ zg6PcN64_*RQJ82=UYq$o+iD$V@lNvO`k0-aTM3TM`*O3V!^7L4qr;PpOImrc-z*B7wE%%5RV$y?ErPM}zodj5cA12o5%!7>*53s zM?y({=7yqKlqhn`>n=;W-=Az9gtZxv@&?m)1AjI*Xu{t%2jV)ChBMk7bfR;Z+R^oE zDTjctPPia5l#4{PimeuIBfj8piO?43Yy$XGwrwuD2MZG;7^Lgm)aEbh4GT)h|89+0 zevbzTHv2kY$})XS1Ye>EKMGU_$F*3y`!dt_XcdY)Iy317zBc? zvRO(CalgdLq4P-Rlyb?K@;#3x!Yk!)lMlUKt>R~Ja^fATq}Nc;-S|r%NQ^em1y5n+ zRZ*A~jIxNQ0fkswf+BA8QC7MLpjNjUZVvWx5~f+C@Z)$wi;?S{Q#dY|EW*N5I*0&# zG|;nA%5XaY2Bg3oNkY8hss<=-Mdnxi3N%|Bgt1`;kOr32s=Ce`@T4&xX;Ak3yf}(w zjE+OTU_Fsc5q=6@bfUIq4n^NH`Q5AC%@t9$6FN=fB8mzd(u04sH&Ah?AjxfQOSB$R z4=|%e{7}7hzzWfoO1$@>`H2W!KDf1YlHgUCOAMOzx_oh2GVos*?kOPvRo# z^n()%oIDNjKO>&NURcAX@O20x^{%kL;XzK8`W~7L*AE+vr^lYQXMWdPHNS|kbWBib z1is34rY5j3fPf+I!ALZqbk@Dn9L^Bww8cKPp^P028i_r-bNCvWLAds@=Oxi~DN9kX z3YGM06XL6gX1#Cqnk2EEv5{CL?R*2qf> z1C93kV;eDg7yfgVM!#K83rQ62?8q=BsttRy<@#4Ai)b?C*_4*rT&D#kfvK2L%E_}Y zOL}EEEi>#dBfRwvQzWT$PYlT$e-COL-cE|+G>OQKvtQM;!^fKZKSnbrQG%vJ;P5>< z6DY8wx_!8&mNuzt&7<;*Ca$X>dscqvdP*MXg>JfYdy0nY=-n-HmY!-E8YERcUCg+< z1LbM#slm+tCtrqUSiBgU)ZpLprZ=kEd{;Q0I`TkOn?CR)Y>7(xrXEeCG(Zss&*1H<8e>2i3;BQg00ec-e-p z7;NhGcJMVAPv=|Q+JQxhVI$$EBjB|V@#zsH6r85%pV{6cokQ~CRK{r0^NTabaSVLk zc$ZMUm9HbAkR`KwmVU!K?Aje`YUOVx@A0ULu)BN(b$a}NVoAFR4E`3>tSkxp+yS21 zrpPUEu~15O`6fZev0~*HiPn-dLnHaeYP}`ue@4&n1PEKJ|J%6w#{y?yW%xg1oaLX? z|9_0D|AiA(tu7V&mlM_Vp>~ShN4Zl3Ak??s0DYL^8h{(Iz1{?o@NcTfU^)Ruf{2Yj zY2; zrG%Y-b->j1!}E1t6{y^MI;cfsnKtvPU-;a(_*nRQdNgR9C+Y5-?O4-R9_zJz;Lxu6 z9lJbh=3Y1TTu}2?=zyWaV+tGV^Ie7GU7q@Ux6Os|i{3vL8>b2!7O}5ThIs*-PIYCl zX=XQG&UY7yr@Tf11M}OCnh~Jlx=cgZoLQif1Nk?R_?#H)Y#zvZ{)16rzsr8rIl#rwrLL5kf@Gb-~SAGA=VPinFnZJJQ5f<8s9X05l-1E#}t<WnLj(_8oMGe8b~PW&>wcvR1WSa4Cm5Y@^ZV*3D!0|fI)7L>E@${E06DZY4OKo}l6 zQGTV9N(Q7lvd2Tzn|1r?8DNpBN7mY+tDMYSC|Iuc*{>(Mw!-m=JJrK!>qJO*)lY-n-oR4rJ+@`d|sxW5@6>1r4lIus-) zY!gQnvs&ca)l^5m9zt{4*)mVKOsryp^D2O}ED<@G?q09s2WLlioEdo2VxpV&2}rYS<~MpSIl-cA8XH&Hrei`Bo&dzc-H0loZ6{JR zX;H0RuO$VfQVlW?v_@@0Tng$XRR3Yn!md>|SRL&^CH+-ofmVDsuc1=*HaXm88F1#P zaZgjbWWxiytC3kz<|f{tn}odpY&HdFouB&q8A1!JB6oD~NzQ{!OYSBQ-_GJOnHlApd% zC0g7U|7V)aSj$H3&mY-S>ekP`E#XXgSJ6tz4b2_XKUKh>Cj^>i3nS^g~u z`(Ha8|660&{u^{vviexe=1-)?v)ZY39yd)j5(5H57wGNO7yu_m8)=MzJJ4Y2hi`<6 zc7&zk&u*=AB+{$;lV$NDWQiaAx3r}qdGW~@a8?R{lKRW@NN(s3pR^zTqQ&1AcAFm# zw+n>(71<5pS0`SU6S>atPAO0G-@^kAnH`vg%Yl`FRCr8Eg=-QK=Tu1j*`H6yo0bbmaUz($6v#5%o(>bORvY*vVMcMi1C>HGGXTbCy`ezvoJ zdOSzB79GqP!_F?ra^$jajHwP((63FdZM$#8qUAz zsMUxze(edb70XAvrBmf5DHhUJhVORKj&?%M)#M?OU^Tsjt$u0xL`VR84{I`|!=#o5 zv+MMk!{8*0nuhOkGL^1WzNDK3LTmdkb&Bm8h{tn3+JhocX7t4vH~4h8-NqGQXxOPY zk%vX-7KEEVgbaDUYZ{9*B=a!!MW zAkXUJIYpv-&;VMvLJg;dpJOE3*dD-y>!EPg-cog?J#4!Y@{HPun<1gHWUa}FLw=bs zLg2dHd7WtaB`;if%*MoUUkMzN|L zVG`U?JYPt;MLVW9Sct145atvr4#XeJnudLCA$Y0SK@mscer|rPR7|QxgUBsRVgXmr%*EsLKs0 z6{69>)k218lGY*gnH>F(QRz>E9(YV9pxlC}#F(Z&_|m_hGqOeIRjM1qwEhao6z z>?g6-YxcAc-9*~sgXeKOKZ|s*V&AS14+h>>aD1aBFI{OSOsJ$DW9mn!iOU8S@uVmTq8Tdz-utK5&jA?2hbj9Rkj@yq6khvFqb@Skieu_&&!YSfCH7Iqtq_dK@ok z!@ZIyYdpjO4nSFUAoJZ@>6JHyx)-5a?K}H#qiB@yuBZg#Y7~oEz84O%^~dV0KJ{&1>i(&!;vv^0PaY8at%>a ziL~aUkl`!QNbl=X)S!!h&=i~>yk&yXl5&CI7$*S2X|K;4H=%mluzt9U93CI+k3BnI z93Y);fzJqjx^UBN3aNK1gt1k)J~*XkTMSctA096sbi|gZ=&HZ))PAu>3ko<7uxJsr z@9vj?{v*r}u0c?9@C%n<3W8aRh#uMqS1eMj9R@kHh*h~*gDlly)9hhCzw;B0K>d}U zI2{W-ofVR|#Q`6?6M}zj3c$+4=f_pApvBGGOsBtAL;>KHz!+Az^C;Uqn27?Q zmatj~h6%xFH;FbG#c&kBwa`t5?&+alvLq=DN0(00YvUwX(pH^`PK7VGEN+I zfg`KM4p$c1XFef%%s!cO1I&a9gZC%j{YR^P8nblk_svpZ>FhyOAMpIy2SQG3L#Tg? z&%wBoR!JP= z5P<1+LLL(3rVu4@zrKhLMTcl!m-dkaQQU9$jRllKNXn9%RE-M;@xNAj3v} z8<3OF5midMi%Q!p0TU^r351%6RaJdDCLW5bDRUZU#wdH-$Cb>KaJ{^{N}x^85IbiO|or^OAR1_ySy5nV3ExgjtN-A=Gc}{m?2+ z;R@FoeCDXD#+`xmsEj3BN%2{SlqaM~k;3|2dDFYeh7vQ{Ci1C`uelku1av{w++tJN z$vJgujd1D8y(2m9cv$+q58+|cRRDveOrwQUifOFk;8!$4Hn?oN8n_3Ye|uV$a)~BU zSbK{Ntj*G2QFGy-Xt9X`oiRHJdOqUqI*4DQVSVBNpN>X`)1JURlL)O$v+?8& zgshJQtc3NLB)?*TB|pE#=ustGfTzW}RzkP4N%<48DBgo_bQh=xr_pcsUO+-`tx@w4al7;15kG961U%jQ;igOw%)dk(NL6#XyvI;Yr11Nli*Bn&HFi%}hQJ zD>(-Yo?#j=gyG>Nm0z}}6Z4C&+~NLir}p#X{)BSyhYth)a`$?eh3%s2hc&;xK6jwm zY?o61{80=ng|{` z2!#sm|2)D@tcb9$=X~~bbojvmE7;+Hr|bLU&tw2D-rn!6MAk)iQ}kpFh-{%bF_KkB zYfay6cxnHk=Cka`I(R^S=JE!?_6zj#@TTeM>g49tmAz@nFfx}`YRXX9l;#~9MdzO? zG-1Rbc#8#bnQf?N2n^3?(gV`gXG@H*=I)R9UIF{9TUilX0E25DumQw{OCLv%_W|8O z%qi32?fUn$(cYgt{5M3w4akMWsl0`;3_A!3=q|dv1X@I@3S^+hPdm~Y##p2vAgXPG z*w=^p%|#HThuuhs8DxDW<|mP$~=+>sHGXg>VBlEZqCn6>p1-BHi-#N*nkjGmVXg zGsvw`wMu%D#;=~(wzH$~mk}M?5(6j(g8w6xwo4ZG?C_fSbBWsZ&=R3lym}c9z^x<2 zl9B;zK#MX$E@=Fj+R!7R@znXnrh9!}suC0}gssS|Fck*w1c-*QlW(`k%-Q7MKexAF zZo5W&h%Z-!xSFk~2)Hc%*_1z?joq#YxPOL!U<_(Iv7Fg~T(a@}H!uHG&kVKpF8b9(rd zh^HBM6eQ@5rBx4)4R!C5WnxJ$Q$qcIg?OXX^m3j%-G>ra1fKc6ucNI~pv`Z?fYrf7 z7E2CkLtjXoT_5T4>L^fRJS!SkQz+ivvLy7BD29tP{u0<6d3+*dhi74ThHc=+j#c9K3r>CWq|7 zCRuj+#p|a0c~9qp<2dsNwusiScsX;sf9acwbO(QSh+;fvzu~3?dZ{DjK~E%Ysl;sQ zg!kDvn^(*sPT{wWQJ&a$oN5h?)Y-O-s}%~F*Eh`|6a^Uxd9Ddeex9F=_#d#w*{qrA z5*DXb8S`!V!ddXXA?sQy)F&?N*@+dP7A$^Rs*U0?Tle3%;SFZ)h2@Hr==IcG70Vu0 z)9x)MD%d9UPTaC+gbKczCc~`UiZA^+S;W-_+0BEL?>+k_tPN6@Hqeh`=QzEdmu?<; zmI&Cc)3$F1nWqaZ-^n=RnpZ@ivT@@e^nmK5TYy`SjT4wuB-&s)d_!dZiOBc)2FP!g zL`Ml`=Ufmx3b?DNp(G92Hlvx(n>s9Is~UOSb0QerH#Y+;)2!7dD5)sTP6)29^?Xh5 zYGP5;-XgLqc3R~_qf^;$X;t3u85f4*3*KHf#}@oxk7NTf7K&Rt*vPOPBF^2dVZ}+U z)fiizP4N?|?RGgQi?y(b=L*RoF@r_C4 zd$RxNRu#86&>}9zw|L7+0i8n6`l?|LO&Ar*i+py||LW@w+QS_yY2@Mo5%jH&C3)Y0 z{|0o3{tfk?&d&dG$QhactMu3j;&k+8Sk? z);gdkgr`*k(I}cZ-A|y{uXBUgqsx*=GV$ShiHMJvq(z8F+r-*@lZM{DpCf-fH2$|mBJrxn7QXiOb#=vPb1#h-kI+->9V zG9sho(F-bt;5l|8RjGViQcW{abCU6P@kTVQ;$^9PUGX9rEnE{Fl8mt?$*Pp}3{o=k zS-pTqZ*Fz=kiJ6P(!IYUw+kxpc_AC6@Z_k+g?yCE-@aaM?wz>XH5f9#W%z7Nc_`7p zz0zW@i&%d+o%m-%CS>6!FJWX7J<|d;Hr`;u_|WF zC|akc@Z@Pp{*aG31aB>i`1WiSOQL5*O20$PD$P$5d1F6Ox zw_g-a1H$Z?DG(*CF@eYuK9R*Cn9TvD)u{>ZybMmzXPiK_CFIsvYfG%RSg{GQHZ5-E zS40iUmeKH9fc{*-$mAbRvaBZye@T`7cFAOl&W#k65NQgh(8UY_FS)i3U<7AxF{sqg zM+w4yVJN|!TgQrckWr>X!p77S4fv_+S|Q`%3Kf|nTu?jfL?SWbhX7NIY5A5db`OTA zoJb=Q+GG#hza1&eaagU4C2hN-NB6Q|`5SC+0nqiCYZPubw(M6EHXtNJObtd38+>}~ zMv24h$rp$IXhoD^kf!Nhr_kQ5E_aiq;QU2W5s<)rd;(R2!ykLm;>R!N0BVX=G$Ey^ zRQ`#hf6x7oG6=r zN7Y3GS1>W17U}!w>?>TPdH4;C(hOUzVCbtX?!1?vJTeg-5163D6dnOOrV(XJ@<5OF2uSGRem0-YQV!SE~^vQiN zbEJ?_;2(&ZgV=B<88iuB(bF34hTGX2N2u2NBpd+7T-466OPl*zt2__%;9_dyZY{;e zvQYs1^zf|}8mwVJ6KVyBSmi>dX!NP#$~;-FUuwoqYebM z4({=Jqb4+W+rYqb~4+)=98P8d`7Ld`Lyn@2W~>; zZX$ja-uIEkFUu52`k)Y*N^R4UzMVGAQ^l{S6u?)n$P9XqbrkFLvCKP8s zk=m9)VuZY<4|@FIc$qDw!`gx0I!L|l=(uV;$IIo*sl=X=2)@IRJ7-!?Y^rVc<>}v` zu3X~e$709Zd(C-%`zXWxD5<%+WBdAW_xr~iInE$tbyaDSq;Ov4f^>(pIK{q`tbt(5>ZX~e_NZHejkQ}Q|H3P^1BEFks_k3AeSIc%ys53xgfh1WWe$i1WZ0;oAi zT*U>xvQ*r`YBwh|?St*g^-`SA-=R}}uccZTvL^KK!5xtJb4(jyOtML-kG|fOKWN-p zU6FqqClJ+WIa*(trC3L}?g<{J9zBjqY}asCX9*Z(>_OF2ED!1`X;W^`2Cb(AIL0Po zh|y#iFB*%AA;jxJBww<}4n_c$IGAkXK%NHzYL%BXOQc3KPtWOSN)wYi#^y7(LXM%1 zOeS0ChEm2&=F6;|b&2YMfPPEQD{+)TNF_X=Z+(@>Qg!Bn03}=wiJ(@2{tASzGP!Zu zB16oaY`(iPE))gAZ|GyjID6#yr6)f-5ktTaB4|c4ihv|8+An{iIEf?HGYj{zWh*I% zH#$eIrtT{9g@%RWEalN$+;3Zt`~1_=6MigMx+fosWy0a`lCX)xC0 z043_2IngDgXIv8{ZjgY=s6HQ5GBlh1_s(kmKC-|0 z4SmfVleNl*p&KjHiFf90bk6=yYWlG7%o~JD)Viyomo==B!r>(Hibs~Nk`=^U{hbG{ zNHSp~vVNN9B~34KR(!W+Yyq!obIxS973b3R)17KxVY(O;mZ%DHWSGJf-=4PwWrPtRX}&aAY_gaqa1FJ9W3 z({@1Q(VU_vTGa06l`v>U3!gUSdc1-R5@U-zI&zsoLH%We)art;6*0H8QX_}TEk_c^ zYCt9q)d4fUNRi;3kn|`I*+pHWyG@JK^IeREs+Z}ht(P^8aF^Ysweo7yXtho%4C*M2 z;mi}i9OoqloeU8WTM&p6VLz1`1E<=%Z38C<+t4?e$cu2zi(3yz2&hR|>o-j_(G~IC z%*jLHMnOybx?UNxhTK~iMvKmAVArw$CzU4ku*3lS#qD$U!9(xH7_0`DX0>|qe(`I2 z3kGL1c)WFMqdgp&A}uQ9GA^l$VBbdr5Su-SD%Jd?K<`*Bq`9;8Z2oe%-VAR8tnWMn zGJ#4XqmFn1=Fn7g8coCRo^d_$@>K7Q_B~ zg`DDwk~wa<0*Ugf(mwdk@9YQM>!+LhAFcuaQxpEjk6~qC`see1UPH0}YpCXbuL11; z4Oe35Cs+9YUIW@arNGd@Tuoh}{%3wB;D6_5P$VQ8X}#Dsgpn_!isN67#Uxb=@xC}e z|1r_WiwMnmWfkBZ3U2Ira(zA6KU@@zplL*gY{kvzf55WvKnR;6)E2wxyUyW7+!5W4B0(YjN&T0Bx0e@C)6 z!s}$vsbVl97daq{3o0dW=!1f{tn!j7{KKT;K*Nu288x7U~QK zEQ`w>X)vki7cbgYtV(x|011auhFqEwSv+b>lddI_y-15LaJpJY;u5K)3;_o!Qm8X) zCXAwnKPok6rAO|YCCKPKKFPv7hJ|mH;bNYL#O$!5b9V^OWSQYh!US{UU5ynw2Ici# z^3}$-aBZl7L}J{_13W0Mr>&CRve&`j!S{**bEzR1q49N~OqJw`9y7QL-OGUoeV~9~ zF%b#_3bG(+@|YQmipMD{*#bxsQHx5xgG64vhN(nhr_-KC8d?I=#nLoDJ<1T}@$?$6 z*ra>bZh+_kI}VV`-VXjwBhDeJ7INkZkl0R19F1#&JH3SpSAhqL$c>ky`8l~63VgKK zcMk~+oEAWLiUW~6c)&^Jq^6u#64An=-bNIOOi8aa2Cs-(muGFyUH7p(oyS%ap4rGXG?>$307 zX-hF1<(P)MVga!`8Uf5w@p#?Ty8$q0zNbx8VgE`KTb@Kr$`NNM6!e)FG)fi7P~R5d zg^Ki9oWx9JOYoy1G%QAch6tia*2CT)IJ6q52RkSmH{QC=k6{J0TvFva(2C-q@s>FD zk;t5fP4W)Kh{BN}1!L?+b5Qq7ipv`U3H`iiALJ{TEqusgRE%(%VC{#Qb7!!|`PHd} zjWDzra0m&+YjQr06P-4!sM(Q_UfHNB`L_hr+OR|Whb%A7m|aMCa^6O}FXA~qZ#BRj$3*9{I(e|CWb4qmz_K}}?LN55rd zv9L0-EV9Cgu{MG(S`obq^Yqu~EoGE}J!K^~SfJ0Q5-_Fkt;-hZPs$o4Vw^s1Ee$2wamm zy$KSt3m z>TNe!5VMcf)eSTX+3)<4$+h7f2`vrFXZzoUwETxpN`#RD6(vcc z_^?maH2ivK>e|jky`5Kja*8yMFNs&JypSqa30fkr8O}`;QB}aO`|gxC3n{P7Jm?eN z>o_6Cb1E*}*aZtG$=G^pCtXLoJ~MuOJwtxg>p%zLS{YiwEKM7z4I5n6M@{!cKBOeb zTyz*V3CxvNhv!0OD%zf`^-a+G&Se{e3iwYwB+uQM(V2PF_vPAyRhKfPNQ2{hC|Zu~ z-sM(9BIuH`3Hx@(!+n{_gaoC$F~eTZ#b7s#e+T33P?OBzX-|ZBU)=ZHvP5UDI-~Vr zHDL<|N;pWuf9HEr(+^1eWFSmd9I_`e{4@UJIgNsyBfEd1=@CqzfT3V3f}U{c6bE|C2?UqKc9}eku=1@~TqN*ueL?X#t=- zieAXWw;mtoxFL8T++_3ntP`B_Hq6x<;|p|PB5LJ7mC%1RFBsYXt);>KubH8LE200G zYyZE&c3KlL)GdfV_b+oB0jQnJAC~L2cm}{WCniB8LB}8@%nraESr2}~(8!*W5BUn) zrGnI!NIhPuEb7{2zudRa>r8m|YH;|KF-Om3O75lXPuU!q(DUW^d=J)PJNV*k`g!9d z(k1t44CDIS+h^_v=Gy)BlvJJEj^T%EXGeFiMgQ&j`Wi~2!0@dfFTNr|v_XgVizW5W zHmR)YZ=h-T9hcOisE#}0obGUkLc!v3zkp%qG*Yov2_4b;ggd(=N=NG@0i&*2xZwf1 z%CE+sFD772o`1QBdcM0m1lo}QFkkt7K0Y5q-8}X$AMYOY^orXf)J&_*-p6g#Ua5*Z zQrP3jHHf?Ovqi0+O9cruxxxB%unVx z_)h1ni{UJY8wb12+CyLU_ z>Zlb&jJ;hFZHM4zzzTbfeZ2B|0b;4w;k3eUQhOiY37{K*zq_!fmI#AS%d;ZvzZJZK z=f?$uud_z#ZhIG0#9D;K_JyN%WX?Gg;#$CH(sQnX#|rT4SZiYwP9N885V|puh^1lT z+T@n`6m^pWL*%0g8HfWX3*As*7KoEiUn2z}GS&*`IM0hc9Qcxxi7H?b%pbgMDYs;fNcz0jXL_IlX@4KLb%FZJ_o zVzvw84>&cLjDh(kIb!cTz4cpYjI z^(s5aISib+Zc>B^>7Fgcm+Lc_F*DNY^}SmxnjfOM;LzSeYsJd-nV24!b*oYn1ildM zc9Mrzfy>n955FCTyBVFgnz&8tK0=fa4%cj9&5%{3ZVDS```f7mJ*q=lqWj63_Ip;) z`(J-bnn_6-)`5gQ=*#d(_md#(l!YOn?bJ77z&+cJVTnl~BHW9iK?3jYeZNfe^NF(5F2@nqGs{@zNVj6q%jgg$-PK$Ot5D*4&f}2s2quW8v!@BiX1bT_+4ThP+S62zWoXE@|(tC*Vmj%Rfw zQb*x%WR*jtqMxZI1ckoRawVbpTQ3x`({OVLAM;%PwN zw6;j%uDC1x8wcV$UfJlPB<|8HE`fkECD9hql1a!Rwi@grtpPAu)Yl1GX8@dI=66>5 z{F61)E5ew8=!CM)o#iM=FS>N{x)fRocd!iY%BHQ=<3=5D_6lJJ>R{-|-ztyAu$7u! z0gY^|Ul#?23Erun=FUY3Y@?^0-!r9MzljJShXmERU-~Cjes!&E-^^2n0rvSH082&n z**yF@!z)fy868ty+Uy+Bv#eLHLM&(rIUsG{jv(d6CwM%9mGIV`p(^AuE>!t-3do*E zg&1%4t~(0+YA~=DIbiCym$I&+^W+tUE2M#LCJ$q`(9mg(McOmJ2B$oKYw63gBv*Xu zn}b5;!bAU#-~uimJZyM>TDE{VxehtCNU&C(PsOAQg;d1S`fC2a|BNI zF}Q(xr=?9Lp38w0=qV~k4rm>winR2_2I<|7Jm4d#LtN&N$zh%?gm8}dZ^uxv<* zLJw%iW&l2%gtjD8CS7n3H*N$pd%1E~J1WPvc&s}ZavY0SRegS?HHt@453e>~O8~2! zxGu$JJyC`UsTv}e3NDoP=5l9kKI5&;`=jP;t=U5gmtMO5-d##BlYneCWGLMB5|*e) zRNZAAV;}ka4SBIPzbgZ(9CJZpOXv@E1SSC0=UqZR6~eZslp(p;^;AVw2W)U2b0dIW zq^GnsWhmO~1v$gHlQ6*)W&`n8IVn&r__a4ybyU@%?Ofp;2OO2?| zL_$*^TK%(vn+kp0VP}P}*C2N2ekphOZz={D1+enZ~#6h8K(QCCsr~xbf zjyXFC*E^{n`Viu?HV-cWQWnItOui~im=3SshILzuVL2gM?}PIajlzAwxZI~AtYGpD zj9odOfyZe8OrQHCtqfU<^KliQ`G!gPE9S-As7*R0(FsN>B}Y?^l_}2xaF@&Wt%Jlu zoB*8Lv=}KULp6?FUz1juOlr+(&qDOMXtt51ge4ZtM8GRZ zC{RkD^5TIbi8P5=*m&YWwK!X&|*Cbc|PbTHLtmxdlQ%I^*S^sORsWV zxO{S`@oe`xck3)kYu!vEEUuuTZv8_W9MVpA0nJ(PB9#H`OVFfL%Np z%JG(sF$Q)?dBEkDfqhsP^-SI2oX)E38#q{2YwsmkCVb)+WG&`3*N9BAp8jj+JM4ZM^GXw$!$W02t4%KErFz0!N%tXa zTi60x*(F@rB~u?FL2ITiJ4M;UR3r8*DwSsDhDpo*OC43{UDETC8gft|>v2?Lo?9C@Y_U=x|zJCm<0($fl*`C?(9>er+{IKJF@ z{9>9zC;rF{C+kil3OXIsI4OdLJ6Axw ziRhpAV9Cae;7q|-V5T;~Q+B<9%j>?uFgK5b4^JI1^n`7#+pk}bc^S%I9Gjy=f!YWw zuQ^K!JzVMC*@cSkoGNx(CH9}oGX&00gL3I68 z79P7AjqaD;kOAAyDh33em^4}1kmS!KjpF8FzfN`ry?6j`FdJb=0&^6cvrB~&Ul;H{ zJ3q9xuJ=cf`9JsdXtoEim)W}1XcmrYO8FOrD!^}1ZQZ}Qy6Sm72V>*yUNh(df4>6n z`NAej)`-=R9fkI$_J8iRzal4Gi#tiGO^ATR>p4i=edWr20~>^;Q2wWT&c9{@n3)*< zH?xA{|D~C5{5Ld{Elru&gP#EJpClb^g6eKkV1Iv!ER@xaX5dHp$7S2dAzT0Jp8#*9 zAFI&Xis`gUhsB7KNhDq_R?cydBGgaT58e==P~N~^F(xrJF!%PRWk-(R@5d}eGP1wx z$^U%6icO4NakZB%;n$N}UROx|n@ZU7Gc{nT^jsp*CFhsJ=aWiH6^~bmR;NQ7!Qg3H zV4-MdJLj1RMvGRiL-R8}pdr&Jb3R3j#Tp%=QRG@@UW8w2SzzE%#aKHdjPBY$8+X{EjH~bWWJQCo*w*IoIta|7{oa0 za7<(%A*#AE4LxN)v1S!4TySSeh?3I0fp_1gcx)L7@b(XUVp3RieO}JYx+8c2WCgQV ztL#&~61m+;-drb?{B&(yt5XA8R_$Ijg*=!NpzOW=TIUlqqXaihlZvwlFWCv9{kga=&xQ%d&+1cG`UuI(eb)>a3@m9d(sJgL|6uV=vnXalZAZ1o0_~X~ILHBk3iV!(<`CFS(EG^@gJr|q z0Utu^VneJeK%)thRSPnVO^-*J0A~}HvvNRK%9O~|{83KxIt1V{9`{E3L}QxEX_^uN zLXwrT0INmQ#0VhBReL2w4njX@WfmbfJ%KCC`viGU2`P!_$s8{BMf6TqW;#}t=>D3> zRjOUt%5eN~Q6R_(N&lfi+8($y#nqnIQA#5UXBTm!tBrBpV#R^iB}?i$ObJQe(USoM zq|`4o*dD2ZUaHDrevv;Vl9s+WRk@fdEvl2%G>y;M9J)vtPnWeBJjU z)$=%|wnn1A0kP^i(@aJevd7jMHh(@?+X7pSYq)0>nber4&Z|0-`m|HhuM)h?hEs*O z`Lwk8sjW&;e-k?8XRn$Hrn(z70?|ZdSubXa=ck{!d7=PTY{xEK?sIi@8<(8xQXv}- z4dhEoVl?t}-`awq;PSvv2xv&QKdN(MU7ESKw{vZSz(=H$=OG8nPe?K(jf#?rD50?# z2p$BLZ#aX&a0BxMNF|XwAOQ56;tO6LOP%c~I}R`0kXCz|;iGm3^w)!shNdVIs!8-H z#-BJPTjIt+P2#9U38`9MJ7)Dmf#_3EWjC#2X}OAk;_$fQu%|n#Z9+-38o0F-guz8K z(RC(TkDIU*d|4LT^Dv_=O#E zMsW0RnT_Wfzbx+$Yw{D4P9IJUD>Ie#+|o@pQ`gy&>rApIzE6+0PvMj@5SU7&Ivvso z1}`$hg`#ckf+i?3TBLFv5=~+=4H4_i#Z0Ni$aHkF_;ry2I8Qc}!Dfjr>~IC-=wH@q z;i@b|Y%=H3NQoK;dMxv=PsUp~WHmoznVKHiovu@fh_k2XT>K`Dr9%6QKtGgJ6@E+H zjrD5yyA3PrNM>(kQ=hP0y}X*>*!jVo!zN#ET|bXccTZnlpY>^+=&BB-NPvMSd*ep| z^pv$-22Kg&PgF3f8Z?K#Bic+QUr#~d`+XGBPBzDQpKI`wb*NT52KxnZv{K?4X#EBq`naCGU3=hib$F?6c5 z6S-Jvwo^4m!+^R)R5;g@Fk}o^AZ}#hX~dCmU!WtR{?1hFFC56un<;02)XXkX%WGdB z!=pr0=c&MyH4-JNk>m+8?v*MaQ35M0=D!b$r!Ald=QY4 zDGrh$uqbW{Jhjt{4?mhbiCcqsX4_yzImITngu&701IL4Jb13!#MP%CfKh&k z$t>2->Mdrh$O#rx^ru!$IMo+*rWGmbSa~^5I5zTy66V^r0ap7bl z2LTK9MBc6={d^UgLCrBhUNknL1H`tsSxEu2p|BD;(#l~0Xo+69?^^u?#H9X(Q1rB^ zf@p4BoOt{i{Lv4gY=Bl6K%xiu%L|t;7x+;0s$&-9(ZEGWK)hy_OuZqK7g>#x} zhXUghs88KR6;eOZ0iLL&#?d4;TZz`dbu0Wvj#cwab$A(Gcrle*5j}KHcJviH^ivwm z5o|nX%K>k=VwPf(6uW5ssN%Yv%X!ySKg>rEuz}2t3S@j5k|uYqz+l8FZTCTG0DD2yFEspfG}CuGJ>MA>*Wao%cLS(6u ziuP0Fpw?>&-|$ikW$S%t2vxbqrCWxQ;9MWIE!?B7iE=UJvpkxy&S(Pj$f2qFvh#EO z4RMKFssl2sTVZ2Y&{;xSnsBE@4rggISBHU_iWrJK6MY3U+6$Q__EM;ie~ zv-$*^M5W_ow#VvYikvne&G2U)>Ed+3c3Ds?bYb!wC#gl~=6X$u=`9`TZ9{s|)={3c zx@~OE1I_Nc-tCUB-gq##lAArILZVrJcFiUKF`so)!~&&kggWSaa~!aamzz+goF>Pr z5*SM;%7ZOdoGaTC-mq&UpduMMxZAh(n!0n#V!mA5T(y}1ePuO7u(-zYo|Pm0>R)}Q znU7rE010>%j9os?Oxkf9$d}(_l+Vh9RwoA6JuSy$>2yZO^(czJrjG3R&{@Fa9K9SP zg{83Tj(!UpjV95~w)HI&I2-^4oxD?uK+CKN>#VjhuMn+@U=q)fi;2&EI!JhNgU^S?QTE7Rr#f^BTIT`4R1=*nA(O7wP!qi zNXt05j+mtN0hc9FM7_J5eyz!Vb*BwXbGb<861sS7V@=fLc8)7JTVS+qAhjc;)4eQ6 z7h(_Q=yV^d#$K)0XOnqV5ps7o=_Sgfy+3WIY4jEh)t{dKdpdj@Sh>uhZXigNveDeW z)>nr&Lk~Rj|6}Z(qAcCEZQZbK+qRKm+eU_M+qRWqJHxhZ+s?4##++x*yVf~-J*>B( z|7n!cTJNp4`qgX0bJia^X#*pOcC^eL#2}2iSIR|#j6B89)Q4lWLe|qb0Fjm%;HHGo ztF}lmjqF|RLhRsFE;`XSTSMBwnYg#gy9e5a`B|@0sLXcvRluWjRO+Ka(?nAv2_ zCtiUXCnJL{#g#=`99IT5$pL@R}=@y!e`tG0tze5D#m3p;JL zT59hi^$^7G`3R2syeDivH)NaI!MKOkzYgu~Vj-+mbmkCFouz3%O#RB&XZOht|D>fE z8D;9YBc|EwyWYHqY2??3YW1W=ufmc^3gbe9o~mk8$N&ulrTQq*-^W252xnWx{Df&5 zcd+~B6TzPcm>wGL?~{~t@7Pz7@-`pc&1-V8^ULw?iDm%4_i{WcYxy8lvx6K_=yZLr zcQN3_y=pa4SmDt_74O8Z3DjBg2>$$w0?V}_jPw$08~*B>@d;cb-<t?}&DS)D#@qmLRU{q3?~3{xmI|DKrq{+^h;Je~iKM|psQ^O=32Tkng* zt))585y@8<{(E3j^e2@tCK?krrvKgo!vz16$IAm9F}WugGkzFTLArpRpxhu$he(rH zOoJfAUa-M}F1sKQUT1>ex3)5j0W7ir!}tO)&kA6_!bDAl^UKs%q@XD?*%Wc zuR_P^S&vev$_7y_;C7@tOC3&s1vI`;t0)X9OTerRWcRr&kt?i5wOibS)X7bxr4o_y zF4MtZdJU4~^bw1qMI@pF2*JE9p(1Fxc|esCERNU$F8l!{zjtVAqM$12mX|GQiIp*W z8V3zYhq`w$niKxkDU1Rph79vj3{04SG=PF?jX0wYxT*>e+{)rmFk*3}Lryv16ok)M zrIjG*1T0PT1`RTz+HXYGG_a_kT=F(GrZusIK|AZn6=keCcd;~`7@0GHzLc|3v{$aT zWcrp!V*(qf`=U(${V46hX8=To?fR#aGW0K(!%bdrAEki)J3^_lcI zuEjUNFMAGnu+^`)j&V{qAR%s9=@pv9YD5?yFi(yX!M{xsoPfKXD3%P@zqoO?LxPS4 zcn=dA=mY>5W&T3)@5KnBv->gYgxNI+CyIX_=h$2x zw}HL!jO8#(1Azr2rgDY7_d-l<&*-qMxfH&QXx`+wAp!g(m{YJ2Q@~RkL8;9@=tE*1 zVXjnxO$5N2X%byI9BR%E?eeuZXey~UK!wr5^<&3iu-Qd4E}LQ2+R@bt?X@gYXgETY z<6OO@bpyZyV${Z#yhsd_Ni#|Fz5^fjY8*9q8z5V`Pe@7d0f=S>cDI#sa{k0~2jiCL z)zYjq;uQ}Hw;5GzEQ`-VCuHp;5D+i3ic(Dn&OAnO%8d=xJLbmno2cl_`Kdi|3 zgn&Rvhe5Rcoy_{RektB+s|botg$_t>_T&Nn6Wz+=Kp$abV318~E?KQ#d7|NIWVYR> zTt>D`)8x9@)`{p@R}76F6~A@>_xWoa33KQ^)?*hbK_U+NJq=-_Z%aws)tb1O+wG`~;@zunqb`~ko75@f2CP7Q^shFW<%23=^QtG|BOT4PM-_$b(&`Q_W zZ=)6K>vq2wct@tdT_fP#VAI2z8_r1gSclWJk{in2wznjbdS@iuk7CFa1-jRQGALF{9CZwaE4hlpD+){Prh()zb5r*pJSH;8BLPh-<`#OR*9Vt+k3D^{f7Vb zZTBM;rhM-U5Z@1=D4t~uv%oNQ6#n@D0mB%>oX?m5tpdM)fl6dEW*oI2RcbmOTpnW1 zCblqDiLl>7pxG!`8Dh^y2-dtu&vp9Ffx#^sm}rs}I;_`E@5<_j@t0pDN%ufvae%hfT~7X(&!prv~UtuNmezD;a@sE4UjlZ6c}S+{oQ zy($s#B};5ZN-w}kK&?C%XC!p^Q^3~&O=Fzl7I0s;q&6j)&~}BB+y`%!Zf#-j2iZ`QMzX?rpV^NWgW5iH~>8e zG@>xAg(S5-z6q}fCi7IwKLXZ15X?htN0r&ANIkU74tuq<^ao6?6S`##=0d!ePb}#d zy~7Llq={OnO9tprlLpe@kWNVuJKV-cNhy8ER(F8Z2w1Q2TCgwu;b^tNP*7y_hj+fs ze(X0h!lh^TA!=Fy5Yq|zEUTm<_v$}e?aWXmbnDH+pHIrstujuAiOE=cvVJlD+~^x< z2)6W23cWwseNwFKtuM6v2D|=#3Wm7Vh`3@I9Tf z1~fODX^v0ln{xsruk%6wIP9@bRB}aSR|c3bsO*)+tqHOLK$@0=`J3NMU`Cqp{uEgg zST-c4JwM)Pt4|y~B+c+yyLUs8tZ>O!9@0Whx>SW@Q)n?ia#+~@SXVA^@2b6YnmykS zK+fG+nADy^mxfz2zFY}{bze3kN(cc?-bjvjZ7tupaFn%Qo)&8bV{hX9wP0XPe|#nh zn32T9#%hrFMvX!MS2zE|%F5Q8HM*ytD7DHc7k`Q$jJee2j9f-ppPb;JfmW83Kr&df zF`zNutYYDANPMJs4_UJT@n_$6&glKNG)*j{0o3t@?)m8Ir_0Wfmph$+)6}L*;=A0? zqEAn#d_wBTTNdNqitu?aS11CqhENXLtB|V_IT;l^3tpjy^;i~XssN{j)elu#$PVKu z+%^LmoBUdH_M_p6B0*fPZAMd(D*#i%Li9AIsQcL&bm{5&CThAWvr+~m5LI+}Plm*; zGj>z#yQsSGkdQANeuNqv2YOwZP|o_FTp0CmeZ|CQiI>K36OUEG>q6l%6<+b$2UPHk z;2Nj!%!3SZ(DOq)c|ZdPb@>g&$TQ!@#?vfs3YgQcB~=dYMzZpDRULO35L5q1zJii$FdClQyaI!A_Rp+r)D2GW`HEdI(3@WGJvt!M9pB z)V86}-~Z>NI8)JVH4@-$as|qVkJ0guNn~}QvoY+saM#6- zmz2kh+c5UsJnhy9z!;*;!K3MC;lSABPuq6m`n)o{yCW1dKX2E*zdye9?z%FoL+|cC z=tp51oBQHAXr0f7xSVyF6>o*|!~ObBE~4z~i4ebxpm;yQ_$#^Sf4V^<^mjMFZnP@i z!clmmbox7(qVbMJ={1GnKP& z_q1QE%rhL8USFe6=Yz=*K*LCUakv4%{f{h7F3xc1$=d+m+Ta;F>2NuksiwfNuV(03 zpQTkI94fh;fWw`6sDlexfI(f43^ja{&Yk(o#d$w19M9}aNa3uYEe)V#2H>u)VcAqa z$&Ug=BlsQpyp@?ERxdpCi7M&&mX5TISrd4>z;_rT`p>q3TOC={kdVcBGqjFR^yR?1 z%(OL?0F1n5Q2blj0a7mRZ%>3$=6oD6Bm;niLICj}cbTiRAJhemHtZU$qTS{C9n`-` zVk2&nO6$!P@-tJZ{A^_q6PXCtPLvXXXq5&_y7?m60xAG!$&&;HMit^kxU@j%{W&?0 zgTGCNEjWSN8EV9+3EDs7 z)yB|I&jX*o!QZsq>xgVUyt(4W5g^E3m@h~IHu<_>xz%gLap^Sk8z3Z9t?9*CQsBI-9%3>ItZ)maR#0BXoPmWk z2lT~Re^n>tN!z%f2bk9$$OVj9h)dwAhkJ#ej?PhOYGfpEl#l4Hi5bTDU*sEv6R=xx zm)*TT*9(c`DnN#7_b4JKa>SwF|J-SjM+zO4||{ z=7ds#G;vjOFl#5-?0uJCB^1Y`@<$UL;Ys zfo+aHbTdaJHaK;|Hurc?AIh-GTTdy8JRFg1q76*3KP8glUS_SXyBrpxB91Sm;a+BI zFC1=3wV88+coOH+c=v8O41{46B0%??$I@||&!doXX4_AtsenPvYHRTOV59t%7G|xu zIuiIXhE!$DIGaO7Yf*n#j&3|qD*cbdpYp;!53|T3q))o!u|fYr<(`PcpTC`H9vFiW zs7?EQYH<_9(&4y|K~I$8b+RV5q@%atCG5`MBX)88G)Sklhac6=a zdnouFY<}TFXJ1elNWR|g6g-UYiQxE953rJ(A5o*l3+wPklY3mh-2A8uH<&Y(ljBS6 zW37I-y6_PCA=DdxQz?ZWi$^2Xpe?Ju#mEHtwDd%y&Z=pn8^2wg8_9K3oImw8ImlEt z+Uo114VZTQyxZOCp>Ak2=|i@ciJD~z-LlBo(5bT8trSsP&Dnai7wzz<7<0_&ye?DB z>#W4^eXu;kF3s;$Nw(Q6LD4WJ8$kZ_xpa7igcLa>8$D)z>O3v>x!YHlTE|M4e*CcllFbT2M|)7t9|K zU>$fGz3knv#12v9a;_h#AaGUC-GyVZ_X1`{to}<&j99-OMrYJ@L1ptyS1xaBQ{Kr% zFQ5<622;liX*>kuLXxf__#JV3)Uz!D+M&R3Y92%8a?3krA| zj*7h-j(=_~6Y%{Q_i;)0kIVfcrjCdB8QWNg~uFoIV4O(DFX) z1jrRj_3XZIxBwIsj6K$;-?T3Jv&FsvUM7PsALEHc)NMB6u?0Orq7b|l1bTCGAoq@~ z*?|9NfcQx1nThJj%^Ik1mS|mJ#d@Z6?Hn}t?@60J>;S6$0h8D(DywM<%`<81s>*iG^N+|h zb(y)kd_1G)>b8VB?E4?|7(#N=tA@g~D7>ZXHf|)$tSJ=`-a!E_>(jL@epnu5mr>4;UqKs$53|>4~E2rTeKkJgo=6YT<+6s zd)Lw+D8`$6W`X+f`m9ouM}aF}M~%JcCJL+4NnkIk&V}Rf$t8+Px2cfAJ9rDzt`H$D zqF_~ZFO1#as!pxRdbH~dvzM`Ya5P(@U|x}8fKn~f@KzAVQmf8r2q!ATSXLsWSJ``U zh6zrU57T2y;mh%sza#4kilohu7P3r9)(Sv+jj)p#jGJNevN4^NKxW9UUm~a&C9sAj zs_~^yq?6U_sY1^4@Gn#sUWfGEfggUfcLAyk25AvHPc3;*?9KeKKpz%e&r0TO1$aP7 za8$FvRS1!!m8$aCiUo^x2)@ByDIvLtLy1`h{Qn1S>-I2yVV@aPSn-oen)^fnQcY=% z)k%l<{ZNf-` z4~WjSr?Tu{t~wHwI|?X$?po!Kifj{G)%eMwJw>UMacWfg(npknDG6xBuIB-eXFz$e zzKI0VQ9rfHhRF2*<`XB`kV0LHfKtfQ1DCnw>N0^xZ9mk_ATQ&Rd}|tUWtf+BE++sS z%N&C$GRF;@di7k)uKm{LB;pjmLVlXx4U)9zkNn631I^Vt~n5Z)(JSkiW zuBGSY^m`Ovw?g$g&@-(4&Yo7_pFO@Z(dj+J5l@|l;wU!-EsGAU(QisD_)KlH2F1CB z*{4)}a6E2&L{%#Lu?N*}1XZ&m%|9A>N#+_hsR|C7dU+|~Kxa>Ls;qxLri4$~5m9)! z^RpZ-tG@xnt7bVS@0235{P);b;q5(CEX332T#eVPQs8)%Pqa}hxyYX`p9ujJRaJy7 z3`^QI$$2Y!i6*54B$8^&ohXJX!(3ZmKQL=HxVQlVw=4+xWiYv-y$_1ZCY{z)yezCv z=$yH@m4I#Oi3 zVGJhiyP4lmowCH>;<6=bqA{88gRMo+7kqbNNr}w}crvq(@42me`Za+k#wp=UQj1GV z=vcwS$d;N?OI8>^?p>+%Tf_5Z%_K}PFr)h9l|aL*tD8s5G{1yWx>0H+(DXW?5jX~A z38dpNcis_^XYik^ooDo{m0bb2n*=9WNonKRuTN>578R`tZWO`~@k(&gj0G!yc}Ayc zzp708mQcCYH4EHg(XpLyArfiw_E@IeNmUNkw4E7MLTqFHE1GoiuQFdv1$%K zTgT~G%~;&pArH|N%9nq?CH6TlA;TQ#b^mVorCW*ST!kE>_$2Xxe>N>^Qo}Epq*Y%1 z$F*F94sv+nV)|UP<{k&c`7CSe7fSoFFLQ%#fO54|*(@s=-%O=O4p-ca%C)9X!3eMd+h7e=M}n>1ArG~r6ffi8BEoc|xi%;ia^KU5e>ODh3z;xl=-(dR$Gt3`jF!~1R-+kX8xzUUofB0Mz@-2;QyEdfk z;2Dn{^N;|2d~=1Ni{0ENP;3ah3Bqe@yZdgVCY11Sp#(_yrQ+w_Z9{wk&LGq4|I^Xp zA90R}fraI-@Bg|jLvjAI0R3-Ai~k0WHmIc)d)|cT^HekA2+-aUmIOirlhwEkdixzK z!Uy90oq{z&In!}}?aI+V4nv=?kK6z`btRcHvOB@Ptu0;=ne*xR`cz2ftYDJev6N~( zJ6}J0t@q{gI_^5(Eqhk)@oZb}`}G<-59HfE>WS;)&C7XAN2d41RCMm%^=yZWUqiP) zU*enN^GX+OrtDT1CBAGd+^CDjChUy)>xh_(UylWwQTG@zn_0W`m5Fastic1dB4*iL zxFRKz_Ioelk2w}%G{9G&!N~`8F}pK1Ub*vOZ-jaRvjO z?CN$D`EHiJwHEljJ{X^OKaulwR$lR6gNJJlp?D9n|1aq!(oS{g#tm-La4d$zMfoJ4>_{G%eIB+g$?+Y71i(ThUhjQYQ`ux4%{oz$xK;`G16;`w;1j40J-0A*l| zShPK?Ruw1&dNU$P!;eVfKap5WtIc<>X9;ayef<2l^e?QnaVgLIL-5O~vD%sOPC%EM z@zUza!`c$i{cSG&(>?CMY#5BN;5|rv87*7=f0dE)r0}g1;=>wcbJ7y^iWvGE5EvoV z1^ahhz#Onmk1&p5y-$6QR1ZzmKtkZonxWxhT`$n^Nqp5tEIA4e=6*0<$H(jx<3{}E z+A(RKqLjvg1nG;KVG%kx5;Epi54>5R=6sw&K=`1=C-TsqxjCNJnZbmgZnAyHa7qON zE=fMo8!$1&UrobNLHFny<`+}fOV+m3vzEkm$k>e_ynQMvIr*Lc#)uZVfVxT&Tv{{| zV_T;sTu0+{2|`*-?hyg&zoDv-KE;L2McxZ-Rx#uWat@{|6e6&#u|Gn1MWT+sQx!FN zV}c5Y@*I~Ik9PXIxu?)2)bzo^UrDod`vMSQ92*q@x*fUwsDlI?dJrgJvgRi3Hm3?J zdWEqx1ye@UMbdZX=)=oAwAL>#b<7VHJz5Z!b$wEN~$P=|tT(@^r`VU*UAX6y{3NN%k;Va_ex~`gB1ULEG+9t8l zWyL;Ch1Ge4@wQsyurFhz32kCy35~1Zd5xssUwy_P$N zxCa@H1~ymw#%16tp=G>W&=*v+80f#|Z^8t`$6I4CcAw;7_;x2#63sp0RznD3i48S4 z-#O?9JH0?5(8A~4kXjOEMGc(U{JSIFjqOry#w;&jdv(naS)GswGO8L@&|lBtZV{8L9(wtie- zCgOSW-yU*nf%Kba5vv5X60x6wo zzaFxStf>a>%3Ckr*<#uihFF&7r)(7y4-p;=GD6}@?5Rvyg?BFfLhF&CBYSvN9zUgk zi)0Cv?~1U(pC1=1is#Gvt$|h#g;0lL2A**~SG(R*^-FBbJu(;^Imw(*kx&W%^jhJV zw9TtKs`sr+8>O6hW5aN5_fhp~Iq5wmIhN>}cOn)RS~4itDr6u`AHA#{W zz^p(bHm!zB!g$s>2uiDP3+Vwl8Od*H)jyA8xJ*&x=e;_!RXFK8HoUBYks8Kh?+S>B zE)^z*B4_XQF#{5PTZ|wk3MQPPrYHkRpV$~*8r5q6x%Z=ae#}XI#c3q9B3MHpXS25S z=JJL_p?jhWD6|QrdfI;9AAs4V=Tq2y%*aq>LLfZw$I78F;p7ia|8tx>44Z%tFS=#8 z6Cq_aeI(GUB%VlT&c5r|;^;r5ulEU$;<`o#f_HqJD-V0;Xl>IGwo0b5n#~nA{X^hx zEW3FGSTV_9U2-4RoU`{G77&iK3i8z+GU?orIZU!c1xp6;5{$ePnSgZa0rtQWluvOD?HypRK&Tpi5CGm zMbQt7sgLW@N zB()p&a5IdZT1Mb|8cV@KT?NHH!?cwE+G(&%lVd?&rJ)ISPx0)k^Cn*>kqeA%T=%61 zksMzwR;7<2TDK9qS{`*ud!0Qi2J9Dj-E&{9g(~78qmj#gq9He>Zl|`tKKqUzx!~ai-Y|FS z%US1I8qH-EdbACTX;!~h3b%QNny{UBl)F(wu{^`&BMra(2`VV)drXyB;b+}r(5 zZ*-3$d!tq-N}(1L;59NvaR;H7F|U+TVSa%-*I57J_h`IpU0ZKlT(TkC*=UETH_Owf zDRpbt4Tt4xQn>^%Xe|}8E`*QNGyxZH;;kAcrylklX+G<6Ukt*;gB1*3)4ovx>w8v1 zWo37v!~EL%#12HjBKFWr1E#*LJh}x-@4R@ZW#*2eaZ{_|#Upa}YhOXH1uc%Pn{=7n?BuR zcaXIXLG~h~D-?Ij%@76eQ3ng1TqWf(S5j!NBZ{(JwVlP=Yi?h^|7fRlbOhkeMT2bF zM)eN4sYjCwT$(2_y6rd3Em2)O>J9To-e6Ci@5>hlKK?qoUTP?2UTFr* z#U^U7pZVTMGxKp@{#;C}hQF`T`TBS@MLu0^CIt9$x9)htMSGFTG(K+YaZuC?muP=k z@bXGUoW1G8R5-+(z1OKEP&J&ZM)bx<50jt^<9o$2q$RrqB_gPp2&0+~16vUM`zcW; zdvyY`R)V&fWdut`bL#xUWFHENRIz=bf!~n(lsS{m z4W^b7-yF%=66DdNzSxr?WZrF! z2|0})r8&lTw8$vN(-4bDP!uIgmBkqORe~Lsg9+WsdX-x$(cpo~i}d5UWLyqzV|Idx zLw~xw=X(ZHOXu2bVLl($;xyS&6WFr^W|No>yKnatAnXd1l~meT57;H=2Dzt#Dh@SW za792_qyV|LH^2?O0KZHLtIl6PzI_Kbg@r@w73JS#sTQGf8MLD4f|#+NfE}a_*@atIita zp7H*Ge{6lKN*Idx3W9EUdLz#N+~&zdMY3PZfQ^BHUM*tN$w3$cjN{lrnKNKY=98oG zNaxHgA)^>jNE5eIwj;E-Q1g6F(Q-pwnaF9WB|sScbi+a_l%vfa^%)g@xcbRwVl%4l zZ4$9bMP)lOFR5MD;`_fi|u^m#T ze4Y!Fa*oiL8no=A2(q|!-brUAG(z5CFaFL)J_}-c z{*JG6aL`I&QM@shM+McVXYMxrrF^I}wY7LbP8+7jGiVZH*xS^KFX=c?ws^RVYXl~n zEL5ngplzdlP28?5{E>+5O@nbGg4dpv;Y_>)fc2wh)J9?WEBP6Iqd0S0>E38-#$M}aZ+ z1rw@}^|oJquR{gk*sj^hz`BN&=~dT^&72auJ5WOVz8kLo#REvh1@nd4{5Y|DXlf;S zXhmM3Pfl{XZH;p!Z9`?+O$C`Rr(#>^-NS^t-q4q(KFJIt+{w3Oy(WL8-hOk{tIKyc zlx?*fq_Sv9t%xePPv!$$&?9(%-&qFtW$MCTS>+3Z->54s4tR}EXCVE(s&ph@@z;C- zRsW#s{f9F7e~RDVk~!1A(b5?i{x>I)k>S4qC06}AD6u7f3k(d*MHkdTs{QXWsR<(C ze>B&v7qJldsGeiJhIHn`r=?W72Vdv4_{<`d7{Mas>kYh-H#s{`;FPHn(HBpUzf>` z_=!NII=P`G>9iF?Kyu`ge3F$SS(Vw^oMg72)TSKXszbVl;2yH!y*SZ{j?^2Im^5-p zrjR}hg;-&7HHkD@^(;W1tp`69YY(v&J%96hezUm=lN+)e%l|9tSL{*Y-uw9ZTmR+5 zjREV7=n9^xskb7Zx6aXDi9@MFlVTnA*$R7{Iu=rM*UUTCsnxxELM=_>TDB%2xnkHF zIT&EtxHAh}ClZ`l0HmHtoy>S&sTS)T>rDJ`i{uc6OqLbLc0i?Ve>N+hNS%*N@uYPV zB&@5%v7Ev91IIpCNcwl!WlkJz<2nIteeaYJo#6*loJRZGyI{aJPcB*7l2tw*|gjdi?D*|l3-O_8#1x;bHmVnE3RRs~O)*55L$*AT63b_4cGNFlML@hqNW`w;zp7ZN-JU%yK_ZRd0M75m2^9 zn~uUWn~oaIpeC#Tn5o5}3GlBv^_{ykxIE^&XtqHzs-FlkUrcEEN9Dy+-^W%ogzr*qM zz7<8GCG#P>!1J!{r&Yx#rKUMRqhHeD{WP-HhAoyS72^rW_$VwUKQfyu=ZqRsNJjQP z@<;K@ZJ%RUK8M|uJ>u#1Sz{E(o`n%?@?$kHInvMJLoyP~BN#D4=J;69lJ04KP5O<; zAHg&n5i{YIe1z3Z3Ru*|5u&W0rsA#87?F%cEyX7laH4S#UVB@aw?e8G5JJNJws=P$ zifn*SwqPmNrUIWbq>L2i`xu8!MuNxqs?{gDS`>A3?kI)LSfWc@Uw2Ql{%3-D@t|)p z9(n7Q6OW|d?BKOvK)&}Xgto|0QtS8%}}GT z%*a6lN}&npky^@mjdMP>M(U*eIu&%k^%SW>s~o=m;Vxi}hDNZR z{8{MY>{+}8`l1-qKm$x7js{@pOiH^@9IY1EzrEmd+fR+dLQR}IlTFZfM0Olo8O2Cg7g3dd8>6h4pi0v#*31UM#$6s1 zqwW{$kA3GK86zsvGPn~X4Cu;}oH+9U2MfV1#FNo@-2zeRdRz-ZO11wM?m8GxjTZ9 z^LC4}FNn7`a}mvcs}Zp+2g05bBK(+tETl7f{HKq1U~4I+tRX`DzIro>eZa zcGSS1l_fWLM<9^RN)rubX;~zi(oat;W}Z-r@UK{Tqm8tS#o{+#Xw2^YV#szlL@;Z7 zFx9$qtz3s+3kUGru@B|s0!_4?n*@R9$zcD|ewIDd)(?Pu)iUEI+}a@ST>cIFE*eR8 z1OYn>B0&r#!o-E0o^$FM;&ThkojR;;^E745Vr}7ZHu6(y5HJtBu{aTX@FOc%u1$t; zp7Uygnjsk_WiW*!r=l^Igl_38^m<-#P7BSd17H6+3GS8LV;^yhvzu~qx<9t#aS-4| zQltZ(vPQlsq>$4hmA*&<=oPrM8(GrcQLl_8*h>Q0PTx0Z7f+;QZcPUy{GBK@>Fs-` z3y?~zt>Hg*sDE^CMmC0jso{(a{~JTd$nf8A2>DEoSv;TYR$o4!cPKaQ*d5@ncc*`aE8+R#%&n}=&U46a!|Y$o>ysY(R-yKflKD%P;Y@T$ z0#$!K&?IiuyvOe}_y1%qrTvw)^!a~hEqzCq(we?M#QbzFs#&8megDjDjp+&)G_|AG z`<1$_yOoopCwtw*UGQ7R(^78y&+p$z#4~btX2zH>`i#2fd2k-8aI8YfJXFRv=xjUT zEUkSi>4z7_6tV4Vvv|*6nv6y0+8+}`piKB={(!KLh=@1Pr9nNg_PenVG4E%+!uR(` zbUm@+%svAS3Yk+d;Ez#~S=6++s|gp((cZIU}RUcsVcz zPOiu@`kGp!h0`EN1T>QYm{CKTbIkT>L`9L4xrHpnU*cR5<7Tn&c>(#biafN`h5EiX ze7i`R2RZcPu~I-(IzKu=68ykWM68PZDEH;OuG0%p?`D&u9adXWiBQjMNjLsnt0 zY6gBtsW)a+A?M;%2avN3g!*6;@KyA5mt-y zi_3y#kWIHqA}J7T%BDvdlC+FK2#fT5`Wgzzfd_0{P^*q(5YB}(0vM!Wl5Q;wlq#tr zofhThU77)cC8ZVa57}R`9s$U>N0d365Rr^sQn4GzU~L#7tD!##1ICX7J6?yNE{&C? zB;XpNP!IpP{+aR=V>;UEVDz(!OH`272S8v|Jawg7qoF4Q@V&IV;QV5MT=K`Y6 zD>x4#tn}zbB<|E8s@{MNjtr`Vh}J0y>4gE_j#{)lyKtr-ICJG3R~mM=w2^)0`fHHH zIm^PRsg4vleoj($N~eM_4pv07Uh^UU7Y^PTs>;R=Uu)1C1ji!u{SWrw<6_ntlWp0b zh2jy*EBne1yl7nJ)Kk*=gn4lBM}kg2oT6w=q>IiZC8biJE?cz^7=ICpeKo@;>9Po_;J zrFs^U9I1p%$k54NyFekkK%wI4DG@k9{KQtiG^EKrUp2*!{P>~*HI#D-t!$2QWG78n zAF>ZddLaz>(r)9;DYk95X}fKbWP}aIRwzo~&|ECGGy7q~_d<{2ue zaw%uo-nkR6FoD<+0)#ue-7jmfeXZavjya^KM-8t{ORYfq`%(77sK>Pos^T#(i~T@2 z&IO*7q+ZEu*|Uqow(9-thyCU!kF(&uv+H26F!)0}Wp*MN3a!{A6`W)BLxv-6oT66O zR#H*^C3Vqg8*%9I>k!xl)DW@aBi1g}4?#-4>@d!-lbyMjoy@ANveR-9n@KO_Rx5Pz z?FwYGlAcfc05IF-b=zscK3itzn9~(zAs$>i+ff~|ma_{%$Nl<`gtxwPinmu4U~U@E zAPI7Nj2x9{S~b#ml9GNX4RD!c09rq8fd%pRkvnB~hr|SE867N}!wW?Pd7`4VYDITV z+#bzD*ial0*3iDo_N2Q)u)hrZH=>?9dgHzUG5Zeo`OSLrw zUrnCfz*%QpO6?CA{4<{KEu4u~anofeDr~YztH1a}zcT?v+R{rt>`ev%&XuonOiZlE zsSG~mCnSMqj5boK?D;w}A)K<_p;X9vME8FrFNz?%Ho0P7y;vBD8Jt7A$n|=rIEoaq zkRqRmR%`$@(jWC&Rr`e(fui@{lUkp|*ydE^eD27i$A;wD2IQO|ds3~5+pInFEzNBf z&XUHrTqdwZ{yG)wXepANV2G<98sn%S9(%thJ{6&_wYzcg+Xe0vN`Em{6t9t&#`3}O zK@(DiK5JH4tSG*BDQ^sV98uycB7{Dn-+8H4lnfb`oJD(hqd#+drH+~q=PH`bL!`M? zvR2IcvU!GoZUxu*kNxf+F_w{y{of{6jDNXT{<^6BOQU6E{BL+vRchlgn`|(fZ`2KN zcDM?1*bFce-k>9Nm!NGBZI+1yX_PZow{N>b3C6>>DAvb7KY8Itg(8xi;Lkjtn&%{+ z)?lar?tg-yioN)}{eHWQeyy1QzJ|$Jf2UcwBChL#?t2_BN*#Az%bfC8Y%Is~O;gcs zJI$Y6Nj;s)2;P4?@dTtl0#1nUUHn&E=Fd>`am~K{Egzt>L42wRnKqiVVbYkNaej9N zcX{~AEM54E`|uBsHmGI~&-eEA27IfdLoZLmZ&!~ed{%62fR9hDtI}LE-Q!+RiH$1_ zK76}9&P|DYO7k3o%TJhgD@xcnvVG3xTbc>HngxCOi~#B^6c7udyMBI&J{g!9Br$i8 zWEl1+R?zT)q;5*JI6r09fO<+N-=EjkjI8n5mIBkWtF32KXt8z#i^<-I&Rr5Q2|-K+ z_l6kRQDghk()U5+pBZa!NZsmT4o`S|dN+G6B5Fyf&o{@w)SlWMl zd=D@W2g=8Z6T8I$FDHzX*|dK;A6t6|%J3-L?^jHp0eUl#p%C**xVOv66E9C8gbZ#> zXIn*B&Wjb&mZac&z=Yj&P)<7A3%=(rM|Nx~(`7xu=a40JwTXIj&TS zS?v6VS_C7P9%gCWj7O;%^>rYl|2{fR& z`RacCutc|tJTz)RzwpU-hdoXI*D^=MVJneXC0h2k1dxt~tm$*OJ3Ch~x}_{60gV-JU(PcPZ8 zi>E#i&jr;r^!#mMPrAVXPVQG7Po0$K5?QZ1 z5jeM(hp)o+uW%~>gJRH9T{QywDXgE~wiJi>N@?knl~~p&WP9Q7aQKhL3&XvU*pfJS zAtOQNo~mwv9rg80^u@Oz*2gRo--uA=4NzVI9)ZWSPP(h__YrybMt62YRT_bP^0Mv- zA7Kt4sNvR&# z9>MESG-Uf-PY!$F_ptRj1A^Sib}}a&%yw0O;Fy7}+fOy!ZS@F6Ff8mwS2p3yDwBqo zH`y9h8ZQ%4i`JvWL9TLX+t7aFH0k1eq*-DD+DmDMW$Wm5@VuxvvyvoQY^>gvWA;PLaNf_mfDol4E z(A9#q4~#{qbx842mxXeK1cOr?o~YLjwj{LPFe?bV+EpR=a^zb0ptW|QigSsS@!p(z zJReoi(1VL-3YSi2h0*jRnJx4mT=$4C*ozKZ`FS-rs`qPw(a(Qy;{sX|#GRZNkF*vy zy0X`YOAaiO$X(VHb|Ywz9Fs>VJ^lX6j#aY4F4m~t+eKm%v%I4V3v$>ZhL%~L)gqp2 z_b&R(f$RFPwT&Z5K4j7z54yhs8JK2u8cAi5p>EtOHQM9|$($sMdt;4}_J(X4_wwPT zukeVBCxdB+#5ci*|G3!MFzDQI)Mg^RLHk%yvv|!^w%A-kV1>hMCoblkFpZE=G^FtO zj<9#Or@^F}hfJkBY&+eNOGZ9V@y(j#me^X zR>C{s2O87^x#WX)Jimk{l~F+$&oL=*C3S5_O;*BTlaf*X=Sg^JOSORr(OZ&QrU1i% zBd%gXx0){?MmeDHe=HmS42n5982_zm{Ih2E?^WZ!fk0GgNW`9h$8G)v&(zlrU$g3A zU|5CgOh`4TJ86`Gd~=KT`7@*ki+v9~R}?;jS>!bq`F$YQzILsBN?R-gh1j@RpR;?1 zbsoWUmr~VFgtl2kwB8wol(ra;na-w~F|Nv8Q76i|C{d19}R%raDwppn1QoA${HH_5HV4yzWUJ@>~e zExmuNE;WgQDcGYq@z=o8`Dh$L%o#6O2;w021bh375-9J8zcFP^BjFUWE0+=WF`CXH zpH8GPnq&NbjJ;EIrs>uN8r!yQ+qUggY^P$|wpCHZwry5y+fGh;@4v_CGfrRZ`*-9f z4%-kv-`Cd4d|q zn-FcOVo%TVL{6jm+k#dwCxn!%kBqS8GP*`r(pHyR2Nm-;E5o0G(#9HrW>DjmN zqM`xB@EA<_UIgtT0zyd?wt5WZ<99=C1F$Ab-P8f0a3OQ3DtS$RqT=7r9U$a46!>D; z>ki5oawbl0+6N&&Z=e~FJ{=<(H*xCwl{ItJve1ufv-o7hdXj(?f};ZWhBQv0VB|b} z#1ecEaHwN0iHHrPQYgihtriu>HR>jGOw!D3sVzfNhLkP6 zHWPb!m+02hr@;2ieR7!=lPsz8f;Ny#>jJSee`?JXL(R%lsL}UVLULV;Ux(fIh9|dRE6pvi7wxK%jetje;j(jBy5;T~E}KPnmAt3k zkvxc=@Eiz+mFX_D3*xg=+{~x>EgvxM14(E{iQ?oE?!dEqRBonr4fzA9t4^}#=tHRQ z*U{Yv@%R53Q-jpX4;c%fenE;~D=+fxiCYQ$Pe8u5%HeONRmn^;mV+kP z$Z(#5h1FW(Q>1+ozhqzl_txl}MOj!{lZG0Vo-|iOFS^I&r&^UN0niEpCc_PwSc5k< z7C8x5l{Tlb{vaf~oia^7D-{AmS@u_H|A}UVd)#$*BHc4b(n%|t?r(8Curq!wsM&`T zK(5-ts0wsm^~;IRG;J~WjQt6F=6eEWPPNGqHAJ0un|eB?m(?e@@aMvRl(bIHjwXgS z|G>b%50s4mOciEi{9Bmt4`^iiUy=!e)kY)M84x<(sGZ>&3KJ>^4M65EE_>F=EJg_T zQ$U4~Ms#l9%0yF)J$VcbR<+7it`;j2zPC8LCvl5nPn&{UfDa6TU`3zYZdd%R(ycn+ zubl3mN1jJs_^J$5_=_Kr9-j434Q;+}ESiaOrgO{t9RI zE?R4{th^jE6!Knx@y~h>31+TJ#lz|V6c~2z3HgBA@b!Yy03k&p0ivcxS((t%Fc4=) zGH+zo$;?88f|`=?L#Cb6L^VY*g;i5*X-4Ah)5%SVm{U|=ed%_RSY}wrB@r47nSus^ z$tB)}_lrWn6p)pJw9A0}gXq#=5MP5uw?N{<{Q?-?Iu0Nyuv#TVuzh6v1CjtrW;=+m z=gNVv<#}l^llMi(w0d86S5bu0-Vz2AkNC;N%n;x z-fBz7E=?zP-UnWCT22{bWv{x+I)jY;lh=}_WT=~ zs4iQNcThi89JVB|3@^^)$5!kpJ@UWPTi!BSln6NO&+33I*wl)rii3Z@vnDaBI$6wR z_6M%xn%b^swk=UmHpy;Y+^>?fmR0C_A~SEzAdEk*@@MW3tN!tFv+lg8p*JlMYwjG> z5_R%TB5Qr7TEC_=T*G!fz5P1TB)jxjf`(nk)%&`4>t*jz`+30FN4r|hJdB=ZjbX{G z!~Y|LU555+@k2IyWvQ#XeIBHPmUsIY32%rGN0_0~B#8qT#Vw?mBdtNlg)>D9w8PX^ zvtDIfsPGRA6Wxvk!_}6e&b{A2Zz0e_q0`jE5G6j*$2(C~KhtX&U*1XLE4bn%fB3)6 zDF69+{k6_;{3E7{k?H?$3uk2dUwq-6-#MM%0pI_bQ3%R56a0I6NVq9$nr*<34QI9S z1!mEX^=y{8yCq_(E{bP#OH%bI7wS&kpho7#Hy!xfb(V3d8HV{#k0BO0@TuQeI8 zNUI1b_#=#-7VeMp9IcYd83^W>Zp}DpM(Jk2v~{jEFb4Ik3~I4AyEB`zgmVQKaT?S8 z%eIGJ8c+sc-YN3|^lggHV6uNtUR}t!ywriD&i-`vO~;F^rb1h$!txp)CNJM^st@uV zv2%uI-grJwrn-M_s?ExQ5IN(NDyQ|9q}GGI_y}+J&jj*m@ z7EGCRi)j=DeoOG+dK~91Xu1Hr5p7WE+7#IjJw=l_m{HhC(lVBnDKZP@<%x|rpzT~G zOXf7jpYEMW23Z?ym%4DXVy3I+3C)o6xSIN@FleFS_mHg%PyQx)_n|h9yL^>T@ppZW zLdQUIhc+;JUHt;W*`P4_C_NxU0zun!z?1sJ0&?f<2*Z&1)J{myp|UV!9pB&NKw}6| z`Wd>yNZF_Q_boHVJ-)#XIQ;cjLQVh}1`=YJ6{g_0%nbTLneyQbU~ntbLJ&Y!3l))H z)FoKrvWiaASyu*VXvOu>iFCDRyP%xu4**9DIEnA~^Qu}xdQYXj>m)5IKRD_wGb<`4A|#c&KI~O8uF3&3;ol^a5!bzfwTyvP~tk zS^)9|jFy>uVEMWu8H2;mfAC}CQKGB@bjWlP%s|I&NNF!iqX*%%lBQVFAQCT8{$|a5 zJLy40Rf=*D#DPyF3^+t9sJn?72t<6v97^cqw0G>F4~H}2oIC+3kz#))r`Xm2$VK`S z44cMrcy6a9Nw4Q49yWX5c$;TlV+j-Q!DqoTl)BnW1MM4G_GPhi!JL?MAaNXB_)fkWE2rfsB0*Cgt6LM92(TnY+z=Zsia!xLW;Yi% zF19T^uil&57+`?9Bm7-bJgFdPwpQHp(xJhG$V=SY_h&<{?sy1x0|I8k5gDsWUk;(} zyLJ$)T(bfxvLO(cHwXw@>ry6(8*U&=+N+oV?0!e51OE!9Zv1wv@9njttQu`&K)2a=*oGv zSOdHsVLpPC&JowzTO7Hy7)p}ZUfO>-`A$ArDyHZQTAFW~VFK^X(o?If0)*HTbV*e%q94=NNc($Q&qA&i7$vM7$82sj?nsx$v3)JZ0wJ3wN>z zuQ@%hN`feZVBCZTp34Gz{4$AVU1e5dli#rPe8Mp;d5Jf2& zXQY6@gkuW&&LCCJ4{SBWHdK$Iy+9e09rD+d&+DIS6lFr>q9s6`(;I(1M<^0{ukUE~ zx2MLk_9ry65HMh z>+Vtywm}c5;^M{F=$5 zLazdXQ3XOa??H8txk=-Fm>KVcSKMpBTI>oO1>kF#*HI!Uftw!R-|a3XDCdWngNd85 zGZE==$w7coZL1IQP&d$gAqJ<4*^T(ghg(p_r_D3js7MEcA=y~FLa&@$3&~03FB-vv zQgC1fU*8wbji8zJDyBorpFDbUU}&GVe# zaLWFA=&_H1*~_J@H=KgA+!&zE>;xu$ z97>rDEDrGqXK8_pDy^zBHahNu2ufWP1w%W5tH+AepG8-=e#?-{PkrT`47c78eOvhj zrraXC2@R@iL0^oYl_A+o(QDVkCPVi=7Q}8t{41x$AyWqfwPq9`zney~fX~!lB7Ez2 za9jPpyfk^xMI>Gp=^l`+G4Z{2x~ltk+x6&HMffZ7u{_rHg!OAcDZPKm!cLl@7^~Df zHiLvZ14i|0N)%YhV?U}mnQWHu^$V6YnnS?GPd%{up37U!sAlIWTOVSuj-jP*@OOlCZdXTlrFI zay;B|9;x@3_@C~rIo$GZ3#$0LfNe=sGO6j>lnyR7Dkxmn>JAIS?A%bo5xJYjw+}rX z)Gmw4!`s8~)w!Y6$*X{<;qNzEZ>*Fm-v%cY{Z8wSEZJ1|@`_&b><+7jmc z(;fD>2}n}Y?_wY^RF+eCh-&^_8IUrISx-C3~M zuW(4#J7J*_B5NDcVY@Ifqo7q<)BNJZuL;MtpBUwb+r+!WpPcnZ7UUiRlbeMZG>v_pg#MZ-Vuatf3}ADt zE@%Dx+}s(KP%ZM2S3JX!V|~Wx4kiu|4|e;j)-A17n=ypWmjL3`y2)?t6*ub&w_TX!EZ@Qs^ zLVpJ0eDb(sUvalFq_6B;B{sUMH1T|~zJu@*k_7l-&;U+1h+88%*Evj?0#JH zbF##G{_ETO_eq5 zcQX6pTQ7^hnx%XjOn6Az;K;sZGYr+C2tuJQA3w%c$v)i~sk$`E?{}*EkA7M*-jDDv z7F1OX#^pKHhaV^vYe(|IRcg?lwrSlHx>&H)>XbKVOvKIl0&P2U2mN^@dgfHVruK^V4sLJ%_RBlQCZT$vdM)#hk(o=%H3RIyYjh0w%FP^CoP-ybc4H zceI`7-?iqp8WGomq`E;6G;NPD4G?IMu__Ki+--63_D^)BdW>0%SCKI<9`aH ztLgsXNd6HrQW-fq2gaE=)M=d1a9samfyRZ}*h!S;0w6=05T>iam>x0OHqBPQ$=rwf zE1uo%ahxuf%zC*sR(XDcMBuV=En5sj?@qwr8gA{#PBtDwknTcPP0dLPh2t?jTtgmL z<}P|7AuM_P0uBqpS|7Wu4Pup8GW8I#gc~?m-ZP}HhM}J}+r>RFxhmJ;a0>6i*gli( zO#l_siwNhkyhl&MsS_?_rdVwdHF-WoXqsXgN`cBo8jxou?`8?qAMCEke)%DFQvK~@ zy>~6J>^$|iPy>t6Z;;BYRxgdwk-+ucQi9{GzKR$??(^CAW|kM&&-J^n9r*RYbJSo? z=5#wYMn$QJO?bk6o0%=~Q2cWv6G{(UT`W zmPvwN;)o8-qQJg4{KcOgVcpg1+_JS;nv-QV}SEr`0%kLPc zvy{LK_I`Cv9h{&zukAEk5zLLzOu>eSHxi*A_Kj=1J!SftZl7X9?s{)5YPQ4eUL4ch zeBCnt>f1^%zuEMAQR)W10gri~Bt=?i^I+_jy8VeYdP|LAq|i0nQm3PC&d*t*i5@WTqL}#@-YD+vD!w8>Z|u1+@e&V=U=h) z@0&Oy6Z`+0O2NqdFJ?XF|HZ8L`~O0G�Z*7@#UzB!IAhOg$jCGZVoaG4@k9LUtGt z^uLeg!ATV1NzJu}%@nmw>VsP5T;^X^pEj~qT!F&a0ByCQP52K_<6D#XcB|9TCm{m9 zs~1;A7IhWD!8#9l`?X{g>i=U45v}uo@pD)G^ z9zBVzayuXlynm4UjNN5pXYSbT?}4fg!_kkQ16ySUMD*B3kH&A^vOhbzZK|FQH`Krb z7E+RrgU>VyN%%tz&$AK)p<@aHAa`I4=tveL%#|3k>>EPR;9^^5yBnd5HH7@4^2Ld% z!e@ho=_d-qBjnz{!n-i{#m&N}#@LiXN9={1>T)zS#_2;&40UdTM8miO%zH%05O18E z#kT2ZNo$U8S>7a`^270dxD%1iK?@15`)a;Zqlw7=0fMMEsa$f8SU)D7&w6ptG@}qH z0fuZHk^ssq2pXkeS@_f|q(K5vm1U_(EnlVymbEuJddhj*i37op;L+tb?4ykgIRkU; zpqw(>&_xXJa*O=I!j?qHJm!Ty+a+>MRr&j;GgU;X&Or0-%sGbDHil1yf~eViMFfOd zy1Qf$5OaZbMH-9Ut#B6SzF>QZbEMI3Ou;XUNCG2oBm z&^HOT(y`#_NTp2^?(7lQ=UkJDDzPgYKq!2847WxjNG<8}?8Y{yik}U!Kd2(>x%C@an5}dUqwRc z==CZ?R&GSD)Wmv-@|Kv9{*u2g0j7hgb|hC*Z*W@6#vup}da(qZd*lYFISee~>+CTlN6{#BqI2UK?Jp z-O(H~qB_K&HVJYWNdyE0ceNPA7drpl5LV?eQ^TU)_-LwO@kUh}&EaYSGp9K52HS0= z8_H>LD5gdu^I^C7W?5L*0P@;m>)v0rrwd*QQJJg{*@+|s6_$Rc1adZ{I*NlXYsQ0L z$0d;3dV~0Oddi6dmpm^>>^|4)FW2kh&1v87(CfgWy^0?=vP3S3wSBEhu)7EGLFb<8 z;-sJ+-eVMmrso;-T9^p7qY&R%0YRcRY<{g~mKYycpQp&z@2#912#9%g1#p_T9K2&? z8EjJLrNR1|0kP|R91AROOYbG+>3f7)+1stdeBs7TJ#rFOxx+Japor zCZ7Cqp}rJZJ!^i`6#PiM#TM;Yy!dOJEHfo{b!#yWRnW&QMc1vEyABC*JgvE-sF&|v=f#(7jE&pB0qcLz@;{<3CiZ{G zGnoGtZTw?sW&WSsecwat`Zx74U46~j(?;}A1B3Bjdmpy|yr7-U-}b)vZ+qV#IVETG zb|VXkh}c;8mHU|wr`LAo>=W1_I)M8N~rmE#z5Hw*6q>a?&5(LSN7Vcj_MK(Y(9 zV!y56A27HXAtuL?an8ZdcNy{$&Zp_eoGUHfHD{#lgj-jQ1k&Qv@Y6eqxWhrn5zJ&y zeYd$c4JZKQVz1PCg@t4=9vKJNBm)Fg9a~5Z51tCQXj5U_l&|k7BFRmezu3OM@cKa@ z4nMHGyF^WYw*;j=Yly%-nYv~J6~miqo3Cw7HREN^%Xs#fMLmRRr4BYLel_QZUqAyd zn0?K@`3lhQ`GX%Os#2BG(7yyq^jP9MrPyA5{wS~t+K+&49-2;KLqe4u5CE^8FQGdJ zP0Kool$AzCsuv41X>;<89HNXMD1Fi_Ho+)J3V@tq0x==)E5{MTI>>N(5^VG*zOG$h z?KZ!xMp0fQ{rMVP-rg%IZ(Y=}r1#tXBl@MgS3CiQ63sbr*UZO{QA zvB3XW)I};F3^BuF873t1B1#%sz1BRknnLc43CJr|35I9kZmvk=Sg+2MYVsSR?R9Si zKHt#*V-zfGWo}|PHm3$5x2ZbIpQfvZ>-FJ@X^R${_q>f!^ z&_eAy3J_4W>n4H`Wl5x{7gE!^r%l$3;%|Q~m^kCXJtf)j`n(_@rML2DuW%ci- z4i2csnnMX59`&&MBPPykBaiF-kVH9cAPtPg5;gMz#+Snnr*A?LW#(I8+vloSTqJgi zDSiKSBK|GA^)DV=gKLYuFEQU=RupzuG#X>thueJXK1PJDvb~ z&dkuME;V|qLCGc5Er^Y@#}|qkQJ}1ei`7fSZtNDNbZ{h)$|XKZSNkQ{5p31p`N%1O6}DmB#zh~NykSFlZD7k3fl}+VF*(IuK`N5 zkz%O*qZ15)wHeW~;@^9X7JLI;zaQETEwjI*wKxaSxI_w+#K{xnRz9FJ_svzh>vK?w zq{c0qlbn6_Nvk*~pV& zP+b8=a0;b67$888zdD_Xdw=l!l?{sx`^CA`8>*W_M@RPdOH9K-BQ!Jre(S)@TT*f8 zH)IHi1zaPX)fw*LV%5tz^FESVFhD{Da4=nAR>M_EM*V=7d=OmZC{8~RSFN>_0`;eo zRe}h2(hTwzbbCki-S*7Uk^%3J=qz*Rx;w|W)rTWfek}vE6lo&-lcuWHl2vgBARZ@s zS4Jtk&3Hcpg&*C!-MB)|5X)yq)#ocHlt!HHwFCy8NWaqB!Ru(Z@RBrpE>)<0BJC(U z2y2}m@7scn@qEv|PUc#Ebg+J3=cvT5FItt*jp>+1XYRa;K8LM6exVK2Lj5Jfg$@BUzN{ia)=my4!PSsCy{a$}^l^2^ znDUuQVi1&UEGcokGdqnI)2RJoQwV2|@6dhsLJ=z>fLIjo`5IA6^wnnbmE)4T8>Tf= zY0(JvMBtvD(6NLY&TmlApaN4h@4L-WT#El-vkNyTc%t?$$R2ta{mWZfF}uZr zM-zTZiMH;VdWA9A@z>esg{&P|pfWx{hj-TQSoXO{sW-;9GH^ZWL4&tq9Dt02$Q)Y0xM}i-GG?tW2~hMj4?L*!U0=;I#Z+@jPx@Cp1ISXraysspvT`BQiem zB$C!Mr5xkGQ9+~3W$A2kvrH9nDTN{Rd{b2;JxnqP?``W)Qy#AzE$6C-r=RiZ#YHbk z>ZrL7{Y7InO8QnH2Ow!+{R4%!gZO(z=iz$Xf+OSv;S7oGtTUUJh}a{^fyh$gD|zq` zjxEjwPlhNRI=V#{ebz7wOL-+~*Y@j61s3yxD~m}XVCCckvHQit$Ssg-!8jkSbi?Yt z^iWP_NjAA(7WOvE>w+dLf*xw$TCyS#q3@(M z%4R*>qIs_=>_dxedP_Xc_3|v zP1q&(C$f`$7|O^3ZzYg(FZowJ`;Un^>@KZj`ca?G0VG?Y&Rd=<>LK9zmVJvQO z%O(qu6`3cl!#FoN8Tb5!+T|M@vx;(YaRxY;TbL^czC)#aI(4jHXG;sgyM-xS591;J z9Ao=(6IJs&L^(6hDHnx5=gs{mlc61ORb7f_1v~JvRloFoOqHKA!D#vJXMA_mzcjn( zqfREbN)DDk)f>G<6?}V2yZDOW(L70Li1FQJr447u;_kYXq*8~aYQtU=M6>HTwV!-0Q%BBT2FN3Fq)Qbo?UukPLBbj?aK7 z_S3_gryuU>-aS3Jb!_|F8{r|!He87kS}vr1Wc9Pe$_)qr=468IfaFb^FD6(xQsAY5 z)%1WH{RpvObbph|Vzx7P)ehxtfBxFkv_Yug_9N>BD|7QBt{~x=FP95LEUXDr9mfhV z7urk%CP3T)o%N*wOB}Nj%@o~E-y`G$jYo=9kPR0@g+&?fy6>-pITH` zIH_P_ds^S60^e_DNkn2i4Otvxd4^l^et0vDV;CW>U6=r!q2`^b)3WgG&!XI7@)wPt z2L}pPS7F=8XZ5XGjJu;-XeeB)VX=-^IUicbvPM0RM~;Pa)w9)ayYbpS;xcJh!Y?Uq z<+-Q_@s|oHtjFJhg@yn_eURU6CJY1IQES6b{>?1vye@+iEt?1+y@9{Xz;(XTPOA2nHjQtm! zP5Tmg>`(t(oh}tBwY$2X?<F#Sr|*}_Ohp@7aP>3`7|R2AVYZA#-v=b5>ju$NE68Nn3eO%rWR_9 z?o1D+h8LZO%;}6xamjvZ6hEct=*-%^A;9J9VcY$LGmwVP4g8D-MbXdk*Hgyx^vo@+ zn4K#CixS^SZ}JmgfEeCwFQwa)7_G>av!`@_3k(LS+26i?WX53=or?}d>VF%+BF_EqB3qWQg_@^|Fg=;WMR|2kNHTifx# z-?YKdl_^{~Vv){zNdCSWHh(XyVrhWE8JIX#fRH7cx$#RJ1#``V6RXVF$T~~QR`Sr! z&Jy#-BA^O>-&ezHm^}IsD@lNG(QI>AgT7q{#uH?3$Z_OTlaul2MGi(pAGSkhXPQsn z25syHhBaDOGM3mJ#ONSqX>ycP+reF-_7qNJ9%8r^H!?#5gi)b{6+7x43XrA+kv|E@ z-HbAX*yyuGM)`ouY+^!;NU@@!C8QZEAhPAFBD?3msYhjv)&na<0h?;Fs8i}}G+h{= zk5_UsKaPrnVz$MpSkKhJGNS;gJaSEbo;XvhQwxIc!5uvV_8 zg|WTB$bnGV z8Kg9=Cp12I$Xfz>td%9~b52MQWX1Wj0kdE@`>1U05nPoW&_bD7xnE)KJPMkk3a7;t zf}YP2A9%O8{HZ5M-9cNF$#wPZ;ThB%67oFCwJO?i`ct#o5C8nm26pyK zN69Utd}gXqY0Wx6KH&K`F-lE5YEkh9U$C%|KSwn}iq2FO!o(W;(pE|(zP~=fqFXAK z{uR^yKCXSc+W)zg{>?uB1JhXl7f052Cam2$+kdvwZwb$Ll9UF-wZ~8B{qObzyok+J z5{TXZX2NbuGf}pO!+LU}m_1Lj?@v@Nfb4bm^MBh_i|%WP0i*VYt-b(81Jb~ofgHAi5Hl3v7*pfh=EaqmN6V|wjH)ntL*(N{*?;yr{PAJm36KAX z5vMc{hA6SY^T@(D<)cSNZOH)iIvH^dl1JB4k^dV~fulBRUcLsPC;AZI#8mOPlK-UN z``Qi~F8MtrPP0Ye*9{Vu-7d6->lu|$a5u=` zDe}8nl(Fv-^d6utOh=ZVl#C=Xz=Gxbt6-tfrcs-XH9K``d^@TrUV}NU&hpW{z!w(* zQ8wQ1@#8>K>^7@4r_NX_gsSf%i5qS|KFwE|Z9V52BGQ{3XyU^A)3Boq{0p6Mc81_2zz!oPg&gT`k8 z`3#*H?l_c_zhEw-$iCsJ)vOqzIoHb;SKBvMieJ(tM~rw<9_xmSX-h5D!BM4J zJW%z+mpW}+?{L7@%VMrbn68%*lTmef(fySkId88;9~Q?)x=!|%;R}iz{MSY~x&;&9 z9k-5iiAyhP{!=^Fh1H#%7$_Lom#YB~F<2>3h=M2fgwLy-dF0TBtzTVR&lcxG!dsvx9&y5}Vcm;T=+*^AS!hZ zO3?FZQ8kF`-DZif&8TlbQ~{ChGE%G-_%tFZ)K(iBi}ocI36uZXce+s0`7(Tm7p;FF z`#0?S51{>L^JM&Isu1hHnBZ9d7ZY5g#(32?6TC64?uNVF<{|x^^Lp6RILb0b_%EDKyoEe5lezC=xnJMKayQ@VMfmPc z%ulXTM$l*GO5biD9uc>{dgXle;Jzt`g`3p;sPFwV=I(xxVVcj2%garf1uHl}mN+(3 zEP04Rr8305Y2mnVShQk@rwYs4zR;Fxsh=m470LJ-9e`s4o-fKGY$$f#{>$k3#1#B@ z$Xn=>IQ9{_r^@u*)l+lm*~hgl>G2P&$)=+8Jw;tb9jo`PyGM&}EMl(i|3!4mq*o`lVB#IyBTgts2PTYb|QvTvRM@ zvJF$m#4ee!w5s72w0CW;3YeDUY?C9T=b&!%cY#>8p2EB9K-=48X0Av)?BJHH44|Q2 zBzr1pks$`*If0_qDRvUsesuwTm>(v%Pf>7%c6g_|gn-6#IK4}GGq#x{724{F!xYvA zgRV6%ZGDOQSyXYDtdD~eTDTXI9sKCSm_=ZuvBhvu0dfe5R>J-2l->sxNb3YM^{KXW z8WL~YWCGSFMw2EVTZx))HD&Xn&M{6=I7*Z93Mq#~IF4mr%LNOiuqzp2`b{J;zRJ`+eXM16^O?%D23e1NEobxRk zQSx!9j2cQ9@mCfEi=!R~(Y6(DUygltj^rhDDCcfj@^%9}z@*lw{tl`!d02)&&`&Cz zq5pbLfm95NfB7kRZ8#cnF86x#NhsF?1=NHeRu!ygyb1@nmSF61Q-D?@KQ2~yuTWeV zw-F>#soXTRz+C_Y_CfVSn3OcRPw_^MlY|!wbayjkY+w$_^vB#ImnVkq8O6B@NHx** z9hz-VFU*A85ch*Xa^|A|vz1#9#UCGWBN`=H<@b$8bK#W+qq)T2Y=#govT%`PiM?Yv zkH%sjTVT81?JLP<2=bmW(WBlpN9A;nqdmZc z#=`msMAh5cD8=lpownJEYD;Jd*lmVJFLM(63&P`+iKLJ%R2uQb>b$FeSmE8%S8Ef( z34Rf7FPdD1YpsEg?R^Y@6Z>K0|B7Vgqu}Ow(X5XE%AG#RY&}3`%~5K#GsGO;(+f1j zVRD_uap&#j<^S0vgO#Lpt3l#=w~4F!*rP_rV!DF1sG-V~5Ngx(m6|(?+OZbgyCw*q zdjsWM;JKt>D`11^gXv?kg${H}q`uyl61hf;s8cBCPARN3gP!-IhcVdiU1$&K&Wa;g zLvQFVR$CV3noW>QKUd82wQ)^v@A*3LuaCmtcSlARR?fdZ_%8{~`ZqWI&w==V@ss`j zCZRXJX_{{R{CdNrDm_v+h(nui4w`4A_gi(@>jrc~>dW7FUsB9U&wOK$BXwF{^=f&c z#_Rn3BwVWe@+c0S0=_r$ql>zI`*`Z7$8YO~E63;gJWJ```r-iba?O4c;HL*a(y3^+q?MfOxyFdHb+wtJ{(mM5v%djB@s?E$F4EK5L|D$af2sdME z8pQ0^wp|s{L>Al^ZvpWCF!m0CnWkN|c5K_WZQHhO+o;&KZQHhOSDaK*afN@n&*}5` zpa%E}nXH}knsKNoy`9nAalR82f%Wt9Mg5todwR&;ty)Gjpk|YGA zWM&ya-V0R9u>B;=wo(%5bo&5eukhFS-{JIfm>m#F>xGb*&Xv1)Ne7cA-Bg{a1LZ>j za_wj=I)a>{R-m!TU z0nL$I<`VRXg`wXJRk8l>XMc~prUBlWuDP0t<68i86XMF0M>5A0sw zB(Gf}@v9T*T2Sv1IF=LGPL>wCQ)Nk{$hXf_ip>N9Phbgc&SNmPH@LZ_UQ#i1(16-8 zP{yYYh*`n|E2`-*x=niADqvHZtHmG~F^dAEndX%86J%*zW>h9stmGX9rN|ik%Y* zigPVBu|;(9Vkgz7s^mn!K?##G*OJED_{7}LQ6%Y?M)7gMcO})yP6(mwzQIq*OVu9p z&tg^UFt`-Rl?3vcmv_ysK>~9UFpx3=eWqp~iqs;#swPSdnF(NQ)Ur5qMNAg zD?6~e)_w!xY~e=I?M*VF-h@UO~-GOEkzPgNOYMZ!LQ&@Bye?k-QFMQPGDBA>>g7zFwyMUkbr`4 z=X7a^q$y9UE-)QUT9%a`M&YnF{yrh1az47W!Pv8QoqJ){YsO_=UoRVm1hIuu()eM@i?8)pp71Q)60+HVqR2^(eY z*YXFnv^Md75^Pxi5qlX~*#5m9{(0R0_j>qWB2P6KQ<2+Zw|w8*VL(cqpA-XxyJ{oA zUJlHOp@X!QaaX`+;-(C*=2xOvO@yP{2Ck}n&mQfP@bldH&8$l)yW1I&06*E;B1PWb zC(p-I>D#5rE8(Gh+sFIUdGal%3nP$kcdigb5AE%mU0}}*@c^bTu-Vnp>CzZGw77M6 zy%S2i6N_*jN)&8*1M3(94J0iNvknIsJg*9xHiI#=xEtnYAuwH=a`?wQDfVka*T=%g z!yy;L&h=4PQ*Cqp9*fj5Qon0*h{shH+DSzvd5=zHeLL(<9_G{)^? zD&7$n4qs)QUV(nHp*Uvf1rMUEfv3UdN`Of(Zj0vd%SUbLCKT?c&@e%QHQ#CpV^!Lz z3m)B9J14I<$lBR?tr`M}@;@0K?Ifb!epmt${t_LIgVgj?s#zYJeiOmaaFShYG=D6WO7Yuy z#+gmwZgvF)(G41_Enp~}dy9KvJW9-*U9OFO#$)%u8MILc>5oVp>WSY`E(yf#;Kas* zV(e`!hzr=tW6;Yrf{_5t@vWoElZ{k)J1z%Of>!{@h#ee=ttXF#b^x`opvzVMw$M!w-j{g==M{H zqwOjQrspy@uC97Rb#NDxn$5`I)ZFuco@arCgs1DBtM=tTG{D}Fw$@Mku*C1| zGbdwscaB3fUKA$qf|HsF%Bq8}yc3;SH(_E*l!Bes`CnhNv@^y8tyqd=*;*qjr6kWm z(t5X(yb;dY_VX=F)wIG|H0v*>wZf|LwVekmMoBxr&KdzK?|d{tnzq!o^4P2_K{%bn zXDW1(Gb)EMucxET=BaxcA#BK}F@6sQ6LJjnTF3}^Twa@v> z8YSqdD_}NHX7HY$jCA{rSuNPJCMB^^<`~d$(aIMlPCu?WK^Md^Y(g~Pmo7jH zvqIO2CfkWN8%(WuWvW0ER71bY1E%ixhZrg?-We)R=Pt6sRP$Hv@8ig=Pl`Ct-*Dsr z?iX@lrc*~>pb~lmhalT8p<$zo;9nVmkv#Q=^XwlV`Mw_BJ=*!<^HzB{*w<~zJh*vX zDHY{V#iDxqgYyaIxf6jJofc0sGKeHg|3HwZJD}0XM?YB4HF0b9Ya*Wz_lgl6$&<~J zAx8fJ2aHHg%M3P^e_Av~z-9DMPIu1epbqFoEGds!Z_Z2>ad0S=G=CDP!5x&+1jB?O zcg_(s=T=3=hzU*BWWvGmoUyBEOfE?~rSAu&BtZq_QY>}ks&c~#G z>P=9OVVErTPy^2Lg{lOHtUHW&T3v}2MTatIlH5%GDY>M1fElV&bAqE@ay|XpAVR@USZ6K2# zjZvA$qFJ=_skQ_G9Ud(GjNIN$gEX8w^YPQ^&S7w2Lhk-vdM>x_QW1z*+QJzm(`|ae zaL(xaiPNZ)3kll(I$$!tf2(Z|jSwqX`Knfx&D~|Z9Z?!Y$@u4*b4I*92kwP6|Fwro zEA<9V#Z1yUolKOd$B7GB))l}XOHg6T1PjVUDK#D^Etu?v3958t%Zu(T=K;Xg<~7{x z{MdoEJW1{GRIT59?1Ap!-N>`Maqgs3S>nKOCrvy;9P7nzboP10_< zDieADQvY<6Y-+7YLF3G1I|Vd`r$v)rDzHLXISff-%QPrpkWJ|LXEhCzS`XuoY6i3& zH9sxETd`lsz@XCAYeGmw;_O(s-_XCL-=2wg2G^yOoDFN7D4nex+wkDLRvzeC7VTke zqSw){EQ*s?(x_%reX6D0UE|Z$SV;L%7rpfvPDlL>tWqO*vjMML=<|kt?cP{+FJta- z&|2q7U#JGpQ{U`CN?vWeTQSo~IB2@CI&M(7W|GXNbo49`b(l|(j~WtpJ!n}M&>z@v zkQ5AWR2D^5)wQ@Y)bL$2_E6wbMydVoax^N&18X*9mpiJjkvgh!!by8qjK$G)vm|06 zNAg&HB4vf5Jyv6*!2;^C+iZ13v))456mtdKBsmhdb=ln3lthEfDI;Z?`OzcVwS95e z*xL8*hAn(&Y`a$JPe~<<7V0tmjj=boX|8(CejG8VsV zt)!VO?5Ui1#DtNFtegaD+ZK?Z3$z1Juj_M>&1z9p#IJ@{w@nyQW{e^dei6CNydBG)p z7JaD=o*i=Yv-OOtcCY;9wPI@bDIxF`W5{KJp;YLb%mUhV%uX=Jx9gRfN#3)WJXoN& zji}@?Z&^P)(N*ZbM*H9M`frJyh2dXeE4F`}6#qJx+5VTXRnGrSu|9vBUh`4a9Fqb< z1N4AjPKpC@erzLcG4KE$O8fD*D3Fw(rEoB(CrBi;bZbd|-^zWv|SvR zPusrf0Nt0LJn4QA-$|>yJw9Bbo;Ny>{jse9?>%EY|Lc z3lHOh@*|-I7~g7%>QGBp*#-E9ut*~;^GLo|t@1~P8nwvp2rCjm+UY=;-x<-X-_t0A*m`v`%@+(1%@We7~V_ z+Td+`Xj_I3gB*mcLr&N1AtJ|8k~fzmS91y=*jpm0vbXv3Yt~X%6BsxNEM#BGf#VlZee?Q}6yvdjX}LIWl@kx!|Ukcy4ROr!0)AIvt$_khd61i2TXAku23yWklzkFgx9j{KU)@iJrTyT|*mHf^vkMTXwE~=97=+ zH~59bCl1M9BaW2oN;3uk-f@;pY+?`_2LcAJ+rMFNRE!Ct5&lNoG^&VrK#>*^W0a!q zl&4_Nf-89~rx-Z7-kDCi-ji)d^hqfpizI_GiH(pyl!`Jl8_AP>OldY!Trw(fsc;?i z*pgINFB9>y{LJ=FKt@#ml~ilh`?b%VMBJl%qsNojrh+p z+@pbcMIU#Qve3$VrJ$Q;i4SRf6GSP3?)9;RNHr37nzVp-#a&w#v{_0KMV>W}IuO&0 zT5|l{sMeNIQF>CI>GO)ubw8UjfLQATnG+%9;wI;QEzAaT5)9L^5AzR1Hc&&z)}#c{ zwVSB=&;i3FZ-!*3HiL0f_Ob)Br^X=7N(CU@!qDL#QngUnZnbVxhXy~>x0@8{{?Oxw zzN{IqsG+pQSc!uwrE|k#7B;qECR^+s=i~U<4fx+D@By@ z9#59}J2u)`umZEKyoDXp2JcMjF*Td8%-3>6C~Q7~cx(0J zqDu1Fs@6DC9FPY_nnHfiab4_8+yR6WwbEe>sX!gEIIBF+)cTGSJ$0PggDI-v^aq%) zlFJpL%zj^#u7*K+wsJ3P3OGU}Q(U!&8&!?HrGZKM;va4*vo%VH3zZTjoZ(Xl<#G?^IN>p0V9q^+I){U*u=A0pr# zRQ;Tyz_pDYsk!`Ym%!HQuA$2~#S-V1f{Z)sZ zD?}N9ul}8V-b+~n>kV-LL&^E_N$-ANJ#WXtU+U(ejE8-GZ*L!QbO+97#vrerH$o6W zHJA3jn%?{(TIP2%Ov>*5Zu)#E5vvHsNfei43(>+#L~K(sHKd`8u=yk>t|=Hw^HR2H z8CoQbQ@8NA4jt}W_Yr|551cFsPa>H6DMAsgTAT7(Oj z9@_y~9rJ@;Tnv{m<0$FjacNH;S^ho#S9Z_8mejyqDz?;r)H(kSM?S(Cv%DPyiWENt2yfJg@Hie)?HF!= zhP`3v>6(=*KdyG1(&C9}uGnTBo&jyZdR*6Ta zz}Q618?Nr*>>T7q>U9SdYWhK~Vmblv)mxE zDfu6)7!-m)5Ok+{4Df2ev>}(r^>H`)Tcjz*qFO82xIa*{#_pvaQo@_#u2;N*VW5>d zhkz>jY#THSeoW@P1S0CqcBTVs!-+rITYY9S21Hra?I-G>HQlYxgU33Gc}g`?ttDrP z`%oCmC*BBX(v0PzGPkdF?(iG0TLx3Tz_NZk*@#}#h*OFM1w5(6gvhoy6&@MUJ;fUS z+;~;7i(N*DQ$l36+Jpypmg0uiJk_rHWD<_&uR0FldBzRZ05Pwr3~pc@-V9Nd-)>fc zD}tR-R@xISEN_Je_O9Ut2_j(U*_JYGkK`P%3}8Cs@$4m`pHCJlA)i=qGz84gR$|gt z?r4Tn%s;4<_1RFSZct~{89pHn%>Z~?SU5GHwY`U^vyl6PD<3KVpRl9&)4dQ65@jw9LrUR0P>51-zBdnV{w zdr$ib@2XAhd%U~C*|_fSUno1x2fA>jtbTRS#+cl>%EW?Lh+ZlVHawpWK{))Kyyj=icN!-oVZy8OPH%N^&Om&tfy_P=GuTqf&zL-FVnT2 z)n$sB^@KcntE#w)CuR7O^snmyQE|Kv`sX=5hv;7_dK0>uewY4e!gv@DX`qjq`96~C z#s%C|6W-sBI%BX>cqvNFTxwDEGka7>%s9?$1(cl0i)9G3Kee)x4|%WtfTSbScmFv+ z|B-?jnONBW{{hPWA2~1f|0U=354h!DCojNbAwVxDCIL8c+b|@Ie85ZMo_s@Ov6Pjh zULxjn^SBvr@1|r1TBg68KYJ--%|IG>J}+4--sx{eLsqQMB;aytBCOS#=(W{e&(GQ~-3GYS^Uv+45&qDIo(+zlucxd#TucP+?-MOUYY>|o?)`Ky3#ACqM&*!Rv zKs>D0K1U${3@1dC2#_7XnOrjqKn5OwBRe9H_eWu03SFv10$NIEe59%{jAiC>fJXst z_QKDY;}zU(Ff>{UA}OI$o*eW{9@%}Hb{i3}D=>m9N!c)%)T_|8NXbEtttBKbCc30~ z?yW6`x=QGi-^kKR#Zy{M;=U~9qT`K%AS zG-L{(FhNt_v%PmT_FM~U-%z-*uk2M8n%!V&nY?ee@R z_p~FDes-ioymp$FEDm{x&^agBj7*ne)gg_Xzd4i$M^R!HJggv7f?dSpR$01g2R7xV1_61~A8jqW{lDnkk+b5nLv70Cliiui$ATY*lY%^ueN$FQ-Y)l zVj87JLCAZhHq+kbf}!p;c!yV%v=2iZoboAZE{qG~!0Okivi&0%43@Td+p^C&h&O0r zQIklfKgQhU4a-~pO?GCM2OZtXD2urT9L$Ui!-9LW(+%2PeV}4r0+F6dGp%Dbd$L zzvPQcWvI-Qes@W1%nyDEL*aTQ`V`BXNHfZ|5u_AZgdr@7GO;z?t3A7Rv@0OXrBK|# z=$q(vW@zfL`gQQ%yK@|4+jHefiXvf>AN6>naCHh^FD}%<-%+DxS5fWJndGQ{48k6~ zn5wMyuckqUPwnd1&z(B8tfm)vUF!qn6EU-l4@4jC(1LVv)qB<}YHr=W%?W8zW`#Mfz+bbspJ z(=zsWhGKxv6AwenKXA zQHu~EIsyk(>6LI6x_8QR;>gq>3)*aT#LRc|ydKT)?)u`)5QG_%6AHmF3mM8Xb+e`q z&)Iq?fdd^d#-z60gK2M z3&b94hLvQr5QwSm45N%C=s4|g{MSAGXfTQvd&Tq~1;?=mPZ+xtZ-a4q@Hut6GXrZ7 z`c@W4Zk|@en{kOG4=}ZmLqij5;1euz(|-i0Gm`;uc^=Y18z2&x@bXx~tCyB{a|6Hj zUBFle+__vsJ#e^9MmowVcYhWF19qE^DgsdlaPmV5H-e4%yUfry4EFQVq-!Mcydm9t zqO|M^6njJX6m${t>M(|FgJU#z-_>w&P*h^X+$S4RmQU>D>iWvUjDt3y+x~*X%#7W{ zPM>;CT=bN^tw+QrQJ$M5O2K6BxU+Y3t-%h!zwQY?5njZjTAQZN1xo@n>zO{{co< zYT!&(Ia_X|ywU2eO~h?%dR+vAqEq&ULuyFva?6Vn0O@@@hf}YE8e~@(*G5c7lg4v( z0(y*`o!+lJ_M<<+acJuy$BEhR<>a8)xhH$C7@(Y0YF3xUq?c8s z&u%qvLjB^M}9vrV+7 zybHIi3ZibkaNZ4v#~q31*~s7(CV?q!;^GEmBE($;FjYDdz>cV{^ouCcRhl^3vZ2C? zD4JTIMvJF(KV> zWm4m8+TUDl>sk^u(Rwu<5_i{cm!{Qf#tU0^<$T=8N9A=ug4N+1;5r%6c;1{tRBbJ~Al-ruAYg6E-6>*738|&CXcV(jbgs*CmjrUP& z`)8RgvdNB!cw+uAxzERKvphFz65_~-Hhf=Gn~!|Kjy{ySMR)&SH+9&}_f72<)c*z; zI`&*S~u4H&d@PxcO@T0Ly`~A`P4qwhM=cQnjp>L;q=&rhPR*LuEnUudh zc$I8c>@oFy$ZBm6eY#Sw_&+PpLUfC@ww%tLMwyRn#iO5~MVUW_fYfFs)Ax(yQp{K-}D zJ$Jib>2rJ1K>>K7I=Cb?TsWv%H=%eO3E83tF#!#SdDv*e_Vg5)dcm6&MXG5RI{`Qc z-I}412}{{-;xRX`VCM9*N^7BVY)D0tlUgU7@5Xe=V|I=!a7O^MTnJ}E(i~-Jf(Y5c zj;EJl2?hQ%P>W^MJQ6q|R1#z#*ww3nSx@j$p~H7o0_EZopV11N1}PS17+c}Z)Iz{$ zhvU$W05nBsh^3+&Lc23tAoVq*5Q^}0Nt|#6yecp>#cI|SiQR?72eD%LK{0x!@`;%! zqS)#El%{8JBPB`Q-5-B~$fzS`cM~>@V=N3^mG>3Du_B>xaM|AfiUg4jfdp1Ro5@jkO)i2pk~wPzbe$=m6BP810l-``{>3~ ze1?2fWtIUctc(2IqHHIbG(|O|>nRU@L{*9h;4;tDk_8Levj~&0W4-TItRyZ0NdaU< zw0E@zL+d}2(j&}~*m!IEzzyX|cR!1U#>0w?w}c!LUVD#c0Fdr@tRF&0L9be*U4ust zoHgw!=TP~2GtDVbeOfpcU-|8ctQ%FPY4i-z%3PvaOdpSmJ{yMDp33v5xf-CRQhtj( zphkY3_$P5|6m@H+>-ZzJ!uQ?+@t9>Up*u8bL**|`znn6 zw@+(1{MUWPf&*S|W>+NhG@aF$RrcM+-ZjJ)*N=4ZmNMei5wUuSFv+em;!;5HVCX^M zA8{UeOc%)Xx7($523hI9I|&;zA_~E~k(RBlf%c}cNDE9;CCw;X&}^lcE)ucZiL7F^ z>2;xrBlY64q;%PQOzk-JZOw$pzrF@TW>z2mwk5 zPr|#liU-N8=s17bWN2o!^4oV-yJc~4wPNtzT!|_afmAZ(u%Do^5`@>M1TTJck=fsk zsV(HemEi8QWxuT*v-Agicmz$aOXp5fonXfvYDMW=|HR|uLp~|#ih?$DWWG5q%f%Pt z;_gJVw+S?Ga-%T0xSH626!pN&|Ah;LfFswkD~2izW0WuZyM@QiQ%zKyr8x}4A~Vs$ zO!b*$Za74zW`hx|CV8<#(NT)3AXcUjm?%xyq>}Pj(V$^%p&V5+%#Z z=*XBL+}@%{CRmZ5nzVazy%(;Z=@C2ktxv{>jMm6TZRFGk?D2e8df*tLyR;aQXO#3@ zei_Q*ln|xf(>H_X7$av=!aK|;vRql`G5ULtlt>1CF5TjzsB+W&=N|b-#Aak={Fk=P z{*V9UUwee(e+fI*X#NZR*j|{+#=ubD)ujBrNTB~(B&DM9D1UW@lt}PeXy472S}I(P zr@p+rpwx(AeDZ!UmkY*7$p?XBoB{}^|M?F5$n|w&fAUp0-o5PAf4n`;DfjQ$-QpeQ z(UYHUmruRk$FHr%^3^Uq%`jc_eYn29&?zrd;Z>t}>QYu(!uXXcu=OdhgWe|;&pLZ-`Sj8A^Y--j z^5gVfp9~OVvLy`9@jS~BnftxOqs0dXtntv~p#Yw4sHGqQ%bs{e7ztpdrZtual?tFZ z0X+HgC5D4dsm2oTA_h*jtV?c!K?*{q(_i+i5U2n|B^*}=xuOs!CS!nLi7)FYYn2%=oPvb0QawL4q1W%1@O12xNTxmj=GA+Z}g;!K#q(#M!7-`zDNB7SP$ z$Y=+fHXCn`;D3?8He0C9s@RbjB8#FIFeg#D+djK?hm%uocjB~OphMVhEZL5rJBKdMMHoF!{o+yLmqhXVcum+$HER1gbD z=8$xN6y9-R6eJ@OGV~6c`5f7)2|c6H#M7UV#sEe(S)Lk(AL!GPv*-a?%ErtK+nI`V zc{)zhSgs_$L_A%CTy*7#!ckr$AB=q?`*)Ophz{`_MO5T(`%;PR?M}RsM+}l06mi77 zH2G^}I9YPJb*Qk;#txY^5(C!FBii@or*?P$ABmFVnCEKF;NbU_VBt2-PlaIZ2n$>y zm_=UJPxfLRi=F7lUPd8I=xOSTe!zXfcfW?81u*e9?8pp~8=BtjdUY&!qMUdW6wKmv zZ<1AEBj`_1ZQPv{OJGsw9S-cOA{ZXBGK#8AVa=XoR|}UXFeQX-nmBMN>6eh&1ejC% zfG@l@D~ihlR#S^tq!ow8B6&+{bSj3->K^FRyx@AM*4kcK9v72$q>VqkkR>`aoAY#} zn>-Y&X^g~q79s_&lOyBfwdPPg`;4H1=8*fB6Zc z$?|wq^O8RASCMs`1-4v8xLCU=C~Xkf&~TLE{MNu@AoBe?5Ye21x3`+%0enD4e;hr%FIN*?KZ-4?8{(`e7%`R9Uiu8^ zJ~`UC1JbP?gv-&*g(KvL@S~EEhEW=CJv`G%cSo#DIPQ_4_77wnlQKf-&kY3cAWxsH zDSM{NgsCzIcvkDT6kD$$_=*?B_8n!cu9g<{pF-KDkoVilKhMnS+0RQZxz7OIp#Ge6 z*o`U~&IXmoOf?0P7j#gK#v@!|2XO$!kEu88xRt*-b$Cw7Cjs(e&)c2~FKte7A;+7w z5q%h!-LkWSoph$_nIUfv$EvX4U4TsAIG{+DpARpZtIrFoUQodxP~mLXF>F8$7y?X! z0SQj&*|GI#Zt@#5OOCGz_-|LPHL1nO`@hq6-<+=@Cd3g)Auh&6#npHmRJ7B z%#v+MO+8w--To8A*pp)^u%;*|{}U<|<2Om7*cDrBR?K+i!(#~f+k@QRA`RbcTLLZW6j(cm|(H{57*zGK{-6)}*w&usqF#6~I3Wiaw0f_?X(_L~)JB z-%j?xPr%KaV1;fTG^)nxDT)>Kz!N4wR9(G9!(VRygztU8TdJfr>7%1gak0tH2GU(H(h<@ z+o2p=BL=h1+LrblluQoGj4=XoKR{<<41hH*QQ=j0cfOH-aDe{@as7k^Ii}wT^LR~H zxo;ZiEoc@k&?MCOg${8RTKxq=`p=9$n&a)>1<_n5H&GFMk_RKJe!Ugra&3;si0+;$ z6qVp%Ed_f0bqGaGIpI-NTfev^{VuwPbYRM93DQ?ni7ZprlO08 zUrqs04(`buRC&6re5*311To^sRY;$3&2fNBPHWWaaK(GeK_;OkWs1gbOX5994PIq6Obin|ImTlLPuAZ0!K25GNscOmz3M+I;Ngi^;DGwkOc z1G|UDEPHs*>;sJR-6Uq>%WGgv9Wm&)FGMBrDP}7yTcAkj)S@Ghp}greX>BdQEb(>s zDUIf0l_`Qu;5&)A%pY`#D?tUoy?r)h@vQSwLWmrHNewgJq`Tkg;sT~c<5n@$D%0{_ zZ>DWdH!rS&4HY%GwNW9iBK59lCb}k1U!98-9BX4QKSl^EHwSB9CymSCFgpgD1uNhq zfvVEmpyJDbJUB{e$j<>jX4jin$PhGooAak7$su#@A`aej}5FUP!+j-TqL zk1?xZXuZ+$z3DI9D~WUjkBqR1x4S+&HtaXt#0e;)Xp_SOv7ujV-3v(neuWj8 zv)NjBhjNov;OZL#%mw9pLHK(i;E&KAJ+r^t${f1>c-@IP=UbA%o9>!Va>`9RFXE!2 z<}TC(fG^-lT#TX+9=0geCcP*Yzb_;`&Pb^cF5VBqy-i}uFY;bmrtSo~EKg0ly;E=o--Wcc)eS+eMUvmnlYyU-xqJTn?{@?5uJuFdw{z8b-^oi8 zpExqo{IN^IQI2*fe`ZiPLkSS-S16UMp}a79e5mi%2!{iT+rfocVLOd#fe|~-Q5;E& zXH(#qCYQyW96? zj-}0!-<%Y2Z)|1%Wev~6na(xv36U{JxCP$6f(E3U5A2x>5J^aQdFkxlJ<-RDHeCY$XU z_Xu*CKIjU6PohxXUbm#NO>@Hng=}`p!+7qCocGe`0B%un>gY=iY57-4OL^&%niHXG zyA&hK)67+4W&tw0E!QK|M7zKHQ)Mno|SGw?@3M1|u)t=m}<0sOMy z#|IpRIY{r+Nf0IN#91;=DLBVv!%f^J#=)(f{y9_rgx*#e9NUc|thBTVPi>tZtVtfk zjuaj1^3N%ozSR>=V;I@^w#_)%8pWH^k|AGC*KL81e0f2=``(All5q~ux|I(&nod0^ zO!d5U32@8xSU7iMxTCCc1&&L&{k31-b3>WyeAaB_n;#^G-WxXL*WtCrpD8ktSy5(( zQnWk2uMZEK6@@HKwR*Lvi{ok7s!G~6+zoneamtju{U%`6hH51#)e*q8DbhVuX3Lkv>tH$Ma! ztozx=fcY@?aL6(GzH@zh^0YlMxy50&HWjQbe!3su5q-fA_V=ph#UeII&;ZBC{6mtt zJb$>n-3tG|xNiQ-cYp5d2oJl|2?2QZz-~S)E?&c^tWQS;E@^r-%+3#P4z{|C7A%x( z&`ft|zPWC*!$uh;-cfvBPFl1lt}SOl*aaCHbWIOQqC-S8g%eb!u%+_O9n*_O3G9Gh zM8&6L`$Op}EPmO`M^&%acBmGQFHe6g%KjL{ZO-W9-Gpr!ztk(ZFvghaE=~U~w=aeh z_`*)7^@R`*zaPLEIKWac;JRR*#2Typ)x>EvXGP;+Th~@YQSTy@DMn5h05qK(G!J%N za022ckN#x~J~v<#jB5A!H14Jt-pH8Q3#CFxUczp@m-w3%ool*OBiZ)(12SKR>v_%Y z^2V7CcS5Nj<+~E>7XVd>!Hfkdkvh>2WJ2?k#1~DYAZUje0reYqH_uJlXjb?Y5^|ks zJeekJOYCQ9!x4tU(2X*7HZNKt*^nk#-9}$)JX~CXjYfff5kKA)_&aPrxNFxiJ%B%L zO3Jkec^M$C4bV!u*^NoI!hTS=W2VADj;#qE16iKt^ARt%mh3ZRaVqCY)bBlJ9>T7X z;W}lRQ+bPCKKit{HF-H5g^rucx5he-=fZ###!Hh5ScR*jg%Pua$bN#7L?VntBpXXYUsbuL$FGOcKwMJy{B zq3!L?(N^}aQeUHYX@rA-Lv#lMQ&)L2CY05A5F$timZ$9#xoNPhR4Zv4 zn3cqk6?>+^x6js!L=8QJzik=Z!O^A{Q~sV*?XCm9fsWYcT;$dtR|a{rDalhAM886^ zx)M>BOhyZ-3!}q9R#0KY-Rxvly>jfhMwmR+x5TTjqAhTTS9(AziJxWVR_jxXXSK6BWHsyPy$;Owb zHd|^}OeckptBgD^5vJy$akY^YOGm?{TbGr=h|vx%yTM}z9HY6!&fB95H8KH8g%+f> zPaWqMEKIr_bDB~pll_^WdDs^rTXjMUk4$=4O)$)2YaCuTbfy>?ZC{Gi619VG2u|j_ z*NU?PZCjRO+-vg$F9SB?l99gf`;@6%497;iK`*#>gvfh&#+)EqO#cY`CU57Vyl#2A zx6rlyW<|YI6xEwdgteir@4oqwcdMjIb)BU@?KmS_W>=+>P@xMR+CU4sMI`?)n`nb2?A-^(? zZ`$N_M^7!3fL=W>jiP(19@Lf35MD)^8|fvEfAP8F@1e%bChk`&o@o~0zHXOm#82*6 zMRO)DR4SfVGM3H{RU1iCJtv8c(KLyb5ru%Qg?5mnXtUfA?&Fs}yq_6efG6o*iQm60 zy}LYvReSopf1K^OIEZ^^Eg~9ly%YsaAjibTpJRjg0J3|N4T8QJ+#u&Gn2>$?r*-jdfk`&qiPXq?Wpn%p4$J23XvzavVMXz{TMnK91LwsJ; zWg&wOh039VsGugGc8awD*z_YFw*mfKq~M*F4$M#5CfUu3J88>9>Oj#8lPY(()vSP{x)rKsrF?G>|vMRcgI^9U*9S{_Aaq1qo~m#<=80&>6(O=47XeP9#T?gvN-LN4V{R{0ww1KlteR;Y%8cxUhcUd)svhY z)9fr{?!n_Ycv-@B4MYZG&!wGuV5ihiXyW^A>uCAJ@( zkXkfdwLG-~NBPnk1F~=ae~i6jkfz(VG+JhtZQJOwZQHhO+wQV$+qP}n>SEWewa!`b zt%$QD?*3OXHYOl<^!DXUt}ZYun~d_JM5=VtKP1UMrLhE|lPYO3N-7M0Z z&SD!I;0|chS_I=DkAblgvVvUK_&l?0Z7@gooq~^Tud5~L_+wB0Af(|tIg4h#9+}=p z(w>WTvg&ouUO660I@11<{i~H!g*+6`?Mh}@$MW<2GXq3Sqsm-7HH~TOK`Ox{X-65$7 z;ooG|cZv+)sxBtpx{UC_hK_c3xvOafU&X}1N!3+o^wzn}i$j~O%&%j8!c&8lba!#4 z!7843HUMu-bZVR+nn8WT=G{0jqth0T*v{d)@&~=<^#*h%?2(a$1eDa%*{3QbBtHLv zdVHcrCV&*9r&|6YQ$~GJ=2IQ422H`iuNGQ!{DYxp*k>`~FAgU^u832xY+I{00-R7l zrxZicO*uB|90$Ijj03RYYf*q0Y_R+YY>t6=hi(;^RuKbnbbiZ?zbXuir zk@wU=1n(6BDD2W`szH<_`qGypglRQFI3qGK>JQ$Pl)!f}{VlXI)sGBp9rP#7$-e{J zL$*>8SQRi=B=y123x;v(vQOC~nNeciMc3KPJw7>bI~=*RS^rRzB7rSap!)7hzYH=c}n1@WL} zG!If}J@NDm2I8^C};G78q< zwZm0^?ksU`p5+5s6uRFcQ4mL)*AeQDKr?Y^#;-&Y<^^NHdCwYX04 z;?C!<&QGd1W^>;xGzR@_z?GDc)q4=>)BXE>)9cIdhgI&C!5`D(9=e_Mq@2KTgtL=2 zNPvFA0p`~i>5L#_FCHF^kg;MQF z;U(1AAL@T50I;W}!>mmcV61JYbtg9xnIMioUd(SUYa2Y-VC`esE;qOLcg3b-Q%`Z; zI{if1;`F$?{1*Jy$ZHXMx-)QN2TmTm9l2QH9%JC$+U2Cf~6;x}OX}z`U=a z7(rsWHMr~*Sdnq^z%6Z?xsJYm?E#LQ523iUtt*}L9<~65>G`z;(xABJ51dD3R?ChW zS6*(LmU_(1Lj-8E;>-DEEztN;{J;uObQMQhM0U$tjh-M0Y|RF!l2Dq9b0Xq^!5npK zeo@^^Y(~^@RTJJhs*3Hl9k2q|Sx`aW&zH>s)5LtW>3?QxSDKXh0dGrL30CI>fHu%- z7v2a;W4y^lvF|d~1kL06Oi1b4NpkJL+a&L=0$N@w+@}F?Gy19k5vJ7P7PX10F9PKJ zQr-f}%)zEm)GUil+0+PF+8EG~hQLOo%h-=4Fb!LD8~D6W;}DyR(&C{)gY#ZBtQJAv zei#tBk(Kp9x;}iRqGp#Vf3VQhH7AMD*Spx>Te9WpweA`C=&cQDn8e{=7UiOX7w z@PLmYuEH6F4tQ93vd2k3ClTi?niq?rdBMLIGj%yxQXLwDfc6+X7-<}+z-=X60KfGl|Hi6VXcALxP~nh$m}@KlhZc3Z z2a{M6a_U5SD(RPy$ybZL;1zmvGt~}P^)viA=TKq7YtRL-~q{5@JOHrBp3$`nub5O z?0L3D;j<1b{qU6^>I39NU}w61CQLWbR{hfBG(nm14`Om(_DJXSAW6~Uq6xao;y#lr z<|oS{W6?Qez!5+GHn`qh-P>95Iwxqr5??}*~UOq5XmVYb!-V5=3Gn5O&L<#8wjG7zRE%c&V<efBOZOh}2# zCZ6;lo)1-ED?}~xuvH~=F$obp=%quV5m}`$vEb!OC9lakEMmY@gV@3n zUV4If$siCt2D!tnGV!1d<+O|1l(b44yX1ElaB>)#vikM+MM{!t-bm zy;iq-77J;jyXYFM({!2B+#)p54*H&9&}+CKYAuutZuV!234$Eu!x>|%MxZ)F{51}) zriez5H8KTPo1UelVP{(YtBfp}!1XB2U3;;^={<5_*a$ zI-qF)4Xr~c88Ng5dG?4`9MN0yY6(+2MV3S1fVzs~4R%xE`de5E_M!*~952yxU~?`& zU!!R|&g_Wj0FCd`cNqn&rWu)2${UQ>(+cTEMOKW)tqy;dKr=2;=-6=7E0sDd# zR*EnMONn+LhoWMZ>g2GWe>w;HI$OzOUxGcIHTLRd;9C_Y^5v_wxy;Y_3aPsYwn{Yz z{?N52Zr{uImZnZpmYx~_DIY@AunV9fm?Y<(apq{LSeR5&OSG6%w|c!d!sam})SeQ4 zD1AmuL?V5Jz%l1xFMIJ}m~DZlUpG@wE#1k?q}or^kSD63T0(;=xH=dR{-l>74i zPH$^t%0B+gnULsQES)Xylo-2a>FhLlT(hIfU$C=w199kzTaHb*Rm_qZ91GV6F0H>M zDAKMZn~|o{9vJ=93a2j9xT6J?d}b~`YfL9;t$&1SK7>C=(ruo532NK*9h0_<0ag}| z#D0gWtr@@zbS;S1pN)SOAf11nkClH1#E%jQZFkQ(5Q=8FU(T+P`;%{-2bFYUo@^m( zel>D-Qi1itz!wxGce-m$FtS%_cEO%_fESM>BIiL%#)TisQpFNf&9j594!Lu9XLHgL zhw*fpv@;9y`wVqVWL7(eY|GDiqX<=D1p-UrY5r0G>IgRKm>wRUJ9-2L{}FLj0G8F0 z5*G{zllu)uj|T{(QU8Y?EHGdeY0f|>-)coli}<8IISA|e0bdxK#*(i8=F(*%5-%tO zv7r(a4+_MYyXN2k-z>T-0RP?kS_#^fT3~%>JOHYAO&>fy^DY$fb1*!0TeisLA(s+1 z^_cqUgPeVBK>^6-!U>k`!rGSqW_JTKelkr*-rDy3E)u*4ZchtyX&gsTw+1H@kdQ>a z8#+X%YeU`5i)ZA3JieX1T%R`~d|d7{cfUM-Zh`diyrQT?U_nsrQEgXIUkU9VJ$$J# zj0H5r`=MD;DdK=WzS-{e36p%m3Y>8yoeDxdsIv$HseZt+KzkGr9>YW(-TdIi-;JN zU6EQ@Y4-0iMn2F9>(OA9pZOkyMJH}}Hxg=XU5%8X%`X5S)q zj#OCVf{hl78xhqKGThLrc^78(W6^mg1&+bpmid`$Ad$Iz=}z`)MITCL%}TgJv&ER{ zSh9xo7uUp*EHSRsLMBAG;=zbP@XGX~=#SAOGYKP?g#Bh?CK4B2LRZZ5Zxf`Q!ByE) zL`y7hdJ>C@d88DZ>s5-72n((9hu*jO4+;LW0d{$C;?REmjwnVVE0rkki;9p7J*-eSd&*@MHF;2JC3HL(+HJ^utUkwlO%08_t4Hwg)Kt)2om)6fn zCuVx5LM^VYCbMM2I4V<4qON$AEKQxMZ8hJ%HRaAPOLcF4x7;}s4-t`&O!YyD>D%ng37<6Tk^I&IOj_V|p<8~00S=;i3 z4CXW1pc_qI1@?>9#%rwel_=PqVOJb$D*TW;ccVBjSs_X6KTsA z^bi|&L(#>t^J|d5xTH(?APHQH8g1hKj#*dcrPtI?zKtbdDo5|`A5Nx&Nc~fVbx1Ow zJXo&FNMoJ1rCpnDHeuGd(LET;>^Zx0ND78Dt&*bcW!U)~pZ4lGn0Q zcaR2FzvH5&PtpQ$E-(I;EmqN?lO{!W{^#=eLhm048rN^h_gXQ6_+jjFq1V^Sp6}$A z%iktO|C=!U52f@!mEm87BjZn||L1bVNdM0+!~g3b8R`FGpA`Oof{VX9$k+|GAAd#I zY3XUjd#v&4;inNpKQ7z&aU*+LmI%*L%<4Sf(BUOi*;BVf>NE!u7Ss3;^Ts0^d(wY7 z?L>bw>TIbHv$2p;m`}e)My_jAk2Ou-3Fdhl{(Rn*Nj_prMfLK|XhYag-A3^!zH+5y?q3teI5kz_@h^Y z6sHg;eE-_XrBmEvYui3i<=OG2vMM#)G6Y#$HBNoF9kLnTPRJ8DGP-#^hwijtq~uFSy{ z!Q~+udrce^X3Lhx-P*g8X*qlxws<6K%wx*XjxNuszv+1NZ(P8u{+$#OrQ4!18pZJ-RqM`33dfmoD$PGN1Z zB9-f!bT}m#Ljj1kR`N(|41{HDvaA+Rs?y&0)2N_@t3Hvr>ho%&{xqC$ktR|~Dq-Z{ zL!f8wqLu5K88;V|yQLAYC-(`9c74GW0c&5U4ZRqL(=;q28q-Oln0?L67&^@~(@n`O6Tf z=ky;|NN~LO$DB(7cQzX{u?n%G9j)&z>XhT?ge&#|Lt3-ZDZ5|#luI35A2cCoy}HJ3 zbE7|?`;tCkXlAyKw(WW9T++H8q~1I=PNn9ZH*0P)d?e`5pq_#nNma|AO06MZ$funV zo>U{{#>2)buJb%S@n*gZl2#2b_}`=}-sg>QE_#m>3X1#UrW^zZeKHc<+tXq>HABfh zIxEpsnFjEP{Sa_mW`&VhL18!Ku|?kws9pUi&KA1^U;3W#%7&Kyb^W3U<>n_Dwav6tZh!Ma-* z3$FJWP2Y1lwo-}~DL8c|eq#|Z1{^!bdwGniyNhU+`)}~~Av8h6ZFG9wmp{zoBs9qv ziB$Wl4<%st0(sq_Dyppx7aI!tSPuy&giw5%{L7)^6ez#543M6>7~>5z2hJk)72{n3 z;YUw63OoN)y`u4vN+17+-t>RK;%^3;9M`I z=}Q6te{Z!l$|y~hKQ3xllR1JBH1n@NpVNW)X5x#adi{5Tm=F4`k8450sdHS42zGda zMcq!@XWK#{jw$5ZYa#*wChn&Y#E$|p3Xg|DQ}9|Kmb-6v;!}i}6Z+i+1eQ-3q z1ZRFDZ6ynSSxVPJBq|JXCN~+l{y0-6K-FyJHjY+!sd+XNt$bUZ{EfQ=SV$inDuHuB$0Fy|==e*&Wkenw_ig@UK*?d4Z)=H&U@L|fmqdTKj#OI8h7%!})PO}{ z;moA;$m(kB0Bp355w#o|d_FVOlZG?9Kb?!YRj!A&9hDGSLHDPp7Q_P$63Su{X%<%M zU^|=wn{)&r2vPx=L{UE}Vtf~JzQt{*a1hF>wW}J*qf>}|NKByzl`oF>GtgnNeDOa> z+3PWF_t8DcjKt*KLbwkCu-2kRs%wFzD&wEGzOB>~M{5sSStnau^A85|NTH>ql5%9- z1#;$`)O>IY$#Ork6?O07a}uHpxo3k)LKnYj?g;Gkq)df&eC5DBy9S&@8?wG)a3vhJ zDNKn5!<-oP5)B$4mszJsaaB!};)kSO?~~*5`=9%ZACPs?Bq|YvCMSQ)eM89xP&hXg z7Q|>0IxJuY`7)YAyJ{;q6pu#;PX>JAj)gUFsl>mqAKSX3zMr}uAUr34p4=uG2A`zqmt@m@qJ5NOTbz(y{#2AV_vq<))W9R^!RZAV(`GJ+1TxYzA?yu9A$hqP6HW zkejwADKgxRS+Z7$DLy35rCv4BWGccrCb0FAB=^$|!yRA{K$;J+1&lYv7Wrh;-T=1J zsti&u(v?CFQRYoI6vW59A_t5>fEcT3D zsGtraA_udxEJDQ}#c{*1Cwqk#(-7WIHvfbdfWB#tyWHn30)!;=rq$fc zbC!eG6lvqBuS2933E4z^%7Vepm#lY zFGURjv&@MzULIdNINucnO>X%oUgSJOq$j^(>e-K>HG(WeOJ?sSU5k0$)GFvY#V*)a z<&l0hIopqWmd@?=k-XYZSW7fBryIYWCJWB@9&1t!tm$Q(XcYX9&0Z=+av4te#v{=4B43s)f~;Wr#a6~50% zv&F?;N1gPY>KVq|(72QWF?$CgeR_MpkbGF-d}ye%Mmw9K_Vx9)M&t%ZBD$SXL=rHw z$NZuc}PyKxwjh=6tCop*c$pBKBtO5IA zA&fkJDhQHk^Vb*wF{GKb#dq?(f=O@c>h59Jj%!zs&JY`5I1me7WW>-TXwY%@3{>kf z9Q@S1Uq>`onjdxS(cPyr%6Er{`IqK{eHpO)`Ev59dk3e@6*2EfwQZLTFtCx?9M521 zw&+}V5b$I32$QcMEAEG0?8lo>`?cP}SC;^;=%iPeynqDDy??P7y8Rxbbe4nQLt!MB z2N_t_;RX{b;Cdfuwo?p(kv8ePvQ^|PS0u=b2KgX^by+4$wCiEy={pNG#0w6uU|2;e zPqZ3gWEl_@BQ25<%OT|@lUmeLbpgHn6BTFf6}na9r=-wIB>=Xi|QDJRN4A zeUcn?NRAS#8$dV$U+~dLMcAg4A!O7~NTfn^Ej>8415%d*AM#27BugXj-vI?H%=HC} z?cTqu#2`O%CD2* zga{j&`k0;@;=&XtKOKZ{h}*Yvm7Tc?2~?MPph2VSYjt}%_?|eNx{-ZKW%1TaiS6C- zV@g}|z~)UtfQDI?{n))zQ#O7-;dpr|aeh<=a98}=EGFw6Vd)abO$hlMhb<#0L(ad@ zVq^{tmi|q@ovcYPJXg@l4MQ7o!})sLB+-LRU>&ja~}uKSZ8U3+pv4wSY=adr~Ev;jyA)sz{Qqlu(({5l^y-tXBi zZ;|aA7CB3XKPo(%n?_rB>&lVJ;a*M95p3+0%fb=?N}5kW8Ha;QmsN+vHYde@_O&uv zxK5zm6@CtusldvuC?C`3_Z&hgIPsY$Rc5N$v&1Q7(1TpFUC5v(V$=h%i*Fi7m~37) z9DyOWJ7jX-Ff$-kZ}*ig$@Ax%6rcYgRrpz2dnpI!9Zp7;RY@MH^h9b3S8^VJ)i;LaDM*CA{}scol4W-A z3|m4KA!FQV8N|o4M0)guH}y5|6=eILAnb2k`n%L*VEk7L%kY2YK#UCkjU1>dojvxF z<%i$VCZY^H~zIF^PpH5;AUU-sql`swx2;lRS8}U7o@LgQN z_Xx!O-Se*zNP8bp)Wna0&fA_HU*GrF&^hK2r+)8FGfPAyVYOVa!AsvdX%cZ5vjrrB0cQv@$ zY<6+AXJd8R)XY$j0*D#2uRRm+oG80MD$rh)TYX-Kv>W|;8s4IYBbx9o!&c0^AiZr} z6<~#v;4Cw&&*V{Z2X;KwiHGMNV+ju(p*gtiw~${ST#Ozx0ymKsOvr#{rcm4LqezN>zrxQOIWQXmvzJsPhgToc?YWk@piu)QzumJj)TR? zVBd`tvrigvU9tb~xd zaPXAX%jU<*bJHHogkIkV(_O&{i7t-=+8FP zOCEJDtd}r@=;3o%HBiOdU2x6>Hab`KejIhUNmhNdwGPT@E}Mhoc{7WgI+y-zy^6M* z4|cGF2yth{MS{R~I$h{}5Y5E9tC&Lti_y+S#8^^0q zDIX2ZDxY^TYGx+MjV8R>nrLx@IU4t#cLjiSIFh&lkZ~_UggbA}nuo2+6O-xR0+yXi zvR;L&Hk-7b#)NBId(d$u!*VsOu2MHBrLTDgg40gz=L#?s+jH#rM2Egiq9n_o$_rmKzE+}aMcPdivFKh;9bh=oI?X!xaMG}FO zS4u=sS%POb#B=BimmEb!A!T=w27aut(~lM}j&a9E>(pG@hN3SmA}-ml#;c+CKspfD zU`>&!Q`|TXMT%flMErygtGEr9BrX9uB)_^$2{nv@TrAr8{0u3zO;!lrch3+aGSi2h zP&sJzBnQlKgODKg;c(C=7BGtzhi?n*5qDm!F)W^R*=909V@fpTKh6oPRB~(ID1Il* zf21HBO%Amce{5p$?IVCMm>>Bh=_&^if;d?0LYa;+wcp}9UWHwg*|y0*rRTO{_v!%| zJ(2~j9-qPb29r~l+dQ(xG{s?59O4e zb@J%V=(}l1*kiS=dTafHh5*kh`yU^Re~3*6W;Uk3KKP%ZIm17DH2O}bl zJ$%S-AE+8=d(rt*1NxBSaI`HP2q*dW3uD#Owa2FlO|K;SbaMsR7q;-Hi-(%DxmEhI zyO~?hAOzA`eJ2U&2GxR`iLaHLffLt*8VBJI&rf!2x!8(P`2Vo=4;)6sbBl$&-&_nojzS&nA5-Zj(mIu z$7TT>F>M5FjcV^gxO)q4z(gt?v)9Pj0>hsSIaZy3yCn^d#}WeQYqpCDG@}gdwIC8r z?R%?Ot1WW0IJ?@gllCCX*fsjEVNeBbKnKJGiug%>kF&W_9-*BEMOV4%SvDjkNEo8Uom`LNx0jjt zcV}stDn|eiOgfbsX6R6%xh_g`3m*|oMjEcRYtIs(*#5lZ$w~7fNYTvYm1-y_z=yzP z9(oNXR7B{cN$ImR+mPjx6JdKw`Tf7=LJr|nEk2C^MBq4CH_aNT*|J!H+Lq-OHIa~7 z%D)E0k~e)JpycuF6;&Rte@qIJfB$5f=s@!;v+TH|IX~o9io__u6w8Y@B?U0VR!T%o zY3b^6_QN?IqaVC&q9Pw~b3+XVz)HHWcZ8FJ6GDHLq1P0>|J6AWYWh;!d7=Y~@)BZy zg8X{&WW!J19{X@{>}#-{ZejbS3WX(uw9$k!mr2^VzH!|besS(>wXHksyxIX&#gHO}kG6PY8QOHp<2wjNYy$E@(i?=*(BUfcFM z!#x|qxGw+k>ixt0v9kaB=KZt8^6#7X->8(D)F;Y`SmC$csXTD(L~l~|=INU^{MV!% z2qFnOxbTVnCrNwol#>f7%QmcK!!T}Fw-n0G7t4NCV?N!^?A`FgSSXRg@?YFBpXqbV zed+qJf4ofHqE(4~b$__9_27A-AJAj)W{3RF3AMF#nYD2HdV0wCq{q9;aCnft!GoK4 z-&1Uv6HbKP+%!Kfa9^-lewNndkLcbz!64Z_eq=l?ovxj1WuIj_vX9TWp#5myRO}s@ z`$4c?2%233jmQk z0n?rxIUcW*@)M0wY^c1e&VWHbF1h<&|L6|n4T7XtD!~9f0%f!^SO&jf$Y1y9`RjLUia>2my>(&Y1=o%_!zlvuFBDtj|YEhcV~$ zfq+HBBo;y6P_^eq3GGAcoV0+PPC23FCahx(6O~lR+0tE;BjHZW zYTJ2>WN>R$`S|rD7>!QfiorSfRyOl}HEZYusRB5;d{r6}A@LrDj`v0#3iwodEaS{a z4V3-j-eyQGMDu+;hle_5{Okn|VI^dn>Jku&8+k~j68rPf75H?=Br~4E5g|_oNH-V8 z;O2SF6#f%Tx^a+00BEm@X$?w&rn#+iM+Qedk5W(&BY&2n#-;J3f>f@wCaqezL!n-f zc#Pi6Hlv76k2I`bi}!1JMCEg7fTZ0t(w$c;kLei|GwKD(_q$a|5;K)|{S`uyNJ1=V z6xty}^P*x5Pdqmt6xE5iD1#v;NpjbYeo!;hjRVwi_=;ZQ#-0fg$D|{tFetSFtQqo| zdyHOw#E8NVSFrI+k9AidaQg*=jW+ zE3EYLk6TOQ63hcitqglww)^M# zy_@yC=v6MmZA7zfIr*-V2L0rXPX^^%N)m#npr4k^(PW?l@o@;MK3jsuqTBwW`uTRpsp!29S0!$ z=%{33LF-~abZ`>0#7dsm&829qmD%0u5(+{Wu=rJ-5Q1k=xT__Z{`w#-+cfQWR+4^i zA2oMyVk>_?7ZsK|jj8$zSDru~72ldaT6aLlwFd)mYu~&#cZWdjK&wQ*{o`t&1okO=t9VJO^A3-vxFk~k*Rt0 z9|?RMGI5BA;!fO}qkG(NVcy6{&D7khfySo13*lTnzE!}Vh#aImTG|+>kAX$1| z4yKiubQ&_BJx<4oX#Cq*12|bv?9cAsu1p6ap1N6FC-SmNZ+|$(Ic@$3?|eNP7auY2 z1a*wQB;(e9l79Al!Akk}Fc#zCfpdTO-0sTq22u3;`u6K0mE2#%?twFQuOVprRY@hd)jT&B(h>7xky28}z`2GDu zais7!M(!z!bmdI!g72gJIxN%jZYf#E2#2-)Trmc1B4Kmv+f3XV+Jyx^2Fkv#8)1*v z`{vaJ4?7EX>rlFHlYzZFI0fwPkGB=qs%gL_TfemU zE;$nH6mj7hyX|}_&F|d)ICny;KFArQ*<31+@3dYQ-h&{G*)^?Ht%E4YYIo=Nezkrq zUnbL>l3c|vA@5t7U=BOQq~+6arBnD#du@Ns@u8&ZwhHi@WhdoNIxm^_tgzP>l1m}C zT=-LqRyY0awb}GK)qq4YNn~X~KFPvkVnj;h)jTt87}4~=!W}B^owN% zhR+}YuSv)p4xsojq-p)gAt;{;OfY2eEYW2Vs+Vo`DXr)}cHowhcNbdl!;cC}r8Jm( zm%SX1AuP&rB-}_OWx;1JCG}2~A0fo?g1BO&L6h*?LbKl8MTM(gxfyX<%@O!D8sU8t z)2(mcq3Nb(xUi^EoPQY3`ejAspUf1A{R(N3u14>PZ3Y3d)R4}a2dogyi8buIp+gF# zU=x#ZF^Nu9H*S_}iuu}`?vE9DBu;UU4f={*ohmc1tNRzJGuUSa3-vaZZXC}+C&uI| zq_+!`FYTIZ1|n*(ilF<#dNU+|kGMbGu(w|DY6-jwTaZ>$76n0mAX%hR5~E}Q%`gN8 zmbPn4BdBL*GL$>M;ca9&We^7B7Fd5;)grl!E@@YA66ku@)+-|M?g16wiJWT!hecBrunyAW6sKl)sp6(!=gs z$rMrhuy87z49%>VEIDUa?~1`($jT|=(u!{Rf7C)OIYUc4{Sdp*f9N|sI($o+uM0Dz zZ9h`(NK(>L+}Kq#FcUOc;6eRuMV|iDNWO~D>o&WK$bh8eAFGOCpD$d*@1megYe8Vh z@ODY<>~TL3b+M_-w**XX@)&_T@f79qBL3`wq7A4Uaut15*qWQ&0Kxkawu=e1mVMY& z9V+9WJ5(~}86ZW{f48}ba=2SHN#yJ8S(PQSH5k7Gb1<9O-{uTe9Yv{e*AC5Bw{u{C9dk)vH z)!`3vgs8CVaV9EZA8qNvW}_Z+1~Z6=8w51OrMwMw-TcpM&w72Ln4ma3z8kQs(`wE7 zSOY1ta-hea7#@W+&Z;V}nJh?*N)bigauE#`6_Wy( zn0RG@WeqOlqwu`=)M zmD+9!WK306(xU+9=SYg-g<1PLurY=|wkyMmDnOA{X)NpW9}~un`>mjv2B60|0{hB- z!U7U0>ZXhh-d1ufMNiEDNjWueHWASlI=CeWGWD|w8p%5+reDu@QI2?Sr7?oH^*`4m ztH!V+t1<_INp1PnrbqxwNzSl!&6Su_(KK-3*P#%%TS~Cq+>IxlGxb-dvvWhc8?zq2 z0Asqws6_9M8LX8K1<2*aNQidO;YdZYn3DZmv&w6h+j=w#M%g!e(g|96M{^3^lrqCS zvb@4&eYcLomBW!#u)R0pC7H0-w{;SJFjvRC8h7UNc0(lL0Uik47RmpsB#H@!g>YF1RC<{uy|#dwIA z=VT}fM9wOqnXFOl3B{JftFd;V(9;Jd`vd6-ZYCO4F2Qq!kvv$9wVsT$OemwoLTMT` zM|~iQBH`kfzMWVhtAL>1lCTcOq^P#Lx2!mB37grEBa&p99?pW`N5)PV!e+gRGihNzw>%nfKYsjuM$=V!-kdz zl}o84hzP@5=0d8_uhr12UZ|Rrla}(QYyjjH_XC~Rsf~wv4Oj3(oTBBQ5xj-(DD+mE z2KQVC_Phghz3`tpM+Uo_y2-u3MFG!vR;ekfU2 zN7wJP`2~817vo+8S6CgGg_VJxl&2Vezvj}jYIeAZh6bu&NM{<=W_Ej5KPx5!jRw7vAJhwtY;v}q z!%h;L=>t!hSTa_VH`1#%=v3082E7ciCG-ZQIN zbXv(ZW9GBXAfnBQwk0zlTIp0TAcw9u+mmns#t>amvYtw0vWlJ_LA#nD7_4sE;E*lt^JDed zhCwLjj{k7RhE~QA1xf_31PiGej+ulf9t%x?uQ5YhmV~OKh?>f;)$tF1;QacjhD`2C zDYDVeUtW$RLo;mXR94c`a3pHJ1=ck8Ox#R$71OP|s9`>AY+GI(wU+WAw2)G)vbWm2oC!!&%9%ZN7Ay?zyqLHmTh%3Bz0JF>8c7x>sqT!tlr?yd&|tND_Wr@Q z^o&DPKBkRiLETZN1eSh9`v9^6tTh_;Bx$WSoPq1$es<9YQw_R0{dkiJnkz8IuxZ6| zIkmY+pxczp!-LiyMG_Cfg=0)V-R*EWyJWAVVM2SFeB9&LgWif{iR}oIqxWsO`bkbj zL^pWv%<%KRS&4ky(6B2Ce7*?H(Rt`6(t|Lb=rx`Q*6+E9lzz9Hq1_J^aO8#Xf$|Z# z^gS<};)YOX1Gx%xC!q1Fr`|HDRb66_40V0ON}) ze>4ixZb$d}AfQ7BZSy9YQ5AOH8xjwMX~Jgk1XPmb$?jQX0#S*u`A=z8}3j$R=fr>&&Tt65~;CmY&mjDg*CE$?!Fh6`jkJ zUboFclhN9-WC5Se&R?crO0CTqX+rIRJV({!@|rSK9fWj&^eY9 z?Gl!l-Y&`KzE>p*;K!HG9!U`~8SfX{!zj18Hynf`M;a#iYt3H(5K1B&IZCVqA)K{_ z-CYLBH&(6#0%xUI9Jo7Fv>V2M&I2go2a=3ItUZmN+M2RSkbq$ALOOOXFJ}AC{4;C_ z6RYmw=tO7WlwW#`2T#_YITn3LjHyVp(BBCyLuU{oY?vbH5wWQSCYh;AQ?q4O?FSST z#m?=pLemxclV~MW`{$1TA7kef9NX5t{n)l`JK3>q+qR9J9ox3e9ox2TJJ~V6ocCX+ zzH@OdPF3IZs##s#)oYD0=QGCmJ%Yvv5C@HYcHrqf$9N7@UL0Nw-qrfDYXygUqy0{0 z&e~_y@&f3#u%rCwYnmb zMYZQhcm!W#x^V`jyW^x#ZX!z5-UVg?0s!*E*uJyr>MBu2lih*7D0r*e+0g76XDF$n z)9Z-|2XNi-^<%p544+P=n*ujiW@k9FbaFK#cbA~+YdSmSXML`-D!X5_mCuQPx=JxWgryg~W_N-{*Yr)LB) zn}d2rF`YSZyIB51^;>z%W7-hN!Bf}Oj^+6N! z3?a()nn#=+W;^iuR*+2Tl54PkLTH5~*L76oFyaeQgPr@Ez0^=3^H3Xi>izLi&jarb z^>PhHb!syNvZO%zgO<*s{QciDP--AVG}g)3^fPa)F;=(`g)wy24-wT^{89Vd<=P)k zB4$lz7vU037?bhG&~gXfdD8p~72psB6_K-I&CXTm<>MJEQ zi!vK13=x3RTdllTfTk&lQ+W!J??lojd#ozzInj+*@1J$nxtUI{M~O+ICc3g!#?X}< zdS@V=TU^nHXMlZKh@|f+g|+fCIKWlTRFFtLnB?rkL4n%+8%?1Rlk zIa?SL@}Te$z$Fn$W1>Zc^;*co1y-K3Bvz+D9U=hSh1WS%o%gfO3(HOI>I<6?q~tY# zp-y+8L#yCDZB%9te?M0n>Us?@2vXz61*KkdB3GHXZKKa<)fh zjE~u2OIlK5oqt5)ft(KKFZ??X)5i>Kyh`%ige%iRbty}S*%B<^06ua(OtML-VVgP=BtuaHoYvsHcz3F-!i101U| zhZb?<%Eo;fwptK~6l<#DwY%H@u4JujGDL0uC8GP=XtpAApX8g)AytkSQ^)P@&SkUi zc(jYDrs+FzZXZaBp}#X=3&|bdZ%$UR0)$bg7l^1=8?-mwW*XXkkQHfY3r2tNXhLpz zUQeowrrF%HS=No!=ejNQ1jBg1(O5ld#5?XF4MJ~)RcSdCe$*-FQUU!_llTRxejZ>D zVbKcxPfDCw0R(xtDL#EakEl~tUlm0a{ELN7tP2B5JwcV*5$z9SE+K$5bN&sm@ z%5ERW@Q^DsGv^d%|M&yU46@`b2DNy#ZiBrQ@#t%EA_)keFy}3o_;Hq5cs|%jQFFuEl zz!G;4{L0tn2&!`*)tK3nFl0hyH5^!}z?cg!XTRl^q$c?_4;6h38;TV8U@n?^B;OTi z%7Ni}4?YjTH`~_9(3(HCS#Bv7;QXj2934L#AWrZbHbVy{gznty(MmeXBM+h99ff)R z9ZNS^$NW5#-oF|uo6;N=phptcWXg%TYc#zCaeVo?coE$XmE;m@uDwIz`{T!WpRbjBhu^XjN()1@| zk@79l7hsUG=Pd~B0U#0}^!phN9(mK=3EKq=SiSH^yq}b_0!JMJKXaz$=;)km>!Re@|V6i zg7vkt`5suKDoZ6k@SLHg?na%4>98{AWJ)Va^p7=Js+1w$rr|!}17*DR8*Jq*tlkv) z7un{Ho6a*YRSnKwt)m_5NqvWhg6yiOL66aSo^YQ!0wm3Z&b_g273#Mzn;$NanXQ?= z!)$zbxvp#~>_P3VJFFlsB<2N+Q7$3p3oUDLB&hocP4hu&f{IOgs{8r?bJNjKnDC28vgImj|FG>AMSk!>t1f+u*OC9V_rm2Fb)7C++4d-!7u(R$ z0)t>K3TtZ}z2hGD%R!3RGJ~kF3T^UBPo$+- zvnVY|IsN8IuTeUeR&!aa3yino(A>bNlZ){{9%1O0$6AhjZaz`6td}{*ebI9>R7b_k zQkLbXANv;uiYo2bvlsrtEKR~0y;q9eHUg|6KTm}O)Uowyw-#G%iV<+TN6-hiI=MH= zPMJN#%;s6b%}BL^Keg&qe>b3>K7@TF{a|Nrrg4R${?IhX&oo4R2u3UJ+_e>{yn3As zzX8qnF7aq0jX9&M9nJ02DEPIg^T}PNuAY-%H!@~v!`*;w19CbrsWW7b871SwAbfu* z5*}y6WyDS5q(w|r&%kLX{*hgdZJYE;ZF=f=_-Xvy zQeK0N@!HhO$mOrceiEkZW4)HnRDT(5I2p|6!1i)c3`>^(>HAau)P>YQ{}vi(ld@gk z+&20Y6I^MDvwnoe%S%kxp~t2&^8~*vax!Vf5}H$?o>0wkBlJuIC*_gO+m)U}Yc`{b z7NNkWG`IElp0_dw*_>$Sx@E-!C%`4QN;_lyj$KSw4n@dQx*Nu@#Wsw z7DF(h!wqenX9;8yC7xY&IuGTIqA1pFUM#~;;zEPNYK97owYC}6R>!8suqC-CRu(*Q z%d%Cwey-os<>JKNAWB9q7@UA9HqKKK*G2Ay1_QI9da255Vw3ZW;_5o|1P@qS!U`pM zy+(t!@o@QbZV4L{K=2f3F(H>aH;%bCX&uAMFBpXcEn@u+*PHZ;T+Pe4QvIkL)hQ3PpUdx_Sa#{m&;P-CqzM^YcJ3=Rl)dI_$pVxP% z8J;e{K8u+j)9dd|e=pH~V!DquJ7a*{+d(W(Tg%&X;3fKj__?LKus>eQ+lyc+abn35 zg}x7!pwxUF-uR6eo^1T>2o^$y}n-SB0L1HB-%fu`&z;r&T9dyir ztV?7HmlHASf!k86?EP%%?E{Qmf%d~6mf*^|az$iT#A<*1o%2Vr*8CHu8y2IMf0QAA z5>aO2^5xsX^jY5*Rv&qM+B#=?JDB24pU8N;_Z>$NA{p&1O}y8X*@yAEdWsbldVhW)0im}_gik{npS ztY|m$NQsa#m2h5UU9wR`o~_4l5D}8elv^NpDZgT313QSL^8&t%U;@~pDB26*1+K4# zz*23wlO=Fjs<}=|!QxH1G=-d|`bRHiRjC3NwauM3!N&r>hLN535U~O3xo4_DT+%U? z^plijCT`;pQ`p(hDhvv=Gr?IjNVdcFw*{2qISZ2wKFnVU*-5sYd0KE%xuzg|K&xkVJyE$>uT@kGw(wT$REIy}b>-FgYoYi9k?83oEhx5*b)7ILK0xM{cYTwQ++F^Dti{sgM z(3exC&40c7{_bXDW%Fm>C2KSs)cn;d29IcFb>6f@b_NXN+8y;J&AH>vVF>D?*!RW;0=_XrR1(Ro=s z*A^-8tF4NMIdVLJBg4G11twRyJ@MSl$G^K$e*%7ZzpW7$d{vFCkppInqfGSu<|i9} zOEf`rkYGY`Lj*n7f;WI8Vv9qJoO-LAGZ|7X3Ln6hSHNp8$6~5)o>uJ&td&hJ(3Rdy$s3)iQZtDk8^2Yl%-C{KaGK^piMkl4?G2f^8@ijvgvl=oA ze~{7#O0a+0FkXC@pLjLYBC#Vzu&yv%~^cdy;%!FNdU0?cO#rcAV(ccuXG_{nzY_I z+OKS9zHNclQT8I41<+AmpkA0%VlZ-F#hDqk2}Cot3GDCkmi=Z+VVeMH_CtT+tA(Uk z-)d^M{j5Tk%WQI6clfY0tF$MPZs$q<7K+yEVg`CYW&O?qEYZF2vix$SG@8I>pgV0t zij7SQ_kmkxJHb(zh?7#pJDdNqFG8TGr|8yBpxh{#$xfAS+(|~dbGI6XYT-8J$`56d ziy>~x_UQH9!e$V8h;Zzf(SZnRod+U~$-`VI#kp@WDB>6;$i`BF2+7%R!Ct zt(!SzOG@iaII9vp5;7`Z2QBx*#>O=;4lyzxblm-l_us8SB1;V}5~UtQ*e2O4@LJ!z*?0Vp zTDC3Infl&dVPsbsh(5Mw`+w|7-U%MXka<^wHgYP>$sXYGA~W& zV>}ayhwKm3=Us&6H3^eCwc7YG;z%)`2Sqf@{5b?UZc*|b9rVhEv%2!Yh>w&oITTDu zi#nuC2T~RBnO}vzKp&3UhyNCx{ugup(pVW8IR2rxGXLEZ|Bu|r{9j-ngBlVw|9>by zB!i-d;ilvNX7Yb+tu;X0LH%zge@LXh@ab1aKBQp=(#xcMatw3iY2KUJlbadmJa$Ig zH|zu0xu0TN&u{zVuKLZ&>=or!j{WQNb=bCNJ1+w9*@GvzCF?$mbNmKsXCPGK?s-;`|JXZk^d}DV8KBEhO9|)GK8~TPlM^Ga3CaAAPuQ8!rt z9M32cZS4e!D#A*G9(U#7XQE3#8o_6VCEz2(63#?YuJ=#>Dx|Tg1JE@CjumKZ;PAmp zfruo?hG?0URFPtVUV&%AuLDR66^#(E2;Yl->D@gT^Nw3dGyc$sR9}MSa82~JUj~>e za!~;pAVV6aH4t?u^$~{J6okY4OA9TIRGGZfRx@<&ks%@#wRQ-kcnd++kow$?32iKA z#S`fe*AU(kfng190+C`2P^<3EsD27=399TG7%nM>(*ErY3U!!JQ-*kTqFn=5$Qo04 ze}?4pu`~URK!zEqy^Z4JGW_dE^7!w9nJ>0ReLqI}77}FcI3c z+Zp6x${To@rij!(5gaJssk@d)BTrXL5|RNHZVAdz5tW)Cm=56PkIp>3#DOxWkAoRw z81=ih>C9X>O(;W9Br=V$gTeZeM02nsZb2kJi6_UEDTS5KnR)0VuQk=4bX7WANtXOf z#EGBYfLrXW9)S84Lsm`B>dyUJEAh;V9HrGvc3jzNc+vhhA|qBICQqys*438WDsFM$ z>|GmI0;UiT7HJJ>Oi+wPa74>g+N-PwP~sw#&rUprBJ{i@6D7KMxPh`NC3GM7gJK*< ztkfTe%QQU_Q+GedtsLm{P|yua;c%xo?;}PF2q9rDP7e8Ln`KoPy$bl2)Vk~lbo~e2 zdz+y04w#^$wE|c_0J;@yEba|neab!Uz+a0lvh2Ts}vwXNm8%n;=^a#j+MC;$CwQhmr139ys_~ig>E_VojJ*Wg5;GA(kH0z z7kSVnH7hsM6d@&$E1Q&*Ef_0Chb^1LOWDOqpqiYOi=(QJ7TApzhd=XqSQb##^$Xdz z|4iz=sag!wk^w{#vU$>mSvE9OtiR5EWL3DF`0kAGUFUx)@Dm3ey(BTKvDk~20h$b0 z;7(@?^3v+3@0#I-x|MDlwgAls?Gb!~koi(K(!mn9nM}9Ev($1dFIhT;py;zKa4wU{ zs^S^r22E>C&lfs9xz|7C#lSG4+rk}mHo7~Lm)|WS6U9%x=p*ShB2sItO=qT4i0VF2 z#7F^5c(@YKTwVw`-fgH7AfSHZA? z1Y(q>^{aatK7tyKeiW>`Eu7C7(ib{9p|6r(ExWF9Y?(>SVbdE4u1Sevbltl=`Ugw&iBi~VY9hNb@%jpnJ(eJ-A$ zjF!G=!$n4BoU~HA`IgIT-oB7|nh|^ii+(>pn&QuVOd-0?>Hdxn_@-G~3Eqomr?yf% z_xs!j4R#uh`So?i_>;F@cSE3YBIUHl2*5eCyRUg-{BDyXN&W}EKOlN_jXe|bd7@ZG zhW^O0s}$##&=b8Mi}}Bn_5PPT{+DK0S^hDQ%l!BJ$3N4|e__8AsgFhyuI+Zayq*kXfRh8!x-t+{51+ei?ikDk9SHbTOc(?GwKAOwJfN7b+xLmPzqiBBYs&YFTGQi8h@g|8!G z76%H5cO?q|FHg!!MAI*kj|yjR)?mwu_`#eWn_MBEw>=+mlvcaONEKD07?QZm zD&>&{592+$@5baM^PsP(ks~k2ZV+~RLD#+6Y7~72y)vsK-_<2d9mW*}NxgWGaj}EKa-`KXq@@okT&hooT}QV{NGHs>4Z03$Umil0u8gnyn6VS#Slx0Pwc3@dzB zjX{oXV8!{;W@jQg9fknM7@8<*QuW7{{zdCe6hhYj0| zX)B9u{Oog@e_mqAHxQ`dJZP3xcTD)iTY+q8W1_t@t&6=tSotUm)cPuBlkOUtDqXs6 zC8vd;jL!LJHYv9xKl$o^T1|X6jR5<$592%2Dq}gr&K0j-nvHl-i1b^Dv+iOs!%uwTQV%}I zenr>Y^s2qfw>pn(J7|Q_=*d=Wz~d}3ZmCh`&G$=Ui_5&krT8CB!7MP;`%-4^A!mY* z1zDHtU(X1C3uTPV?Eehjf6qbuBY3m?7a&ZQ+P90LC_?8swKE>Y4`Ox+d5E@h<>1z+ z&7FYTNjz+3n;Y%-w`f}QvP9NN=Xu2vlovxUL`){&`!AQT$71$?IwgF-V2?oG%)`%z zn5z`{556qS;!wVi&(DWx+kr13eBznQDriC&wwmsHi^~rLi>kf$B1tztmmEG4VJmYZ zfkYPpmU#wMgzu}%p@iy+>4+{_hyfvhPy@bYbJ)VE5*B|g5iYO>t=G_H8goeOums!@sHqpYQhle7Lx9tT(%f;Oe*evHQ?9z^r|u=cIR|5;&?YKJxlL z1A_JdeP9z=OV{1$d$F{9HLuG@HiCpdUe) z58l8`5{_Q^*2m19a6m|!PqBW*dms$kZvb-iLWjF0+*v4$6bY}~fiOY*ojr(BHfjE0 z?U!q>Q80Xg<9;b8lP`_3%xZ55QhBLtS~Ao%#JhM<*g-qN5NM3gy-rbs zGVXO6aDqIyE6HO#kKr^;wmjT0*jSkb#J0-tvQYKA6HWUFYK6y!Wbqd$8Ao0LFVBF zQEi}3%ei+v)RRsK-$C*o+vkAdB2IKUxkWi(De($kI69cX!483v#v$%jw6d`u`yM%env;@c72bt9yEb)cepslrFrpVDq9Yy z0_o}ZsV$c+(qOJ?>D7IctVu+pZxh9fd^=lh?~A;z3|oYybF zbJ>)ee+zy8i)a7aw=(|2z?F&RUqCV}{{K6{`jj?&hi#~+>&IMCY8&R*wd|!XhSfZs<4Kd zFf&}4zdCJFn+OaZm^p%r4njbdX5NxikuBl}N|=Sff{Vbt5kgv$cjGq>(3pG&KmFTT zOb};?ca=f1QXXE^RPxi>=^YFH-ou>`HBEYxdWPUQi)whoPhPee< z8xr)&n}>PNXD9?w)QODg{FuUvj3F*(obuCS9T}j2EP8$?i0ghw0dJ2!7F}%kGAp$u zq8-7Tv(FF0%4pA8E6^fN|QpRY&+Ex%;n&nD7Cz{v>Sau3asa}D=i`0G&Z$GoQhahJ{+Jcc1GaJN7ht1#dVhue~@o3<8D?#fFKg0;VOSIoA&?vhW?!>?u%Z zfsy1+)!(c}$wB2Bj4M>5%W!zV{3(;O#i~kgSy+(wnIwnnW!tvS3oQCRJ282p1Z&v_ zJ7skuUW!=*Pf*Vv1@6<2*%93DKCf0j^ZS<_tzaehTvH(QG~9}9Uthq%3wJzfZ4;*Yu51kx*O4b8AxL@Sf2tOKZ^n?DhWS) z=@i`iWo9Y&r|36pFYYL@Mep>5PKX_rIqqjT%POss?>e^dCw>>X%83&=-PY5LU%uOO7#~lfntMu0&KthS z)1d$3y67JRBERt!PC;&{(UcD3pC7=|_*i+y9yBO*=H1EiU>7;|f^jBe6+)yKci(dI zoZrb8U|r2=+Yp+(Oa3^!qg`|>=O zX+Kv!KRe~jpa?sXly6&TbxsEu_z&hN*CGSguF8%t$z!Q=HV>?rybe<@V-tAnUWe{F zQ0VI`2!+)A48w*=%Av=I_;2s@;ccmy#wM`6?$ab_50!$uE|Pi@U!a`&3T+n2dtr>I ziDqGlkS1m^b}2*+L35`Q>RW4xFjj;%b5gE^)gl|;;k-;JO@Yl=Q8My#WKY@2(HrJ- zGIWU_KvpRzU2!8Nn*%HHu^REcVV4TOc_vg{vM`kl0vO$4E3cP4VeXSf4aor3;J3l@ zZq!SmjX+-4#ablbQGybh9gN!*5jaWsZG!VD`b59c6_7L_DPdZ^g@vgDCLu*x+CjFn z+L#q`$SiBw0h`NwRPl$N1rsKbM6!u9|adt$4Cya{cc!B~zpBsBg za8gJcIFBJqSs|C{%^|B87PO^72QusEinG$&G>UOz)ubgy$Fu=i#|9jY?1i++MvmH& zF#C<_hGh9)rVl4vd5Ai;z@D{lRZ$G2z_h7!MEgqnS{o4OM9V0e&VFbor8DheS-1g% z64Xysxq+11Q~I~@V{%z@u4!xggNCBb)+2C1x)T}rZO(G=F%p{ zOfN2>WUN!LT|RaWBB0nCUo*mZ63J+J+G< z3nhcP;#mYT*B*;B38I=63A53vCv`logha0k7od4lEULm&^U2C1)HsFu*2(4y_AP|F ztRvh@H*L}w+`K@j?&&eEJe&>*n%oF&20YhPSz1x8ji!aZ)*v~Y={oTMEHEIA&0Xy= zjY{=|`P2-5{v48DMcdTc&x%IP)FyR>-Jmnk1lky1Yvn}4Mc@ZeR4AWtx{CM7_yfBV z$U?qE;XSHZ-N~s*NS+dmR$4gJ`JfLFo{k|NgyaT>-;J4HdDsO9N2yl=Y=lIH>+%Lf z$e<(t=Q{4&4%FVl4$O%Mdn*YC7AG;i+Wuz&_AMu#+Utv5aV%N$oVDP*L`)QwO30Q- z496!e>8LwR4dpz`)!DpC(q$DQYveN+VnxBwe&8Lz46A8Z8GgN9I>Z4KrTDu3;J8VC zU6zUh1#sAWrdz$AmTS?~Gg|@dq4JxLt&7h7uaBt9pt;~8TiH(m4 zsK+|hizu;7YzEohJ)#)Xj0F-oad=ULLKI*-Qf>4vKaeyXz;dtD*twp%s=a5?00Tvw z?L0&oef=h@zDIxn`uY>>;s)%^VgpQQo$8?iKUOrhePO3ndtIJtQ7wGJ@Z+>Vc}z^f zC_f#2QWy$zja~42h|P^I?Qjq>i)i}u(Xn2{zKD<2!4`ljlZv{!%JK4)Sz{czp%}B+ zkjSPZLchYPjTaO-;t!NnE;^^N*k|+8oZF&og!b^nRG5>cx84yFW6_y>o z+i$z|@}=3;cf^47b3ODBwLC|?aAM%F#zln3bgTXS#3MtUS96^0>UEFbPN)`SnZllA zr3i?apopA*So3?SS*s*}SU6K}>&|hxL_9@tuvwk?OB=aoEgF2Aqa!}_*$M04I>h#? zbsXiKtV8D5zPM=mV*8p3Vf}hNk2!0PxOW*wgB%;t%ASwMxQ8_Fu1efH>{6u2{}cqB zt(MF45Syc{a*ZNLo^F(I_$t}e15v3^{nteGxAM%$#_<1b@|aluZr1o`qWUlBp(6G1 z>hHSe<~el(oPH9sx5Q6^omUlt_6D#viZ-hRf)Uyo>(@8jDHux4WMhm;5o;x^Y>%4> zAtv00FSf6SV%DtQE?9s~guJK#@2}^ImrJ2HH={P*nQqsYk9{fR(`GxNpZ5=2?$=y2 z=hrs6T+2ZXs<(rRMHw}d$MBelGHV>fW1gZcKIqh;-&d`KuX6*S6qZ3}_vNu0wacBO zPJ&|-(S&u-g_phRGzQV7lF)>CL0$`D@$91Db+$$CH)pm!t^L~8(4@WI-rvl(iUV+? zGCo^;tm&GM<_!zZhe917ZJHTDxWM-XC4T$g4&{bjq_+8V-OjZqQhPTs7)s^TBYdWL|x51lg($ke-r(;GGUaKZq#dp?473x4vP_>#&BgAO-oot*>iA{?<1Jr@}?5 zW1nb6;7Tr@6|4i0IVSsJVY}+bnsp2-|Ib1bbqhRba8jQNRrM#OWlO&=&k1XUG!dK{ z&Al9)gGqasF`H$lxCAYqLsw4-m7%Ym6cq)(Npm8p$}TG}2y<)>3WpPI3c`f`qh(?V z(iK`P5SfD*nDN#Q!L~5&>q(m1qpU}f`ju6ga~N}pvf$C01XHq!t5oT=jxDg|mieXg zTN9aVXBZoTPs%63iXdsd2ZI6Ev46U;UO`K_D|A@^6LN?Qks(0^b?lFdJQ4|=P!{5% zPuyS505Ucdv;u!LGQdkhjo;6+_?z6BskxHUCst_(6=gWkkQ=^o%cC^THISE?bm-dL zh`Al*Sr}ozzH&_yUvj4sPYEB2kZ3y+wS_2&rl)L&s-~|N0hEMuZSA>)pN{;Smz2;3 z<9VGPr9%ulrU}~6A7^Nt9m1wWj%Dg`QuUb9KwpwshP;uyP7v_JqRRkvsE|&zRUNXx zb6YsSAaVkbpk)B(XLlSppfY|d;Hiu)s6WW_w0hkC#OsV-S2}qc4Y?KRe~RJ~mN}|u zAmNmhAOSpwEJH9|(kkaqGk4Cd7>eNrSZ3XAopdYL#U^XMkYdjIyui$d(d3?#0C7Dr z#uNLpwl6K=P)RSz3^{A4H9?HSkfvh{|kTUVaza z^K?@#&CtMm)-hXUV*u7x)L9U#8+$|MdsnLMBE>h5BJxDa=ewf`Y^-WD?lpt zySsaNcKo`pl$-?W(+5ae-liE}scR50-y{WH$d!)wtxu}1ZJW~VBxQQeyY{$7S_v^k zk7+5em2YjN>suRn6D37`SWgjtyTnx`sh9C+JO>f#TBa*|FL~qxT6#VG*9iKz{LAet8J@X)Ij4@Q4~&NOz_1I67(3E?I+Yq~vt#I&u^>10j@{5EOWub^-d zqAm2WiKyhz)Xkwe<^21sePP3nX{13Gg(B1DGL|HY7HrHojOz$tQ&Aa`DO)3pL=T8doso)a$?hUEBPUI(Tn?s&$yX*IB2dk?WqZZ@gDnFAJ zqnNx{`4_@@d1V`qYA__Yb-kP|8#uX)r$3LK{>CbRj{u4#sxsHCLox+@mfkyKZy3r4 zb77qgObs+{>s(Issol!yt@pNGX4m^(q&qqks$27I^(Fpae#K3|jc)6K81y?M_I7|w z$i9fY7M`p?foy0^h)O5}J4hlc(83(v<8HgO>ha=xrsJzTl!)}ecozUEWeuc6wWu@* zptw?<@`5+cs4o5??G*E@jLBP!k?Ep5{Xe*H$#t9OPFvVi(#C?Tb4A~PZu9OzK0ZP} zRt!!>iHTq)EtwUM^MWX9TN@t{KZDK7lAhkEsJwcbIIxI%3wGa?0>_NC*wW>hAZl29 zrEj5}(GbEOc~G7Pj-CeIqSa?f>;M@Qw5d$Fe&$n)@4f)BC`u52BE%wl1oGtDdJp%C zz58Gx_EL)ICubWiXpRu&^-El24SeRR&w?kM9H(TazLXJQ0#9*;@;W83Xye;dzd%F!CW~%2;nBmXQmo^SGuA z&mIRsAVA;|lYNIsQJ_Db42Kf?g$CZ&X`B3^0121PVcet`D!=^qe-7Nqyt=J{<6J6- zYjoniVt-jW1@ z<{r{Fwmx{nXKoX5>S2ymj|J#OV)P7RKsjNME|gzn3>L8z;sworNtl2&%=FRT1B7T! zmk=m!sXHE`5T`rLK;pwJlwWuaJB)u!nq9E;xt9|;jU3XXA__Mv;VsguRNYK5^dLIfkgP#EUg%R7=AFu%I?9IkQf=`N{7RihsTg`5PPKW&i;(9BocS= zt$%0gv@}56;<8JttZ*mpKtcHqBKE}*@5ZAx4|y-mMUq*g4@EFw#ZE+)9Qb-jyIK9-hjVT5O^c;Lv0*^pvgc#ca10}Ixg86?zY6Sd5iSrskh^PVQ+ERAjl3n#(2*yniU5#v{C`p z{V^CEyo62>>*I>83_yX3Cb5uMg>?y@#E62brrgE~uMlA)w}^#L%mYjXCYS44V9|nT zH@&eKUz2sgKKaWJW5}3G#F7?E^-tRQRJ3xF092MGLVTMPa<^CQV}iXT&lLGAXUeCx zz_SZ#rA^WhJiWj(sL1oOYOoK^a;+xU>@%t=9SN6+CCJ5D1-WIqS7+trODfKCDmPeM z9$?+ElKlLTWg+02Bg(sHOGy%cmUU3>G5g zip7r;BsphE^GI+@x^T$5eR(^`6E2T_C{F>G3fE5zFqT9iyKqRqV`CjwPbpJz@!1b` z6~)&PcZ-tlL}K$>+M@QNBetc#9p3<{4%rj$y{`_4po96Aj_YeZxD0G2x(g=*qJ`l6 z@b#r|7ntz0~?GAHS$K47u;?}j5^ zWBnJ50PBCj2wZAw*-M)kxaP4|=e<5EL5Q-+@J{X7o$5&kZ&^`l#_YduTPbz3cP%!4%}QSkzQfLP6o z4*!MHes}uj6$B^e=~Jp7*9)pYa1Fa-m<2}hO&Sz`ng^8IGE&PlXzpboX&Id5crGlV zfoVnxPBHbXv;%;CoV82M@VzsZnD+fE=@Mt+z9pnALu~5LL>kO8T59@DxM{4ZFk+;^ zzCLzUKqQ8@Fq$hc^l_F!d{*3O>)vpTe|_v5;B%JDC(NTi;IDwgp5GK8S9o!OZj8o7 z;4uo{*i~Rp<=iW8F1i*rne4IPvRu&;re&uzD4;vcV~2rRTtcGC_F{}O;@1Ql^-HkK zfx2N$%R_<9hA~KMErh`2o!PKYy7aLDiMp$`B!3Sn5N3m`k=ctM5j33v%mAU!$o`AW zNa=xS3}p3E{TDsC5TKN%VOV8_hs0iVq(oKhF+nOMo+8|X%A2l#4QsbUP98bblV6!vN*xnmy(ci zQE%^Y`&KA<1t#1XgVQq^kvzv*zkUbhb&C-y(FcFqby(mn=a!)Mpgo6B|UbskagQ!Suu~nV-XU4$5;ra;;1|T0c@(i>TH9HtJ;!u*mz;0 zsYD5o;Yhrm5Y6GQVgP#QB->Eq*(Oe(CIUtRO)p9rUn~>pJB-vS#b%VN?-;dlrJlWE z%z#l`_`^A{rv4lid70*qmC0@9P%-_zNfl0+N~dIR++(?jQcIEuai2Df=8pCf|CEkN z-(Y@6!sw`?)9RVfo4Ko8E}Cr${~%E~0PD6mKPkJtNcef5eB3jeJsq%pG7{~27J2_u z0^^!mTk~$s4D!2z6VYdNgX-?%?K5<%+6wAx;bYm1tK$*y#V>1^9p4hBoympaBbV;D zcD9-dkqyEcWV+^Km%f9VjxN{4eK(ktz;*Bg7ov}tl;tFiEfh7#58OM>?@x0;y)4+| z@z-qWRMI6!;xo}z8|#4e3;Klf$g=lhe|J$4d=vMPdq=fJ{dA7v)7h6>ex6s;Xb|_t z{@hUO%Zat?*UKw;o~M4-F{|pk+`L)7G|BU6IoY!l5>aVUrsb?Gol?UrVTdcF+5e@Z zEJrF}=oH7oqE?Eug2#=zVPU9m-7EA57u&enS&kC6Bh!g<^dSv|jcEa)DrPZiJ{L?a zvP#}l#V4lmPiAfb-owY5Lff|fW_A-qGkocF z*gc=F5B*}Be;a8x;w#s}Q{Xyz*>#cj6YDmBa_g0&@8)Z^_amGwjVjw9nM{D1ITRpVhy=|1;g^^J|_N-XlC*ufD^_4^o3W zvvobFPTOI9-_ z%*KLg+$r%wna@RN-b&_EvsoKS!dU8>uD_p-M}AJQ)dFO1HkmLF_Su5O-B3%ZVsQ7h zD@&wD@OjnU;owFjb-k|lg+j)QIpt-!)dsQ)$k+PHwExH0I|WIWeed60wr$(CZQHid zg)ZB+ZQEV8?JnE)Tl4+Jy#KkFi;2jq%pJLRWS(>Ov)6joXRRMTC`}>^nc`Qw-t`9# zo2+$$@^L{m@oC-abn@p~)xsN*fhO?jt zJm?*UA#DP8mRyxC_<5fyHGup;Bni43vMVY%l-OcMu@4RU^^BsWxRIQf1)=asGBYBq z^9e%~V9q`F(wtJ~m5{QfyG7BNStXU03W5(lk~h-jgs0KK&!rT?i!eRw6a6;c2er)I z^1YX7?DQsi9z1P?bg%Jt3sp_YHTM*4WavTSq$7 z58c{@z;@_gI1i}3n8T|lN@V%YdCkq_xKCPd#Rbnj`G68DG_=cjBc6kp0nAvHwk=L- z1KfH*Zd1{<`E{=+hwB>!T_vS3cSLvv)dAe=xWL)GEw#*cZx)ff@UJ_-KD;UEvUJsI z1b~rWFJ2VsrQ5=t%@%iGx65!?4WS9OI<;ArIi$52Jw+OQMPhWOMSK2a%aID*3#yyY zD4ZfdTeAl!Qqaodo|i0e%qPydzAQ5l>Nx;ys_e|166JD<$pde4ONMt;Ls8^Ujewbh zN4p_&P-HF&K!LNT6&*N|+~K;x&H-jAY6rv&TJHKoCuo&l0qeDvY#=~9wwGBuW1mUO zu=`NbvIlLv6#*_F*Q)*L>l>3frvzF0wcP`w1mPq2TkjX!%}L3(IS(-AZv9@pQ#yrD z?(27(9{fxX8b9u%oDW{E2%_;mf!-Vm{V~#SH<`q~@j68T;14L^C8S3R;%ITsqKX}2 z-vczxBKFU>lb@rZV=7E4Ks z_KpFHIew#?w)wnyJshjKcA%zFUe*PS-e`N zn!@?O>hT&2SBcjWj41vPd^*3742DYQoRA;&X-~DThALPofGJLx08k&U@K= zha1h=9yA&Ow$u1JN`?0VbSOC(a1_>TB>=$(SoPPT3q>Ihaf+fpkFN&Q@$hT9Kl(12AOY#42g;s+-tc-# zFvF4(8~Ii!yZox%MSrlboU}%keMK^q>@zJ(61Q{?Iye_T8@fDH_3AA`Y#BC-KzZv? z4}!FMeuqQuqS7_8=KRH(Otg@^5nXY>p!)SrN$bHkT0<|wL+Lkf0*e&1l6JpGSY1j@ zm{zEP^y+1{L5-jnTh4S|lakW(XF|@%eoZvjh#gzJ(^3;XquXu*7HOl(kckSpps1`l zj-IEP#qq<`?}I3&w8BZU;#Mz99MQV`{@~<=>;+e$ll9%@26IfCMxH~T!v3Ua8uxRT ziU)FAvF%Qsf>)D-<;T5^R7zy~LUV;fT@~AECd+n$68+nT?Mmo}pb$562jT(yWlKDp zlV+dy5u%zr%S3}%?Fr(gLl;xR5e-ud7M&d6FZgSUn8a!@jI`faJyzmg<1ba2ZnXry zomJ+p-8^UuiqlmtbWe3zuwH1+-yxT9;hfb;!#v7IBoY5yRxei-L-4~h{z-d z2C>MO6S4XTUgAH0_Q3b_oVT)H<`jy#j|hP7 zLEO5nBI9?u6$Fu%jQK$6r=cdQ@^W~&P z=l50h9q#V%aF$c`vdKr@xRsSB-m=A;b(-sy_jZ?O5`!fQ0F|h&TBPN106&9P@wfQ~ zgiw>d*rnGz=_D^dm2Td4NSw0Yr_?v3BD2IS(k&hxeC?b4c4esjK~#nZ*7mB|wc zmXEJ%D=XX8&eYd+#@vrZya4W}2i)TiQ@9uesLYcqq4$a@u=m;iT-;q&8@TKo3bBmy zJpS2br3iq=I=rDRMwerGas8<(UaMod0xL;(*WBe{2l44UxgFKJCV zMI1Qd;%y*gilneJerIv@fSIHQKQMB9{U3^CctKddtSc4kbn+lgsq;k@m5NWAC zE7sYYA8BO}8T|mtjB2kcA|568Nf>ael>;=pbF=E;r7B(%++&*qD#$WGY5p62Ve|7w zgiOp;`ZIf-IG$_`!0m_?Fxgkqf8Hr&vGNgQC6ETKODG}F?j{_u-G2szM)$T$4z(gP zYOqOq@U!&S1${p{<7&&3#O7=sh?ann8%XVL20N>K*$`eZAr1=8BWDxN;3b*uRg;M6 zHZLZ8yI&=KNgm%e*XGH)f)sf6W3NsiY=}*sAo8D&;YRB#k&Y>VW`bU_;TS~;3P=E& zHJ(57<}J#YkgBN*L~71sZRJ3B4aITFb8fP3L*_z`)bbW%BkXdTe&%t{7|U)ACEF;5 zQ6SbHCl+Rkw-#auGvx=CGP=;lFqbOu*ycJHptn6>LeGrvd7aK^P^>BH&$X;Ofb_Hq66mBJr>9aYeWRilYZal`Sm13QzEc;! zDW!)L9cZk&g48ScL#`6WEpiqV(U)gfv6H)cVNIjjH@(7_@LMHnrgWMxRMDp*y)6D= zZ-KFaM~n|e_c(-$pbXDTqrG&cJJma#y3TvTKI==_tqiYaCZwW+P~d`)3H_Z*U%j;;f6)Tilu4Zv326{NZ5`wxHckyvf= z?xeJVe8x)D@w>pH=vabLOVR=G38<&4^&&D^*7W(F>Hj`FOVL@1aaewl3rcxy(>p%; zB>Yge)|2GR@CsNo-Qh`TCeglXnXO>wO3N$R8Q^IlfiIE@8oVQW!r}Z0fVDDNx@5&R zeN3Mpu&tGzyb?kTtw|Z>$DveFu5cL*IO#kFzj76UdbJjyrx7KDvr0?aY(AO?Z6)HT zj`iMcY_Cn3oHOOohLIZWuGW#5_nMc}L4d+qJ{Ei4cp2$U>Ebd3Km0hEmXiF4oTnP0 z2FteSJ-@Td70uE^|7|#1w_If9bMuD7!j^#=8KSm>?&^UMgEc%|`C}em@37csG_+M| zkBs5r(F1AlP!1ip&nXN&B|nrh4LNlk|7YVD)t!(17BPGO81@@UZ`&>!9rP5bSj3;m zio=C9ip4(_wTWlfW(5tCbKkLQMiQGuQ9aT(lFpba{iZlWkZ0|T`CLv|_0#3!<~hhm zJ%%c30@iuRLqeYA38C;}N8s%4Y0AqjZ#AIY0x^~ShjY$CQtV=|1!j&kY~yhw$VOLU zUnnI@rWh$Zm+2-n;OSv$9ofu;8JeT_c(g+^ZTOH4MwMJJh>{TwIFg&LKfoKV7v?`j!3s1q$H`6k#kBY2mol6k z)nj@fDoWog*lqM|XDmYz*7ubITBmmor1rHr&lG?n#@ckzudQmH+9X-R<68Tg9+UzMa)nOx}u-UgE8Ye@Ol&sQp_A!P*zh{=!L5_ zH;G>19;*fIr{&BkH)HpjSv@ll-=_o6udds&CV}(a@__3$J>C%O%mc2t8&iUdwv#G_ zn7$}6!AdeD=^{ezQjb{w)90Bt9I-}ich?1M^UV#)p|B#FKu?g_{Uz@$&Lro@$hQfa z(72nc4HVHLkp}NB9=;L4ya!48#xbKzTySd&8hj;~zLV%KQ7uCdek?|@un{i+_$x2u z$Fn&0nNtnoX&&|6piGn)qNbsDgl1aJ-6KXb9FERC@>1XyXYT=@47cQK@f%jUp27RS z>4^V{ga3uN=@}XSp(Flw;Qr%`#QI;z4S(g|H&_wB+tAE#{3fs5l>)>BG<`+*-C_*3 z5)ijeiUsW8`(X0rEsly;1h#l;VZa?x3Dc2bd23XsZWosybl4N}#hi~&^}CwkhmBoc z9gmmy$HDdVRXQJB{zc^5yfk0W=bQfK&rNio&%JR0t4%}Oui3(8#j2Z&6|cF-F1Q{X z?+;pn{A(a6!X~KvW6g1V(#e$!qWomH}r;mQZ;D_%Y+vEV1qYI0%_L&&)OG4~Os`V-#1I8%u_pKEqGTXUeDcL#q8CgDNiw3h?i z*819Gczb_1w|3%sXHH$MP@qA;PkXmkMmu|2w|A>BLu1Oz687;2smUe#<_#Ah&MD!` znIn4$7m28yFmk66VJ2EBwfi86rq#aA$EpJdVa>JJq*B<2s|&`6JY(WYb$|fE0M!TZ zghN$@c!LgkyapBj>5pZ7VCK&^5!PYz4b?jLo@8dEU!L{A{0QJL>=*3mvc(U7UU4hG z+cmVC-l-)Fyr-GM!Oh;K)=7GrlL%Gtsvvuxo&%G9XO+Y=ZwM``H2W|~Logs2n4+rM z6Yio)$X%Wtv?!e76xD|RwViWID9iGlcvtcjsm=tli@1j;!?!Jx*fqSpR4taD3!sxB zh}7dENXO>@h<|)i1l~j)HRIwf@+7}`;u-Qv4_m*IMjP@8x(D_n~p~is+*~X?_!tg9y1

IDl7 zq#uiZeliac^;QFgNG6uh5O(s@>@Mp^FwVr(k3jn^{A+@D`OaW0qnP?r49<(pm`mkb zL-|J)QvwI(hrWd-jKl~McF9%a$X(0)2?IS824-7!Ac|K=rsY28DC!I+U*p|`xpd>i z@bxhGC#;{C`66itn$(p57-fHODcs7frQiER7%1q@I(8-ols)Ebg$>{Zd<8QJ%Aun= z6lcOg9|EK;6RayK;H(+#I)^z{qH>Mx!w{`(?ab1;*x^pp&+?f)mBVd9cf2u3VaIPi z{j#7|CNQcUw+9E6bV4yHGEwhgEwZ*ve$DzLnH3d`US)3!VC?N+B|#{C)s zL1Psh6k;L?7pN=6l-i9!^^`OdP?}IAy~Dw9-5RL`BuxVVL~aUYYM^DR8VE^*JRf3R zU6eWJ*;TQJ?4Kg=4s`~L@JvtvIi#s{bS^oU2s#eoPXD49vNO%XGCzX7#idQWksb}j zuQqO-JVI{#sZ>uXF@QItV&NVTkJ1|pxDS0zxr2GR z+Gc`Mf1AIr1vl~{m=86!z1ZLcYzgsoGz%i9HJ+9rAVr+#9c8 zKkc|!$Ro5Yv@SS0Nf0T^&q2EBu(Zzt_(5~ZZWW~ zU8ZTWl3c3^xoGA#%9ym3cykoGLls8ktXd_i@eEQYtq|F0LwTH2;;HO_m2@$S;NFXqD&^r-d0vr^ z2+N-8vT9=O=TsZrq*enNt)b(ivB5w(kAq~aVQ61kN~uhnDIYIEx(k>1>l!Vfb2K_D zSd8VQ`rNd_W5rGO{kuBhvK?^?0oA?v7iqcR^t>SedG0u;MwSNgDJjX6pFkE9(G9Pd zU(H~RzNXHew6};7$FMF5{34913}QT{w408`X7en=qm{(g?-@_1TM9JWUOn}2HC+dW z6azG*bT;&RXsiQnH;G5fAf2jIu5_@GPE$gEs_~wxRI*_cE}4g=G)ZGU(p&iHFWu7y z08k4mq%B$q)g*)=@dNTsSgZeVporiR6R~Y0Nozu@In!ny>Mj9wLlG4JRTXn!wKivv$;eDyphLtJE@*j<3xX zQH~i?hCw~CBejhz#~|irw&k{MZ29>6ZUE!B<5x_}lGj356*b&gAoHq`s8G#H{i3In z)E%l=k9W)TRZMq2VA zB&>nrdi*{)F-Q_uJN=j$l)A8otV4B-sE`GU4N!>XT#N}pl3)?z@`Y)NOe~9 z9lLEjWdZuf13+Gnsjz}m7C9eCPrdEt?^kdM9z>b4ruNVuFF|w^k6(2!P|XN^i2tf1 z|Mo;MvM@3KLr4B?kpHKS{4Z#hzjWk32w-*q!2mVOw6R)iARgo%XHWu)xo!7XDf`z9 z`Qoe5Su(!O0zcIlIi~G`gsdVjeO z!@gCmgjsxzkFQUjnA}yTlhgdfHJ?QO)pNiV>j}^0_Ne>^+ne_#=e+YLo@MR%DBPZ7 z%?*x{LF~qn#?G{o+>aw8n-T@WpXmIY?*9AnIXo7iZ(&!&NZHXpz9b!=N|YxqTcRt> zc<|b{({V7S1~HwUe2Q9OA#tAsjJkkEAenY@Wd5Msi=y1HK=}kO_h}3HTM3H01BL6; zH?VQJ-ug%e5#^yTdd0fUzGRxPy4yQocS``K94qunrAgVzoiD22(G3sluPIwl{=QQiG!(Et3nIy8A-SjHhsc9AC?|r{c#84B zzIzOdbXm|cDq4yzG|C*gtDlj?{wNMbqGQfnb&GASH4~WZd#sR^SzVx5nE?<;wq@Ac zxQs(_%2O+j_~A+Un~el9bQq0Yz|kUAgMnO7;94P9m{9^4%#I_w{}{p~fM_H&oza+q z09(~>b~jc6Gze)m(35z)<1fnuysPRS)p1O;t;E11K~Hr@4MQA84tflO68hJ93Sfrb z_5WEW9B;x9Hz*SuoQ?DHO|a8OEsmv!re09MSnG~Z;w|ThZ^T>(M01GxfO>t=d3Wr< zFrWHC2f{F%`q25%3}hg2C&q#3QJ27W_%?$<`koJrGss+)AuBfe3M-|dNRX$$dq$8g z4mk5=3$$|vC{oxSBGhu`NB>;5o@&aF4NVLU8Z>0mljpX;S@uP4<}4yf+=h!Lww1eL z7pdzz&~~f@MJURpI%e2^NR;i|tt3t=aj|O^R@ftRC+hP90S_V!b%DX`QY=kEPk$r? zksYgV@1&>bokf@?a0;XkP}0?;Yj3cp8xOHBc5z7!C?$rSbyf+s9ECiPckQ=^)i_kG zISWz6+mWzCk)q1 zVTWo`6IuXyv%eD;MzKW6SB@fAA(DJRa4B+tx_g6PtV*0Q%)Jy+PLo3@LJd_^qkxHu zdO{Ob_Q5--?B55J>$6Llgn5Wv2YuoYhuRiA7#dtm%2=2OqGS_1xT9hd-0#tBlQ6+c zy#a5kk#9q|)N6B0P~1*J8GQ#+whdfkQ*4vS!wqW}ym+8u>wDiCs{-Lfe4}17$(a75 zSXq;v9`Tl|e#n=*Pqfe-7cU3sLyQd7v`qH`e&;FGO$Q`0bQxfn_T{S?C;#@^WLO)M z+N5_GM3|>4a3e4D*Q*wAup&|_bsI!P?adp39Mb60pD;}>&rO~G#y+VDvT50W_q15> z_`u;BW*v0{y3#4ul$ixAp$;6o(;wlOvyV=BlKTRFsWjpMLAUg*4raf;Y?ccHcE9LK zSwDoO84JOHdX2f|vK7K6K%*s&pV<|?CI1}9*BV#SGj=$f=Mu}*<<}zg!l>CDsnOcc z*r~!Y%mfnR5m0|ucpz2`gp^!JB%nmJ=3s+G*G|Y_4^o$4gP$2>9C#=X`$dASVqzZD zE${@{cc@ZvfsKUm$wXJ73)G?QRo-090v-+G;V(cj(c)D>bz&iMycIOUw}@Sxc2o97 z?pDD@bJ;sUNXC{rn~150cYyQnc&U1{^burNP!phpylnItgb%Ki`Ri~=NE0a3@`Hkf z*l^m=6V2i+V24Snni_~{;$A1%Ys0#^l5C06t;##jt+Gp8MZGO4irObEr%RDdiG5Yl zNx}@1N|B|%s9Ad`+%Nf_DdBiNlTcno`JaPyJYOcNyJFW@@;s3eTq3 z*`wNyw17bB+GI<54B23#sGdyU-GS9w^5pW2i?Q(lVM&k~6zZI?vwR3h39#ktIX|F! zQKr#j%WgxIF%o&XrA)rcOx~QpAk&vhZ|+iU!f){gfto z_IjH!G8ryqk81Mh=`0q z-p&wAL~KdgYM%TbBg!ZdLrSG6n)&k}*;xhJD7J>Ho88WUj)~bx$_}#wrr=ZbJBH3Y zyvhnXzXKkgYBMNjy~e3M(^h#${774uf-5GGGXnYBQ7TffP*2ZdDVex6*$)Nq`~zOH zk1_u+$2*ogA3e3v*`B7Wl{{Emfw-E~B`1slqXu>Sj^7h7D`PJ7 z$-6as$EJgMdyg5UoQiwi*mQsC>!gD1N}ZG!(sd0iO28B29>jSHs(})Q5!M|*04%{I zHkZc9%37`wXPlMaa8$&>^4p_ZApz4g0_V6eCWXn=eQ7+ZQWW#Qw5rL$#`!{V!4x&Ez^=kpYtp(a~-f@*o z1U|)#_Un_Bqxh6Ms)9grGxeU4M%zMX62}0Bg#40PQ{xXNTc1Vui z*UI~C^@}HwYt@5K`p(fZAKTQIEv6O0uV1U^My~aZd~9u14^zRen7ro2vl%_Cc-tnz z6n(;i1FQt$u1DwtxoM(AhT6GbXPaIgTj(8DSY(scR@pvw-mRse!gudC%U$sws+R&! zmT)EBXFj?f9U|MK5R8UoJkO76XS$zX}?IDabgqd&K+1qwg(;09=Z{9bS3jhw_ z^NV?`^I`+do3eY%=KOEZgJGJw{#t;qvX@Qry+9zdN)<(R=2u0V5w4Df%1X%}Jpg*F z@%HCTO8kYTGp@6W#L#KIwg^5^n`4uHvB>~!TNi^I(DR@@pr`=vpfcAMipb8bFsT@= zAXPE#liR^%*lbY*K0D~~dlS}fM=!rKksS;WZ|%ZzSKOsh*DS#kr_m}pvM>Vk_6ci^ zGt(mU&&i8j2>_30!$vsfC1V$%s`o+*s6>rd>IzH~DY#%Y;JM$|>qCuTG%+q(`pKzE zMrcS77y(G~DPXL_tOo;C0e(#c)*4)dntQ@SAnth<|N7Yopg!;+?3qLco)XdqA;^G| zc+ZH)Gq*~_4t!|5$|HA-g-vh>PRc@T0YzG&h=gP`A?OzgHC3w>bS9v#LBdqj2VQF? zBWvsfd7mnlALGG|(;XMq=N@vvKoJCWk=t!^63dXu4o#%hgm{neKB|<+kwzbe0XP4G z;xRT*ujWx7*k6|^n=Fg%~%YJ&I7)2Od6&TjZK1*r~*mq{Bv}~Fy^V6 zRBJD=cFT+dQ-jveJT@z?L10KaI1Hyi!YmRrV@~DLHTFgpQB?$+;u0OhE&>qN0W(G6 za`9mw@4_jPShB>|+19m0jh~D+MbF+Q>`WiBV+qT3L8|cpSJjU#rzQJ*e#t$@9K)Pb z|29H#%NtbMs$n5(o_L5jFEQ^va0_-vOOtx+H-<35DyBuAxj!7r(hxnvoX}S}9acLp zT@NnJU;sd2DVH47F1V(OU{yB!**scak}Jk#tLLU zoSn~cbJMItjSM6qcyl2BdlPBuHvjU>WEE% zhb)b3?ayqN)9F7nF*&(d4^Vf{DR$ikS9r(_x#K0ajS`u39$g-Q0IHz$>VxkCsW2Bx z0<`PR&Ine@&+3zJ>(1)qe=Uaxx4-Je7PSx0Y~|+nR`xiE2ywI=H=5k3m73Exf|Z$* zdum00_b3W%?#%D~ja!|MAo*mK*$izaArjErDIy|t!V*yj{Vnb=C!U`w&B>c8XT}a| zz9%q;Q=FA|oD`%I()ylBA5Lvn-Y`p$s$WBWR$rWH8(7q)$52Gb)hgKxW9>|hIrZjB zV>b4p{+2qUM^Gdnk4IcYsGViJ0oul0B*2eHTSREhWvl`EXq^fZ+PFA6DosazmS1ur zeNi=-b*8vqKEqLLmh`lBvADl-g6T|I>#PXFSemAyx&B2v%)gayhHSms{>fp%gOK`wN{ENtSc;Y-XN+| zozAAqTNsz5jGT-d2Ld&u=O#DT5+1z(ybMI^L;^iWCcp)qvP+x0>2QfknJdOAn`ZI^-4_9qGkLeIacXVpr<)U`L+DCLWbx& zTEP3x@(pP^}BO(SO7t-br^E14`=fI4(~Uyaj=ST1N8i z5wOGlVJAi)S~yRTW1Gbf{Rdz(j@82On9VnV5`33>BHEeBMja&6xs1rsD*ALcsJy{P zMo=N$URNGYc!78wuxi;yQ`fX-V5p^$^Rkn=*LcWC1{G)OV%O<93O@mb<}fMcreK?OXVaRq!EnP{}rvbk=AdC043R5`+*IzI1p?P^gCyVBT#Y6UPJ=AY$K8m;b^ zNgQavZYs-M8yL`vC8^^n^PYxl-CV^NUko33L(Vr>!-gIKWLJ?EsI!#CAM;63*2vJ+ z&|%h{NQ+}3r&{^#*3a_FHB&G{zZj5dFkY%z0H8yT8vFWPY4FXy!KOmB7NVm|h&7T- z)im{8Lr3T`vFK5?Bcy_c+Pp-ZzxT!EvlJo``Wj4MSsZha4jTJyTC*=)Kv#SB#LL*Z zb>;AAAmk3+eMclRCrC?6#J|0N^~n~go||U0{unG~X~LVS$0jK}?!Kkjsi(>r;YAGT z{6(hEQU*kmh~l*Ys0QDWbzKF2nmJ z>y)|F;EKMjllB}RNQiCpvRZ&HL1!&V{Htpg z8@-ukCSm-ymcHTRp^VAlEe4_%Vhl-#p(jNH@n zGiBvLaow8WPZ|XIJ~yzd!0NQUn{1EH5?ng1RFVm~+3sq8<<&?EuV9Iyqf{@M_z}oa z6NYoAQ0vHd#VCl?qOIM+wFf^0M|5Es?h-tbx3ZsnN*WFA1G#fdbzyD`fTjtiaC+cW z6ffcM>ez?4)K2f8Q3k zE)2&ud`GW$Ng8@g`gKoOyEWot!lb*qJm_OLGOa(La!DqG(Sml;DVG$!(p=Sh3@(>L zB%+JBr7ew>C10!;tDAqiMKdqR`_m>&nDmPNn3Zb$`4fiEqOTvlYUBp}q`REG1;^3S z02_<-))`Y{{cVK1f#cp+rlG|NA@z=fCdc)(CEd%4zDioI09bZ5>ht_Zq$z~hkI0`j z?w`Ni#IQbtpDd4aKa(EGJxsZreWLpN!bEcm`7sUKuAq5Hs^*hgvOmF87xhWCvb({Fxh`_-7Pjn*N-`4Jb9-;mV3am@>|2*8&HP;-!TRp}> zQ9)gGK^&zz_~8WXY&3x-{^#MAOca)E=5B~6hT&{@6h{{Eeit7@{eLttnScbx%r5Nr z$n9-!zV}<(=QI4F(Ow^+w~vdMfRLVxKbg>adT>i?3Q1>lLfx#U&O4kicC_=y-#9S2 zt9oIQKH>P#Wnu;C0yDz&aprWX#=anthyiCE;`G(%cwy!gcV@{*(f}WQ-}&+0b_dMP z`aSN>ch-0N`2ghp@sb!hO&YNW;>rA+eG`tpBO3>~TjWpV77%YoN5m3(@ia%J74`+{ zdg%zn>hT)7E4by9{t#C$`jRbWe(sPHkJCwDybcRo7};5vH*+tqrBX8>s8m1~PQ!W9@XY#m1J z___5IP$hPzm}V8m3=KvuK66ux&0^`jfcf2Mep!Vt$qYfbZTUN<=u7H+Ky*@f zK#l<<+(9qPwY2R?FDm#DPdS_1S+R3fA8SuM;k62-~xH&#+eILHbo=QOCt$1wF< z7?jPh{+WhN6+lmM{6#@d3y2JAAVbp?f>h~^F&dIVYFaMBi*xjtqKh$PFMMGUKLiHL zA-f+izoZcy+BGw2B73ZmeuR1oLqZr-YQL&HA!p!+LAx@hrIEDBqjCSfZLt6NodkMI zlp^@443S3LD>bRZOaV5Z1`jEt5j(XS=*D?-31OS~?40Hkx{wg6v>R_^csFrtVQhLk zVaWJ3*r$_K5s8p+NHQ2dguL@a1FNv@PoTy9qAJWi@J`+?DwRxTfee3_?}ThT=Iq>W z26c^)A`XOPI%1g9L0hm$fo5KdsEqbGif&4t@_Z_-E%id?7_B&g;$m5~`TN{%FyHEG zkUFFqKRf!`p4#G`1H%hgMGp&w0vcqXA3FZAOYn{YcWUELuHto_4>`T~nyP-GqA4B8 z&Tm6~`k{rUi)x+9XSzD6Ip~7HiN#U*6tF1az7cWCqIxg*CX*by@@~w5=zcX@WX@{M zeB{|WM5+e@szxfYgS2WTzg_X^*=k3bkdvxF`6+N(G{*O0blk%a6qSi_Lm0 z&bTySen0QE2;iBdaX?qICH9NNJ&2)I7352p5fZGnvGQaST~Q#``h8 znLJD9u-xmQy@%Xl4eY`yalDNT${Y_`$h;KK_`}SLn_230i}_9EF8Pc`k=`yIagd*@ zAfsIlvJh=mJhh(<0JacG9_Pf*=gQ(MQL1vmvk6xL$9H7ja?L03m6C+ii-bo5PSW5} zHDEm*@KYch#m~c~v8!zrE%c<5G%=-4AP;iN+=D2~TcZyuSrzCpIvH#_k;}(8Koatq z<64@5nCR3pe;oFT^59XCXG>O`=5Q#*?w&*YwFkHRa~3z_Ii5y4svele<)}Yn%BxXh zQ7c6_$b$?))lCE0Z*vaxZ8pG{%MwOcnzVzJ*qaycA@eBZlHx+;->^ox6!w7PlNUqakJ;4XJKGtEchE0wf zJDy)}$PiOQ^`zfDGE&thW{Z|{ogp@o|)ag5(s&`P@Fb{9J1?MWbGi^;yaz3#x>rB@(m|T*<4Bcr+@6D(iZz8 z*z`$x?_1{EnaXhYJA^I6{`AeA{PN?G=PWXfpCsB)lPj+4;2QD|mSoH>l}5_5JyK|Z z0N&aZq>Po;29F6b5@mzT;XxiAAYwQV-LpF#ie9d5?Bf8fiQp{#PE&(+^<|LT-+0IN zA6@qiVQ)j;ym-N6(e*&{?TMB{yf+~|PKkR@8e2)K7eK$H(-ruB2C{E47F|2)mDK|K z#0~Zjd_qSN)yuwE{zOvPSL-ff{_MY|BOh+_`By#hcS4$x{-0=3w!h0M{;4Pa3$g9u zTTlF*r`A{LrT~Bf=up{AN`0O7OeK_T}TCMJI5(8%m(0W}55D z%WmwZgcgr$ImCIQA1#F2}#tWGcHH2GJ(wX#LQ+$7qaP}lk zaa;&j265Kp8VuI$*V@YroDOq0UPp;u`;~0-e7WcA_2(Asd{&p5?d!|Q#pQFOXG`ia zC=h~rmPIj_Q_W`KMHeqI#cN{&lS`c3h4G8{_0lKGH z#Tl&iQfv3^SXmbY>*P-YFJE(Y6L>ZLZk|38qvrkouQr>*z;@1>=-d`na|BF4&?2g# zz9dIQ9^$iWGHH$Mx%Sl2WzkmCVNN`4A_Q;-a(Jep$oncp-Esh?sVP)6sCk!& z(#y7h!fCHt*+MKYv`8x5nZso()1 zB08>u*_4qC*u((+puQvY{I+q@v*2D!&s&_oP*yDsv9D^wWAF&^AT)sOhXN4-Cdcri zerZE%=yWxMK~MG3uaHb^FLHys>h(J^e6{6S|Z1`iR7r9yhBo=I&JTLwr& zGhvKZF6cPt9k)fsTY+}DKtiD5olq#RxSF>KTT|g0aH4!*4_f$;!)r^dpQV6w?VA~E z6j|iK@Gyni?RDzM1-+feUfA_pLnV4Puhswp1E@Ffl|3m9>b@dg^O zG6a4YYGEXprfkfMX4jO-8__EwWhDb^5@sbM_SW%{^qU%VJ_++0tRp7=26--1`B~M# zhBl;D$HwpldM+dWR#VS*6r#1Hko4&BJ@{jK>r>@?vdtdpk#t{sbZa1TxwhplsK?;( zu+oRtGvVDlp`QciwKXxy(+>_ACaU8TnAWd5tT1gNy}6LeDH{HGyj>zjC0(j{L0}^F zBZhB}y(5;Yr#zm@i6@WP_c&A0X_L<71EUn$Wj^aD(-^EWJFgNDpx_>VzB!LKog&c@ z*00e{7GUJL724(s08Mbqnf0VCBlN~l%q=;2GRumMSe;!eu@R#SmN-_;wbmW2{ctg_ zkCdmx4ViX3MOB{3be_E`KwC5&wYou?Yd*w91&=CU>Qf#l_RJ609$eMOYp*hKvlN6p z37OW$_>;Nhx1y=EqMr~2d8P4wZ?xUBZ-$63?Edoo`Qjn|0L!5VTC*+pZqo--#h{7& zB#nxiZANnSJ~2miULdk^Bk5BjR}Jgqsygma;_vx*Wy7Z4oSPq`)NGayW5UfR7Jf5_ zBxTsnS86mKFEl36Vh-=V6yu;^>4M;{)*0Edq4YN}0yM!5&~7#t=pMvwgu=fW#>z;#4fpMYk)TjnRpI<3qx z%Hz#A*N8T;Taa1E+dzx@2NTJ^ zfVOEyPKXtm_e61<%mgMX$rf_L#%UP|afnrxaoM*b2}c}Q_yAFxorn6>`izR8rGJD4 zF?Uc8N0bzo!CLqQw@s!r7hz_9-8{cJeDA#!O6NED?vXqhlGBbi`nU@GlAPuyLfxa% z%t}(F5d3Q@ggloAVAwMc8ON3?DLMA4N+fk9+rUD2i2~0C(~po(D#7i&TWM}%NPG?8AIan|1 zatz_JvL43z_%Wlg1xllSANqEt;W_!F5&RAOoK+h6?y?}Bfd~yKN_wYc7_Z>U0SP*K<9fWIcp=QKJkgWj zX77zO9~|e*fgr2;p{i_}FTMAw*NZ$ClLss_kXByYwNguSH@amdP1u>Mzg|Fz97-jK zvYrFiC3NzT2J5M{r3ZKckM>e@BaNdAiLN6d5SsHtIv>4uM_0Xyr>Op`s(Y~1&G48e zYC(MTXyq3cmI{B+gD~k`+!cI}V_zPG%;CO?^{Ng9L(Y%l)y!bwKqON`$bKY36U!+j z%!S-)uvpt`71M-0e_=d-b3o#lSso7vO5Vngji)$= zYRl`1rFkpU#%BDh0k>}oP^jZ3QHqgegEU>w$y<}}nw}fFeu=Gt=Z7woajCn|uD9{E zO7^dbztq24)$wWL#bx7%s>UJssC=$`DfC_$5fFhM!l@2?v!P56kIMc(#?C3c620m29ox2TJL%X) z$F}XHW81cEt7F@?ZD(@M%$e`ZGw;QFx1YVQ_o{!bTJ@`uuzLk?=(>Oj5q1p?gvMXe zFJ{b4XnU3o8JfkK-NWNDp#w|zNLJ0koHBVQmZh54E3h;HG~0}%#DFLweLiwStQ2pO z%u*~HC8|m+9aPkit17Bu8V*X4u6jjm=k-{31I(na_82`T%o>XldksVOwR8onKTy4X zLg>|}v#nstR5Bg?t`%9)AvDCzJXGCQx|s(DDM05xYAB#u(y+zNa&t_ZK!pmuW4Fj; zzjstsGzet)7`2G(BZOB;{PRqd@g0=jmD};$kpPhw9+Ao7Yeha$qK%qfc-8OOP%v|J z%BhF6S^BEfn7Xgt6@Cn%;9k=VKf!Nag3}+h@^_E&lCZ>65L8TaoDkap}ceDmib+HCIqL||sYS^g5@ z*F-q!GGTc_SlMq88e@siI#HtyVo-s0gTJcfo;wD3e@nuf}b z(H=-)eqa0?1#?@L>y|Im1}kI})6mF^=-8)$fzbU8ROynaz|E~f8CJ3-Kd`*9rROR< zOA!eR#~)+!5Nr5R{HP-s%2o28boXyD{d-KuME|e-F!q1qzW?f%*#8>@+JTz51-2;i z_n7XuUXSy^{30lqzyAN8VjxiUeU9tSZk}iD6n~V0A7-4Dvf5hfru&@kF+2#6pzZLykcEMg<%`+S_CoiU~%r(~B%!f|mjWagh zS3KR5;T!V;LF89K z0wU5D!M>j^2a=w1zMn0|maQ|;9?+SxfYgof;&W6f5QIW~Ab43#*Y<@NL=58~3Ue|Y zo?H@KJ~7J(Qg~{C^1$sCW-oY1vV8As($HCk1?J9|&RJGxMT{&&u$pgmEc2y4s%|N8 zG@H^X+|%PNb_`8VNEI_cW=eq7#w^Kxj|Bx323VdEg@iE7raQ(X8qUY=`RQW`bH7^o zI-=|B%H?Q%N`>VB(8YVb{Z3c}lOUWoSE_1Dn< zdnBea&7K(Ou)gtJLM zuJ1zmWJGDrj|lDjU02d+NzBsNQX4K$C@5w8Aa?s8Dmf2X>=0A!lXCSoCes zSP14Y+ZiTsrkucIMyC<2Z>^TW`qpX`GEoNtm2a&E-H({@_oU1-B{X#`YDLtBNU}2! z)w7!f&a>>E;_e=+A5Zh^?33<&V6{@06EL&a&cXD*Jp+M8eR{_%>{m7kOJbhuGgmQ- z9;1p;$ctg>GENM$qq#5=*eR9q+9jCDCKU}4+)vOVc0SYR9~+0Lg+dStlQpW2ei#gt z^el6O6LAi&xv;DFG*cjs9zv&@3#ZcebM)isIX24GB za*PWw%FZU0O1E5__9oDg&}SqzhnG238qvvIg)V5aW+&}^xHaKOznrTY=oV)RW-7M6@!L7m%=P5r_=Rtino()zLVN^yfim10_n9=TmcBOJTG0*0 zf!1&ppTYmTFINrSHa>4cw~Zd;5Gx5R*L3?#nL>~*yY~<0%`U1tx^W@FlKFv%5?GgM zTiYW^DudEjU!y~uoEBGcm74rv_<`{DD=DXOU#y>}Q!D#a#7m}Qsl=lGiHv*lob`tU zCeP(v<*!!m$K9R%(v#CkJ>jUGmQoQn5t+?fkwnDrj4m^CGY~j*Ptp}D*NXYr zT~Rx$-7dF;ie#Xi`HCYEdgr);`66W){z2!}5`miHPFEq5zu+-O%QHBC1T*thj5mVp zel|GxhPv8)EbhAPaulN-AZ_k#{Tp?y8g(9SZK2%JeOOyvfblk=c;3+G0fc)?Swh@F zg91^WFA+?$rK@*1qCnBy3iD5l?DwIB&)`SCJddmYXuJJg8~!dMEc6_I)tSFOLo%}e z6OjCO8ToHeOauS2-Fhgu3VsOsTr@)MCpr7#hW&LQJ`QlA@OL*hES_N4{H1ZT6<~#Q zD(2)~x=m2R@_2DK+;8dshobq{wchMa>EF1^=Mi6QjoCWC`BcBOWJOBUPENj;jCsPj zKe-DT>aTCy!sgQTGQ6Jmu5YvwN-}+-sTrc`g{)qv!$X|WO@1K;rqU#a>=DLVlqqpV z)RzjCUQ~qkvri%xGBQySuIgn(A_~I4|Gt_X+vEQ~5KY|QnO*H;q4g&>dsAc-i}~z! zjiX4vRii(zyjaM*eXGyAUbCTH&H>{CM$uAX6&FVDtoVDaJ`Qd^b{<`yr>m;xsox;k zTeQ-4GObbL?PiIn)`!Wgx4G8cwO+)pA4+7#pR2W5s{Qfas!bOGf9;Ubir(^2Mxv@U zLDtFkh6+CbQ9!ONLqp2Q-AKvV zTD37If`sJK;r@uEu8_|_@^ThM)3STiMF1$B(-Jv_{=gTj@w34|3+`TuH7(_txbM7$ z-zDOA(?FyKp3~T?&MTK<4vS2Zvrlz$fq**$hO_>`P0rW@T{wF%6L-zCQx-%PCOLN= zB?yFkpQk`t{teaiKk83|?iQ-haq9`eOE0+Qp?2E@5^)KnW<<~E$0b?y*B_Wp1rN;9 zy=vsSH^^zntYv}Uvwn7GV}!zRg&|tx!G?5MHBhC}$xj0TPUeW~Ss9N|jBH6vcYg-sM;maPp&==@E#v9 zc(-<{4A!dlOe{(eH4|$^;2pl46MyA|J{{;Q3RM_p@yNNUFVUL(XUjlVaMvy0===bZ)F^E$d{vuJ+<3$&%~D($Z3c(N-J^S;A}X zB!Sdn4scyD)2xm_^3a&vCc}UppKu5?_h~VKA!HBTchm+z!XFW{ zzBq>;rn%2iYv-sOv{o)Ehx&h667lUF}5z^dPLYkB(P;-9yPN`G= z8(8}uogbuNiGF-hh3~MBo3I&+->f5+1RHF%*i3P`0Am!Rxng8onOHVAVhRU>LZzw3 zo=oZ*@;+>ug{<5WhYTzSr6n4<%H_$CDkUy8>N)Un3#5&YtiF6GO#3HQ?av<4R-qh9 ziGbS2IU$<#JM;vP+z@nlu{z-B7**SR#*Y05OPfjsh$Tp3iiQPi5>6|_@>`>i`&(~%Jd%Hv8da^WE?2n7-oq*Ok(A! zI^^(vekV>sN`XJvj6 z8G>fcX=QU8U=SS9A+(v6kE@B*X4WYpWDai@V}8E>h4U8G*;&kHP0fZB8MC8m_)Tia)zQ7%buB#(R8{5 z6%Y(c&1%$HInv7ghuDkC#c|3fnqw?pG!EuP*BwlMaJ(sSxtrf;!gs+Ljg7PBlr<0q z=zCL{6b-af?J@h*-;qM`+^yZFS)AQ?gYfc)Q@wgpQd`~49?MS2^-W*nD-Y0!@zO5|U#jF5 zTiyC7-o9UaIT;qs8}3SUc`36q#TC(TB+8&p5r+=ix_`1DYVgHxHZ$;I^K=IzYviD~ zJ+V{quQ$+8P$A)bZmBh6aa({#*DY>YER{Ma1R15E5Nif2^u}%MK9!}RhQLdc9bQ?`( zh6a30xV__$hYWs`_=9+FM9&V6wMAej^4>CgNzJJ zEdTRx;rI`nHIDy=v(~9TGWi!na!T=UhGaPmG_+yUH$(E{Uk{gRozQuKl{k|)QnTq) z9o*1@;plWjhTiL|oos$+ePnw~>K=A3^mVDN>`(UhTl43)@AT2@SJ1;#F(2IImlf#u z_J$WXx`9aQ5MB`TqI-iLc5!u(-Q!MmU;D4nJY+q+T(LcY@AQ!Yu}U9%x+1embPxHU zU6E-%cc0VqE+fms^*A$oGUo*YL zlX_|M;e{r>+r*vw%FjoYWIm#inTPU7F6cewFfWo|CUy@N183I^V_b}N;Xv-dXm%_4 zr(e}B#MR+k5X${7zJwp*dD=7>p)%mMCcLacgtY+rPPa%&h!x*)0WJscsjw!?2e$uR?LZTt7(e89X z!`mk@Dk2`9Y>oE9z-9OyW14xF{s+EFMtemoB9Ojag}ENBca3sbeI{n-Kf-Y zv$}yEgvmv%IDv@B3D_v&1@S`HoTf6gW_u=aFtj-ap0(n-j&4`y9zCXZ!^C!dq37~5 z-XRs|luQD-{L2;-SKjWr$4Nr^fACvvx&{SyI(jyL`HxsmH}|>n9)KZEh|dkzY0(mp z`^l1U%!{CsE~n(R$sQxy0p(V0@(?g-pw{Q-&s%@ zmTgklAl;<>5py$X5H_YpxV@B>B}L8UMo|o*d#TCJn~q5FTRD!^h%m^_Eu%tp5uwtJ zp8r=U@DDuI#bKgh0(UM+lOwHg8ZS#H0&`=|%9;%n(rrVcP4Nd;Avw!}+fteUQQXpr zGH6|K_1Qx_4Zf;wU07NWu}Q#zlnrn+?kzBm=0{IxzWo72c>MiC);8AL*b%O$5{p{- z!Kd;ybFW9j5EgAA(h}oVR{B$OxQ@c&LsY!fLEeUl`@nj0F_iw3oGH=Xrru7tO{h(3 zGnFLQn;i7mF09%MD@0hJ6!`-lKp9Y3bJLcnmd*ooBbVpuUTU}y4%b$ZbM*n5W>^i; zm`-*pLP|;S$l)_UlsN%Q02QMPo&}k5RQx%$<{z^{Vpux#QW`QJ3f&7f=dRTmtS=XO z7Jy00soHqLnRO+_I45!ta5!9MOmuK?m(lfA0tFL^;+Qp+ zFujcDgAWGr4T#{Bz%BDxTXp)3Mjo?8aTLnNh3R}~`Rf+ou5QuJNZtp5ff{IUE1X9u ziR=}Mdz}|W$$>+xUitQ6@)#bKg|4~(CyB?cT+ZqPVAj%)!~b4l<|(=bfBhZ}5a z@5<6XA$gT|o}FYU(-scmap?iBLSyZ4;;X30u6(W(P7`{)z?|YGweacSEVXjw>5oC0 zgYeb1wF9UD61j+uA}%)iixoTePfQ}&R9J=9X8NJAY}MvOE8=qOmlb8>gh{ej%HHEB+4{8jc#^1h%ae+7l595zy%bFmJb5}npbyKjD z!(Qpnrdknq?B^V+9l6E`PP?oa9B78*VQTHf^Ai}?S>ef()X@zqq%%({O-t>`rkUoW z{({fm{pGkv{rWYt3JV;8WkiG_A&*C%;MvVVriF%jqQqE=Yw?|T%#jYTNEpjbURp=u zZCj)E{xbt{hD|thsu={@f+eCA8}viH$!)imxDC~ncJk(9OmhzvY^rpj3%idY0gnjv@UdfNsw(IXxHzms!`L}6E28PR{ zwe&Y7^L&c>{52;m7ls3KXGo%H9*qPLMQfwKJ&$w$L_C)AHe_DT<;ri4xl=iJB8@^< zwZ;<#>5b+0*4Iie+BD5J2J2kou&r(hmS>j$(gZNgxhYvUQsiF2_C-k%tN zXQdIaYPIx&zaPRZ%z&rR=3D12?^>BGTKmZT#d z>lSlljph4~dh`@&X|{%*;Z~kvT=lYU{MfjXbYBz7FTE*>vu?TJ6l6fB%!Gn@m)_h{ zb|n`>UQJ&##eBMyCc$-o>ffoxk_)*#ovhVFt7fAH;q{Csx%`R3m-tYshvKDR7vu8t z_UqnYS;94Q6mAomz60(GeB#+WUa}gzl=+?hUCN^x_1dL)Ib8Nct8_80he-A%B}go% z`^OO$DKgAcASCtkn(B^Rez(9(1hFFKg*BkK_r6Bh-4^T@z|xaE%71!t{QZvj%O7E+ zXZ`n+1i8DfcmRxpjzM$COLWCFiQA6l*lAV5|ZW(e(ERSvjvr_E7ErLhG zIb1l)hORL=GqB)%&)a>XP&2gx6T_VMD<+t7e^`gyDBvI$B3$9?A307pER&{kkQE^y zuwPN5lrcY%6)7AA`UjvOP6u&-Uns!q#sURGGLh{XQHoSjJE zgihnBA}W$Km(x`J%>}yw8>4Ks#YPT%t@(IaWPg%H-Uc95nhHSYn9nJLmu6rZ6S*~` zU?QcF3V1uxfQxgszNVZ-CHzqxRXy^HY*n%V87hP@3^Hr@G5*m8ro>T>TeJ9w5TtZ# z-;QRVLj3E;8oP)8_6ENOxLhn&1HwKApGZCqG${&W3HV5nkAZC4(iA^gmPQ9dEM+(A zti;54;@M}~UN3B8dj$SP z)I;r}c;+?blmp@-p&B&Lhu(GceF2)CFXllS{)3TmTA)UBz^X9>iKxoG5Ge`MBg1HGPFCTc476lz|&}TW53TuiC~CUIe=O=`5rfse)F-$R27!a z=xLUb%)2UE#DmoQ<|Ow@2v6Fu3gZ!Y^x_LhVXQ@nLT${ZnsBat6US6=^NP)J5IZ!z zxA`i|+()n534@kY7SjDTVfG!m%9GgrA89`Y(zKd|NjbnIQ@_IEvRAdzZS*2SmRD;9 zV^ZU2OL;QxS`}hNXnt)*NVkEQl*;!1w&EPnUB#cY@ky5_4f-1EIQ={j0DuvNAEG4K zeVq-4F+4`M2=iPXDobas83HXo*i`Bq9V9c@57>tYZWJRw)Lh>nRAWGMg#@au`59h* zVce^nsAh`Y>QdaFlJlsp{ZP}-#xB2>;CJUY*bB75+x-hkav%{suZ`Nlqw;b)T&|%* zhMH~ip;Cdhe>b1`v-RG#f1|v!*DcWIMR7PUbn7ZEg*BQqj82Yg+aIdZT04^+{+(%o zBSA!A!Y<>nHgMK!6+mTJR@6cl!S!w1k6>7$^@D2)^LQ`<$Kx{@Rocdrmxm?upIw(|*qZDylp&u^z#Ks4;QZE}hmHk-S` zbpCtyN2HtS=^ZzK#GGQpbMU4ut#9!CnrAgocBRIZ?|28PYf9$60(uBT!}!Zmk9ejyQU+5SxKc`CT958iNfZW z-ZR*`I?d;QtRVkPXBk-N{{>^>_$T}N?+WtYz?i-(Ncf(}-(i^!-NN!$5?_P}9%o&f zbaZ=Fdr4Nk6$nGRm$%YyJh*C-A*o?-W3k8SgV)1x()f=LzKyNUlL=khbD$o2;p08x zt*zfz-Y?T%3#oe0_tiSyzrXUs@7u2ge|);1bvywjJv8%HXJP?XD|^-|om@^`js;sH zz)-1#*HxiTu=fx4>zB?}3ghu`(V#kMQNM13mXIcWpCJwpWqc(7lxdy});lM9)jPH6 ze&Exzf-CCwdhu-7^Q;l&n&{r-bxziJGRr*{DS)mp-}USvYQZ>1&|ZPmoI48Tn{X=P z14W+*9hjcre~ge7u%=Z%SsGLMk+4TE&1^+Yd~ zQVRn{RLx?!lDB05I^+id*6S%J1|R>_;K8~kMs0__&ipJ49w3D7|1<~0Te0d0?XS;4 z%(Vkf`qH8VAD3K?&mMjsgtULF;bhQ>%5OZ7u#Z(f`Eu7`wCXO}s%3P*QftoftlIH| z*dxd#uq-EM+!#WGwd+v8o({DST0~mGoJqOTgI~cxI*eZ)GF6{8d;mwF5SbcQh0vaZ z&{glycCtqn5i8@5nN1+}HA}1K3QYtH+<+nAx%n6=w>~P{$h?9ogH(mx9=G_t`u8c) z3xM|0DsfGDw%Fc52MJBx#eDTqtduxP{WzUwHUgg@GYr<#UWX#1su_U(g_}5Nt2)`B zcjUCv!i%`mq#z|iH^%%)kpzBHCoy1xv}E7Nt+_5&1#m~(@S1Z;AinMoY0pBOH|If9y; z7^h0VD=*p^cP`#QxeEz_&7*}W6%NFm5thpfR)M8Cz<*))3NaZDwFQelw;!QVAM$|U zMNLvMOpGgrB#%bO4FDCNcZC;}F~%u03G8u->mtzZwNJ`hv$ag?TY!T|@~qa>rdZ3C z!4dtM!Awnwst?!#*^$p1^Nb3u?JxTYKQG|UQ;mgtfbJj4XT{Q8(y!mn;T zu>K;ARqW0aV`Y9g+$oF|3JHz*<_9XR_K@0&2tAFwWX#*zkU26}XPBR>Ac-=1k`s%|&1j>tgABR^br>$@aF`=Soqcol zQ1|v9G1mQ__k0OH>jQFG&{~9y8>NN`99@~Cec3XQUERZ`lE3@PwKrPhEHSC`zHbaW z^$Ci)v`^Ts4iRBUGH;K4aPdHeX^ySW70U?gQfZZ!&K3aEr2GBc{W=j1>ZPMJy{QfU zq~e>BJt^cLkG^B2`~J&9J#qy;Rtnuo5OfEsD(c}0@6*u5`&tDOU!~_5w&EeTn{GJ> zDXcHn5XKsemTSR}>}x=YAMibV0jisYcLTipeZX&1C44@PR0bcHJ3mgl^T9*% z`-H*UHx=B3a}JBk5g`W;$3aqlFqIpQa6ENJ5HP(~ z_c?pe_~cd47)O^R;r0A+eWG<}3S(7)ZKTDKmMaSrKA=#l5k&xksLp=cW(z&@B&SB5 zEWxvPtXq^{MJ0-^QJ5rIXwC6TfGECGa@IRjjE|V`t*Pca!+HaF(BBhCczr&{ks$AL z+-}FM4K1)D56@RuduPs7r00>$ZBCq}$nX*5JFY7N9FTN{mR&&IgkIC?W)thnxTSPuk_4@+m0ek*@*}b2?uEO~g2mp1 zK%kKPi8M+*5i!W4jpue?^Kn0xg9GQF@^XCV`Gk-IT1MxJ%dpkHZ!TA;&~K%KTSL|+ zxRmQ_l4lu=9g}{X{CT7t-J!6D5odu(K#OwWaJb*hZQ#k(Y`f{Mg3pJ{*k{A$19| zUJ(Z1O|-N+44&3?7Sxs&Uo#_hMmrbQz!I{NF|I718`O&U**HVwK&{Lr(e(07OAmY* zq<7naYvp?<6w%-i+FTC%m&oFo2&UC9{PwE;kxr@TsdDr>1haG;mZK{cs7CMp&WLz( zXe+NZ2+0WWjn-^z1HpA0U-#gCK&{`48MdcV=nUO1Enu#UM|>`dWrUmo%pa!tnTwCg zA}AUyWlNWF`TP4pH2X5?_7)ZrG-x7)STPOaZWRi)e2Zo zK3vlm49bVxH36O!OVd+oh~!4n8S(8y&iaubI@cp?EHvn7J1_3sVX;$cr+ca)%3{#4 z%S8LqO1%fEWj+B;q-pD#oa%dX^$47Lk1euhSYPyHhg?1o(KJq7W;OyZE~N?L&M>#fib%TWtt^wpwgWs6y|FuFSJEz15U@sn=N@! zNb%*at_}cKJ2{uaI~uBjye^HGt$=%R`reDGB?;B!qlV}b-zVB^+0884OymVJsO~k| z^7(Z-r?FsCb<7>edgO3y@Gzhl9X6lmOh%HfKc+X6`(Amcv5E$L6tAPlLifL?ZX-s)ptyl#16y)_EL~h|Ca8*<0Z@t|C3VuPAuZntl@zmU|2hHukE+nVL{d&rXQk2zm5&J0{R#BoY6dH?aS)F*2b z#0P7h0r<|=u%+{xOXztGj^OzI;b6NHPg?Ca?(J$TLjjA8O;X3(_1n%~y3|aGV~s+A zQ(;LF10>=^oQq@_?`wa9+`d!pu|Jj*$qcPqbHQ;2rU`%SQeYm_-7#gT^GJIrAt%76 zulSTK7~Y^+$YAu{_5IlYwoGL4_%hBLurI_rwYHrc>7410<<;*B}d;+?~r z$h@SL?s530#BREJ`f|veWY!`y06&Vjt?eZ_0)KBd0soi}fVd~Vbf4B0-j^jdfyapo z?kA3oBGUyw2coYhL)u{&Etnde-MZIJ#(VExR8H+b3o0Nin{fAq-0A-vBwSuGM`HH7 z^mMkGUxPJRZC8Ac$mj)O7G#GxWBvgGDf*-*)eI!bFDtfG4Igp#g%}D7I|LzaJ3Aq# zA|5nVdEca$kCb-Y-x)*s>9j66gkxQg#*!7d;*3zq^t!i9))XdboMxz}ALv_gD5eF% zH_JXt+*lWr1ZjSt-E|Gm(!5QVM(}YkSkz^1r|vcMOqg3 z(I}$z=%P9R8auYO8^sR+xfqc|Y_CT6!KyY%t#-o%HYv;{V@3ewDVmi2g6KQ5CnuKI zn|eMI$1AjGi5Z_eO#rPTIr9~f?}1o4U<;ihol%3tHKYt&Tk4+jLxoJ@7EHp%49j5! znejjqhNWWP)p&=awaBvy0Vn0pMA3t9OtwEcDmHD%nws7KV}06eb0$BvAPR8^q&}47 zcpUNW zFVsNju0T3vAxjTuvHdhge6X}xI<5{Ii8#+M(PYOex=;pyN8VA`tVNO@L&WfnHuzS{ zL`uiX)*MAuhD~jG+8#cFpEWF>{Mbl<5i*u57ruJF*9A$YpiGx?Pp|S{U!C14G0$2` zN(e@Ew#x zmkx6gc&cCdrL1G~z&C~5udRXVuC)Ryrk7+J*{HMH;}+i9 zo#GaFK~C~pNwak~(meZ|-TZPSg`l~UI@ILt*fK|X&W)C^gEZ-9I1Us>CX~v>r=~KC z+?ObEu}IPS7}WKSuS&*r_<6$$T5|aC<%7r;FIK-YWmZU>sfp2L;|5bLW1(sf+|)&s z77W9@zL7b{lvoc^4IrML%$h?C%_B|aX}_BF!ZzNKwHim*d@&S9(7GD?ojOmf;0LXM zR(0Az=tT%6>iU%rbQ|GX5Wz0xH>@Lk)(oq4w94Z`Cmg(s!8UXy#3_PDnJdqxlyZX} zh%RQvVgn)47NwkmMH*Pccb6qCE$ZhHf%tQbeOU@;-30ilhaP9;cd&R2<=msVoOwxK zdwd9IKTcA0)PS5_2kh9|+P*%B^hU2Ld@2yi?Waf~714^IxO%jOXcjD&FyrE*0;BQL z+oI3`EPuGYa$0v&!woTXe!BS;#yKT>doy%vP&Fo=TmFJ{<$*%EN{Oa%)FTJ^`>&TS z!@&+OEyu+b#wx!=p%$x_@b`vO&PRo$bS3L7sz+MsO%k)k#CGD>Qq#>Fw&epAJ?CUl zxHD995Fm{52tA_nz`LEXs*Y8}2kPTRmh0>Xm!Gz5m;OPq=PY*Jkk>M{!I*1>8J7c1 z!vOa7HCB(PDu(N+l3;i{2)KmhP?B@LT*;MwW_HT2)9dp)g_-r*m?_oNL4|}i8;$5d zY8ubiJN7@vGwnBto2@5hCq+YsMJ)>wX7J{<^8iuDYN4k}#=Rpx8Kv;p*v1QL2)JP`dS#Q)BN<6KTG1|4wN~{WDe(se5i#>^{*2T<;Q&A7G)^|PEB=h5YOECBns9A>pjSYvA8 zw;U$=^h;i#)mm4NowADa;{@_FzVs~5v<{;Q6EMN9WCKF9p=;`owSh$r^e=^g5as_x zh3$X1@}yhgTj}*uW@Dya)#FNm8S~EPnXM#FXP|duJ>6G)A7nR(me0_w+u-)%_8jY| zgA-$;Jzz2SUexG9ybC3^c}qeU+w%ypeibO!u#N_Kg*(u`4i45VtGXI%^xayK#O$M$ zB3^x8M~6A6$ld>sMfab91Oqz*!~boqnCSn1Gz$~`e}iUe{C1hvzg?!O@7AhD;#W6_ zzb-Bpz*YwIzOKDwhHl5-s{!tg&F1&3T4Eil`Eg}k?#{~1Qg9o5!QEVQshi8|!am+& z(}n!r-Cy3%2ZB#af9^THTdU8vk7&W(x9I`!`#XDZg8QbKtu_gdEzvxvw+QO>U_Lk< zUL_$5Fhth_0C!SRt^nve{Y_depxt6=!IbrP)C-1e`<4_gPEl*`Y9yP1`n5!^q~m*7h` z5Y^2LxI0qKhpfBh;42xSBd?Fsz{U?m%nTx~xW7Apb8~OOWgosW99VDoNbS0A#PoAU zxE*(f@Pnm*BLFjwYKqfEoS5!`f0|O`=ZOA9nqY$VsCoX45aGx?buO##=$xU|gijDA zYQYXWP7004gaX!O1YsDCa_**2P9WSD8oMy+Z^0kv2y9V3F~Fv-Z)M;=Hq6-!xJ{2T z1Lu_jl3R$Ol(m&&3~q-qS6urd8|2TJK@k4X+^lMC#!yjamy1#_G%AI17G~e3-ISws zt!h>-AFI@oBpnKT1lRee7_m$>gHeOBgXo$Cg*2*>@Q1|;^02zdeyGB4Wo37yKdK$n zjlH&sG@a^@le>^c;hv4)GRPcUDnnEHSeiZ-z$dCOUA3cg)_N6YrZMNXfnN5z(LJjZ zx=9ME08K{>{pxx*iJsLM#v+%lZ)%zd%%P}7hO`RHNLw;+`zp)JI_+z3KRi6nyo7~w zlqACkQ>72=^m8VziR94p%=19R+JyfM3$dFQ9;!3;kZLHR6SPwUqW|*bYtaf^Su);2 zR{v?FBmr{mCpSw4CSOgxT1IR#4F{sV2nVwN>7>=G7fTMo_ux?@Ooh2OO_tn5tbn+=rZs|KmAA6R#j%>$N$>tEQAw6Z zWk#h*^1OnpoJQ;rv`j=XRrFwndD!LfhcPCWewxv$UHL975bChH8C#39Y^7`h2v5p{ zw&d|9b?;%u{C1ya;t%`z^FkrIZlmhP5O#bVeBtWbbVkc$NO0-phk6zPx`#Unawy zR?9pI2K+X6`}{1FyyhxFhsn}zhZnF3f0s5|dE?EaK82ERXs_Nlg2R|G*HlGNs|s;H zRs^br7j74Z7EB`u(}WjCFgTIjpM@KqS?in(d6(7hq z*K2nMF29|#QOiGcb6=X0xVSRUSDr^&>RSmC+@@~?YN8>mMVOAE%GB!omK^a(_!5=x z@4AkDG`L_7Zq_^HM}Ykv?&8<=>RSNKs6DKx3{1(>#QuZFooE4uy8T7j=D6r$PcNT? z2q8u>B-XrR-z%2ha*fZ1(?9VeE`-WN1nS2+i=V(ZRZ?XsPCuPOYoRiCJ3MW3D$oB_ znD0>!febmQ-00K8Oe!Qjg;y{0YS(p7GYI(#FC&b~;tIWX`77O6GX^xly1tDWx1h@S zq7Cd~d*pFVtyO-&{DvJ#i6R8F%DyZQxX=X;FL+yn)UkgVgF!|Fia616feR7hX~rK- zBs4C5#8!=_a|LqpF^cDQh3L*NwO$eSy|*j1{N`5k$anw@r$HMQ%V12vx4?(#oPv$v z&+3Mu1eN6v!NuzxxBO`h+>_AZlNL`bC?~++i$n=jhAoKSZMm8?N-`>YqnGOZfQ&tR zfxG=eJ(x^$JyFqKHv&J~-N16_2ZN|UhV6st2YmozOavtM=eY{Fkc4NV?DG-Hb!_QM z+&Jp8W+|aXDe$KvS;UgCgQ7f*t6iBeawFlU^EKjq3?9j4B@XBbe80eK47B>>&*{S= z!^Z_gS2WkT+Aj-A)Fp~S)tRlv(^{5sFzno=4{L8J7+4DbG;-|s6Y(UJ7mr(^J`?ZM z(*N35JUmn!eFgFIz}wXrZw3+piB_YKy~&Nhb-V8I%CH!B3Uxr`X_d$?z3|C*UX6Au z&t#OhX;uU^T{COvTfUZa4)Ei$VPU#ramhTI3>pkyQ!;mm8LTi6Xmm>vQRB=UyiM4U z06O^ioPTzkjx*+PscPbt0lD(~Y4MZQ|GF}~K49}ZryN8s$1;FAl*|gYpjSIf?U4*d zAv)?7%kiR)=g)=3dJz-rR%GP>YWiC8xQulV*5{q^E#3GcdyKM*%p&ZT7E=%@!T#w# zDDe~%7td%y>{XwzEPQfz2{2v=9>+@GdlaMn!)wKYb9MuN&8}>jy%zsW<^&rwP?xp5 zl2JV2`duxaRgRtV*cW!O_pJ3m(P1leFa22BU9VrJEJtRhBJ?GokTr@hQ_XEIAKI5tEyA=H_T1rAU zVhgpmBA>%~J;()F*5RAfXF+`wQ z9z5{NY7p^j_I&qi3f{zjRL*~VeFjEm`u};8GW`FT049e21`|;EZ3O)t*ZtqPK#hOl z0)_tv7sz{`V>L3uYBs$RE1E}syCmZtb|ptSyRHXCU#;>%Ajywz23cYzjKOly^uZNJ5ao~ zwhV8CT}lMr(ayosPH-?z1E%)o*Q?=#J*(_0&7=5M5|bxy(scpdvoa6rGsSTUE&E8z zt(;rhDXLadY{1*?+SuCM$HBdIdpC#!D~cSGxKj<4=LI#`aR7UC)Y2)x|AlMgV!eA% z<%H#)J?I2cS+MLq%FwAZG18}w#U3E;3qM&KEoPU+>!gWN!KqQ|GNcGvImYLSHtDtI zGlEjuaDVeXmUp&oP!(Lpz}4bz6zS|;*CwhZ`a1V(KK#IhRRtZn;aC|Y3l+BQMQGC|0B4#?Yp!XG0yclr^hoY?f;7r( zu96LuiM*=?lyHt-sNM`^D6uQC*fI?4GZ&UL(Y+N2Q25wf5s*J4as>vB#b1mc3>uRp z&ugf&qUtnyz`Yn0@9Cte;2zTpIiXqK`sMnAyBgIw7GpmFL3-5*U1U72w!&ETko>5P zCDjsAxn<1}BY+DYdHTWIo)|7SOpm5^sJJjtR$8INrt4z^Qsv>$kZ=>k`9?1ATL<`v zWWYdpE-HO1rgE`O14M2URN}V@Gbk@*V3PJN^LvRY0xNVLxw2?lB*z6D|J68Y=sJLu zf?yP@pLzsD!r)o&2ZA0Ty+12#S?Ks#YZBez4INFV3xX+-evW&4j3a_v#VIP-G9+dS z5?V*iN=?p%wfN@l_`jRt>>>+D87V{;>N4&jdrWBrOW9bQqK)g^0=sjKg!wVD zmvoB}a~`|f7IlJF8|#n0-H(s`02p1-pEd1awizSqEbB=j@{u`V0O$_JuGlKLrXw1X z4ry!?zz3_TPIcx0gg%`%VK2!l8vHXobWxaJoiN|k?$j*%QjZo0iLw+BzW;vpO#(9&@T43=k11gN2qUs5|1pR0F zsYWL70B)ZJU#(oqy0;*b`RggvJwKj3I?ElhD0@1?*mC0_7fsI+0{Qt#3&n-@z3j%Z z*ZtX?%RXXS$`{GJ%nZDUvI%G798r=&nus_^=R0&u<+tm0A#8CmI7^C2#TZR_;cRGm zEOaYHD2ks7=s7`n3gA%iqQ#>$Bcq3(HQt;kL;U!MqMsAHxJRdtTe1d?Y32{U8m1nAra^-Jwb{z zjVgS*7{hVkOSG1u=xM)3jEx|f$ysTu7}-g<{UgzCb#HZ127lhqUyks~MI}M;>Oxz# z9_cL*rcZ=89U^%n45&akf})m;f!3z`IH*=d=1_etdB5TL3(!pCOAe@?pkR%`QM)fE z&X|&^pTimA7^Q|=Dw4Ke(|=5(yp$29F}j!6f-Ydyc>aV-@m$&3xO1(}n1Q$HuF(-` z!LFIX%=lu12W{nray{jyy==oK5ZGm{vP8g?w(M5pp_N-%LB&RCzif6ou>lohezd1t z__peu8bD_$X|QuIIqg#X0_XC1pAp+xYYc71b(q!LugxwV$c6Y zR-+Q4z8b&cburi-4@Ij03d%N*MF+c zf0x|9$29CL|LSWP{)sF7tFK}BZ(tGws*>evBFLL>zf5szI8C%MeGxR@Rs+vxG28wZ zWA7AQ>9$5|r(#!ZvtrHIwr$(CZQH2Wso1t{n-#NiverK9-}|(GU+l}-+Ba{=9)^nO-(KzgY%mV* z#_>aSx14wr%rThne{koptl^u z$%%Uj^$vOkIt>cO+LeR($g&%Yn7}^IGOlov1JyAqdx+xOX+z;xhCItbH%H=5qr+Q;u0#yBb{~(Yf#?nyLPnjg^w8G#FH8Lnktv*Ah_9h@#6_NRBX`R*xm- zP~|{0822SvUq%q{=vT=KaXTYr<>rFcm)A5ZC$G(owAKC zVIQlzP02=YGz@9gwnX@c8qVu#LhI9t?~^Xqj*90FqpGTr3X$oyZ%F+A+(hXlCQ^ zyJm+GVc17vvc{CRk_TkN_U+{^U5ERC&Umysi+iCL~XEw_%Cu4gc(X`Ddka{?ILwV9I$AWL$E`@V5gXhe*o8JpXPO%{Md1@R1reXTdDb}2Hd z{x`0}ghQ3^?p}g?Y7iB?8tUDkHH`w6RLxVNAyhAJ4qQ>~(Bj?_i{LX1N#g2Fo~4yI zw+xImgmzmNd8!g-3F>b&eFfj|DmmDCok=+}1|G=fEur#EDkiGvGeM9dx(-7uut6Hz z)blI0+7=NUZw3A=wQT7yIzSQXtm>gCZ`R3^Fp4es$9zbkN*ZR*DH;J$;O?LmJv}k* z_;-;6Of%PEg-SZ~a)8h(>%d$Da!pZAG5rXXmn2#S`<+67a_)d2g*-kaoZNMZ77P$K zm={b={Z@kMb?!LTX8O~KeulHa&c-fQh%zKFJ2ogw!yPH6!hDd_J^Sznx|2Cy4$SqN zhpgfsdzCrH(_its2~sd~I_C-U$HUO(lSo#D`d;3pu@dqgZ$$Csu|OWW!@t$Ay`^6? zCV)NCwHEc1{n_n`KtKKib({KibG zL^tma9_QD{@94e7z6efZ%*jwep@;~l`#z53P8ZkX`fs{UE?#Nac7Hr?GPxuqnK`Dv zFJQ*9t;+;&kn|P#bM@caJ{HSnYk4;A7;T#%bUutgW}f|$eH17c`}~RZ@-yNBMw->< zK|4}o$HHUHWyHCm5>djeMD`z+Luh0(u2b%b^3sUyPRKji_~GI4m1&)~OP=@Oa!2lX z&HYkLTvYubDIKQX8_@OlXodO>)d-J1pVCf#HC%j*L1oq=A!7|8{RzW12LnsLm=s=ph5uSPfxtA-JRH7 zmlJHl@2p&3_EO8#8&?bi&{vPmU<47(Vck&1N1rIb)I5HO`{UK!)qHz^861sO7^6*? z307i&8^+Np7DExA2$cbz>HxwAB;1~Tn&~znN6Q^UEH=@^TG_CE4o#RA=zD(>o^3nA zu(=pZ)Sca%;q&PkIDP-+{BU5y_!eFd-4)QWacu4~Dc+9Qm$$T66OqiZNPKBIlI%vQ zn@@WPGWGCj{cZEG>FvgBTc4vHJ}q6ITf^Djnq7fh=I+Fp2G*}EX>kkK?_nr_7@|^= zjMj62QB&>ta|?!3eqlKa=#@)84d*;~I4LM8Fxe}QP-+ab25Vf^p9i;OO0(lwJ16R# zOpInWp))L10dvN=A*1Vn-gb7{(Cxl`0aQtTOAQ&aF7i|{@>R;5!D@f*9fdp}im~5*;u~V;A zh*7${(IOZWRL;Hv!x;J7G8UrDg{RUvI=IFpCvY%3rSdp-ASMU4iV0_Cc*SwB0Bls3 z{b~4Wy)w1(2r0vr8+of~yCFUOu$4D-X}zvB~;^+*8yNVZte;?^_zGb`V&` zz^820x4>9L)-{muv{5<%cmmEo5#&QnNJ^B9NtJ!LZ#hU0M=lic@hIm0193GENagh7 zyl(}BQaZJx24UY=<8FU<=hZPYQHs&soP9cusu2s%8P6f}zmD>;Dv*Vlt_4MX6PHkx zH8{i}Q#Ne1Po^bxr=A?5pgn6OQfL)&-HP};)|i-Eb|!_!a%Ehc%KK$g3nuWy64GvT zd}^2Pn8$VKLdk3I3;OOYfV{;T=NP%_oR%+kE1#DyO@vYx#@}8TRJ7S}7MF;u zN}OUrJqjq6cam2tn0Po{lNOxhL#%QTw2rXkM%i4<5)5|Xhjg&1q$5$D`3;ZU?%|QL z)67t+Onp|UaRg3g7HEK`G6l33>?Nb@t{&vrp3^KGJtOVGfq^0{DLqqK(NV?#;>-zl zCSmDwmhf~74VAm@F~w%U_ehNI@xxawp;5GFq^j%S;svp|6xk>sSwk|da%*x68(;Lv zQC@vmQ`#j|c`u1odVVh26w?b{?3_@IN19_gL_$6+Tt!0hDPx}_#A90L4g}_s-&riq zUE*jUUDt=K`$QTBe(O8ESN<{tQ}=_|;iW%Se@%Z4(#R(8hlX$`GDVHNhvbMz_N_(; zY;Bj{F~ngKY;!gd@~g0PU+_6q*2E8<P~)|JwWi z$HB_@{|}opG5#-M^Tx03)jx3Re^GLJ*6RO7$qD#3B_|7$CnTYC5?nlBliApTE!MUR zQ^6pq-?zjUf+0-4l%9=Zcyzp1_Wo%+w`6+@_A_e$L+hQj^3&(#{9xadlZ||L`Z%%C zMalTxe8kXD1Y#fH%`DX*>zm8dF^ZJz7pzPaT_J=hGA&dYV$PCk))_1vIRKzVs$wdv zBwFeRWRet&?|q*5o!^bNF~I7q+GFK>V)%HR@JH;v^uI->9W``8GPOrO-d#`I%03;> zw=Y^CE5Y_}IaD1rw23iEddI_rC47JP7OsnB_c=8}P)#e=L-!)1mSJ>M55~Xd1~bUh zP7@JqALke87yrmq)B73IeUi9<^oW$`7NEZ{tzE>1gyX9sVlMYP#v@og;(fKSYBY`Q zc2(+~gXa;Qv_=1F1e;L|<`01?sCz7L3rM(PeMLizzMToyrNs4#?wUx~R{va^cKVR2 zZXSPuMih~v8NShGw23Q=Jkb88^)G2Q2^%6_Bo(JM9G`8Ef<|UUymlS+nKG=TCu4L9 z`5eEJ1IpB>GlM}hgs$dbJ3UTuCm;+YOhL7t-X>kjv=MV8y*%WQ9g2wY`FDRoC}@r7 z3;?4#@e62b-|17v8_FSr9QCJTt=aSLi@_H4`$53#e!fze5MY z33v2B6pkZKS9WlpXz(JO;8D*u9?zK^-Va!E>B12g*KY#x@i8!pKWXR}!@&)pK(x5> z^QyNC2{_qB+$rP{>Js_3loKH_xTQFyWCLas_7JK{tsrBQP}C+D@9wYQ9 z+Oq&JC(2ELpWtcl@Al{_0>3gB>48%voqUR@T>X5?9#OkawyGss*<34*VX|`BWTr4T z(m}r)9BU0cQMy3p;XwXCM?u|Ha6&*=k}nYhhM24J$_5)&jx2BC zmdL6>y}Gzn*-`mf-cXiMq?2!j6s24MZ+$4GFesj?2DfM#5jHMN%1LC4jep-VBn^~$ zc3}%tmLo+)Tq0tW;QiGn(KtmtC|P7XCggzLhBFC=Q&om=Sf9>?b$UUK3dY##2S$t1 z%fqSKP_UF#c}wcwr`R%;W357@NNEi>;`5%9^zKdLIW-)4biVSV%w zUn$MENQtQ$j5bh-r$zCOs-EF0+UBMCuDhTw%!V0^cp`ChDJNanA$!iFp>O9YOg~w7 zv5y;9VnnM0=Kdxpfv2T_orgVdWo@1|m)~bb9Bq2IW(NWR0ZqyLwYjlRO|LVI7&#Yl z4|R76l(9&_;D!{lFl1L!R9VDJ7F@B`!WVRxtscEQAhVa4_N2QXXm^%3CexV);%5k^ z^Tdt4HAJ4Z&8rb>+2^55sBf*WnPAO+qdu*kl?OM2nLU4cc2`B={2 z8Yg4Sr9t`$pf;4~&LNrLDpbrylLB`5_fWIF>v1ZqXp^qEBKj37ZVnL>z^O3 zm|aas~BO+uAkOova?-o!1K=}$pw+h}Y)CE$jo1P02GxSDb=mb4dl-&Ni4 z7~ess-iIF~g<`P9BJd=5kxpTSOo}~yEw<5S7;)-Ez!J70ts+JR%ZI%efZIx06lBE9 zs$2v`-|x5sP^A}q@lwjQLiKNq7VtKt0T~t>*Z=TnQ}Qa>Nv;S1G*RUgk?}PRzl$hp zGoT!cZ)%8dDiN}smg(w__Dm1e-@D*A)!c#04iK9fl~8Qo`^Nk+N}&KnhWT0e2FkJE zU~-99_sxzr%Ex;=-?CdloxO>(t%)8{U!if;neG^YOYCVX$Hpm;L9SM%oi>yHF(#1V z>Css4T#BTJc!I6L+`^MG>dGd~(`x^UxfaG(s~)sNCZk=i3ryn;OSJwjK6{^l;01rJL*|qifXu z4y5MrrX-(Mun^S8)o8{F_+DP0l@?9?@uM(553*dEqsCmc-}S>G&PT-G(%#5WH%rN$=}?|Bm_;}M&u z@${akhYh`00qWABJRs<+8O*t1h8)m)u4nNv?|R81?dH+>_D_CBH*58U@VT>-nduGmKb`%4Hz;mCexxFZEtXL4X5bRz-s$s}oCHF6I1ylX9 z{WV6O4SwB_#C;S?2Id1sA5l6VO*lGVX4iO6-!}Lfn4|O__LnaCG>- z+~!&_ZomyE$XY4HAHJF!P*c0|n`p0Ny+u>{$Qkbnt1XMvak0YC%ZJUWPod}IyZtHM zWR5Iga*jn7VHH<+a&!<+h83&IRB*T5+Y%!t zP@iEn-p+Cu0L>+J?T9MF0%-CAR{Q=OgC+7;cO*j265{IYGU1062Z;G?3np=08&(@Q z;ZNYk)=^)i-|Z#B?&27ve78a@Dj>eqZt{`rfLXV+KVE3eB;(~^ight;k3uZvyCo3m zX(N+HmbOEE(VpduN0HoIk(%yk?*|nmVO}-MBql`a+cU5q7p7h(tg0dmVySWnPg&%5 z)7_&H@cT6?<5-}CULyjrM}sy7wwYcK>Guo!Y3YJ4x!cx@-d|SkJjEh&o8gBb|9+`D zQ6fn|i5|OF!k%dgTn?c@&=M__S0r_=i~sCioVZ9Z@@k=pcN(=zG=-cQ0$If_{OjN> zP51)R-9gtI7DV!Q`F9-cqkv9tulpA;5!c(M(jSk3i3wP8!Xu*!YHFi8LLp}kJ%frQ zUm6r*eM3dPjr0kT%Mw3c5_2y}6+5y0PTu2$%5d7;6OL$wo=cx=ebVNokwTRpW&4h} zEFw))5?s?9saL2r?5v%5@YC$yy;Zim0{*Ailwi>w|lR`5Z@`z!Z$iW(qD6Avq zVOB`VP8Yrd&7#3*ABv_@wx>BdaG}jn*Ew#yfL_kBB4(u2rgbMeHzX^_q&>3svm_wN z{Vqj7bn%dZwF)lP6LP8`Bz5a6<#4W696NzYg4-8)yNXhwMDet2>EjRh%lBk>KG@T8 zyLY^wAX(Vjn$fmDaM_*O6BT0a9MiE^PJtonqV}8cBWoNvb<&EG7P0d1WYtp{&&!CW z))~}L4s!58B`&2-mZE)o17*32>rttywgKkF6spM-9Hc9_a)I3yxL(Ne(lOEgi#5l} zX9;gy6I?%wTW)&Hnwc46s7}TA7tA-!J7S7GrJC%PqazS3lB0}E?d;?oyNL8SHetWr zg-nsP5yb;Y@So`L4fIiAeXB+R`N)+kKC#8PC44rb=rU&%*0mOm?>v@-D+|n8c?3>l z+!8h0&iY4|t)fRjIZn9b&ry=Mnz1{uhS-VHo4``4%Ycs2BUrGDITatIC*G9IuN<*EeL#j``9H461jS{pZy1 zFn9B@{M9#{5Hx>14WUz?9N#B2|kSJ&yD#jNoW@!&JrF{b7G|V?};U z;^W1wW@)Otq+8sNY z^l+X|6j4_8^~c00t~1xi>+S9rgv?7Tn}y%sz;n2fgS)H{KwcJm84l`x(QZ0Qw5nSP!kl(`I^ zH~3EbUL{lzH=#*1PX3tYLx9?qC)%ro-jyuch2+RlH4ncA*Q4d*O_)#OW4tDCZCucG zK|Dd-44iSw&SW<2ROBduibWd!q##2-Ta?z39|7K-JnV`DEYRxLdOf?$Ta*L%UYI||s zVr4i{B1OXV4|eCVsN8TC_xO;&pmES`MeC}%$9Xp=1F1!fp|_7XDz`An3*zfYg%%fC2+JfS!ANwN!G}QLdIZdc z+Fay(f~_C~*xJZ$ntZA$4I&;WHN8@|97y*#VNf(@;^f_Pnw1Txj2uI_1ntr+X<1H2 z$ofDW9PDB}<%Ljw2|IzA6jBnzOmpz}n>|Ly{P`VTSGi%AK8nb>B&iBXdoxMQ?(=d~ z60PhmwSip5zk^uTr~`f{?#Idgp|XT;x!tb@DD!!`>DpV+h{DSEL5)&nx()Nk=pJ4W zJjgf^GWlUNFbD|iLklsmVR5^uJKj56!_)~4y@ten2gc0){UfMZ@7wY{Zc1F?EEJr4 zp(}7JewMuL0q$7)%q}+tQ&JKnq@tBuA?&Te;$jisBPDX3W zV8@O~hgcC{P+2n$G)tAK{?t42`{04;29q`BUzduqtw6FW9iEjkG>H6M7RI4;)`2%r zf;r0uhD_1}7^VC~aF$q10!bc_lZKLKlZm1LN&FDavxR7b?#!wy_E6lef&IuAB24Z( zQDW#4-3l&6c-49j6_QtCvWkjO&9%(sYh{d!Q=^Yjs%U{uAq4;?HKF7>eNKM^IagI> zmmZ|8xr4#$lvy@Jo@tc}*Q5#RB%~Wjo(*$1Q{PvxKSvQSR9TO|x*4__HqO~Pd<)yA z@#tOVlq>ZdW|M+#ov30{N|;c1Dokq!lCOC7d&nYSufS$b6+A~nyl4{@pZ{}Q?6h)@ zPM0ivRMS>|cNg%-)lQid1hgL4B%wVR3EP&rV(zI}t+^}fzCg=(Te1e*zEok+B5OBE zLSINTRWi7+GI{tsIAidBR)i)VB23BwEYk(*U|Zp zFvY;i{BH&T6XQQ#!T%VYO#d4L;QtA#@RDMHa@P3S%78o2x01@xZ+*#C+p?XngwaLW zS_XzS8tZ=nwaQbz7y!pNuKy1MAb0yKU~~J$2Kb8skZbdD_lEy}834oU|6%|v{fhx$ zqf71lv^(9O`dz(%*{N0{$vN39gol|3O>%Qn0+u3fj!1r4*dVMcl+vJeVUs9cFvOPu zsN{`sz~>|Z?qg-s_uQwY6<*5q^Y-QB;@%*3huk%2{664wyVxxVnLA@Ws5^o_4cWTB zs{`QQ{0cS3kYbnZ^OZ-@x(=0<{D9BaW$uZhUMy63YIDXx#tp4|azNwY8$NWRM^}Jd z!iI^#o6Q%~$(vDairQL}9v1`r(Zn#G#c@2`4+kk?=usY$CZggFxC}pLRi4^E-vF8kEQzS&`h1hA6BZXCat z{mhVzo-$9dz9Rost~?7yu!%;dfXY7#G^iIzd0_bTgXYU+0H8q;xiCvhxikZx%2{!p zJ>jfRn9mK{Jo%Z8tV7b*KWr_63(RPS;dNwaRvJqf;lUCU14X=nv&cyJbgipOXfmOt zE?rikBHCPrxavK)RJg8SWGv#ZkQD*s*iQ{q#xtS@V zYuCDDOjb@@Z;7d80BJAllQeehcuK2wBW2P@_!AnQR-<7Pr zFDUH|piS4IA@jUZ9KUKrTgis35!{tkWFSe(-_jQyvf`5fOgMqQTnDz{Zs|YuVvrU# z0r!qjsHq(efoHOkBaOn{@zmMC^}Dxb)9iQ6j6U?y1VXMI^>OWr4`YlN8TokYV?Tyq zItY~@_Pkuo9TV|lEK|~Y7cQu4-G~VqNYN&>R@aguaq-lY$)ZV8iT*-=|#CiVj=0IW+*K^P9SzB z@od9_jnHopOPO3>iZ9PcHHIWLMPMSI0iAScUVFlc7-%~7A)(^;gKU;8GOq9grZjEB zPsrPjRUE~bN}#K{6jgmdrAGH|52)xv)OTUtX!{gs2~fjR=ZZAoZ=8a?zZ36(kkv83 ztZ{Z`#uj0eRjpDEDsN+fB%@E<2gwsZ)H4_UvhTI>A%)}UX(LHd*x8tB49K`F>`ZEZ zP><{O(hJol^8Uk2dl$&$Mg^WosL0~63x6pqr-W<>ph}D%ca56$yiUC>P zU6^zCGhgqacBbspXxw(l8Cejg{()`XPp++1@%AZGZBa8Ve$`q*K(Pi)|B)|IboCOG(DZ+ zXUtmseiXq;NMW#Rl<i?MlqZfrMn*mx;34uIV z0Fx85Zxz&lSUC2fJ>m(suQs|wV1SMc&f82+@euY( zZ1%Q)XX1m|fTFU0DyJO*yn*4R$!^h%%F~*nWNBF7y~Ok_CzHPoDL*hz0Q}m&F7uo% z^%A;+ke32(&ny*30)G|CC#sB3rMCpOXy6;nNJPVk(4V7$Jv1&-l+|6loz{oXPuyw& zyd{W@xdPNZDABKKz3)Zg!TGjnG7>H0QpyKKxQOta_3L-!z?5qDb_Kt~sxP1;iv!eL zqHvCwAME391nvDXx{2p{xQfzZF`j=BtAvx507}4^BZQZr`eW3U;e|Ivxyu2nr#qvu z!xRt+L`)8T&Gj4=15z}NfsFV&J<1s#)g{@#?#YOC!Y3KuB;bVQkYkpkn_N^$-n#%a zOua4{39T1zRdc0ITws2C982Wx5(2Kl+_q{X(E~Id$zg5cxiqsi`w2!+M#~k@T0z%Z z)>X8~(=pB^i<~tQJ;5cDgG$ddr5krPc<#R>m3=B)BT7yJ63H-$K72j-kH`PvtSX~=91x~qSt zbT@zdVYo@Pg;=A)Wvh5PKn;t#Ubd_3@ zQ=EZgQ!JCL08%VpH?w@#M_LGL=H3~+>GP$s2@ei>z`|@QX2|@M3T*Kkv2OlRw+>Y} zSam>FmD?vkQs~>U!MF3z@o6(?9ns>!b@;YvH%r#p#hp01OD!FrQy=5?udbNQ!Zx-E z*Jw>mIT1qlNlAm5Exvnxioq|Ui(F9GZw{P`u|LxBH z_qqM|5fAu}!XPH5f2?Q!d1wD$!sS1|JZ2j#2%S%=U*HE+G*)>&!Jd1x9#(RY1HFS3 zHve5H1l`-Wvgj{xmkHVL9&SMv_4EA-BI$pJ%NM@FSxnfKygG`Jla9cQ=TXG7J7r5#?3P50RuHpje0Sa3SJW>gyMSU4%jmE)_ zT?TePg9+n1!0LzKk@FH`aNCp2?@uq=VbkA)v1!ehB zI-fC(OH2=^;sXXen>y_=7EXqFsJSSi0?7<*r7(h8DCfT?{aI(kX(m$eZijKBt@rr4 z)T`C}b*Wbfu%dj-qD(!o3j6Y!X{i)C94@qGAjbq5t;|#gQI;#3NCvx-cu5O`kcJ^+ zppJ^kJGFq39N0o(?YQp!?28&aH17Y;3w^=g7kaey9pETLoUaRgwldEp@IUu?QSv`w zYVDX`^sNZJC@ha|akz{V=1ACYqD0ra;(KE*OnIx1ee1-+-aE+YV?kjl#x-Vyecwn< z`*h2Rq`Wr7VN)aohLK^`qIjU84XwiDVqx}O024o40O5`pfY+-clu;DPILU%g_Jk~t zg=Gj3L!~MTg3XWvCU;ec6R&oD_IU-ZCOr_eDjTB{eZr^Q?&@m-ApoaWmAV>0%b2ha z+cPG`s&`xj<*pP@+Yk67Mdv;Xs=`=d2?Qp28=J$l+9gZs7^>cFEy^eKhLrdkPE}-= zx$IkWC5K7zzO|)r&!q5Jy7dTm%B^6eK?CGj0cPe9J6O1T=CO3GpHRa<9+)b8C+WbT zwF@}L4_xK3bF&_BD>GMsS(*r?(Xf{X{Y^ifzk9aFWNi`d}_4yyxRv<6g zuVcs#NV>eP?b?}NzSXQ6YnT0vfdP@~8~;4>93{egF)jP8%HX9r!m{7@(y1RjeNJ1C z*k$I1muR?k^>ZBck~t?qC#d_ys54#ow=k1W4)ES`-W%Q~yLHz2Chj{>W@Oa{3-CtP z9@HfH_c3Y07$=U=kaH%OGcq3^?hrh=(ejNDV;vaG`~& zFj;2vX^A)YOrJX010u-tJ(_~VG+z#l1O!FV8QHHxJb1q?qtHo0*F{!raUB?fg*2GV zmaGh;Va#lZ%3qW|_?1nCEHc>%KVH4W`!vZcOM>JicDPm53o;CfAXw7S(YWPz(7uUL;m6I}w#*b5eaO^h`z=OZcAMd44BMoeH%+eXz24Ae^DT+j^lNa_a;FXP0Sky|B^p@xZ8YXYX3#}^7gmRk-dvNUqhRdPw6-y zgjw0@ITticf_;i6LcPqq^22U+WmAv09xK!)S38hAPpJM}_<%Y0IQ_5s2h%@72Lpil z-&AxarhhDR|2Yu;r%b%Y|2GhD@=&jm{6hTFb%39bjQnr{Hjv2aFMxiNcH`HVi>3Tf z;AX-zs@t_ulwKNAg^5He#QDSV&K|}eB_JJ`=#bTk^B%RW>%;y2Jb5$BAC(B>8}j-# zZVQ3`#}?w)=>65Jb}5E3mKV<4YT{%styons<1d=yZl;iYcuTF^fPMat;#nr7#W)kk zh^6%rfMU^C6-zdzF`@i-^RF%z^3H_#q4a{s1Q_MNf19vQMG-|a2{W(Gq98rQnGg%F zEZwkL&F#jVSNOPU9sF;m&TedJTGP=ITMDyy#>5iJ2Xl)i5@zQcTF~_EIn2W(vQmYBRJ8-U z*kUWr;vyUdrjJ*Lg;dbqAmNbu0Dy8*9RR=$j4ZH%e!KEg>c77r$4`fdBKx# z;%jEQGova3T_F-V826{DvYZ3>jG9DH#xYkX6E4D8+YPPal2L|)l3`oJU=S0MGH#4A zjyB=Wt!3;uOIK*=MLL1mi+g6W5ae@noq?g_hBvE0HXGRymiiYZtZK5o!3e&^OCfE92_ znc`84qakGttIXwLAtV{dP+w*2-F?$>JXzPms$fSe+tc zL-*6L1}6B%B1Z`o|Hpsg4z*@`52Z{~*{zCktE9|;ttR9F$r;hN zVF%xoDw$gBa_7!CRUOCBV!O$!#>Ud|$|LpTM&%O0O2w5Hge#(l z=oJPx=Yt5WZM_!pz-L3f3L%^J=k8}Skf{D87Ey-J3HeD5 z#FqMh_GzIU{p=dTiu;06$qpJhJz+wS>&u<@psbdiGEsjelAyKRIalepj0~yom3mx7 z1)nbCGrWod{d%VabesVUQRX{(8#UvT8IRj#Ze(}geX_-5AJ+Tb{Uom;Ih>PFhQ z+`f^|YLjMTZL4fI7UnknVP+7d?_F5HG-6!X7TztACD^P`CkT_7 z@U1lPbP1T7Ms4O47v57Kk-(ff68xk)q=t)+_PRJx)zo0&N@l7KV#Qm14_Br2O!2MA z5h+Bgfc{Q2!PXo4Gw*y!-LkJJ?t9swa}QtT0`u{xer zri68Jqx#4MJE?K2ACC;%-H=3z*bqxe05amQZ$LOJkDy@(3APY!YYT2V$%k}ugF-Y8 zAjZa0gyQ!HAN+F&jcaVQBjE1@EDQiEvt+*RTwhxCMH;!No+$Bp$fM>!Zg0RIZ zUB0(>Ri3b}yKqMVgVG{ZbC8fPz51Gq_A01{k8V%wgr}n zJ3^z6_?}MQY@Kws>?+psg93z`gQWS*ofkUmE1YfWG}Y-GCm#w7J2Sk>T`JbOgE)L- zUSuGvLrKazE+?W@MphZl2(PVdG7W%B@VGax{7?DNx%g@ai07fmWZd(_@W>x+4=1@^ zdu1qgm9LTY;vz2pnGR>+;<3)3B+2Q=Z{DBkAQa^CMEE(!IuA6(pcD}(w znBv8NHDzEipCd}=qy3LY`E%DpyN+f7^`swFJ-@5hhRWmznECugIJthI{!Z?=?ZSI+Gghxp6?bt?m314LK}QMcU)%CySG=L!80Mn=VpossgW6o-7pBx-cqm!?(7sI5X*C4pYP^Qd z_WM(6e|t)|B;G0t-=ySMTT%mWK7-WViCF`l(=GgXjTaK#C~AVyqtTv26uC3FIqhq~ zg##?0XjmJ{U+{Gs(lmi#0T(sO>_?NZ0ta_q?tB4i8eEj1BnZ}Mp82SbD}8w%sgWdO zI|OCQBLYZ$EA8DxVA^?K5{{pdJ1{%v_j)6WU#7i=Ib%pdd0@QO>3OI}V^pKrLhGx8 z=ZDd68UXp{&Eaj*g?;#i$V znPQL45x=b=kyV;lmQX0`Y;0vI;B}}Ej0EH#5eJ}$U}_@MQmR~HZXBpF z2@2`K$63G>%EW3@Vx^W(LL<}s2PQFiLBA{M=hM}tZ>&vWD3sClzM)U3r}4sx+^~C& z+?WPHP_sKe<1)ks?rEo!ef3P{YSFSPP!i}2oCS!#Fi1e-s1n?d4`1Rc-e#=GcbMe! zs3)qWc3}VTUcu(-9d52BnW3>h0e)*DWgshRoUSK7K0}gbj1Gt1t<^CI9$_v?ipu;U zmL%`+hv~jI{C()RiDXq|mX||S|73-c;CEL9G=Ye|p;Smmfyi040Z1Z$!l09%5}f3T z*I$IvRh62uk8RTs17Pd5fcL6su)C14&2iJEpB+R17e*F`BU8V}!~*H76#zE&(ddt= zBH>+U7{ls<;MEHOpuASN*;cY-5fW<_wdV9vifAOyx;}V!Y;!Kv9+~u$Z<9qc{-8D1 zemRh^jZ}MM8SPDJnx~%m9r_vIbd~+^T2+%j^I3SS`cH+m1spVXfL8CYn2^g9*cv@m_&2_@#9q3ARtcq z)$-f!1xgmR_6vj9HHtl}gIE<@y(^tQqg=fi<(ksBCB5P*K(d$5{qdL>H2MnLhH+ zrJVw}STytIh!mE~@Y_untQzTA-Blx$+6Q>zAwFU)@8<=H$SFw|t%D^Sh+VHBcmoh@ zTym5B6vl4E?*&?wkvi~xi|np+zgyMG8#4!%izW?aXc{YyY~YAR{hrA-q*U?52D$v3 ztkIzV#KqbQre&fe5xY`Wz=9&TL=3w+Ia6&YK3g3{S}F!Ruq6q7;CwHBj&m{kp{hC} z(aUVan%-h2x{0SAe_aJMW0t)3ku6y!G$bo~_0iQo+lb|^ksR=OT(m%-o1^%6dA!i@ zfuMQ-|C(hXq?lbO=3Bt&@$;CV6#LUD-w)!C!f5PX&vrXiNc-7AZqv2eHZR1@^6U{f zz9T!09hFZ_M{}_U1S`r)T~&lIcjU+#@++&}(4?FDjC}8oceL}!k3HC?DER8W6M-CK zd-~mRrn{Xjq^mt@ti(q)EOdLZv|Jz1)*Vt=tPb4!8^kT9iRV7jqh(l@@4Rrli9{7} zx6v_fxQW|4R@UF}j7N{Tgn&QbTDD;F&06SCwxYsZg&3?au4{i0jVFn=OAw4sE0F4Z z+B~CM(k;*Zw{iFP4EuYP%fia~ZxIjhkD>8DUhaVZh5B%)AsKnVg78(raKla?BVj9O zn093k@z^xV2T#~+gq)Ji_n6R)FaA?hJcaAK31OUenoaAW0(aMIIZ5Uu{fFbLrvY*% zW^*EV8aha#`pw<>bxCe_<{yr_Rf{KE3*PQO_Ka8U8GzIVrTKYr3g$bmKa4*anEvdK zqm;1rv%TFPpU%6=7u0X~8im_uky3&*{P?TcU0eLXgGGtxYkw=JRQA;cuNW>cu8#cI z7to|8e}C~;_xpzL@mKSL`01)lNQHYkp6{25F&t{;{`oYONmHfpW1G|7#O34RcfYwO zm$#Ko>Xg^X7TvSQ@HBxcf~nh$!VcOWoq&P$GoJ;$)j`>PhefyOGJ5gqm+Bj5Y>K># z33BV~&K4f2ybsqBf6ebx7d~(mt->8Nb|Hh>Uf14wS-!o^;Ml<-aoVTd#0WpJ3yA{ zeJBUo?c{Np!_f(7FZT!g9;#G^CYMa7Mrew~`f9a5e(6_6+5MR9QLKF3awi4iJFS*7 zmqT}oxmpPtY0r0!Wj^MaY#WC})z2XsV(c)?!Y?odF9>!>T6h{049k7;xOch%9SVP` zIHAOiHs~io9j|PYr0*O85~;N!ZF|P9F6J(`V}}?$5Gh!5qzsy=5GKor69;K|%Gra` z8G(l%R*j3NaZ&(IeEtIoxrtgoq9=spiLO;vsK&E^Be;!x!L^G6Fan0PQYCHzALE2o zy%sU?0@o45_$6t^>Y^JwiS7o8C<7C6OI)BpOUbCHttIecB@*Kzyf*yG1Bvyz38NrM zb+lE1@XQ$IkcEk0H7FOO44)%`W$L+Kt%q-CnoHk*B54;KwV^`~&#*-EO>qZJz>U24 zo>o%Hd`L>Y-a0as(7Og14wc6#dnS3GYXqP7shG}+#n>ZiRXwU$bUC7_xHH!9_j%V< zIR9#3)77cmqr)gCA4QrvfDM&U`3g~Q=a6V4eMoi!Xy9rO<2N4%^5=QRrvb^i#OMzr z!FK9KBF*pZQDaNm5&ws=cM7ru+uCT;m3F0V+qP}nwr$&}v~AnAtxBWP&YOMup8NNW z=!f&PBX-1o+cD>wYkq5td48at-yRd*ee=l{Tn~j1&82H{I(n6I%r=AU7{L9GR+|r- zy71~~`!R`9f8@^zw2$RTV+=tgT2d{>YOae^1z{DHaQR|%Rj#_41Ra&fs~ybqFOtB|pw4c<8}JG;s2YHnEP{u`?S=&H7K)^hwtBDmohG!U#>(lX z4NT5VD=QEDE#?OyX&TmuFRy7ejsdJvn&dnUi@9V;+f&Jz(_4p+`BY)bX7Z+**l$qz zgGrR?Bo&wWjCwn>e%3_1C)+rjJ-%fs1sh=*FBW4EE64NTBc|~neJj~FzJB*Zk$}Fe z<;!N9;$J@Gj->((jdOosNe%@L1!MzYtNMdI6QLxlfp;<2`MqHqh4U#Vfg56%gloBw z5|TX$AkgE*8A1Fi((569;AkWgT2*>88GRdstSclBM&UC`ErSTLI$TOk*=NOLqw^tv z>UV;93Z6s z3VqhLl)^06VW=A%CaPunTgToz%ePlYU9RNN5<#aC6jR-oW48a3T#dDXysG|PU*l+^ zzhgJpe95|0eXqu>QvEyt5u|mPpGz@c&)&0=gwI78T@Wp^7;z3DUT#n!g#tC&hUr|y z0bePwtI!M%WMjTYnlm)@C1WOB{6gHfEBQ?4%);v8u`_WQZwa9+P|4?gNH;#Tg~w*Y;5{0fLM>1Nrvm(DXeH)((m3G?C8UWV}-`8q8yw-#y5`v7U; zXl$w_?E@R91M)TIFRiZ_R9D{Hr z6g_U?Hz+BQT%_!%D@-s^7vCkwqv?KIK^ORJE;T2Pbd3nQLa_GM%LzT3S;%BSOLH3DBa2mx`-fU)nbt zv!k7G#y!46#)~g4#sHe4!oIGC-khvkha>jl{4PkkaMC0HcMJh3ERfD5N> zf?d>7zpajH7sg*Q_B}xbZ8}!X-bIB^>xihZr}J~B&y$KYpAhj| zw&L@G!cVHBe!YGgn^}@yXsU8zp42xG?$6OX`;69bUly4wfnzSe`D_&tEd3iZFhUM-N_6)CzPnKcMy-6aO_cE!k9al;hYxKzez z`E{Fbj|~qvza=dkMRV~8WVhiN$j81}pP)TN5}E&cocQkwn1POg{U67P|AsvOd7Sv4 z=p*WqwwSDc!ErCx{aU;dp}?WU>XqE`iZ&GC`6;CW}dg%29aw zF4I7VRaB6EGAokn@y<(_Q^Bi23#Iobz0u0mfiyqo2;RKpVv6lf1J9K7mEZ2;yCsj}r8S6FmY7nCGj_ zHE|XDh}Omi!NqkXu5w4NLUOUmtV|1-boK26nbUOxe5`(vYy05g3A4dq{nWk#3b&tm zPKPdl#4blC?|<5gJ4XUP8{UGNkHoJWM=Z%0EyJ6}3qo@>d*G~fN45uitF}JM>l*-g%~$Lg0sx5L zTB3I{emM`Ww&9Bp0>ls-?6s$Xgw7lHFFnv}9#^E0LS&r}D}rnHfM6unB|C;%x3%E( zHb{z@av@a)T$9CpZF}%sC}!)O;Hh~g`01qo9p&Y6WfI0p`niMgBkXaN9((HiSXnRt zx_q2&^av$GJUF1UPw%C}X3b>4Ubo0Hkwt7TUbKO?(nap76)miE>*loq@fVrSq(HiKrq(h>JDX>zjKzICU zWV#L6{=m}}gG7)zgi`_48D(ob(-bk1<4C0R*{A0vIFC1g6Cxrd>XJtl8WYyROA_w2 zg#*Z|_mo`20Cc5pScYGDdI>+&=_ZtTX=oz@LGb!#YO}qt_|}kT)Wkt8-waj9r}@_2qthE+ou`R z<%(8nY1O0Hc~2)d$LZ`DY13eQS0mb@_s3l`vFRW%2*%IMc_8e`!E$|Bl{u-a@qTU# z=o4!%hld#CzQJ}X2%gEsU@|GMB7TOJNAXVh55?vQMzFNppF^C8jC(n+{ zn`%GA*i2o)S$}Io)~z6S1E<4VQg7d%G0TJ?cfTrOocKAQ1q$s&PA;KPYEe|Ro}E6h zLcb{p*lPw9kX5DIA&{W8dSJSuKe>cx6J#jb7{nwuH-z_mc6Z=1~z|8*wR$=~M zz$!)GO6~s(jP4`>2=;0;e}h$)`QZ5f!UC@WO%?g}-0d0?MQYF{2wN%ccba}vRUX>k zu5WBhIF=|Go%qjvqS_+~eSN>~ZZ<-%astmn0lwNFo}PMO5q#cgK%#YPeq4Loj=yTA zu1r4wu9&}Bq`TmL@_4<(v10@WB@@+N4ZKL6Nt;qp|CZt3B{ zYThqP{dLni|5!*nD!g-Y7nO6y(l?R&!+F?xSlT~_TsCu4sr2NysR%%b1KRLft^JBg zP3HEYl18jddeO9?Y5M@+OLd)dG4^Mg_>y=<;^PBgPh@FV`@C%D`{#+d5E{5AV&^S|~{AqT2kqeIbI!`@(_U`a@O{LNHuIq=-h$SwI zdpq0DSgmrT>Lsn^uVHe!yQ>iRz|$`B;ny=|BO@j8io=0Bv&u&~pwZA8?j zshv;|n~R`Q_`7^zaGfO`7H4+>j%L99Vatkr5A2nTwSm8kM*=p49nWp6$3~H@jduw= z!tBCz)}ECNkKP8T+obG>W8btYJ3_o{)5%49xEHiB2>ZmeakeZ)lGe=sMMh81 z?@$+PS;0kK!K@&j+cXUFeM)>l+Z6JbU&1>$U3v!K$P){M9~C_WG;h`O^0L1*ho*&>gy$&E?WY99+*WAQfq`mm>2UZTFT|-(fsdOOia(EWV)AZNMxy+XXG{uza1(j(j zJUR^iUi?Gq*gr(cRQWb@T#oy=Zrh05KzoQb+HL=zjzbUys4X2$6w%uK4C`e zpx}&R`g?o+xPl_rW*~_{+LlaGpXo?KDGoFXHVU^CC6BcssSLgeO{#s8B*!XozXS_5 zBN9`EY9)g91-djZC4r=uYr_|yIx|Q!9hLnwsOjio3a?(p5S|S8MPQI-At@|c+!0k$ zmzo=|uuBF*MMgi7@squ27Z(b-nyrzAuaj{Eah9k}@@hSqm)Z}-0_hg9o`4sZQ?4PM zF3;iNS92EnOiV#X1?U$Yl2F%y2ySgWr4J0x7XeGS?totp%7|^wXMRBP1oJn@pB<91 ziPx=xm@XF^WrPtO5Q08{Y;Zxm*q=@+&up|GtTs)5N^xafb=u_Z~vwkekV+e#Ld4-u6%h!K571~C;X?-|D7;p z{>OuA=6}I=F#j+3jwX%&Ur#^=6zpBs`3Jp&2sA_T%O{l4D~d?r(Pkd(A%nq`?cIcp zRzAw%`RQf`4~!m?8AfKD-i`g4&-eQl@^64gRAS&)$iq&JFAkSiOQ0je=ZnL4o~S&E z7tZ~!JQ16;F3iHkfNp5)HG?QIf&P)$!MMCsfhm>BH(ATEQDsONYJ`aft17;rlIkzm zmgAzz2zjs}25Jn3TCH_;sQF_6;b_Yr z!0~S0;|<;1{#i*>xs%T>On(s9IVSYlHgQcjepcQzc^(@R&pIG79v9TNFHbkd7lfU; zv!%U;o1qPbJAZKgCRGC0wvw zkaS-$V7y2=d>avLM$i&s@3#@!<}Nt;YqW}?NVyR+LKneBBwzW8#Uhda7~*J2SW?EF z$V}s}PO(M^v<|947*vmS=AdQBU}77B25y2RnmT3evBWdXC_o4Rv-X136d?nVA1yW2 zV0kxl_R^(bKSmO#VX_8p{bcmAQhd%MP`eUARCPMFH2O(s0j=}SLp=?%UNI3sM;tI!`p|87E0Rrs~jxiIa$}=>oIr(;< ze#8v1Pn_);Ww<(x@tf4_*VhQS9FGg?5-4uAp_ujEuO1-3BjAhD2AM)IsTa$a8aM@Q zd$*fQheiRB((t2}IkU#Z6YPRyHnH>kqy@OB>aK|yFMKsuoE1h(TscILL2-(Ft1k1C zRaCLjo__JN-AAzi$tS2D#{NYOmsYPFMflX~U+7?1gnF4sA_l>26okfo949j?o^zZk z%c-UkfkAIWW#b@fE!ili_rc?%Qlc%dx#}6LL}QR)SxDxDVx-~sc#g_=h1IC3UjbsS zKeB-agX4Z`&D73yOC>QplxW|6Xaf)JfCWgf0qe?aeYb2Yz3#Algez>A=-igzM2%Ek z1aSbY)?SP&Q3)c}9bRTFaG$suQ;(*wZ*3Cab@>yw7Eu>Zo@EUz4X@msm|N1AG^V;{ z{seM7o2c=ZrIW(~V&1VbM)XKlo8VPHuAG*BlcCzYZIXFR3(#`erfX!B-*FpSN^v&|u$x7XS5dFl0VmB=Cr68D)ljgUl2n7Mx0z zGUS0w8$9(X<83IuIVB+CaCZ?PlWginEJ7}pdX-64jt@y)hohHq2MX$^cI-o~&}%Rr;#DimBT7cwV)UVxe2DBV7>6-~Os)2h9gJEDhVGKh*1Mndc6?N%u*_SWpsipIux?;)vkLSk(?&n!KS7N5f)g~x8%B|x?K8(>Wr*CBg!W?C5NGZu%i`Rm z8A^L4M5fHdh~i5O`uH1)*^MBo>&ObYXb%tJF6B$;gk}T^#Ue$Gv^79Tg2t^7UxJPr z}t=us{e5-&?O_i(yH5 zrMmh-ffO=Bn~R)BrIK6HZH}SSy?ePE~~VxP+@Tyky5jy-OFK(N~H;siYjED-aD082wNRBI_&*%x-jU- zQ`3v&4oSl24!KbY@C0Wi8U^n$aqn;Ii%OWVtn)?b#DF;E4hr5-yKaoV3E9U)uo1Ic z6K%!s+d#0Ple|n-Dp|{bqFU#;dN4cJTUjpLqFL9BuodjU@564?L_}^>KXd(YjFP#s z*D20ojB71M)VP8<1ep@!vt#gBs+j%Nqulr&4AV_cW;>X&>0&wYT&}l2yI9S^d~gaA z5|ka5$UmHMah9JY|I8B81kD&7OQbJ}04Tq8Q--Z!Bq`e|rQRvCS(8Qj6Q;R~Qu9|IKhP5`ZES5A{OXjNuHwmo znzUPKC|$OkZ$a~&nL7c9@vl-yh?CxHbs&Ru`PeG-yf@ot#_zbapsD$6O;QC{-d7eM z(`wEese#58w1GMEU~7hvdnB2^)PkbN@9sFa#&7C`p$U=}YoFKOcm6T8k%XYqE*{WR zrrG}H-{o`glR< ztCxGVFyacCV)r3F!wJ%^*F;eMUbmb*gbz1uGtL`whKW)7t(hy*=q=Qaf+kGT9L>FdeW>%Fv(aD2CSg>W^#x3@D?r-Cc#7G}-l%gNL)a}RR_e-7YkRDizD4Z{tjcZ$9ETB)9 zz$ZRk+8@W8r4!HRaU;tyzlP0UP0~zoKe@boQi&~up-{sabco8?LL>&izg|JiZXr}c zTxb<@l35Y?7VfxE&kctcBZr%75v{`u3ubhq7q1cg#q|e2eX+Omi4vT($qE^<9e{IX z^uxf(;muxT`XQSm>d3J0ets~p_sHh8N!226Xry@_{VVnr#0AVTfKuF_)A!e@;+Cn` zDSkPl^n%OdtrYt&qvQGr-)#>ty(>4TnFtp&fIhRfT2HfXG4+oi<+!Jj!^ALeeBzM$|Ts0tRzKI*t3=)oNVY`56 zJv{`BTUvTa937#0DsjARA+}`7Q66sGUQKB z_`a87DNK}6@HnGqYe1p;V;VaxBNx%|Vg>VZdYU2&k=DSOBGPrXNc2^qqwzmUvF}cDeD3 zjxSEs@B2Wl%AXT_TvhIUSP?WZBE(z>BDoooc*2*oClpUG0}vp(5--VXsUwq;-h5gy zpp^Lnr4Q-c2!6N}`}E@Po8QVjMIyLE#qC4A5dWl!{}GY5&lHB7cf=fFzB?DY18-M7u^y0Xu;lY9TE+C&!IH3?s$C z4YNYP3V~_c2D7F=7ClL#}iy++MIl15ar<3I`tRh8Vw^Mh*&>Z(31dnPuFd7(8||Z za?pW?QDYDcvChS$+goa567HFx#ty=*a?*=W+OCjgN&m{*-edQ3E^tW`geMw2ZGaZvF;uTrjKz zZJlpivUX-OU#5O4WH=Zx70ILoCPH_Z**+{McaqE|oVtUu7fZL$yDVT#!qgQ@cMt?$ zyO|QQ5?Nor?`Nr0=X6}EmYyB}X2gIeZwCE9;P*5nV9f82 zGCRu8CC#a0BHyg}4qDwQPbVgBbF-8GsBu8k>vyPbaeSoQ<4N@y&WGwTNZ0fMcdB56H zzU@UW*K*}ql7CN|IelObS^bu&9YSgs?C%Z$44}4SW<5(V9#-%thU$jq3_UFcyiPZ^ z-%Pp|RuLB#NV$&*qRi^{-f0{E{pRL@+NwABmj4BuGNk^0;1oIu)&CEig7P;w#RaeX@Vca;9G6(S z#RXMre~58G!Iit`wOvDj5c&)26K643q^RV(xI6mcPrm{!>)EHMIC{k#&ybUJjGa%4(Gu zseg_aTvN@_<|c?uQ;8>^ts(gv@Fg+ylBZG8$U<=f8k3=MV>FMNMD9WmmZV-hr&|X? z!Hev#ng(7M)@vq$M5TlfBw$S&#D;w6*R^9#f&_=?dFy1&fZx#`b{MA#ymQF|Z9=tK zQK{l<%p@0jL;Jjzor8{3%R0Vk#LeJcfnu73H;Fd}8SKYQCWQq&hRsds+*FNQoyS|V zpODBePtG%(-x3=Lv~Qa}j0vN-CQfj%9H|DX5%9d=XQ^f%$3? z1GJ!SRXJ2iZve6w5}Y9v{z~K0MwFg|4IZWvqJhA~gjr%mO^A7hEAvQ_T@rrzZDOsW z{X?!@8Se3ml{?)b6ooCRhd20 z)FfD0%_1os|r2w~d!cQ|93$L&*DB`xKA5gdRiK=vMdgwBnWJxw^f^{9HbQz3#b2uA;4k zcnyD8j)0Cy08D4Q7M`S?;_iBhT?pz!XUH|K9oipi7nEYPQi!&y$^yt7ij~3)<|dPs zpBh#n4tdC}c>a!C?haZwLi$}OJ%=^~rzgQS1F!H;K>lGqE%v5nnNS;<9x*m=hfZdA zFfbO^^x%`^hm6|BFP_Hca3L*55xYFYA4zWlFS!J+Hf_IM`0rbhu33bOpt1&cqoWOk z!?hCDn(G*?q-ZwDA{Y_R2G(|)txKEJkfT$n5<5e?M_Y{v$1@H7s19;p8b-Hoj!@~b zQZi`Cl6s-!JXAiruXj$iEnKsV#7nO1Gbj=EzREdUZ1OlCI%z3t`sKtc0k@nwK?4qN zcV6R2uvQ;s>b5;5=-y|ob1Qtjt~JP#N)%c4y9W&A$kp+b`pBL>H2URK zv=K^oWU%iIFl6RAM!#5<5WmNO&i&c=IUV~iwV2LeWa4{uQ4@%B61nbO9LPQDtQTq2 z{$96ysX+G>|F`v%j*D>PJ7OvmH(E1a#Pl_ALp#|#y7F(0>ObA*?}#bgKO&|q{{nSHkn-?V@?N++DZ9*2GpA)ZilE#lCJ@P{c<0ewz>lf*qa8m&oY;>|yzjo@3% z5}Ud`s1(Xqwt6~zIhM+F((|A+o(vbYv0koQcwKtDPCmEGe86vXS3W-;k7@cFt_5bF zkFAfpuBFj^FK<`dcy`&O|FV8w{pC&mKkH`*4X^aIoCW;+AR&P~ws$|~$Oo`fCE!l!_ z6zB+wVfoKfHq>|sP1MKT(FWBdG^#>j=4Dd65;-*G`e^_%2wep0E?_Sjks~4bCNnQ8 z4S)zT*}WF5^0+L83S%?*=LE=~v#u#{w2Y(GjMEh9)U|%0umX+C)fTr{#ZRD| zszzm{*B|_7md0(8e21^^(<-Sr6zo--mlH}DsGf&?88Dc#phH4N0m&RV6ckyth%WM? zMK6Zutw{p#B~68zPzE_~OUUgv^kI5{`fgfx8yay-Oc$^)J$%-P?0IOb1*H2v$c-5w z@P{LK;A+ONFr$@NPMKkrM&^zfCPeEdW0I>I%0+=cQl0`QI%E<(^!k`bdv!QRlbht6 zRJ7d2BP`6+gJ*M0b`Eaw1>AzBf2?Bpzo8XiqAqidXX#LpzIvoAurJF^SBEzpY2jRp zbW~SuR#BD^=^*|w#mM?&m6o``PCdg;w`e_!8eVM{l1ClTRNC26hxb`l@0S0NE{2_` z$1Nu?Jr*z}#vi$spFr5;m)K}`UrQbt41wqAnO3dK0;H+B*bC$&06}%Pl}PU`-l=Pl z@l;xrR&V6ZS}sr;Mj-}`2`Fr1zY0DzF^t$p{~A@C<>)7vj~c*Mfwp9ElvW=E14;#jPE!j9R6eUaFr2qxYxeFf`4*zP(ngZcq9> zB-)CDJ&9p&7Y8zj^{2kc#imlA9J?f%!?IOJT$!^`K+~#Xy1!DyO>MH*G`bLtoDs+8 zVreEGWkaD->O`<1H{y7AbWnDrbyM4f=x`j!?7@_6gNz-L_t_&sA)OxzvfNfqp612o ze%wXMv;|BQ4t|%%s!6P@Yb-ddhU&(vBZ9ia5)$U@yIck^BO|qy_LmsZ&i+Vg#L{}m z=v$y6&(1N{ga`YI%I{9(g^l&NF7jWY4#cxrPBq3CdwJ6$i0QShM~yFI1gK_v7oJ0J zu-<7PZb_1gh)!MUXoEs(lx%%1+($*5JcStfh&#htXt|MXZGmIl>fO+5Q6r2_ZGLR0 z9|hEU!gDYgfG5cjiC{Y!T6G#NzYxv+;~h6hrsy$`L}<&nZ7myK)dj^W9lQoADhdBQ z0L@uFcFS0rDF}s}4*}~kMwuL9D@8A)c|Pkm?c7ASf}nw{I*>*@-*BBMcvwZVlkevXdgat`O_7Atbt8+j3dD6* z@H<(~oVd`W(5?6J>z=SZ;QE)|P2Iv4s#hMvyk~COPRT0Q`})UZ_YBG?s`Ng!yiZ+Y z<6n)-)?Ex}`MYt^emAb>zZzG2|D}g_@Dci2G1t0NfKa!1>ioOxmhS<`o8rGVuK#Wu z=~)>5fu>~nZ^rST6W0HNxvBbILjJ>7J@M_UW@umpb&%}fgZqcDI({*5d4N-sDDonP z8&NnOmp7q)h^oX__DjkDu|aO)urN!N_8ZK*W9yscmvecT z6~wD6yS%P`bWW?-{!Mqb!wywVwZH#1R+qSn=Ofb9i4~p`$Wt|#5|mG{Wk@!v^yRA? zbWS5y#Wzq9oPB>qlt0!lOV@jJWVF>OrL*Rqt>cs9)A~2gxkgsQ+Vp{FsyOHH&IPvT zI@2=&^_lES^LczsSW7RC;ib5iZPAKBRuH1)vLzL+WMksgu&Z0gbVHf1GSl^DgZtE& ziJNVm`rOK_I;#+()^ANA)Od)ok~$fo!VL}=`|332Y##=#C}iCK{-$SMGKD%qvvD%r zx@9x=G0*m-!LCn2BUCp;3WB1X*h+z{^U>HU2?|W;fFhkoJhuMkw{q0ON?-Z3U+~j+ z0wQtJ7|ugVV-h^s8X=d!E?RR9*#Ag|vvvNYj{wqcOIu_kN^-r2Y4b$mU+jB_bu_Uc6HzlDgz7pr zn-uy29Qb`-pTTTylpu1;ttMk_et;Y6@;{!h#H9?!jS@ zhDY)O?VVkq1klN)C5dg*xS8Xv#gPr2GpMF4x=UzFhtbv4W|Fx@ia9>hSR5#FG2YP1 z9ugO8s)kU;Q70G%9V!oJ3(O=LpG5`j*ic9BMdW32i;YjWPY78dpo)|MX>J$(Q;HA{ ztj(B2sd^Hc86>p{6W!+Y*l;5hvgVN*eLVJeFrAW@&fr>Nw-s#;9M_V1xJ24GarpTu z$(=Yub_MlH16zgktmt0#B&&@>nbhj2*AS*?xLi7$eCud5TA31PjRBewo;Ee1fTw42spP3p3u?161r&-*K&pbVu$3t1P@@<~ z0l|vc5`AURQ{0z;76DFj$Gn&V(tUxttB zX@aH%_7t&QgARSKQ4H8{#34R;By>i!v4bnBwHKbkZ3}rn0Z2e$oDavR0b5G<6fzze z8EIlf+vd3C5z8#8_Q40#LRF;l89liYbW*)x$&ZK0_CkhmQic{d*qJz)!6YfB@dO~e z@u1XKcvkenC=&_HizVfA1tg9Bye_7Twn486dy88RbN@LXR;d1VvCOl(G;o zQS^XnAu+++2ht}lVC9xJtPFm`=l}TA@Vq#7F~F&@aOC&k$;-lnCBy;MF1TO}F4k26 zBLP>_D!3l?vdO^8@g$#iZMQcs4>B{2t*0m2Jn}L?pJD#X^Z*~osg#r1Rn>?n*MYkf z?*Wq3OdB=UAdeWT5-XN{l^S$5oFwp%GNP#!EoQq6{*y=m=Om34uQ(b}$9c+vz+q+< za;iLgN`lF))5a$bc!8E;) zQM`i5-4)dzF_IL1=v0P+>)Wi8{G9+^1%$;@?(YwCcL1Jq#h)|nyDN7%p`RNXoAs!~ zkn;IsLVJUYVLw}14f_0DMMoeY5y3W228P1sXZP==7WpY78>CvR>CV)fNI~Anua@d1 z6xEkDAh6me^o!@`v8@Yi1nJ<8^&F4jSBny@uL^+S7o{IQq5aPuwiaR~f0n*CrjZVE z=$dBTa~>}D!_;8~h1F5>!XcWK#2Q^ny;pC_1Z@sD-S%$eTbA`NI||_-6^uUeRO5Oj z&)=EACT86_ek>m6_M45*eGH3WL!7_iUe-Q#8S&irxiB%yFCN0o=)SVFqaJr`#w<#9 zP@wL3jMJGpzj9(2+Id%fmq56wJ+Jl4Tj@DYVk^3lX+A3N$55ST)(@#tTBIEwpD#s_m&?BhdiTRgL zY*Z_0TO24Si*DUXZUdx(F;IqO2~1FF*>O)M zu7xt*8NKog1Di1**{amA-+H!NMf-qAw#km?4G!bw@)0G*o{nb!aCuRF)<_um+J zy2kPsj#5ue*GFxDeDOoOq!V>|Po@2tZ{uoC5kaF!cikqE@+S<7^dLSX;Fz`#&@)7c zvgeofNaPMxyNlR95AJb+EuSL)^_cPBZ5#vLKZye@|Bc1|^O*6!z>|v9rDrx+pu3M% zpSAFQmC9m*Lo>N20(Loj`eR3IHQSJ_1D+fE`X-5qCs~n7Z=gyOsPBJg$LcZkpRaGO zbHSJ?xM6VgvVfuWi?6?vO+KEC?~ZZ@hktfveSJU9;cvdLaYLUUj&`#!ozZ=9Zdcdm zM(Dp6dEdx^r@ezrDfx=lI)y^}qSEhcT*R$7Rmq6ye((T-SSaBVQ*tHV!=;4$CK4L* zzZe7>1>wMd{W61$gmf1-l&L=A*cZ&_K#uu7*YZAc1?c;f`@b{6KjD^O#_}bCa zifick`JQ*nhRmp$W5?Wtd`>Top3DuRcptU*FQm1N061=`Gptl|%(g-Hqj`dkB<<5< zXITJfY~HB?;ww5oVRr&wx>nh)!KvJ;jHQj|1yUOwbu5v6R4w~ZhR^FLASxt_qH2MP z)FrM85!sWL+tNJxXZ^&Ve1u)QvK$!c&?eK)?1?d8V$E}LzWic`^M}Hhm?OEGo!O!* zW&V#Oq`h}2KaN?=*WtHZjV+&%N(T=#obgn5!~&tJw)OK3)oknOV-6@Vg_GSBL|XUj zMZXtvd-dkYsYc33!EnJ)aTCf}#ER}J5|<{y;e#z|h2VI1aZokdPIRn2eg-aw&Kjoe z(QgEC=LlfX;(84rH!K?NbNw_$>)VS|kn2okwT6g@~PT!~Fr zY~e*DbN!2d#B3#qQ9~GBbyyk}K+@Bf9D?4LEuHkEi?b)Bv7?^B+BTNbnZa+a zM)571L6=@3{G%$uY)Uf8Fg+~*kyap7meYjA$^M3i4|RX;={B5B+XqS^<&Jcp!l)LToY?4AP0=-AUPYl!AfI zAwlCj+o0dB??BSBxJyD~>$hU+0+3`V*axzotRt#ZDIpZK{%C>*)h0?2|BMNR4{ zyeJ7RXPO)%u~I6{eoc2Z-7&tkzTs~434cd?PBq9y)X>lNqLUO%;^9v!>$=x64K?g0 ze#zJ;du9J9IC9wVL^4(Qld;bITfcX0tva*HtCkY67BaE6E9k`I&|)23vCBpRPLXa0 z>2O7emVKr0#j!8UG@7#=EHxHI+OW(+i`xX+8nKK#HD0qi^;M>eXoN?RLQ+H;XeRep zrKJ#R+Wj1}404uaH@BZ<_&Ds9#h}6lahU2r{R1s=PBR^iiz(y7gEdaIp<_YFUSlu; z)R--{eNJH|d*pi2;1xTJL$^3g>5~j)>z zd3OVpBp6H)5msOra=4Dt%k;-X%=u<*_1Mqj@X*r=ntP-!o6e*5U`Dhz4h?jDg>f@)tbd?by?H_>on2{rORTBh2KVGvW zT5>Ra>9lUIac~Kp(^OUEoeYr;XJ)lkxHuH5lYc55JC%zj;2|A%U*I&^h~@x$Ir-kS{;u#s+2vY6?9Y_`5NY zXq#_4YOAQ@Mb&SK;gI}4V9dLa1mG_AHc;#iK4AqZ>!sYCRKtaCBbCBedT>8~ zILzT{{%e=~?_QIhmGK|zPS$_n^059dT%NA)D9Zs0^j}dH9K7n%RBJrCI5u(rHEGP; zNPgGLMzl%l*|qy8$%w^)2Rawe|6F1kEKLIq>B zc(<*1XLYy~VJ2h^mO{L48cc-aY=p179%S&BawawKeU%9ATJX%3co}(jNTiuRC9f}Toi zfm_m!Uav0HI@80$>+)p!RHnT{kevy8LY^PfO7Xc#KQa$-u*lgA3MyvY2o^bUhFJxJ z!2}jahp$r$1rx>7Kll~RDhIUSx_6)is$LC6=|##IM7e!Z!YG#5wZAG%GX*R-i3FO& z7U_i{)}xpE=4CHVc^RS?KfPPL&8mN>#GhQ@S`6v6I_LyU{7GY_7k$z?+$GeH#l;pA zYZ= zRA^{VRO{A34NdcV8b-4V;8u?b)qi@*OX>%st2coy*G23)iZAZh|Lr;uPh^vJ4!G59 z-;v>0d1u2Q*#@6?z|_{#BP?$WaKuiTO0`G6P+7l9RK`IwazzlABS7rW0ilNnXw-~A z5|OKqz$N^1u<(YYzGJsQl>4DT@{CGJ4kJgm1)3zOEI5g^oYE3Y0vP)V=zmY{DS1xWFH^;@wN6y#UbArls@jF1QcW=1|uMRKT6 zKd9~6|KaU-r5{`QmB$+#gx*VFFi$l{j55xt$UYuH<=lQ*h#%++lf&X{DRZDWMWU zvShwLt*AWw_AZQS$Z#o!#XK|??Nu&m%0V^~AomBS$_WxaayY4X^_zQs_@x92kogm!=g6S0 zEK3AeYN^pX6IRK4Dc??JvL^d76W1a{8TV?~x6KN=usQ{*#(}M*gNw8?3zb#KfK0R? zPRS%ab4o@TpR=9bcI)yFf;nUv=pIsP%?Hiavp}Vk$-I}%FQFXQj&^@A39{U-_N}il zdTZTw&>Y~__h-jRY(f^e-TNLM^eO>CC)Su6d%$c1Xz}j7VIyo@$TWJ?ne|R1#$=N= z2ftny`I(X#Z>x?sWVC(s-6ET1*%bcvEEacF2^}q(h_4$Vj|`*cCiz4)MQP90*3>Q( z*k77Ale`z9dLsBSC>ScC2!yfg`;i4uJUfhV?rac_JdHw_BL^3-oZoJSL)0#-zCKaV zGs-UhwEf6f{BJ0v`Lp!Lq<p6mk%&!ziO$RUuA%dB!lN|lLHag$4P)0O5=E&?^=%MFGz(kx$|b)z zl$*atjklYXzef#lx@jCR-ifD{9avs(v`?;5dx2Nh#+@A>UbojvFrnR=?}rsOi|!xJ zVwRSoht8YZR0mfBxS=z+i1{j1YVgL|@JmdukooGvTg>@)G07%_tRc;g&|>*m#4Rw?E!cp*fyxWV_gTx?h+eU_}#19vNX9iixaFf%i}Ig6cGQ{vK4 zw4 zNZxBrFu7Aac1vMSXudq?*S@%{_BuK;IU^YJUb{Xmcl`$(k`LQ{z&VUt(Je|}8`_lu zMTZgxxt(Xy(D=I<;(r&mCxXvwaIgoB)_}G^sA_w=WJR zDie2b&U%_6#$z=U_NPF=`+pdFtEfEFZD|__5L|=12MO-(Zo%DMgF6I=;O_1k+}+(R zxVyXazob`o_ugNR@vk#rJjX@dHLseJ9$35vk~A_C6^RoZH8&Rl>*7r6d=N3CX^_-2 zB5R$IyZsu}i0M%cf3Z7s9t}w1OJlqVIT}SD{cNMj14*iH0|z24>gx_VDM&y^hy9Mf zk4J=e#6rP(njgO0K{>J>KVS*F54aLZQl4L`M0~F0n0=em1davRk=KEY=WGV8E+IO< zWGae_SkNVPR%&)%WD*jmnEv(|g;T;5iy-$Xtcr2oH@P&@15QQ5mT@h5y4>kfKdU6m z4^RCipG)(Ulx)xaR^{#{qZUg{$jcA>HN`c?r-nw`2iFtl5mXTY1`_>zm<8XC1d}wB=zjDkz8+kpiSw)Q_{bNpj>TN^C&R|6=m63Rnnn8BI zU%rf%gf*hsbitqgo37#{pLpYO?Y)A?Wn0|*Hjw=|YHUrc?Uq$2NdC{G#omC=h4KjU z>_v6oYPwA!gtWifr_GC`QygxW!}XM9NQLSsJCc5gDcY^;zD|qX>&BD!ynYHaJ=&%`4C<;$81Mm@0}GiPtmkP+os)rm>`-PIm*-7gp{u8?!y+b$Is zZj@R{98V_VgL@b}v5rfygtG$?cats>czM3QAy@Odxp@9MQ|T8S3S`(gq4Klyc;4Ga zBgbDJE(lz-jfDpYPqUSxWjl%KV}}RQ$8Q^Mj{e&Elbc%rWY3d@Ay8SIyEU24^ugi& ztGhPj%votMn)CsVqKu!z_7`hY44^u&E>C3)l3|Y=6`>c@P;)o+u7Pj^z?o2XMEo_g zgw0o(ZXS*S8Ml9x-#?QhI);DVODdW^&s)>s>54Grx_qZf#%8nZj#E=kGRfw0^2>?Jth^2i@m;fSc6) zUII@5eovrd&FUO?|LEjB=)v{EnF0ho)2!6i0X8=q5#4+6V%bVHm7=jWQGlRFfiPKD zLsP=OGir*8F1%WB?*u|fkR!B283|<~n(%9%YIfT0;;2!gQivcp@EdJz!d~Zt4W^GH zU>~*@PMcdI@XY!1^VQ(~PN9qrnw`%QU?p|`rp&jjjKj)xBKVl52|~-OT-%lz>d5*^ zzo*OLtE~+H5N>vZ1!Fu9#8f>4S&P|TizDBkQ>}E{1%xiX3JX44jCBAG29x8nNjm-k9mOS@$Pd%{dfE&org442mg=V4uZk8bFVTjRDOVd| zzfn>vCSM8-CSZE$U4Stt3M*X66xQ99^I<`s0Rn6%SoyaA1I{Jn`@IV=S*{>oTqy&} zr+EO1t|}R8rGSnRyQ!Z@f&|i-tqK_zAzkzZWiIkO9cl+~0c{^m_G|9?u$=kLrWhYK z%j13?sC-YJp)Ofw^#2I3{Qn5>7-Ht9FmN7~9TyflSIjC=N5DJ@^FpNOa8##HVIQKe z@F49tg7=O}4jOHX+dVCeLKavXgI?xhH%$<>1vP#M_tMJX1WJLpg#=MQ=H zx=NzkvjHaXHkw`^R4n>#04EW$HYwy41&66LfNdPIwY-YmgQ|jVYsf}>a+I`c?P0$Q@V+GX;I)pdo?gj-D1Vd_&_u^%xx$BUX zd2KmFMaq-Xt9!>I$e-TD*U2;YxA>C!P%O3DsdThdQA~=Cl@teQ9hRdfsQ=Vv$b?F5^=f)N*G zW9UfbjU`fSfUp7#@T}RJi8o?3!@5hZQ&04D%s4rV{^>CO`S??L)HQ@lC9&zL1$Brpt*i^ESzxFb{ zvG&jQ(UL(H9NsQF($wxcQTsYaK`l}5lY@tU@}Fgs>AyppM3q3M=9!Lg-nx?DhQGw6 z+_C^%B?BNGXsw-Ho&CT8G}mfIyY*rOt#Ndw_WSIkT~2FDAvuA}l3#@D=l`ax1ZrdA5951V{C66}s~ zL3nAXPz3yVwlc4EVUUFFj`DFL7d1DzcTosAhN%g5MlqDj=WZZaK;-j6Zq!ollp z5;*w?`4u?nlOTq%AcwR=;wY^uG$9$VSLD=Hj-4m^Q|1coO+@>n_G$jdSsw0Z8-;0i zS`ntPSCg*iy)8{AH~X`cS;v{gh1wnA@sA#$9KLK_ahdC5?c*?R85a?_!VaVimNsbV z^5J2}smd4gOYt96*l~Spt2nN|D_p+*)q;`DoWNS{yz&EHl|Rwld<%dJTGin^RO+?U z9O=*8rcwO~qqA76x!9cfGl2br*GB+giIHlm`Vp59t$DF>6^y=3}L3Sl2` z?)N7Eg3|7-@t$%F(YPo2yt<|2g8+Vt)G1WT!aS)kRviAqwm3uP2aksG{Lm30o`ei3y@{@7>VSQZgUKBcg@K0#Ex+$JmHD^wCl z!blff7Qp(#3v*Tt60suMxk`Iy^s+R359^;H3p{JtF|DVaa~z1o1_TJ`!6G{KGP+d$ zC^`nPIe2d*ljgWZNfDc#k4mV;y#04woFX=kfR5m7~mAFn?w#lJ`bx_ZlZ?U zQf&q$5Y6@mdo#O;;Ill4KPn(`%XE=(62XLIpk8oPJo-Dkj*#B&%L=cU#FUDVe)fux zF^48)@^j_05A?J009I)UK0+y*;wMqeXGbWjI0p`z6La#2(#)nkpsqOIlvG-k^-EBq zj+<|hc8+2^tF*|F*K43=P0RFV)UpjBXN%(;^k>`nwaVvI(L4X<#Gtv=$ZTIuRCP|Y zDHsP+-!K~luDSpf55~RXatdFN+$n z?OHiB4?jBjk$|n8HDd{7QbP>O88UEq{Lh^XGRK!`k~7pIek=lt_RFZ(^-t z1+8Yi2If%4fk-~`%jwt-*>9P&RgUH1ql)cC2M4wlBY@8~O;moR=kfRfId)Q+LvUbk z>U4jIa|9w`wcW<-P)n;^kazv5MLh5Ef-X0CsNk>+P6ZAKm24kj$q$U&{=yZwgd!1o zf#t@Wx}niQ&gKDh-dHbcezv$!wmxJ|q+(dUGqYs3Dd*&^)4SL@SV6zdWM0N_N6oc6 zAdsD)_9NxR@h4nnh?4x!e_sv-M<~FL;0_&ZLDj;zmU12FkE2eMy~cGGCnWAkyi42Db)U|c$P3lSyW3> zBf{(=CIG&m)p1*HD<1G9J&AfFK~sEwf+9>6En`}P1uD=sLm>2Y_X1DrEb;l@B=@(D z{uMT`{e$~u{XR{aS^(olUpubE$cIf2 z@mj0gk)seh1>Z8wFQMnS6zT~XNFYxFer#`Ucb!h@T&Roy>WaS8t?b%bqy-JSszP(&$F*Q$H!%Th7B~zkas=t6 z-v_A0B`(S5_8@RGz1?DW>}2AjmMTIoa+uzn)tke<3=f;0u6+DV0EJe$v-j1x$0*DuKh}86do(@fN=CwM3_tQqc@0w8&|G=(<@3- zUTKhB{Cde!yQd)^bcG7I_Pb;dhf)rmEl8r080mwRj8dFUYFMY?EV6D+Et$IvMmMJO z2}vTQ$ZSP|w05q6)-0Yszr(P)Mxe09r`k6r$UPiFD~OF_uSW(6E7jW#w2+T!9jn>> zmt`muJXkdHSj9)O2Z+)YVtI94Fm%=K<9;vlYc;_DOp(MjNs*9-s%7HE9%C)s;G3Q& zCn{u+FGi{5D=^WF;IgS9Rz)Gaaj0RvMA1!KhCCXeQ1TX_69x|<#9m#@T@|2eQ5_%5 zbqL9`f2J(x^U}fQj8BzH%A%ZU&!I|!*S4r;ZbUAZ(Evs4*);1F)lWdgo7eTqX*pvR zIw-97q&6X+ zp5t5tsk^^;?M(|g)#t2~4Rl3_esZAKm<0%~&?-fUoLro3A1d@^d6h~?k*B%CkI=I+ev362 z4qWaxcMHiGw~vD=PG`PS@y zd}U?!7BwR&PIR6AT#i%*Y2^vH+~51_I&IN+TvKWKX<3@{R;irh249ew^5TaAPXW8s z#emWsC-`WfWpXDju)sj={tFW;G3m z*S&qjD&``wjp!}bv@RaXTSY+QtN}A6QW-QZxH$J&k6)?+*BH{get9@-C94YkBu>UT z(Y47{{zW^0W4(Ll)0ItlM0r+NvzCQcP~4!jFfJb{*FH0iC@QL~IPl5rO*1I{E?Eck zz+#;EqKs$6&i;-(dhYYIr9;MANaYYfS zz6k6J@xFd@0M&&0z;60|5^ZJo#QoQ_-2W2Ecdg^{Uw3v%nwx5 zFnVgtS;heIUNiJO^Dt`GMMm?`tx|x`<^NiVD||o}1|^zn5^FPOQqbsV$0RwG{de2@ zFO($WPa&|)ox8||EjcC`)r@@Q-8z3#16Ru|LPQ5TQZihTol46+NVEC=TF%2~bm z^cy9S)LY!7<}AR5{zdY0GowBoIFTJU4PbO(zRUi@=wkk5bf=FGdfq5m@zs1^3)OeV z9T@P^qRHZXAH{jfgjwE=ZWcnOWKb8u0ZBUs608LW5vr(?5lu1tkIrw-91&JKpveU5 z-A_^AdnxRenH4L9sIQ_yQl;!|_Y0wRVO zQVMLenN6Y&A3soy$x_~(9Qk55Oc-)&%dF>YB2J_(^+8w{(&h&+g=M(zbe&R3w_#Ao z*2x@1Xp1T!EeP^fVv+GGJdKV%{eu`pr`7khYHAz?amRvkZU&z{6iS-o`zKgF5g|cL zTnp={qZau`tp4tF%;mEs}fK!KP>mW`bH6*eXfwTgp&35<~A@z*RDTdow#FTpKD$RBH4=H{KHeX=w` zy9kxFXy1E>)PJflP%6w2e{7Pz=O<>xiMHQV)i#O8m*j+&tYM8wV*Zq!7pI=jbVj5G zI_f65v=@m!1`S7Mf-jx0peL#&o|?-$=KSnb!?C|{<3;iHOwe3v(&BiwP#vUz#-XHO z1`Eo0*c-G>hS^P0Z#&eaR)=O;v;fq~rq>T7DM!MOSW}O09f|_Uz)-5D5%$7in}KaM z2|D1j(g(ZC&*;rm%8%vmf8|cbJZKJ}) zJ=^T&3RSj!Eyaa=I5U=J+GcTDR2gL<@DDPOubBcGQa@qh;)1sI z25$%RKWsuXwBGsIxV}3l*0&>|kr5=Nk)rz5^n|P|Vu)G>(l=<9-$pIwNVr}2VOI1%-3UL+*>>&52}z(w&g~53%7f&bVDg><1S>Xku`bq zhs9+?>!NCz-VbLT<#o;1QZ#-;rN$&qNo;eIR&RN_c@+G-##8Z^QVi-NEFj>WHXo7uy9|yin$x6SBCi zyVV=Y3_uVw|VJGN)$9vicFBo^sb)(^wK9={!k*!pYvY^(!0O~E`Xr7+at#$*>Nw!%k8lCg5-wSMUKRak-x_ z${!qQE%7e2tDj$A$FsWEvVsx!k9H9FO)PP}ET*gkfyAv@3E=yc%R-17(}YnYI+!@E%OTh%a$zIn)ol3Ao(U!Eh;I^FU z6WUI;G4*cF_g)*2v6&-MjjT$*@kc{J%Ta3$m_!ib3TQH(UC`;lHBM;5l0qb1iIUI< zX!fB!Xk^u5MthOH`+>|`=(_Kc$pZ(OU8~uUB#_sW#G=gr}Z~*GkmEY67e;xM7{-yY(fN#4ej6B5zUj z@4V|#!|p6(8*Cb}3-Mo~7ClU}Omkk3`S^`A|2Pq(HHa(myE#Zd9h;4@K#E%!wC*T> zz&1Y8aa2(#lsOC6{LD`vB4kn7H*vjrPI@Bix)=L0Dn=Z33o>Z|Y!1vVnfX2FczNP! zR@vqQTrtSZS0ht7WL*OsLiA&w*dvAyC#D+cdU-aa`5xTdRn=+HV~@#?MB`en0X z)A&7(Gb1l@Tm6t1^X~g)l`pOiB_7Z8?ybDem%L1sQh5XkaByi}_YZF!%Yc6aEOPNH z5YlO=he=G6Hz{MMV)ch&it#FpwR;MN&g8A-6vDM`H0~&dWmwJh;-Uf5=oN|y&j zM(jKMY*m64W6Gn0X%orRL6GYy&pnyCRUM4j0&Iyt=gJy~fEX39b=y?ZE&KI(bj0%^ z6piH$Di@PwjleNheiA|ClUk}xg)}qH@savXHLN&@aIy^Dj}G04d$%!B&f6}ioy(Ht z-s+H~r*&0FvVWs)83N=ARk|6{l{>jfTtj(7q6Erap{T`BE0ZBRPiDapURk%zg*!bKl`w3E&^#-3kcUuicH?v;zKp z)Fj+Hj%PGql`Xl?gt{ZR6bC+Rna^;WSgcwO)sGLpdiSqxWmc!@mm!wb3?q+~9cMLM z#rnyhuQ)=~&2K?tY{ryuZaA~Q3}3Z8ZXWOt+#PG;`HM#5g!q(R(2t!4F|@ykdro5E zV7FLjKJfn}2ls5A%B%lG4cpG#E`eVSc5{?+xFX@ISzYI6u}w~6Ismi;?d(~Y8okjb zZ;0ukU|Brx@Wm;46&2?F!<-xT$?O#T%nFf+b?@cuIt1KYop zh}r&|67g?E6^2AR_nS`px0( zwpiJBs`3t~8$A;~$KC6t`sqaTO{O4V|3bU{_4QF1?R@cO^@B&N<5(kK!c7AA&oUg& zvY30bq}=BAW|=ekY^7WkL_DIgFAheHEl$-cQ9ji`1)zf0}$TgDJ?Ra zNgl^HO-_qtbV}=teIxnYaJA>JdxreFPf!dUY$~C&pKeQKP>|i5P|x+T!rmSGBjsGy z$K2=>Up_7e5<^*3;i?d3YUl2e#p$j?B8BI6LeOX)^r$8#M9qxTf{JalMqx`YW@;g< ziN{bDs_Lw>%&?zTkO_pwa*W%Q5TU&+#mkn3FvqMTZgmx_{!7Jlr+m ztqyp~ZQi)_@~?^0{5}4KDp`ECAQ(423J;&z=JbLY>)(p%PE@ImTNGTsWYfg_Ns%}3 zX2kSdK9fl+S;fjkIx5H}({-N9jP$!lLrtMUm(+3u1b6|#&ZED#<9l-Zm_J{%e8B0z zzJa0Z=X~f)fRPyzMp|@5Yi@sX8U& zs92r7`ekk0`blJ-U5+93d=@M#gh<9{gw^y$L@=F)j0a{cyZR}0AM^1^T$w{+^k|_i z!(Ahb%Ls~9*e6+5@tV5^jCd=|a%O6ziRcwHa=eH57(yJpjVpwE{?=7JEn+76l*U5Q+nb@%My?+!YL92Rz zZYGD9#Gf=7jh2fBSv5B>PHOikeoVhYFS`Pp$3aDYAAT9 zwr#E|hwWCH@)G;Mx?R*{P0L9h6<;_lq269@KCnqFg%^p_?Xp_r-)BBDZeOSu|70tU z2ep{vKRS~>cL@B^BX4Cbfm`P)-f83i+^e(=)3@88e$8NND;L*X!S{RtuDENu3ULsP z@DOUadwvgmAii}0#A}bWb@i}!a_W`M)dLd6voo=ZYLIbxNDEL_O9AmqyvH}- z3my#Qe^u5$c`O}0%Rj(cwm+=GKfUUI({lZztiN}}Ik3Wq1E>TG?Pgv_Q&@XM`*~8n zNcBtrSUcR`LM$<4X@|JPfQcI&h;1vJ4_LI`y_R+$X?;9Fz{?}NzgYfNxW`!sKQ(A+cZ^H+(?^cK~tgFT)0Lmfq{spbC3e2>bP%Qog-d9%_Y>-<4G|T<| z(+iQi=@kc^rv8EmGUI|AF7J$GNUeM#k5w|xPJgfDC&35=aJvnmxdbs}gQASgAjmGu z$Cv+D)fw>W>eAn_=05wlU~Bk(OH+(XX~?#VS`DJ?%irJk7fDL*v&IFmqAhmnqvly7Eyl4xT&nS;l( z7SWhEmBF6J-CZF_gPL3ohlj8v@mDU2VO8@L zdS+9Nq)78$Owc%Y1}P|Mx{CF;^haI88a7n(pkm~WB>bIV+VZ>B4UoAoyVPT_FC}X? zKuL>oDvU9)racXO0#<*m7J+fA0~s3)N&lJ*IrOCzm7YMaMs)gWzbfU&1PdmYI#3~! zg@jzXQp4%*36_|M@55})3w4|74mcF!VG&1C5~;Ld^)6X@ZJx!7$3Qd`#aKCghI!F z&OPzeg>`i9wsOeO0C6XxNJ;j_FTm$Bp6bDdF8=wP2l-YpZK%k};Vur;bzQqtwdrab zL8>q4O0chqtkri4C7p>e36GoZn>444Fh{Ti*R(8WFB{FSD^lvylHjRXmi>m&T7W~0oUqtz+_;1*y!@!@XA0$}x~EZIeRGUo zX8joo%XOHJ0gpZlSE0gmf-uh*BRF#w2Wa*f+})%)lNCrtR|(V|j@gMxp#qQYxIB0H zqZt~Eje4+ZEuv8%hK3j-U)WMnWJme2BrvJ`%CPk0G7MXM5Z;#Oz|!TB8R;(UZGK@3 zpp5Pl$c$eGMhQp-(*2h`BsQ7A6TZ!d3{OKk{zQV1` z$v~NdQ>&juhw?l+9q13Hkp2Dc&^5*gU|G$0T(u^zr^mBu@DGGDH}LK>iR^h`#ywl} zFebvpsDX2n0ODF*6mPY{@l~2oCYY{$Snn{TFWxdC=#J#@Z3E67d)jO-ci&{PW|(NK z%!+imkz$gG$f{WdMwG}f)jCw!A<6lpnO!i*muYo2hDCKQQOm~ z`ThnDcGYRZW5)?Kr^PJzA;nwI z!j}PyZvX=@<_V~f5>N<`{Cc1^HdFkMMD;y%FcIGO(Q7hamUB^=E=X`2NaRYDDYd`8 zTUL9oyLZc~e+C>t&WlId==t{BvX;qrzgyN;&$kk2=QGzcZ|a|a5eKz@5eE(K451~> z<0}PDkY6d0sDkLJgUqn`!74HOW|^{~!()wlSjU3KmVlvp9MP43BJlluAAX^f;xl(Q zs3EXH-UkwJ@v!d&R>CjB%D>&`yd7A%%D!w(_p3?`503QFcq%zQyj-+3b2Y(ZnQ{Ou zYkI@vu-Lc`8ZCncB;cNmTfVk~_IXy|*EG|lx?KO=*exN)K{gh!`U>8HX9z=nd-~|Yqj;UI02?3A`mNe4S*fk zI)!ZTcB33M7!D-v0n*s0Sy+-}GgsxX9vUIA3k7OY!(t5$wTV8}(zumE4YuNdPKg!xn|BebD9JE5C@VLFoFS1_pCrtBj`NlJYG%o&hAF)i;FR`5!-=$DqA z@abBjLJ-VSnp8lW4|7@z=gM#Q(;&U00?Q~7Kk)XZr2JQZ^~4wma1O$EZ4w;BOuq>b4AsrvrW=3`sWKEm=z=nz)h*DB)AC**QD7gKuGfzecwPO5!Q%2sJ15`)ZI3N z64&6fkhjy}CcWQQ$z7jSVIOc%NBsqQ3LV#2BAPgrVxZPgSK{R~Y zqNlN@P0=#0eAZ&;6RDE|N*{4DMOgwzetd?)h)TymJPQOX+%hx2@A#EbY9?T+ zlwI|9H9fycC~C$leja6V!>eV19(Z$p;T@W4(=GN>Inro3`h=&D5irwfd!ty;n)-c3 zt?b$r`WJdbPVwl4fbbA55W>^BX#S2Idm@P6M!IC@{a6Y~1^M`V34Q}- ziC7=*AR=*DxHjPKaakUGtokn=AozYtKjLC|%2ks*g?U&##5Zck4%?83dF#a z*)}4VUhdSR(IIu}m8N3gmIpOV04O`+tUl|XJa$@OU-5Izt>;zSlT>;C10>w)-Gov0V1>xAe@MizESFW zSOH|b?tq#?ot9|SNDr=xg8a(QVlBmXv#INe7rXmrhO~n)oF<5g2*@VJp_`|Sz_nEe zFC0l8!RPreKi7EhkUZfvLwOVC1t7BO4WG+~_0OI}_0!q_F==-KV6P>{B&HhRwXcCV zI#B?wM>q599UKV#3mou(2Y>^A!c*n{9iCnR!c!jm!2r)=TrYc`70r+NZtjoHwvOzJ z$oGS3>+CoeSKPhGsRt#EGWYU+ovEhLH#_-&@Ki=N9uS`Xk0bq0csgZ^Hc8>Rq7t5m z99Vf*h04xL;ljkqXkKoB6&e_YEt1Kw`VH;q_Wb;<3%QUlDaF>t0;KdV4)H;#ZR^n4 zmM>WRVw=Xfn<47enP}7&wL{ia&Io4W*rr)HADWB!y0R_oH+D6qL$Fvr$(?O3emK z6Pj5RX0k@ZeomlmMqNFF6kO3=>hkE%DJmhz=uBj)2`*NZ-ziN{ut!P<9M}A~8OTyoaaA{|Qeaaq7^d z1yYg1#C!v6yKR3MV16`XSs@|^o>?Q5G9#2M6#(_sjI@2};!SBGl110gu_2}WJ3W;! z`yLlwp0Xgo+X~}5epn(Y`--bQj~WWT)1;btnz}p(a=u`@gd(BpFPv;3P!Fc<4{BY& z$q_=u&tLm2 zDWR(=i}6Rrps|R-F_MaX&aVzs6%VflAEqzT%qMTLJF${_C|YsbDKRr$8jAbMpR5Zr zHNA{nVFi|>*V+F?#a`92g0Q&}TFsJ3YE=%7-a6gZx5vxqag+>UkzM!aa_aD*nhebH zd4OJpO%682RTR?U1u?T_qZnzIPPzrG^u@pr9a*zyag%tK8 zH1TI8B;4ozb7#fzG(AHmA_s~_3VCasb}A~o-Rmi znfWzVITxg~xRbQ2bSJy)LfvKjqXx$Z=emPG;J%b%oH2du=@Rs3n{yN5ko9djJP+|; zxDel*GX|PdPZB^@+xKzc;NA^s9vU)HyNuXFtKV-!iZo!s_tcf|vJ|a7QTl}d%W%jX zm%if`Bpna4z@XvmQ<8}`Fo{M(Yu8}tF#rz$f5!tv+1~{2XyVn-3jak{{}Ri;LR6N& zFRd}s{-Fl`Hl&QS@6Z4Le_a*(`8OUwSo^D^qa&q^*UI$cKEZw&U@S$$Yj?0lgJyZV zFcuv+qJnuq^bkczo`T!-2KVNe&(PYL1r79qo)wbg>Gkq--k)+h+<7gK>9unCbi@-V zI^G5ie1CMa-g;IU%H!m6tbym88c!2odb6>$(VY?+6u_b+h@&jXa9!yQc*q~3PKu24 zL+fFp3F2wI>#AglanN_W_b=XuQnY1Cf;J#8hd?My`L3(ZUi4e` zHDp-%-{`xq_qI*|WI&7hvEzqm{rNie)Np4I7H_Ujz=W1M!}yi)F4z->Hj#lwpkK~; z%vp6ize)nvS{+Ju-%s~AO+4`Zu@4`An?z|1zNKT(NW3M9eCy-=(d16{;LQg?^f6Ls zcTUCLBU#4ifaX!MxqI-@z!HYcDGQR!VjX9quZel1YKI?+-_z%_3cU;6QmM+N$T$5n zH0DSXLp;w^vvXaPX`$PtFJBR*bp-p$7BjiqO2E)GTM0nf(v^EZJHe9YgGN_|;Zdtk z%yImPQB*4LDmL8Fj{-Tg?yeSB6ctVy-O|Bum-2%|CUu?huP0^PW{E>3r4>tc)tvv; z+h>U~bA#$ug4s|C+(IkQYA7&H0Z+X?)d-^++zjFR3)YVb5=<`i{jE<=tg<}A+4!Hg zevGW`ak8*c^j6(jd0ZH2beA(Ciy!%AV$6mtsjNosaF6V=LPQLtEG{)UMeupdHc>#9 z*+82o;`?KNAR=qffz-IEBT3qY6rCiUK}!;Zbt?-SsX3V2c_`KM8(Rz+^@1+|fyEM@ z?spWB+c&6Z{+_eBbgGiCWD*^Nd%(PHPLXwxsJtggsX;AuRD=*t5Q6to+;xVm?=0g2 z&{wuW>N%!kOaHQ~?P$dkTY7jl7O+bcoG=5~WjlKad-Pp1wP0pQB;K3Tkbnr!lDpc| z@K^=M2`-C=b>pEW?vo%%x44BVT#BQdNZhs%yC8Q1S!wYGE<*34RZ}-AF-N}^;uupLo!N8w^d*BV z^Zb&%xfdEE!n+?7NE<*$1ihT_y88Riz*1}3`sdpChE`=knayJ1={n zut)|(p;H`TOddKpyW2vu5HtS%r^x&qg6rHl{b*s$yxt3;XF8nF{l&faah^l3WL}~> zwz6gmvIj)tbNs%!+U(}{SrwC;7239RS>rKQxs+Elr3?gUefPrr4A5;{Zgsm|pbZFUaLsp)!9ZQcbbAO4o zI$i5Gog0^v=aw2?@2Y06fmuIe`qNYGVsMAVbqBNj$X#Bp&4oh-bpffyR&=Rid_GaX zZL3C^clNDb``0H=8A0EA9Q%y>o&L{f7J8m{x>x6Rcg>63OA~FM%vSfe6L`(lRfPWv z0b2Ryo`lJ9PAPi{7w09Tn61t#nh1{o+i!&-w$07u)ZWUU@VcF-{%!m1UqbpH3ifXl zfRXkOA@EPl{ck#7c>ojupt*p(1uby2<%I>XFfb$4fN=HWKH)&QR0w`OFQ9T82;X`f z;Z$T zy^B5WFu>p{Z0mBCw*2(3_KeFpeCcyh0w_fzruxJ_6jU$(|y6PgeBZXzPiBK|5Dq!4NB zeehg0_VQzRQMkjvb3va?LN!exi`&X`44~?RsDJ3*vV89(%ss+R{bJ;mBDUf*>y3c5 zk;LJV_C-0+< zhtYL|P_+~9Jpza!7feA=4g{5Kp)0^#u;1mR#T?g~AuZ~}Pg#}rRd<^kzl@bY%oYuvy6U~~0+s$LHQ~$iMfS52l&>GM?;$K8-NbU!VF^fluW1UJsp1JKOcI8YqT8wk4fL+`@ zp-=qp;VNFxMLb@xO@^dMUlFe1oLI(;=A!qv5F{e%ft&UkRk7{`iw2HiD2fCJ#Gm7$ zd0u;6%6C@{*G2G|kjo1cc4(3*QyPY9$wH>`wV`d>o`pqO_YT+TjtDZT5@%Z5Rvzed zC)E&>+qYF?i3-NUzr5Ag0I9+CuD%hw0Y6*eeKB8kY^ouvkD4RUr)tXc$}yi~AWnZ( zglD^oq7oNiw=i8hzMVPUX8a&^BBNem6>KASA|Z4pivoVo=12w%bSb9!wCqLpr3va3f=W8CPrQ@ObFCx})h-kzUo{H}(&Q|ESX&8$@jg=;$sGnS_zw%=2tATZ`fD=YGnUJsC4wqe^(0_>Hgm~7bD$& z*XH^osx^N^b=d`FfcgaJ_hBQ1ZSeQQMweL$Tyx7t(;5KKH6(DGKuCO!sL(5*Jx6~MXj00M#{YhT=g?{71JRWRBDJ!@M2K-V|y&SxU>ecFn+94z3N1v@E# zNt8S8`@~8(Mn@>tMrdXl9V=+`ePZQto%?%Yb=?^zOHkKc`#a=M?jb&#bFsVnjVP6(%`gA&4W1i^6xcNAcWE$;g4)RGRP?5ol&R1z| zQS=($r0eW(WN8(hw9WCe9JE`t9InVN>EMGHZR-CI)F%BO)8a z$h|7uN?+E97VOQ*j%d@6P!XO{)w`rh^qBSCN$Y3c8zkU+o2Je{O-VFz$9chznB}Vd zwY>SPYdyZzrKg|iVyBzU{MtvLHV>jD7nv(r?=s7r5-FQYH4+si`uelMhfUpLY6B6OZ1}PD zsa2R?L0FWoF3AvXm{7zVQM&MwhN2bu<}Oe#aJ2N^pi+SA!Q+Ij=kad16ym$%R|2WFgXK@Y zmn;{LmMl#MlfF?=mX6LAJL*{B%YR*%P#;r&r~#{83Ctg@j7^1L^%0%|F8&33KV!sa z1BBZ}1+hW5FoWguy|uT3E5~-Pav!P3fy`)DSOo{NOZtZnG9Mo>C9t}2QxRK*8d|Zx z<>OmIDLV}%#YvuXMvW8l=V#|v-f%#;+9VfB7v4tbFS>}5LTq7bFA$-80u%Zj6CdX zxJu1sP{zL5?X(dN?Fh!^@m8aYm2NvzI-co*%S_tWISixZT+T=PCQ^dj1c97GBwD@1Co-mO3LMW1`+@RypOC3y@2o0AZ-6lSbwYK ze-eVf7sN2q{b2n*z z3!e5@hoJKncmk7WXD)!S#>{I6)HqtfG{kSEyd)!}B+b}{wLW^jjg_~jO_v%&0 zPBV#E8+}S<8)CP+cExnit<)SkNX|)l78g-94yRsJD>{*rW)Oh_dG?WrsP~26Vier! zcWHQ`d$zCjRq8&O?l(4%C%YHA$!v*6iBEqGowx*B~S;=O= zuxX%bUt7hauI~;kbB8{)pvW{Lt_RLtq-M*NPTZZOE5ohv6%;VDC@9Pkq@M=*C#sR1d!7DPjiW99Qjqq5BKXC>th{%|$@`8&%#u~$7Ro62Ri z!@jZa<@UN@l|Cfw6Gw;AI4g8ItQGD{Uk5gmrvFLU*J*A>m!=@LZ-_?%wnHSWFpjRjRPf4@7a&syfP`2ofc`j00g5{D zTl|K_aRTkzCm;cB3EZZ3^bwX&amD2bs*aQ?u!U}iy2czalzC~OQmDhwRp1%QqY|o^ z<*u+J?kNnMsast0*iy-5HW+yTcDGW|zfFZHudNd`s6S#2ud|`{?uig0N0!6KBNG&c zmMIG#SZV0wDqI~(sKiNGD$WhK|60l=QvEGr=z||Sb`^`PF{E{)L6|TLgHdruMyMBO z&zPC@?Nu?IyJG1CWk&f(YD080- z5!9Py>=$Ruw(U!Y73z_z7=mT&OMYE+uyfOsIf*Fk%@kt6efLW)3~9~$=)@j+r7+?2 z%6nl6&(6bx6jUt#A*f*~277Cv9L#CtN`S}7ZJxuD9nQtiVs#;(jC-oZ(9wWjtoheU zC--~@IoYjh{=poWKV?}Lo4R34(cul;VQcRHN7_3ESGp}wyRn^))v;~cR>w|<9ox3u zvE8w4t7ALqm>u)3^gjEZUEjB>?y0(eSFKg~^VZ0G#~kAsYV$vjN;y^4A(aiyjP$Ju zZkvtEu(fyPFjLV1OnR72P~wOE0roH|KnnH`cWt%mXZ%yFygxPFY&^XKb6 z3?iUkK=OJHE-Em0@J1ZbCd!V{_f>rx4$txCRqN1_uG-Zkp&%x3la)67NuKk&Qz<;< zSt>X5DM$~jmoI1^RkFB#h1FlZbAfE+5wY)m$s~aKU$ysd8y0{lVEg#OpNK09nqzkpO3p4mPT8BrA{7$0f_u0AB|8AG0PyKzC>@8A<_E7Uvk8<2 zX|?cFm(X9A_}X1irP_aq<|{jK(dR7!CHGF3NyLxDfRWF8$NRnsATjXzyEp;6nB0NM z`34@mS6ri_k-pZBn7ljy&IJP4=@k5600VY9$=W}5I<02W8wxA|qu|a| zN=FCnra(o}F}wO2ABY07SA7LJ9ZAejC^=%j#7Hk)R|F!wTsgl+{Z9IvuKX`9Z3;*7 z!3@R=u8Oh*rYB})4As+9Xan}aTNaB}+vWrnNYz$Wf>{16@ zd_a;M$0Ja2`*1vLx7WF)SoSTIqwL}tQqfdVL{q~b0Axcu^xrunqpUR+!w(AeK#=Ow zszsv_%7A+(c)unU3V!q45Md6rme}(eHhGQiV}{ez!O{9fnJvHqCuZZv0;ijlc?uqH z9bdC=lEXnAa#O+KBLiT86UNw{sE?17s-yc@XN>d)Uf&o5I=l+3@oQX~(iI1Sny>;m zi@Kf?CJ(-(_N-*ozP}vdj@5`_hb6u$VmFtTRBVZ@3UKp^K~uguKY7l_IX0@Z>?@TT zlYCO78{4C{gQ#%6%T->V=3(AMgGPJt_w}xNFfrCZO#vB>R9@ifB{|D5tJ}ab+$+M$ z1W!tQSI)ilmSnQK#!C356|wC3m`d|Y@@)w_)`IXr!F6frin!|{#BU=}_RmzMHcDvO z14#h_?lB{sY@-F=+?LVgHk9j$$v_YV@2JjBPOLuXRVLd`O49W(-Lk;<& z&DK{;;-;MY<6?MIs-nneT-TjOmw)D|STUjUp5ZQ=C#@*1wpU4?%b115O~$DoPYRt?s+lH?c0;KBy_0)>!kxFUMX z;MZRi-(jhm5SYJz{zX}a`ksu?8NO{u_rv5<*WQTIu3-=K8ka+$v^&9p45RzBMJ1%u zZ=d1FWLbW+_JH=8Se&mT|05i2YdZM6w~24KI&WV}R0 zg*d64F#Ld0Kc<)h&&MzP9zFa0x%+%B_Z33!p}=7s5M%0MLevQ>=V$_Xi!5X=Bm>U? zjhXVL2ApdLo0-916$l3L1t(qz`A1(wQPX5gyLICU`UUA5kl1fN(Mh@k2bmyqVsww!Kx!!2`frUeAxO4(vOdmG}6EyM+#u@LW}0 zx8_!7TjqEJ>0cAiI~}t(NFy}k3~MM(3>9Vj)Kkrp6PSeez9?{_H!vHsHdc>!ZEm`Zbv*xkVuv~~0iud+y*ixd zIV&|fd7y;*;+P8=7~jy7qjf9ODM$!J1*Gm{4DrqmEHENUi|ntQq~?b27i+U;Q^;t` zXfXccO4+_01l42xFc`+7ZuV^s<{%S8Vsdib`)57r5h_?BG=N!AL|3njD4R+=fPTEgNbD^Yr_K3P}zN z49^)TDl=vb)iJO0D;Hg#)h!8Nni$%S%k?plX^aHn*vyj?(j(`67>IjN!?L%<^_ymg z-=i^ttymdpMpK?V$MYwK9U0GrnxaW$UDBp%ktk?zrmhr5DtL?#XnDQ3&s;wwTlvls zA2Y%#vKAF@{0N&sXb+}vaZ#G1+j!1qC0=N6`SinG@2lK1QBSDe$#dO=C#DI zY6|Z^f_IC34nLa(?^-XrYyfV<$56COlo$|N1;JoBkST>WH*>GhTNx?ugs}&xS@nsQb8%0#BzD9whSkDU^)$H0= z{ZKGKNZW{)W3H#ME~2UuDzcY?;t~;qcaZ4QzlY0{HKOYk;db{hLoFNSi6qOl-===# z-M{KjfGGg&wR1OHmz$kTHFHqdQuzf7^h9l?Dm`^~M%}Pw@2lh^}TnmCwFnUS_X& z`@FBgKdhD``F84ZUwGMEKcq_;9Xtu_a(FRE*0s@pL|3QHGy#}cZKT^JM6`YrOw+|s z?@Qx9msU4Dw+f#d`#3!Q@>l);_^X4<{=SBn49v)S0PVF)@Ww8fb!~( z;z#2tw(;#BdcQUaF532|y_SAB=lArV(>9s#r7|~Tonl#o0SE%^KZ`r3T$#H|=vgK> zYK0c-4MWqF)w*iHx8Cv}E=PxHM}7=n#;-C3v|AmhSF|$79u|{H9?KTjdLOIpW-2 zrWcOFtvQVvE9q?)bWd(d8gCOj)UJ4SC-5Zs6$$r7qE7SRuLcYNh8&`6oj zf**0!-x5>j< z#ap}$a>y>A_KFqE)8xX@C8h&S)9+ZRaS#;OK+JI-Hv{o`NAn4E;!h;N3NNmlY>~S<>)~#ViUiMt@-Y}15h$2bk z$kZ*kZCJqr20)*I!?aw=9<|m`lIOj`?C?l9z}CPl5oy(yBaG2Xge3|OKX1l69hIYo zj{vuZpufHs$KWwr!!hd8SX223Ka{FiNIPFPH{l56akGCe;8vC;?N1!3RNpzZONyB- ztE=T3yi-bAE39uQyUbhnAS@3xTkj{%46N_PEKCJt1Dc^7RiOFMdx|;+C#l@iSF*!i z^QBf|{bg3k^ghq)rF!#uEWPGKS^&smN-P8qeIAjZIm)^ZBk|O zuVd@86KKrBjrAk8U%snG=Q_R%!LZhR*8kON!tu>Hs3XtrpoSYsq>TCKAgNc9qP$L; zVn7ir23Dop{z=-}!GJ(5q8S#AA2X^0&&)i3#;1TPy8WpttSu>j@$P#{g0q4zyng;tbhm`{vZL=J4;Mxdu$iDs$#pO3Y^X zl9B7(qG@L07fm*Xs;k8dBuaFz0(?VjS(p>R{xRH4t=*p#W!A6ZRopwz|{|4FxETzcwplJ*%D4~x9= znRN%9p?&%2vL1dkt}2AXe}9;)UCUTc|0=J4yQzR)z&~!UnEvm^6${h<(zu#Xm#o5N zMe3ZYI%J-)YRjXd`F0G|_#Yhn!Z`vL+w z4XMS6;Exu-Z0(GBZ8MPfIaXt@XIk`N>K=OAQvDF_8@t7_MQ%%&QC4DulipgN{6mxE z7RkjnaV&WSsE$B6H6I)T?=Z{#4)=9=-D65-D590F%wkmnWJpnUWX*IJ*jSkvFD4Dn zEZG!8?hd;hsBst}R+9zj!AK@;^W{-AQV3-S<={|!{I{-Bw*yr;I^G372#F-wDg_{4 zX%xsha*hQEmt|GSNG4w79^&7$$e-Mu5koE)3W6l0$t^{2#WSZKgR83m#%kMi9fY7c z5RZvr2>&x;eP-|4yo^v=4F^wJ1@>!n=o&z4{-Qg#p+uPMxsnDV+2CPMkvs99N>bs>B^4r< za=anf<2itGzoj@K%_1Fb6a zWlqPh&BNg5*GP}!X zE77NlWuGjTy>MMRMtTBUN3In6kN}};`8oKBi_=(_vJKMJU<=3FHFWi>_1xFf&*p~M z=FBOLso7HQ&#j84pVd6xTA?wnK9RD7%A%i#O*rgul((|pCuJ7cvE4_6fdFH|6QvUYg|{nD`Bk!T4xYR0`dd@E_!1 zcxSn#l^*Y~fT%d5Xu|ktnnow(=I)tHVD0$E#P=qN=pN^10nRYM!%5!vFf&0?(8K9x-rtg;sfJ^kU>>k3F++4C+i zRmb6j+?{^;rss4nCO0NRil%AZCwU0ezh7NSFgBL^cINd%TwEJEe!e~?+BACUb`p5& z3x5H7^4DFjJb-$JY5#V6 ziJ?WIU-Pg39sc%v8Clr=5g23oJM!>PGvj}0jeYcS|Ife}^M3+kbbq5`LOzv-@FqK~ z0-_DZf1(XDUjVf+=l7d`*2do6uGH=i(%(FagQs`9ykB2;FX*;x7CjJeZf7_TATk#> zpXwW(FYA-f$_r0Fyo^l}fC&tkxoQ1eW(S4VZ$a4x7;M6&oCvM`Pi@SdvJE3NCndC< zE))hG3GgeEe$0=Vo2i(|M}yM<=e{|9zT2*KS;R6Q&o|pYm|9d59~I}f2iL`Q{PpLg zdOTJLXX&-W$D9~_QwH&7luv8B2dRAXUW4fXOl^_XN<4aNk@lML0S%hZh9-pm@q-;U zjb#Xa>}UxA+-NB^bif_+QvQtXAS}1QgU+1N&s&&%`AqyI(xF zFgKP1U@xpGrW32uEg};FB@0S2C`MHZ^geoG;{mc?D&tgz2Sa{7??3+eb-@~Nl?B?9EHJ}@1|KkFa!ETAj9C32Gn|Rp*Qy)x{6Q3(i zo3kS~vKS8^ium)2e7L|x`zTL;TwrV;cjlsTMIyhzBG_e7 zT^-dwt(z&wp<_!tT{%hXD+!l?_oGu8u7c>-R4t&Kpuni=?96JLdXy5mau%$Y=7?c0 z0<7R&vg|o|>sfsnT6sZHQQyoTN#BuTZvcO?<*xL}H4=iXYiT{OK*2rcsI#8TSs8B@ zs2WFcCzC_)A$>NGnA>1^NzmnI-qX8dxtDVTnRCP-ymMG0Tc5A;_vOYG>(ClcqP|oe z|7aRJug;NkJ7oX9JgdPS@{at`5{DxVRo$=+kL_ZW;Z{M|fWZ20%ogQTa{UoIQqs?p zT-C>!Gi)v2i#Cc1IaTanMn)W|uED8}VCSo{s7nx9I&PTA=Es>J``Oq`f|9V@@}z&` zCg%33O*Fy)3J)2Mc99d6-9r;l2OzbfjEM`n61fQbSTcIaaL@CC3>Yfbc*$SSUo2sZ=5NASDCWbVNN^Ym>xWO7W$$mrw{yh)qrSXI5fr*faH<^ z`op5#DfNsW-N+ze`H>R{!d1TNm4d1Kt90t}wC89j+vuFN<_svrXT=46`iz6`@ph%G z%1*AR^5xS{9>wW7!`-;(-xyOz$tLRFo{4?tNB(2?H#!jRR1z=R15C+_73K;+L#c^EjCFKvTFTZBf8ui;ZsIC#5A8(E5DtlBC$a#vZORN3Rb8 z(?|+;A;DHSUx|u*UFa-%*LC3oqEPf~{jU=GxA6<`ga6SVWB!-^81w(X{+Mv=fBR#} z8xl?qr>^>vvI|dTPpS!knT5?h{{M4k!Rg^_{qp|L%tGJY^J?+mGYhvLGYh(anS~X= z%mP=qO|s$>fW394Q(J;Yi5^i)hYo-sj`o{i6^ye4S%dT96cgO9ibu!BvRfmjn-p%2k~oabts zURYwjI2r)`Wd}QvZsxp#+!e57poJK>PRDY-bU}kj$sMETa(sDAIzdKi3Fsos5I8wO zArku)xvbt}8_h)GGbOCn9<%+vdnjB*u+qisPio-9u!uzkAEDN z3G5pwl^yhAGi})a!5=F1YEd?=q1r5^QMD$NMPw{f+zH3d;P7IHbr(Tx1;x%tOWn}C zZGo(z3RGYQG}q;)tc#hs4U=((8Q%>nJehrQA&x1u!4xAw$~lVaZ6s2Hot^e>!43~M z6Vq#k!*8OlG;fo8^al)7Vv?7&Z6k*Pq1gN?IP67E7}*%Q5^wM}5Y}0njs*Y^t*I2# z`JoePup;HD%UD=zS-$_&UcB6kC0#d0JrKi`c)ltuWS}NFk|G=w@?7`=6cNz4uvAN_ z(oWLWa(>qf5K@w({tCEVwg%*ojnjnZWmeF^g=-ZRM=&0Z$aMlJP5C9p2_B1Izr4`GOqemONz)UrRY zqy?1@%hd!x#LKK41mkB6g;NkRKakhwDCmnWGdc&_oZ!FgQiyhZcvo`#HRsK z)P&-~iP4Vqv0jrge;{$Q{yQi*suT)9mAzvj>rZsU=C&t_y94Ye#NcNMect!+e$p%q zUN~dn-EZIqyQB<_xepgj6UGV) z_`KcqV3>VG06Gk=w+Fj7&K!%!3%hk!*E=iN%bD1PU#BkQ!CJxZr<3ms3vyWtik@|m zGkpi!vu(zT)JinyUv+58++dQzCYYoa(RFP1ShONfz5$4`f{ZmfVn>h>IRvz$t?DY5 z`i6kt8OBBU`am5W@p14^82z-?9DF9&m1k%6$G*ts!=JCkAD<4KCzx-4^Y-D_zUT{y zYRqIsZ!EOFasMe^P5qr%d-&7Z!*7x7m6;rHza}Af#~0njs_1*Z6CJ#^Lv61d zw(_F*J#s?dQ&X|9G_J6xAdr!;LzN^`!dr2>gDk9qVAid^US?~mFwJ23w zcC&q%_dBNd5_S3g(o>9}9YvZJh^>ku>S*ZYH7zZ%s_xtdlmmi$=zBI{BVz3WnEllf zQ0h|8aIib5xqy`I*#qhfUr?k(!geHEOZ<6p6vSc)W4=JqBa>|5=8gCOpd=3_o@z59Kv9MFYsUkbq5z6IX(T_p_P3%^5kHB?;QmKZGn0uy z5#&ge~QzmV1_l=Kmu zx~o8OLbr0;UVcWPXkZWFD5!s7UmefzV1><}6DlpAB+@$8hHakF*LCh-i-^c&_+oF( zgqo;{*tRr+B+*G#qwNXu!|#406_K_P134?d5nO1Una&93~t4?(&L zG%vcO1^1|Av|Z6%Qs;;;w-M>b71HjCvr2>n8hfm?%L00S`#NZeH1`2S7`Np)zTyA5 zVOx;}+^{Wt+_3F-Id5Q|{i~+_?ezi*4FAY_G5;N8_@}1+FRie@U-GBaT=Dd^73Fa- zF`EIPZk-k2R*F{3gwMmYKfgUa?@J?keA{Gc86KBNMi>ze2V`vy-*{hUQzvf*5p=)~ zhro2O_n%kw{tylb{vsT7b$M}-yx_HB0#x-c=GNi|bBj32>Cv#H95EY_VDqbprJ2!3 zgMmdj8ykRsRci_*1V_n&e6^z|nx z&Qp!Y%krzE3*PthtE>Bjy4mThZuxVt#iP*dd&;aW8U6{cUU6gyhoV2sEmr_@>zh&F z>dk*nsOqCG5(i}#VX=OaqyGarh?@dH4uV4r04{JK*su;w^YAe|VX~o{Y9uTv z`hd4G=p?Id^EUt^mQn04Mr@)y>(0PxFrd9qB9=;vyn+0X28BvqeiI67b8P)IF(ra6 zR;p-scqe0&zoJDIdXjmTX|`1daVaFTOo`);?q&-d4V~kwLV8XE;B+G`kbIJ0BkIFX z9WAMLR(5cDh56_&z}s**%Mvr&nXI@hj*1Cm4e2hyBgc?LA4MX3?X8V4#=@~+pU+nT z`5qwcu7nJHk39mU4n49+4_80J4HCr2<~F%UgCQS3hY4|87tAB;M*}QocfeuGup391 z&J^t1!VJe}YWOwK7hi9IEfPZ6rA}}@53H#Zm?wGDd5Eb)C?Ri8zsXMz6-KVOor_${ z#L-+crqDK0;|22z+8{;5p57-gC7br-uwC8E>d7hS@`X@2ZH6j$23$NiR+6(8PB9)B zhg)^ZF+vda0SXE|64yN~A&GXrv<^cokZ*SH#D!Mb)|O%CRCYnuL<1whV;Mtuqj5t{ zs7%|1NQB!#-{SiVB&oWNjtzdr?f&Ss&zfVJ60ESn+$5p zu_a)DMHPu=EnR2zv`5=FMbHXk}{g8rU7I1gb^XTlwQ9s-yIij3o`tItkD{mPHhYDP%3TZA4KRaLZxU z4vjUJ5RblGGardox!GQJ2Asoov|&CbNsm_1Y2$mJd7}xN;H^B)XwQIn!8#fwk&IzkQr=$UiEgWhuB~S$ zh?t2}3rb?<#78ZB-?Gmy{#n882b^F}y*(D+=l`zYzORA5oB=>womt!mYdOCkw6X^m z5V8h|I))iDTsRUBN-n^iuWbElYT5akw& z`}XkxJaN_Mo$_3Xx`7W^8UO} zYBd@gv<+~A^#q(?ng2S$?g08?^Hzf)08f>O(aJ7~qgeY>t;0e%e-$kxgA>pB+6NUSo?GI_%^@;=)=tC9nUl&N zB_#P45pyuv8K^$Fjd4fon@M!J8f5V-{sOC_js^jSv4aBVB((({#lDJgL76EUB*TU1 zJ3eD+MkB$jGQ8y%gZqe(fd;*&04WOF1tI!sh=!BUMq8-M z05k3<_cEQ|`nAMFT>f2OLv9I?M>HcGJ|b>*x;s%YMfer-I$z|ltgmBMs$89zb7rBD2C-=3|ZB6D}g;ZE!NQtTgwE0x5)tTsPb zr3cj_8*^&7qF{L$$b|=*_(iIa<{A0o62n8QUwf~|GUy$rHuS*dIvk!b#d!jpqw>+| z@4{<+HRfas5k3tb1~|ce*}f3XG=%Znv7(}aoLVyWzk^;b!xzK(B_qappjzsB$Qjlj zLWkx(h=C}I-Urc7f5U;Qw}7+gKK)aLngHF8eInQw)K7MoD|aBp)ud>-gQzJYuC;DB zRVkkFNgX3Lf@Yv0EiXR40wzNqg^vxikTq5)HJdt2o`U7<#6jg2vOKmpv=%jPBg#gS z(4Ny2nY|VMt#m)>T%d=sBxrhZ5oy#2CZkN~(GEV18XD~lLz;^^P-&MX=xO$0P#6aM zcD9HH?zh2ucWwKLYYD#>nn6tujg)IJnO@zsT!XL;yx(NCwo3B0(BVbJr)u*K%1D34 z%Z6pOb;?qdWvJtz=YqHlTYBux9WXiZ(8@ne$lIYoae%bR1FZ#55&w~&Dpqj$^DA`>?ZK*Y{`n~H#Mk}`| zjKg(P_&rHCPWEa-SHfmk2HX3@XTO8~)3I8}yhqnfnXPot!Z6X4IVOBPT3&m3#twk< zT`%&=#FS&G)mJTYO&R6Pjx5W!sD<*8JlhH`_}9y?KMMTEYhY&m?@S{L%ioEKf1Hb1 z{>T2=Ka;%j&CBX%L7PM|O=7EV1_=QMY}8V)GlLLdqU?Aq9o;E1H4%3$riWv<=|OBe*(Y7R zaOzKj@7~0pXD8}&R-T7a@~3wN33{S`K`mbSzT4#U_ojB1t%k<%+#Jh9)Mx$yBm`0x#BbL? za>N+AFgG-JTOit~9CssOI5=Eq=)K878l;eMbE6Bt6)P$~VraRTaXD6(VunpTO2of6 zy;}j-VZSw}%rA$bYi&lM<&fzUOk0of8PPw_PLW{BHcL>JK*)=a-iD#6+KG!=UxKHX z^%rIxD%-L-vNW^!trE+kmZp`RZxAxKZIES6NoWt{gdSK9_!g__N&SkaS9cL?_=;!h zt$!X>jynA`UN@zFR_!;kIg~(l zgzEbADobO|x5vvg@~6kdwJ507A}2x#k&;56JltB(Xc!FxKH(0AULQEKIw=nGDbalu zQh8S(6)?zI`GK>ULw_-2en_+ku|!m*`iV9u@A*#39s%VL2KPqT93M z23OhH^v8^Z08;{X&$V$$i35UewT#lwpZD(UfZGYOwo@*OiiXE~E9#Vf+5T$Ms z^>zGlZpXFZBtvN#Uy7{-*Sg9UJgN9P9NfO347a4w44*(BAv`ypc^XajEkKCY_AYNS zUjKQbTd!F@{3~(Wu97bL%%t}>2)Y*1 zwKSnye!lw05;PqIWoX;US9&q>CVB8n$;^EvRBs@syT0PXX!5(!p1Fgnt?iys zQ{#9W=l1JEQX`I<;HD4O{>-@#^P3xkyZuv;J5*~7m{hP3PeSSMeAo!e(DZVNrKId5 zt@e&-QYkZa;~$Zxe^bBqKOt;1{q)Xt;Q;NTfH^{omh7uKt3nwT%JD>1Z5NZW$!ZiC z9&F!Zh1U?&@m*}|rNlZ10KP|Ew1B}+Pyo}nf2I?@JZc65rf<#O!Lh2uasKT9{6{GN z|4upI<-Qe`+v_^8 zS$8|nxCp?mKgmzyFTYPvgtB;hViA%dXHFx0obJCdfBU)q>-;LI-YJ*hcxTaA?0Y;u zV@?PTWgjf>wSA!}L;FT8v!UNuatSGsC=!ApBX^%5mPj*CzbjBr&d zY_Vf6G7FYKLM+_p>77thBBR+$fposiZ*FL;c|Rd`1QmfG@^GWD9+3vqHs~3$6mPnb z6ySb+hC+)Eq8```Z?R_}8%ytx;aA-E?TI_yZO6a6 zOQJZJs+_1o6lQ{GqTyot=2y}WyKyH;D5I-Th8t0-Xczmvm{cnFCYkL}XxoFBtWYt) zVvcA`h8Hv+o!?;5vCx<4PAl_G6hyiyWDJ9gl!Lr{B=7~J6fs@t+=4sJpR1}Pv8v4X z!U(x2-6&av@P)rP%z~gcwo1*`u35?jU0*rFW@ej5s;FZXTzema zW+t*U`qTil4p;2vQK^XkU>ava!LYiUwbzvyRRh`NoqxjJs2 z!%0U$sn=rv$W#hW{+d|?WXv%;RvzQvzdqG}TV-ra|47NO{C)HLkB6G|f2sULsf>lM zGr+AMP}kF~&BYrn0~;M?O2X8ov;7o3vc^|f@k^EU>8jn^mf@fxTN473LeUjxD*og)Yt7bYOBKG` zD=&2;_mQZeU-fW=NgJsagp4Dlbmwx>H>_u{ zVixuaRCXcco?J1hH=8wUppn#q;fKj0&@3(v@E$zlN&!1!+&0j(8IvGR(06y zUPb1_?&wpgz2{nGphSqrt=rel?6|qfOp}flC7g$Ffpw5}$fk)`?ldxTS9iKjGv~;x z*yZ_5nmC8fAz{Ia!R9F-q?sjxu%ZozP;ewj9rG+S!mNR3(IyU#+GkJKv?kTRA%?m= zAGPh~`6)TqfP1It0)Hw4MVESet5xi}KY{C!-r&E11aZP}|J$ST=K=T-Ko-`2JSwdJ z(q>@&U)l_S#;*-=3o^g}xN!q^dLY9=0*m}c*}cKW7~7|BGeV|54mPZNecxwzrRb@d zb=40+(lAGZUf$^*KjGZ@dVj=^v$`}HxC(dhZ18A;==r`&An)^R{(O(RntA1;_53!( zpZ(+g2Rrdx<;~r#q-95h=j&JL#qr+N6xxjq?ZGwxN9|@+J}%E0WP@qIHIvd}%tb?@ zKIQ5>JddHR@Y7YR!d@EFyzXEdrD)~AB-F=O><656KE7gIfSI`U-XT#{CBJfNT_*VyrP_c$IsCYe>(@tyhE@$vTdpm_CUmVUylaNT;SPmk_;{2asXS2T_@ zsNoA1UEdh2HZzv4jW^6>A3Rq(mvcu(zXrv390`UOUAK4+6#fm9Z*Gc1aAxS42DD$Sz8$58u4Dx2jFJZi zTk@!MY`sV-iYh4Ymrq$g;$$l{@!Rm_kmsUy2rWnzLhA_e`y4kGn2L;pHR- z)h(RGGCCt8-xKYoB;1njEDeE*OU-bsf>J=jtriz9!-8xu+WE5hvYACqoBG~ z$|6t3JDAb9uGX-_UH&rWuF0ftV8tQVjigLl65>WGM0a8$n&o0?_&5v<0Y+4GMP6Ux zhxl{wAe|G=r&{CG=e*=Lw?IgS;eEVQ?Q=g-RA_)lVmlzKlCFXYlw~le#{ z#cXq7=0)-+9pdv~YVEV6fmY(ALZ)0odr^1gslms0yVT!&=d39;1wEE|+nO7!+8ivI zt;ja5A4REchV8!~nZb!1%_9+QiigWd=xMQm%};=N5!S5AdysVx6-X0DfsQM{(6I6< zGBzGT@~fQ)u86?39Ai^$6sLV28WzE~r${(`e;5U(%8pp_Pc9BrgMOMH>%cLaWQd(m6BAoPbbiv?wK5-rGKjF`i=lE z#@&YArs+qbJZkPubqmGr&B_HCP=i5jUX{}x>qNMG|Inm4MyhpBua7yqb{|_N zh7Y|?7YUxRD4L+xGC@&VTwXJ)NqGD@2{p>Q4J`;xPs*pxKZiv2#R`~zNb?fB&z5+( z$=G?~!9Z%p2(|^~v-V^%31-m2gMP>spQbI)rBUh%P4G(JP`@`kGyC_gbl~`cG028d zmz0X01)f2S8Fn7hQPHP$cUq>9v1OGh`lr}Y0wA&m@AzWfO@dLCrP;iO-GOZEftqlW zUdowDEX(E*L;31RhOzWekoJw~VOp3?7H50Hm%V;yfUKG!tL1^tXhdy}#cq@6#j)z8 zzQO7kpxr868y_ohrYdQHt)5wpOD#T1_0&R2Q7~DR{R{+3*3nM^CkavN6?oyg;YZJS zyk4zn=MY3}sNK;DOC+b1mkSXh6ST|~j5jS8q5Ty{GbQ+xgH|2!e$9rLX>vCCnep;H zgCt6)DJIaj@S9D&P{%Ju${Qh)lH-J-Yx%S*cBAWc*&%V#2{8efS1kdGbBMwhsC=!Tm?OSuU zR=fL_4M2@53N_wbnxPc~72$uWH%~k`Y`G5F7T_OD!FEvz={P%(ZAix6}|!=jCQ4kM+T zmI)L(#VmtRM5k`j2pA-))Zg^PX))%aLUY8Bf+HzEeQjX5X_qWpms`Yicp-0ZutpWlJuAadJq#sgwOjAx<3o4p>cm zQ~g&;5-qD#?09lXt8bNz1Q3Bv9W1R26z0YVGa*gR#+wboFN71w@xw!Ei@#pIFb3Gx zt5h6Kw^!(%_!|odW}JHLfl}C%#%nY4+95Gi?%%Vc!;_IF#bRL(5pi%7K3~mOqWCT> z@oD*t&_-6$zTTN2ZHP7gIN60RoKaDLT5tGbk#de#o z;Ogjie!(nA!B(Q0NNVZ!g3AGoMVzw>GN)^ChnHghh&c(3LKWI%@25 z+D@*luX8orL+fvy$U)?OSouk+vsX67Za$S1Fm7X&@D(0dFG!tqUPhpvTW&5knZqdW zw+1xGGH6_6z&VI!qui;dUt5HrAvtzbT&&){&hN}?o6)%A@E#TmS&LHtG-A4Q-J<5C z>a(I^azk#Z9_YEBBjH1&yck6}d;!=EMd4j2uXuG6M5WHMg|D;+p#{N{lM-L&Zi9NG zf z$#J2Ls3msD?*O|w&9rR{YO+~DWd8P_s3y;=`=Q`33vb4i zSQfD%3I5}!jGpA%V-8A;N-c}S>jj)vN{qv?!*kye5@?D8+T+?LPQapI6{qVo; zu^-o1u_9v5Z*GTEktZp7J<2Ih7u0;jeGif`k^$k+UL$hYx<9hS+%^@ zKEoqwgjGRjF#MqBiJTd=qQPcO;Km9U!4+KFj3JA2WtjTi z;$FbRT!^#hm&_4FZ>hBA4?b<9b#O%p$Rz zEz|zCGyi|V5dS}7=kI6#Ukw5iJ^jBsgnvXD|86G#7eii`s#wLQ@Lz_!*)@7`l^R57 ze>RO?HZmZN)J;S(^qy~l+jmY+mzh}?No?w*DT#^Sb)1hnn+(t`XW5YvzttIg)GiCb%2yjD z^pNoqRS*{NQy}Fp&G1_u)cS+L({t6^t~ICZ*8aqCLc8=);bj7E-w*Ar;sTDopyYSE zq9(?7w~TiPUpDqn>_s=uvxMenuwdESO~OLa@tKYLf8y26jb_I-%%g~{0SPnmNTMMQ zL+V-xp>T2o)YdhTjk5vKmyjrPM|gnWeY~3=3}1NM0Ua6DspT&s?vUqY>?N2tcV)6z zV@;U7@>^qg1AoB@s(aTDR1GMJT9f3AIq=2x@VV(?OrXz8!M(q)H_qnTbm4fk)FKu* zAB+xc?1N5!qj~5_65vPB;EWmuXPC!#k3k`2jBmj4FoD=k+cn0F?s78rKY<_~V%FbyC zs?iC$O5m_C82uTs5|Bl}5Nk7w$(}`IZE(fkXl=cxbpVKWHm-IBMhMmSLGY8~=Vp*y zI0Zit){)b#gqL2DtIK#O1${+TCYB`-2E>&@`ep?dTi1qVL?o-G-y4jy>WChVswKLX8-1wNG zo=10yQbrbBwvNKHgarHw9aI{_`$#_Hh%^=+hpC7a{ycl4zKP?YQPo~fC#B?WoV;IO!`r}Z8Qux_iuzrirr53W6${4~~wH^lLy5Z={ zCmMdzKt%LpfZDyB{Ky_}afx~H+iaI3gPtxDj;Rt0S z4hhRRb{n=Xgi{B~{!YrDDtu+2i5oJ)iSuM%5 zC$WRpT3-b&VjzL5oKWLf+)=*F?!%u|7l=Vwt`u3toFg5J$CQNcHu%VXK^PlH-zxnX zu)_l6EuB2gV=~Y6NcdXUAC@)F88eXlOeDUP}@a{A-nC z?&kI-S|ShT{C!+iUtZ+=gQoGLY0iN^>x*or!gm=10riEUe$Xr zy^(`Lnh{zr6&F6ySSsfXgVpq%AOV8r&OhE)D@PX&$kFP?YP~l5BZ!Uav0kbVfs9I% zo`Pm64vBzm5L(;91=S|@xF0Jm3;D|PeK$Q7s``9`Rf7vk8sTfBV z2b*RQ_Wl*(0y?95(KL(+W-b6F8o=}X>R~jD80$a%^xODP%5u*$f93&yOPq67chK~L zE({z&ov=&?+;bfGrJC%oCN86ycPY@nLT7^05yfW_Ew=F`L^|)guYtm(BiKn3Of^L&71$FL#dVufBWh5 z1;~D-_MfhAmVf5$3@rZ+HDdWkp7QS^^S}7|s?;ZN+ubs(N({VG=#0k~Ax}GVr42em9@w}TLCa^;sl2IL+ z+1cAeeSYrig!FvSe|W=_+3fa|eSD1cz`=g9CVb!Yug>(tnTl?oR^u~wp7pyNEH=0b z=L2*hIXAH&dC(%( zPZCIx{ur2RsVz3)EikDCI@uvj6&!g-Za{wNCRFEu8OV6sk7p*I-sLRhWV^@fzrMd* znbc`UzgFU*d7$1M;^q9r#mx!HN#AY&c&c{k(YaUSraPnVYTQGJ9Mf=({CT;ncJj;w zO<-iHyC*|eol?MA!4Zig3I6U0ny`xW-JLz-lzMO9NUPZGIc@TA^?K%(&|D{V8$pJog%2UC^{P94DCCJY z4rp^8I{~`5ca-kj0dnn6`l>1DXVr&s9!`yrv4jewUqa8wT1k8~!65=*`xXK}jue|s z>EwwMYJ=94JfFD+hVSGFK(oS*?3r42Wdr?{$)cFj?;;OGt~1*Yf^_VxZJwK8FSeSAz){*G1mO69oO>!{X(}2kR#)=wpw@ z#e4#NUU=qccu#-fTN(2EQeANb?cd||(He?{f6yJf+NF+hXI>~Mutc(nzJ{!Jv7wcu z1nKH-WCTyJwldnsZBNs|1ww7!7NF?hq{2Vy#XO0{h|ZJRjC%%a6GgmH@iezUbeD~d z;GvHt@d)!>Z!OZ-)P1Km9lRkB{0(4X_1hiEbRH>`?xkFp!oyc!xydZZn+;Y z@?b@|Sd&Lx8>99T+!b@w#wb#ySL0^rA_5VaL{Lw#R4{?G$rn!t2#gmJHYvCF0R1;% zwGJWuAUZ7H8woH!;Vtch+)5XCAubaZHTIIDW3auZI9_uV-tAJe6HmP`0Z-_*K$l)9 zLgivJ>An2UYRaW(`TA zOkTcAowzTKazEv5;~*1O$yP_^$%0u4F*vNh{R?}o=8GDS7^;V>7!!b^j5-QH=1`Q~II)vedw z`7p2IGX$^By(#?+>JV}X&`rxzS(?O#U_jCu)~3fvhn9Q}j7_R(gQ^8Gxa=C+8o3}P zEe*>AVWrAUwO#di@^&UmFF}1Ng=5xppo8UR-^cE?fau`;{!{~dJs+SX=gYR3rJ}iy zjKC+>Rch-#@F$^mrPiHgtA?@Lu7jCZv8HMju|^&IDm`IxqR(*U{JXU|l9jvcyp$!; z<~z%>impFYWVn3ePhZ1UCa0TaPtwk3-6L{vB>lc=A#$Bc1SjR_-8sxS*u^66^f2YX zd}DT(K}Pn2TcSW5VdT%&t?Yj3N-4XX|$L8XjWv|yW?smvvOD&1aN_u|nWRQApA z)=P~v7?59k*ox-$rb*qUg>9sV(ub9Ew|X)q15+El$c4l-dP;ATz)V3G^(*Eiy8Yuu ze;g(znw>&R7Dl#B?i!u%EMt)Op1Ai!SkVM(?8LIJu}AMJjhl)G0W-_#6F3T-Gfjv} z!j7+uX!us9RkFvm=hhJ_%-Atbkgtrd-%u__ZA4TNt`siHsW?3tI|b0Bo=P7hA;Qf! z-|EYDjyT6%=*Z;d#+RD}?JEc=h9$CWVh@EGu7(~>ZC))fnhn>^%RDGeyjvPK>Txi1 zW9!#wJIwASlLi(#i2&9BS1YqY9KMLmLhNnwM{N#B!>d=rdPlW|7uU^uph{2P$Kfg! zry7jrEec!=6+btWUM@R3{0LW+%h?Cb6y`{Ot$%Z@$3`Nv7LY*d47nj5(u z93VS*b8$>9CBMo^gxfs`r)u@|{nSoqeooRjbiKLne^qQ<`H}lTpjK?+3o~upD`7qE zMIo4ZxY}pmY9Y|I)zdQbjcy*X#d2;94-?oLzMn#s4Xv;s8VJDELYDWnUvnsTK`3Et zhcYnjw>T}W%A1cuHiwKrc}$$M1)FQ{O~qBOE7B78$?%N$UhR?HENcWd8{_+tQff6v z?39_b#?ki}APtJyNPrZ$K3~j(=Dp0T6UtWbUe^?4eu<)^X!;K|0E>f3>!D9PMRy@h!TjD+gt&2YD{s*wFNGmr) z=r3BYnBUQSkIoH2SbE&>bTOaR1S&{ zw}}Jh3wx10DKB_UUbduv%X zN1Hc4x?edrEnTh(=f-L#*fQ)hCniG&hBxe%8i|*(dl<7@l7Z8Rsm-IJ?g5* zUJG&5neP4$^JXth7n3hba7Y^=J*f{ck20(_AqjlJQmdmwWiV>_} zy!=R6+bwXhrZ6`dUzacn2BKZLKR#%`Vd_rpW!R?}tR?77Yw3YWSbBf>8@M9SeLWm7 z&Ld!Ev%_Qb(ThAoC1jc&XaS4Ol1!MLZ`joM8&dfBy+)(YsduT#ZD{fUGqadM9cxX{ zNEOBoPl**kC6S>iQ0Gz$X{9opp~YoujT;+@Qk)BS0uCiXUy=Su={&~oydRH(V(2_U@TQ0^ z09;R3h)09tn%>oG^IV?@@4Qke5}-L*rV__T`)dw+*C7eU7YaX+9c>i3D$w71J`}5A z=8ZR|vaSz>wk+kuDSyMC&S_u>qV}V(sw##<=cF4hT$RL?B92dQ%8f%Uh^*1%AemPH z0GX|VH!>#q0ER*nO{UL7JldRUMs?&9g81(pM#Ka#4#yaDSgaoXd z+cxjy39J*Z;#O((we7qBWS}OLURS!Atk-yp`W8}pQTUKkRGl$fj}o+HZJR`f7X@et zgA>DzZRRqr(S_AGj}w#{@!dn*_%)1?h>^8RK~gq7!mqw$Yf@wR6fJjcA|@r5_$d*C z0st~Dr&Mr?OPA%>?2cdx0N|FSsbdGphC`;*-3Joy# zN?s?bHcoA}uo0?dxmDA3L8Y(Lq+G^0+UG7*EUgeD;0@_zxIV5%NRVPXw|F3M-6&*0 z41i`5ou}9gh>2yYyqryc>CjJXHZBsso42*WDF^CTU~h5S0K^WR->svyR=>Swj2ten zsQcGx9Lhx{;svN76~O@RFyVGQtcvDM*JA@(r$z1AF&_`T>}8kKwxwZ))9S2}aj`2z z7mC4Xn|GXoE?|!26@K`oQzaP;!NSRLV!{+w04kQwU=f6vRL5>7A!dZW?Pe;zN-<8B z@1q79C~E>3g00>)9-aeAZowYlcmcdBSAd2h?TS#)I*lDr%*6>OGN-3QS4E4BfhU`; zXWbmK*HMYDrjpQsle{+4;zttCwdKlL`7)a9akSfXgDKF2>s*2WDV zd+`Z-1#t=p3drqEVl;u_ zGA!Yys-T+-F7B~2G@rj;q;0y!Kc>yB5$*xArJdJ|n!C6v4}z_=St@QP^_em4)L)Kt z-*x24WTsr!5IYq7+a0A3i_WZT{sC-0OYWQ%p71114bG9=9O4hToHrD@<=IvQ^4?4) zGgCmRLZ;+g;zYuXQ_)TD|#z_IP_ug3Y=|opq|7$M*o_@(?=+E`0PJc zMi*B`PFAFTea~pS0iwk>i?9@6j2?F5YWz+~4fg8810U=Q;e*TB#dz?CJ1@BpT`%5E z*;U~bCBgr~{KY*kBlD#}SSy@;%K{_Er}N|3qmBae(grd))<@?DTVQu!5r&zJS)&KI z;)@b)*s%}xC)m3)J=uTN_P-1EU-g`UgMs;9wf#RF@2vle;>|a<)j0x97w8^;F>Lc71X)-|kF3fkZojZ+9m0pnj@}#b7L;l{&&*D`D`7hbjDoUN(;a^DhO={79;N zJmIP%eN|%%LA($QeO$Idc$3fwz3gwlrt-TG*_O66yTeI5%*Sfi`??of8?5Bh?aOfl zMvaM!U5rI%>h9~r#K^+_;k{YiIvDfSc4 z@%K{j8L9#Z>=sTP#ZbiV1m>uKengu9p+E5 z_kO8(fCNR}pmM}DqT(W;`yUn_c&MV|mhqy-sN)bZ7DgF9zl{wZXPG^&Bk%L98}rquo|reXKtj5O7?3+v3;D z!RRTF4#vmH^~RBBhQrJ0(#%;Flpv}!+o%)-=kxfpEf6fD_#P8_`XfQc6P(R5I-MS| zCqR~f^)Kg5N+Bu6+()$TUe%3W(FQA#)6?}Y3|glr@#!Soh8nqz{S#T8DVtQ!ClLDo zFeD@6WnA$4nKxV%`h7H;cb{dtRj1C`ZVM(YzsYHNT&y+PUI0MRB%U2B&eh*#KYg`v z7!r%dHyEz$;h^Z*G=whT-i^|=(ai0Xl zxvn}_&F^$Q90rVfrSgA(y9R183w)D~I|?K%5w zz*Ue;lpN_&=*DKjfDFDhi2yITssLw$)@4yXglh%Zg)bO20b^aOpJ{C9F(T=cItgMXCrNLYAf;Pq)sY~7^=u*JvnEPrQU;UIJmQl zGtD({7$mJ#p1HUV-{8-pv>ye@*{c{};pmmg@fjQF#Id2b_;Y{@yVI+SA)hU=LiQhtj=# zEY4?;#|u}d1*MxScdb`+h)B_YGQIPZ%Snlk%mGPK^rFXmdVe{5BdMOPWEJk8S*m~j z4N=*M`ra^i!c4b`sl1-6np%*_I2!B3rFlGad%CN@Hxc#)lRFB0W72R2!zVX+@}Z&= zl?NqN1dsm!!{|#HUxEo%h?xl>w-aE(XE42e{{k0E$wLUKgiw?thA2ECh%8TIW#nOC5XqX5u_TJIo~t+VQl*z zc~+l!UrE!g3r=#5N+2Zv*-85yTmZN7cCBZX)YoX0ktDhqE583USSRQunSi2(4xlhR z4?0Tg4AUzZ6hz}qn#BC$1K6p!1??Bwtor~lr=R*mbyp$051tfDF!%9qV0kDSaKu(b zGEW@i`H{N9;~-RG+3*9UghatXN~mXT3+Hq2Nt4#}zDz{52i;UD-&t85$$R|{WI#tT z6GiRP^@ypp*jC^4-DT=NM#9udpNcs-DN$u17LIt3HuYx$VQxR3uc=e)d67bb8ER#AS z)`HvdJhm!%4#e5BnZtXnyZLBH3vf?~pxY+zUI#7u!eI6JuGf{!?dogK3NG~ri4jy- zK*}QBd&5CO4QhWTA!)jy8wuK{l#4>geyU{5{v5aneWWw z=+h>Yu}naJNCEsbZ?{@!a0ZGpkWJ*tP)-+!H-P}H0OFxGCGr&$OXC5QTYxm@H+PQX z`Lc34nVy@OW~&=5^c-6O+Ds>$mot}?UZPDQQv;=$TablLK8+fPliU@Jxs1|TWtld% z#(}ucPGJ;G8cJj=VmfC~Z#5w@2C&(d8K=Ckj+~$pf-gXURRj@u$pNqC9+ePmNyHzS zH4D?)8tui^{FpuDMaUqJe~$?iWN0w9f7WQY@2_s}9lzK!JO+{YArw&pmQoOxQFtpl9zsl)t? zCTadupk4zN%jY(*0=xu+f15|TJU}MinYFq4yC*X$w(&5#NxGBgq#9KD$Q5fHJbq%qvoY+Cj)$x7NGD(ab5snN0{0Z1-a4CVlOU{aN zHv1hMc&;`6jyLQBU~yO;{GU(ef7X}`3@rbGM6vyc%bx9jaoIO%h}jsnAatLrbT$Au zwI;xsGUsjsJ|7AGf(_Wz=c4BZ*pvA59;KumYSIYbyAd6@9MP{!u0g%61KRn#yS<9C zy6F8&V;{10J9YW|7L%j%`8e=cgXU~I{MFLb^Y#2N^y+gyg^ug(KPW7SFd9ne2sSy^H2B6$Tn@|Wcc4DDNw_-HxFT1ij6%47 z-GDUtuwC)!mbYw>Ad}?xr_I%HeQdPwbw%V1Jx@#ufAtT%n!>xc2%mW?<&%N#t}lbP z1ug4LtE(PQuKJIA%9vYcMiDa^AD^$A!^h8C1ttwMy6v0$b1~et58~)ey8&xI^qxS1 z_ts#Bgli`1J`V2O-4cW2g$j1a!=4|A&_7kOiKhpB{!-i{vGA3SBJH%Ue4lunyXMHw zKbB~jAzw5ePzTeSbmuCG^!HG2L4)=%UoC4*;MDuZR;vQ*5hfcxeqYRF)APLbf_tbp z3Ij%-sE=a-zK#UpjAH#zKWE51kO7UasqxzDBV%?gvx`OCTL=}N{VcWy>J^qWPMxe5 zy=SAKJJ+?1)DHu~?}E7s%PuGyFdhfg*0|RyS__7>u207Z37;ozG0GZd|I*S^eQW70 zzP0pJHckR%ntbz!M&gQCCw2M14=63q>>1(lX!<58$}`GYC~>+6mS#V7Ir?PQf(@DM zrUA>f!vh3i75995K*Yin)=xOp??~hYp}O2B>P4;$sff_!W)5_Lbd7JAu4B1UdlSz~ z9|832cuy~ykNm7fBI^=Djp+`6x?qZ#u;`cj9FedwD741Ga;aRYy^obk2YF6R4k9E@ zz<*{(g7xO!v*9x<`I8m82;eijgQuQN|4Ps|p?y#8a5Oa(#q8tRulN%6{puEqQj^X2 zRVW0;1Yjo6nZ|g~IAZ%pF`PM5msZV#6612fT<8}9AYmYvo1()0E-w(GqqChQ&_qs& zFGh?b*$|wD*GKD`7V9B6X=-(0K#5RJ1|Zvw%^ZL!4$k7JrU%K!FlNUpu1zS zCyn1y`VhaZz_K;lBlUUSJbdK*MnHqBo+uOcD-}cGKClW8^PDr=j*PFQ@T+65RqP7sTHb!E>I$T=?E(7=C>xG~)G+RANA{fYn|a z&sB=JWnhJ5_3{(NBH2==Q(JPDhW&=nk12kiVcy~NC5SnQ)&-6du2g|Q&)?NVMsr7B7adK z{5I7Eo&k>f&Cu`E8nYID<0I;P5lGu{<7OHS{hPL>RYH4EsB-_DGCbK@hx_CaLj+j@ z#lD13j92~&Es#6oQM|2{H9Lq^u3nq&A?VhVltkkYB9_IDE$8*3)tf7NxrRZE&Nh55I5VS2VcX{E9dEM!J9pcGv*Ca7WA3|CU3Ia1*Ix-RRc>MD|kUX-`_gBRmbo4zyLPxzLe4xygFx>5%&W}`$ zeqQpKy>ZZv{FvwPyYq3yx$Dr@_?DKEbGZZ5W6@yDxJhRzFOh%tHJ&xuGjL2C^5aM3kQ`2SAh)tyViH3njoDjlLF+7o(i!L$`xZHxkSND>x1OY5 z<5VZuiui>fYv)YGk8BEaXxH_|GZX)eCt%8QYi)w=z^I!G0Ck4|zzTQbR_YZfp=(Y~ zJ+32*6ufL_K{QLox-cO=hSET|EYug4|6`(Lv@xU%Oa(6_fGvitN^#UJNGRP*nc_?n zXAKHWGt}N5e_(-Yl&q;bcY4@-l%H_}jkb_XWv{177QqsD&y>BZzn(2ZySP2JXEi0n zwvTmmi$E`~ndG7$zcT;BlyOxL1Vm?2fS{JvDg+Ns^~!j0YB92z=g}*u=OwL(;d)dd z@btbObi`YDUDN;K&|UK(f2|H*;|QuCtZ_9W?m-eU4_`tKR#z+{P(6~{fKh8tf>R`| zQRR|^Oyn*NukcRlqCRE03B8zTD{}_LV?vQ-MX1?vwZM&U(VH+ofW!UBn#>J@AAc`fOCB+mWEE*Y2H7KN~z<@^#8Fu|C$Bv?urMXhD{kuqS*9cLp) zP+o8(iZbVPUvIyWma5CU(?_R$FK79=#atREfXiA0uVY7u@(^tfDxKv_AX3%ve#_EUN%IfV;9AS;gl%k@UxP!lY`BfSVZrTZH66aPegpl(%vU!wD~?P<2gXDN zXP^4EKA61$p}*7lKvAs(rUs=>g6#<%DC@S3K&xmZtWw5Pu+ao5wh(gz4$gTW9cX0z zsbXZ5x_eJKZq(DMQseYiz~WS0Mopk4>u?A6>|}4^#{59VhSvv{!oN@&oQU0;_7|cI z0X{vbOTc^KJ#>m839+A_%KUYc4i(#MJfuch!F?}|);*2e3eIVowxt3dAOuhT1Q#mP z|KS>A3s2m18MRwOA@|v%#D_Ib4e|7C>3SBC{3qa8c;m{IcbGZHn5ZzH=ZuQ zpy9`HiXLEZdM1##CoYgfUQpqGTDCxh1^XKvkzh!iQ#zVj>k&$;Hr{ZcHJcm{8dW`& z)kMpNz1UUE;8YoaM`!Yd!;FgLXmoezOEv-8??+J)ytMuobq>4wE%vf5F#_v7uTBdhY#5jUF{$@D;a~Fl`GX-72}D8W@zpuCAq%OVkEmL(X6;$byriWxpXB z#W)uDscvb)_=US+%DyM`lk(H^6cB;M3KYiP6U(~d^QkoAJT$`9+Mf06_6{FYHx|EE z88QNgS>`VhEyBK6SQ|@z@XkRC+-_QeMOozsJ0d7%^|o68&trgVFMuUS)h^14mqC`A2?S_D`3~2lFfH7 zppH)2NVXhdJM`tp-i^#@{sPQtef)bt{eP?8|9*%6HIn$|V*M+IhV4ICD{TJ@Yh_7^ zD`tZpdi#Tl87)-e%nTsdmsmR38VvYE*73Ya!*Bb0ea)MxiuN-eE8+(v$=%Hjk{Dma zkmHVJUhdLhE`k(ROA@vPiIO1o0W2bF{xB;PIJ$l79w4ts%(v`#dMIzbqHeG}J z`0&J^W9x^O^rX%GaK z9_zV-}+ z4+Begh8usk3@5HkcKou!12Dnh;Y-kl-qPvZ9-t31U*PfWf`6u16*L;9mq_Cb7F}F5 zs2aRED=KYG8omP?P3~M7Rh|l(jcr%c{>-%_Bioq_W64i!$TPrx1%vdF@PRHcDui0>Fjc2Nd`)3yJ%)+ts`U(B(H)3sYh=`{sZQnL+ zNoafb12triGiOO?%ftr((>TR7v624%l#OF(r!hz``_W7dv);*$%tsD%S|S8o1GeZ+ z_j#46KUfZi_9PT<6(8($o?SgJSxvjqSK)Fj6dY30lpfwV!QI;CDzw9al7BOwXo-4A zNSjI+JOtXz8?C8f=KMz=k%8G3zXBt#5oQIJHASiiAYm!^clPiexDI@*6YuQN3CS}6 z8Ma2yhF>M(q*1Pf0aGbXkmhnYD^Mu$hpHOD<5;waXjG($9C;@(zJDoHSLzP{f5d9e z;KyXcq8?^j&4p9TtRJHIn9$*?;_DtL)Vl17GNAPz6*ywP+A-{Ahov6UguhRUWHU3O z;~nM%knidNtLs=nBhBA~E_=f$H(fD3N1{MnNH`eZlzCP%oA;gMNW-BdjQy(Ee`oXH zh2kab)Z0yY$l1#%XNACBtl=fNtd3h&&&67nHXdJ&HqHi(s-X|v(|i^ZIab3|V1f!Z zzi_jpkEf9LgjNCFo|+}Wd;Hk}7dXVEYeq(Fh7!0X4s+K%4G*KnXpFnJHh;uAlQ_z3 zI3gdCwDpaTucPi#VO{1p;-peSdU!Ltrn)xqKg5@=4ytr&6W)US{7%v(Eng5_e?0V6 zVoxp^m{vwsmMA(8Cz##QRr<-E;&>GxAGnCdp=vTeo03P51M}o;9lJq`dtfeFt|)XK zpINA8Z2W^|a|`&2U33VUt0UT*1wmKbXap;zGXmN0M<*7`lRO@z2Wx5SoPQaC`k+Hp4BWlCqpGu#SPbtUC%VIO8sX08UkVNbkZ~1lVTast`K1H%Q&A~G zOAYC)bTnIflkCbszxyy*%aw-az`8PS51D5|n`PPoYfm=6gj@7VYNd??$EGLrs913$ z1*}fJru*Un2^ysp4LS<){vGP5oD_A2(5Pmzz}(gt)m=YjyWI zXdZl_)2;Tnwey&##g!9nQhUQR=~;Oi1%rV40A#DS`2?)n-QFT%tr+EKk~=_ONMSdj z*wEW<^v?jSEnOv5t&}DHOI<%D6yy#U6(cL?swy0!A6B8avfv$%!J`|aQ>Dfw_#LHq z+X<~#zugBM5`6SVmiwSOk`+7g7Hf|*g<%2k&eo?&y;OXQ_zyIEK&Ge6nfjI(qgHA? zZ9slmWT^0JW23@}n~m67nm*;(raoWXfZ^tmN#Ku(5|bo_DL1<0s_*4-?@i`KX^41N zMs3&p3hMS%@@6Dmw9Z(qVyN)9S(+E&J!c+wfl}cZ;MKqusL$IS;orM>yYY5z>^Xb@ z(daU0XqJA#Z%7o|s(`8RAWcqC{i(2Hl1p)?NG^|5A@4J4j`)md2G>&-WUoGsfSKyY z2)gscn?T8Q=H*n%HF%bEu3>hzn&rR52C`5CmA2djqhz&R>?yeO`WhJc`gQHaNaCdy zO_u}8@$ObXmf>v6Tj=9cLO1%oduDkL9cDx9D^|2PAlKs=UwDfPoHzK5_}opyXAy~1 zAjMb<)Ri}Qyz8Uq@;>pO_w_&f4hANcf5AA}{t?st>%wOLU$8Ax>S8s2B{jdPoM`@T z+Y|!`_FMI)jn!BOyNADDhT)UXZM(lpX|RnG9e3UWl=|^gZV%cdCnj-FTiWN(XXYUB zBY)7CSX)k4=DVa%&u9JHO~z?V)+!jbH4TpC4!i^Bl z;^7G#|Nhqb98Teo1l-I4c8*y@%4u_mnXTGXMCLmmh9(>;0xRA4`R?KQO-ajB$4bjq zNE0mQg_lkk#^{3uvSbfdd`MTi<}5>Qth)4kpHtz=aRE2Enoo%03#*CyS)=w8b1RB1NBM!CXBGs0+md~v39l53)`30ks>Fp?BRgf!e@|txypc4{YM)St>G*oorTtx~&RmHCgQ_y$u0) z`zF@~wu6Fz-q;3@x18HS-RVR%KA=9(fF{gc!22Q*8tyo1I)9rc!BX4iubtn_-mJ)s zsE}A&diE%LB=jY7+On3tV^^_rvnRcy(-y4Z`XTJV=!5DhAJ&=4GWM2NN}RWDJzu|yPRO& zEIH89K`WyWTF@*!w1!Ba;7efX!M+ARK?yM+GEcToX(^MS>d9NHV}+4hLXQ<$F)IVj z3yb|wt}He{vBQ`iRsA!vDFr+qb&_HbY(2|Og^oWh(lzJ|3O(UcS`fHt?uq*@@nfi@ zRs#q*jWH^Fus;o+ECRybu<+M8p=8ohln02~k*)I5Vzm}NSbN2E1TOS#p$2py>F8|=X8d4vBZ8tf3%(Ym;;v%i zUXT@ET}dY69Q}&F9Aq(8MOLobJ+n2lb>12_74wH?k@+Fh0cfOP+^xD~rGzAkYH4|@ zY7Nu1y!K~goF&yv$a>5~D!yX5xP7%iW(CvW68Q3D^`ml$R`ic3VDbeAN7%h2zhFjm zoTqgyinDbo8Y)a(q6pMF`szGO$%?9*+;6>93kt))@iRANZ981a3)^f$JngtsPsuOvA6d^T(`zxT4| zOi@~%mru78V=LOGTQmaTDlW@D*X{lV5R#3w@{ zfRL#@1Q0r^FE6<`e%i3L|DrjL@9?>lDw(I#u0Z5}u!KOqQ2s-52i_$qiC{zPLvfggW9z;%0h&ljF~y zKYv`Hou{Yc48_qlfLNdyg@3bdNxS}vYM>lJ8V665MP*v3=i)GNI?N)Cha%|w3WQww zOF#~1q=RJjt4CSJ>hcoHvKV$K>TFGx+n~6rzs$|%ZM0cypW-N!wL{}sQ(2^JVrvHV z7u#LGsSLJtFG0{L2R^Cb4uJAY=nf|`1NAF1GK%=mbZ(lVs_8jdZX}c#wkS&d@-B^a zTiVB+CGWZpqY9$_ojM~X@N+7lMTXroh3*UlKabYzn-By7flWOpa%(~0&L%HvLiKPB zp2oaqS9(8}=&_qW8L??G!w!_q4(kE=9_uAKofPhcZsJ-l4@vZAkxt$Sc1}2VaKf5$ z@4_7@`Diw9%lK6$p{@NDy;)rC_2E5FtZTKHASlYb=NUx6NHHGl<>D^5D(WK zvSqiQms;Q%`2uw?vg+Y6*Ow3=N$Jtf;A*dDEL0#Wpr|ppLe?cPAFAGSB`Mw~Ipgg| zO@d~tFvs?rH`gt0iC6aa^rC?^zu#E(B0UC)R)S<6ixSvH-eLYocTwQPI55#?C3D>RAg$o5Y*| znnTAlu@gH%u|jg-Ug`g815;gfp=>=Sudh|lfb?bVN2P1bc)pdXBr(~GlUp;kuL z2SCvaKC$~5qbjb%Q%u0HmP9d=jw;Wzl?Itw&PM_G!Co@YOgNq*syPuqS;ssH^zLRV zlfjv;+$P?&QwX56t~mFmczvAel@p5NI+UDO(g*06g_`}p9tD3_`u|sM$M!F61p9vg zy4e30K-ZLpSPXRw%(wl%)WNsfln%lanSNmb=Pv{P!S#1w7mzR_e)qwZ2x3{0ICa@N zlXE24eMMB_vmJt%+3IA;SNFS#K2kit8+ZM)+gF&w&ueG*Sp+KMagl0!;G zY&z(EM_lBQh?FNH0zl!&DL~@iVt{(=265SI^kW{nd#;(RpPbfvz=H2A??*k*{B21M zRI~PBcenJM@3OBdq+Mait{>Vy518Fy`@L+?z%Jg{xYv$mjHCT_0Cd2cuUCfIU7lJC zn(ra36Nf#C(2CgFe$uW?UJ-zt=m16c27??gc7M)d38m<^!9xl|Wz)@pk-UM&jjPoz zxsiyMKZ{ms@a8R+CvKaCvv5ln($^%7A%fdj#FQj~VJ2~Jeoy1l>yfIeUPHzi)6V)* zP1}y`E4VR--ov&#fZ8EUD3ri`8c zDs5qh$!i_q8^$65)klOT3ZQ>uyQYI5%w5UH+VM}kp0DVkDzfjONA_1$84u1+Vm$MQ z;*cjA5)W}@0oR(Nn}lrA0K*_&=m@+@hXLq*}+#&O~?o|lYo^p zO>!KE)=az770HKA8cFPT8Q-#=UHH%Kk={2-lp#Fr%aCWrHPzo;F*X8xZ|c6uQP+j8 zS&^T^h(~lb=gwkk;fYTd= zD|NubEV=@?BmKW_>1X)uz;D~>Rd3aI`MS^rxebFdJi-0>6A!8a!-<(!xoc2!C1_EY z3mtgr4dhi$e;&TAVIgudj-Vdc!@%yX(JXh0oAcgh<&gkIwyn82iWI(86wO6OQd<$F^Rxl+bB-}Ca;9h)A$d_!v1q{jc0E`W zFBr*KaUtvCkLH1K0Y#yh1A})K*ipH2=z7G5M^~ry3x4Zx25#0Uz+mH)Fk|~^R`TZk z^lPN#{)vOXE$axPnV44!v4ui-XZ$%n+>nDomW{5vCrFLG5Oq-rTA&Ovp{0@|1kF*F=dR*>?vY44z8t5O26oAoPtuJMZ{H) z<3UHun`3;-}GBN>c7N z^QhP?`JiALnu{s(ay*2k22o1%?sf?DWXT5#KiA$&-VK%+9;h@GkAYb}E?cyxYp1?T zoyndhzFB*QV1`U>02(uMX8NWW;(lIbM9MPoT=sZcSDZ})Xa{nK-gm}V;myUpk=z3_MOP0)7<-UVWeKnZw&m{?jl(P3 z2SPAjlYH9l*r89@id2o5mEa|(9itnQknGse_URe&Qhev*;)~)_k-UFoP1Wv{x$sqn zjx(HDmQxtAO6j8RHTR$iei{6uNb#w>?D^>piOkviz)!!oS*|kaThlq4v-Xp)aGgYd zF4T$y?zptAPCO03e-rY{v_T!)F1aBD$uQplVNbfaLV9{*{#(rrZ&byTI@5`x!(7L8 z6pi|XkC~yP!7hfof-pu3N;u#|&=^H*xTHg|DC`wj!PjEy$iW&-PiI}${WqS?QZzAp zVx{ngz!O&GeUT_jhUiD0o;3Flbg4u7dXYMfo+Ac;t>A4Vpk{ASi6L=Ool34U?pe*& z76609D){}bDUHavY{qT*9NM=OwTxMTHA_D?7^K$J!H+HkbWYXdo*h9pYqBwCF|b#~ z3IoxcMtCK(6 z#UyXPyM_rhSr#==Ez{nl#y*X0MR`S4o@p`=5_KUm{Wj2r<8lPL$%q)shMI>M-6WUh zZ}ZRzFt<*I^nV6J|N|YvnQX!6-mgPdc(S>K@X)R_&Z`pq_TRtfolaiLYcI&uPXzrwp}X7y|r^9 zG*!4SlRXtIs|$4gno!ei4ZQ)z?}(;s!6EuC08^i|O=l*4C)%#i4^(UGBMRyx5^N~L z#Zm}XvgUDeh4k$xMIoU-*8F^uX>7#pY#YYe)nJmrsAZ>M;1AA6NeOW zrj0B1ewVl-_z->n{L|y-R5=wW$ux6H2pQKLUW9SPm>4UXW4*)SBqFPWYI1En18*f4 z0KSXTN6J-RgHd@WLz%oDdubqK)C?A64!Rv$*VaQ*3Z*e$23&l}aNUQA$y+UV2HnCg zQ;-boZtXeOpB72zBB=;BMK{*_>G~0rHOpiFy_8P+IlbCCX_xOF-HXr!&r$LafVr{6&dAFBcrIwp36_2O$@&2vKt_&yipc=JGK2aSc^?u1%N+Z= zi2O|bZ@I(wNSgDE8FTio9vwKVF~rcoNPa z=qh1cwTM!?B%}t+NoyL0Vt>gfVGOhg0@s=v!d0P+86*nhJ8-~uZdrm>pCoPbu#wOL06(h63_GKF(ZneSEyRCu8SJo8a((+pdQFe|^D*y!+a)`;k5i zuH9>Fs6pUW<7(Z4uwca9UeE7c>?pqUC|3y1H~wO>^gb~cQ$b| zCYG~zQq@J8vZ+o8#T&9U8`!wS_WAe$S%+sab_Itv$(@-pw6IU0cQ$RP<@OW}6D+f> zKnzPRXIIES6lM>#6K#gUE%srgU;!={-B*}5q#kEPzLLvk@chXUJJ6z(&ISQ(#1cmm z3*BpIW!E6O$j)&@PqDDe=&yLKeYO@zqp7Dur(iP?qpP0N9iSnzFS(A9)P)nMC-D)| zMzOG6Q=fPV<+jf?#y)kNLI_&NPv`m(&1Fr^66T6d9TQZaT>($V${oFhqZk8XLz_hW zBhU^o%+E7K+!vp}lOL2%FFc~tNCc4y?8x5Eo$mVpIWqvLh}mE`=LKKqt0sWw4x(YFUAgi?eO2WHqg*5yN9+1R*-zWsnz@9c0g~#r?t4GAok)X-$5o z76xUfSO?{&Ly5R8sd2Oej?O-=9PNLuQVKzvY;sABDk$3#@ij$muPqw@2UiUKdF=lx zUBRHXV?{%m(dbFpH)x9nl23@QqpeM$Cg@2_t!Ce@*q+XikysKY|FD)qWwn$-MR&i3 zWKiIswC6H{=o$yA_PTB2SUKOj2H;n<5)rxH^ET-{%4kQa$n)@M3&>Z77YmGmula7m zP>|fyQJ7TfT*BXfMLZ*N!-m=e!OhdJY{uAzBK$$b`q3flyuim>rQQ?!V=377hlXVe>gr>|Q4hv=6Geu>UVi%{TuWGkC%eq%> zC&o|}?zPiFl~sIQw>=nFfAd+6d!k00#HpvDL(>u{KS%d4XicD?27o^4CN;fT`*uoq z6J|#7ySihnZW4*Fo^mqn0y89@l&OsT{ZH3o-GW&}q0UQZ_i$BRbeYd~A&XjHAZiOy zj{-x%Z)}Qohvm3uovZQ4s;tD>;&HvgPK$-Iiv7k*(cEkCW^ zW)$;{P&?Mg_Nf{~pUNBvohmZ*ZC@6EaRl{qO%?-xQ_ZHsE%2ZMm6Vz2!A8wrL^$>F z0+*0-7`c8{1^i)OTkP*-%e!WU{4yF)r9u{~r&( zyT_F(7zM1!9@-u!HxBy#TUR-h5i3qyG^h1n9j|ED9X>J`9@duk$YXB++#e<0n@5kg zn)ehO4eI%_)QfS3JVjd?0UVP_E8Il?Z%}4F@*;P4Yn00Q)BHD)_P)W#Xlo^098Lj3 zy%s6PAEie=-?V|j|5yb6dwI(6i(UCYFZ`dIITSPde+zv7=ZOA)lT$RKDrL7!kI;Ln z_7=Uof6tVln!wtnQM?O9<-ot4kH1W~0PUCOu^!7tT+zNz88i0MZPwdhEAVaWOHt!o zB~u2(za=K$kajz@c5;OE+_YeWb|*&DN4J+5ZdE4;@WIWt`?-qpAz`xF!HSSmOE>P^ z^}fs9JAo8KI;v4P-z2=#(ty-}zjUoxcxwoqGAxW1!TU>AC&{pl5{AS0X9zHAbtJS^ zVeY+Eb&2-;V))10#pla;{@dORz7=m!pzGlAxi_PBW+-q=gV`r%2cawXjISLqEo}gM zfBFeB%@g}(dLTQ@eLmHVt{jS+jwnYU&TRFO(N3&Wbm{_EG7|hq9gkw6mt5wds8TwL+`4=w^$y+_?>=64)T&hX?L-@x5u}RL+ODLkC zQ%@xcs#JL9tb^WKk=9@v!KPR;)x*3;YD3->ixBe)SXxIz-LXZ8j@S*oDLklebOswco1@GuYYg!h0LVok zpG1h9y1$`)yFy|dwK>xn`S@!AP~$S9b|w!2W9Rl|Y+o!Rbq)U;g^umt=p}==@1o$(C0ruepb*Dc04z9BW}Fd{_edkrJ6tMnG0*yqmLC)ol2^A3g%5DlAW3GK3fO$- zJ3SljOK~X$pI(Q^c*22AVyAiK$Has4(Oa!*8Qq!Q5$n1<23w9)WND^MwBk`eHwG!5 z6e2B0B~ZHMreY&}EGlr3OYvBheQ+GJEQvBwDux-{zH>>_Z@pd+x{>+NTQ6>g+mnw>^d4p&l}iL7&^^2HtNup zS6%LL08LEbA0#_Tf;H_7s^|4TpL=~oYG)%c!#zOHLAa$neZEG%X`9l#74V0jutMM6 zwY#J596h6goRcZ1(vAK$V7<3gzvFwhNabbtm+aK0v8muNxvhXA%+VcO|{8P|8SIyG(@OOpCAMBsQ%gfr^tLVepdBOEt zetAE#Lbkt7e&vr#8|7Hb?Ea};?7h^K^CH-@4(WVf_4Y_3#*~Q`A-s(e-f1g9YS@5s zp;>q?2$3wjY7$1%wpn(iTBc?Qh4EtmXfr$dJ>dG1{Tlwur0rb?(#5F*1 z7KdOcc#qUBMR<<&tyy+*bJ{oKtEvtXkwDA3D5; zy(CWAIW_pUVm@~%mARfc7RJxW#utd@0!Er5`u}d`+Dcn~n>lKKDv?R)i3P07Ag)dk zyMnY#5|T9~ge!@?U*~ov2eWEp57FE<>1k5aznJ8kjUq@w#Ou-CgjyU|oOw^DxGP>Z zBBRNubVAZ2yKfC5fUB;KoNy>H8S+q>qv}F!y`ub~^&)(>w@Nw*1L0t}<-CQz03Ls6apI4b@U9>CVB)yP*E0&gvQ(`c>pyG~aMRWocm%uoVbFW0#39PMI z40p&Sflq2sn=tj}nZTsH;(za~=1)LAfYM?q3l1_4(F*)Udf_G)nG9)qA*gEP*x?%K zpq#E$q@q@lui>8+p~$Za*gU$`W+bF@AjZxSJD0xxUzAT}1_j9BkB9dWu4Y-_fRZxgmETRx51GJLt6F?&RgWi`R zGOOzh(&&KBC^zD3rT>)HOE&;Kp*T0o%NDcA|O(fnQOYb2%$^ITKgnOLH= zjSGD~PE2Qk1&Yli?5Tz^vgK4HF5)8xGwwcZkU_YS>{=!(oIuwiCHSN84I;rN^k1g> z|F<6Tzy3A-V=JG08&X-wwb<;d=*n@d?Z2p}sOdFqU$K3=0U&IHzTy?DN~S zJvlxg(8G|zdcC1f*RsAO6}^-aD|HxM z?8uNGHe1LID&u3}SO6K|Phq(z)fJc1`THC=i)?r4+i_1%%;vuhXFxmd>Dwj}CAk== zhFII&AEU{K4&TqTYrI#J&c9*z`q2CuD}~|mkAk=z3um*0q<=?m7-1@bq>3ortL^t{ z$TmH}-8Y^mad5J{Cjm|8$UG`P`05oZ^E4&ic9AHlqtRjsB?;%|xin+;1Ew%~jM<=8 zax3@?+Dw~^1Ew&~+$NMrgT(YOtl8+PctAmv1j|HraRT+_K4RPZ7p2uSVqapp>2Xc4 z#~kGlQ|bfg*x<8zfVdD9EIait2?`Gb=vYV(sV`#3j3ySNx3@=>!S=k{4REe| zo%~ti1aB2NDT}e`9G+2iEE*Jt1(<>x-YZpY5~INimOk7HyBL+2!+j7?KOn|!O2gp$ z)*U}%zu^jM@8nw;2I=9UGfhiiVemNf=!mPzY@&VTRAbj*F0boct<2i03}k}Cm2uR4 zA`@sfEy+ch;76rMRBI@t>8Ed#F+j_#M$vW?wqf#!J;u@K58<@{I$h9N-Q^`jD$kiD z*0AcL?1W}AUL#V?Q5|RkeFm3YjGJp&ss+9;$M)wqw&HU4e-}44qWNNnYH$dLxlpF& zb*h*al$qRd<_e>IEo;cp40WUe#6sRg*8hmrFh7aNQ*id6+fLY7_F);I?ze$)pBpHKMjI z>|2zaYD+bz1mzuK6+Xs5S1{pG|(@c*|3;7ejH)At)hg zNc@pVPT{dLjH@$(30-Vc1bIMe{`p zubkzZQ|&E9W1AVX;_9Szj)@SZ=vh3@no&C<7Xo-NV6*}ep?kE2o5x**#8$B#)D~vE zs8j$sP>SQ}g#30=Gt_4Oq+0V=VYxgzXtiYs?K5|C>YgLg9Nl;z{bB)Z;~#6(oFQMs z>6l`zbI56?U=K66@Nwr0%JA?{3ZTWF;+h77H4j-L43?D*Z*f5UtT7fQe{wR(1l}c6 zKIwo*3oHDMd+|W9_UyhZ=3>*ClyfnSsn%}aHQXDyvx7=n(HV2Yc#Zv3iql`1nPUu3 zp{b7Mla#WR0dp70x@jddx2mcHkIIJVre@ah;qA**|L-StGLeJbRAojoT>i;18n-_W zUV}F&v{~%w8iU#((b>M!rLKWIPEP2dy1h>5ijoxM8{VP8D>QkU32ex1E?Zm8p$=G8 zGs;k;KTz5-7*JW5Pm3@iHFg4afK(@d-MJo%#0MXJ^nQCIqci-3zFYFiL6gH%a0Iyb zkPj?3$JVUe?>KD%z1>W7(pMH-vW6RnjsIxVeBN%foL-((Q zt^KNkOqaDS*r3@WYns&f-+o^N8Hv5VgTI3cc)t=kPbS}p==Z4HnYO&pyz!S6koO8D z@3QGU*4NTvmdW_JcT~_PvVC{D$zc0rIS4K3KJWVeK zQ_RB>*QA)V$wmJ-H??f0Atj!%vVVnMnS#I{p_e*ktJ>8;Qa&S)P8t*B=;2-a+BHXK zb+>#yJ9~S*wIpo?Sgs;!M7T@4MYYGl{%4?5XoeKp_U%U~Va+$*m_m0Zc)oN41 zM()V+^C6@@0}6J(R3b$b+@U%Q`@~3O{_!l^%qZ~lwrQLwn(U#qx&8*rL{8KYC_Bm1@ zGpc~l0)9!8uVIYL02Yfsh{nyrIb&@L_7)_{4hF+-5Tsz3fNZpn60@?R&Qv*w<9$%>C4!CK1Xcf~HnW!CZI3RvG&irN1FTPg%L)#fR8UlG8H6Nrx1|S z-P6w*L3N0n>H9b4f}00PFx&7xhCgKp#3#3=j*&*P)on*8zEpD7a5kwQ$wRV3kjAydAyU1K1$*%hzY&Q)5G$K` zc4GMO%QZ>m;yp!6L*gBp*ub=suj;*ZA!CF-oo7K@}`s+y;@I zrm)XfO$t4LI3`gnBom^%u1C42!d4-;nVBf?0>-t-!CEhPp$V*+cu9AWU`^i3eE$;P zpE(ExB)j7uyluPFBj>EWv9j2Zjv_i~m z+&<8DF1t5T88~rNs%r&^_mosq8Q>6>wpLX0eNC;jB!v?F(5AiZFsi`@O(_(l*0Ozn5{P;X zc5N?4Ex~b&JFK$wP#3a1+ArITfhnnE*KJ`e%&I>e7Z!_gapi?3SuoVL4SmrM(cCK& z$U&=~HIV&aw>%seAX5NdN%82zcGPNNvIf?Kv$Er}-iv3W@`v|HMV`k|&w`#HD< zw<6?7r4{^Rb9bNraVX~UoF>bxNP%IpMiO3&xTG$9>6|JhWi1Pt){?;5@>g*>i_c&= z5$OvA>|LQ=T(Ass7p%wW=>*J4NfU5hV@1?^OXDRJ$*yLG@@zHE4?=12ftHnoX!2g9+=rxJl-lZ7u_UD4 zbO#~T?iIWG*`+RCr_7w*%EmsRYukk8u#&K2o4Mrc#p7b6@_Eie$;g;eMwyW;BA#3v zlpxz-$4~-PD4ziPW_XcXY!03a9)|7HxBnwO4->RpF@AG$#2e1ot44O+%r74>TK7K| z%KsjEGq5rJ|8V3S|G^^1@&9R&qmwqVHFGv+z-MG&VP)s#h5CQ)z3$m7-X7k{BCYm0 zT~D4~dy5w0d$LJ02uO|fLbUP0_2z;QiLCrcjq&)zGMxVHh}-MK^hb=g)J#K8*ld_0 z1AnkZa>B@CIU}QiDKFR$`=|YxfR9hORCaKH%5Oh?`d;VOX0El`E|xjUWOF#BR$z5< zrZOXhJ0azgM@e80;9aeCr64@A5bD`zZxi!0Q7A_r7zEo}XbwW8aJPA0nF$1`2sU+~ z(dw){o*#j!AQQk46`xeCoP?Id`hIxB;v>co$HG;s-T8Y&q{fM@$%Hi1oONC|;^Ua^ zGz79UqPQ@zc7I$SPlKgJy^niIVAn$Q5TdyWNZ!PcUqVS{wr)BZ4k&AwtP3{HGe!6dQ_2qf9STx}n)iO48lB5m8mJJ-)w5_CLnHN~h z?87wRiU9(PbBqiPHDmZ0jMOYP?!Nqb^WkxYqOoWkHebO8Mu)}Y#KlI6ze*E7Wq9{C z_co46?V0W4k}qBhV(3EI#-Ic~WM@kudM>hiegD`x<{R|x1Ti^;dU59OC_VDJ`3sMC z0_NiZHJo4iWn+_;j$`nKBHzB~gZ{)NzK;7oT*dV}9JkF&@q*D^yxUSQbQ(H>oDlHE z8SF4NBF+v;Ld4tXo74;;wqXS0^|RnU-=aIZ!E=b-1Ryy|N8jmMzol=<;hv~DflmM) zzf;;0tv)Bjjc>(+mkJXcIL8XB2zQ7x+-1@)-m~R@RPm=M->#S@Lx}k%-FV2z?EkO zPy#L50A<5?Nj_rrzYfOOB#6mH;8KAPxb3Egy-d>0gFb zd^MN`8VVfb2Ll6AhQfNGGy>oi?l4&y&M|82du5V$Y!r~I$!WciXlgfENVyf3^m+Lp zoVtEgXFe+s*jOsnqmc9#5N!4Uv{)hLr026({@X=^sBPOiUg#hIqaspM%Gx|GPmdKG z)CK0s-<_wuthpNa^0|7+frl*Kx_UUnFD!7E3@UlP_nXp6LI{Wsq@9bU5Ok4IrWgoZ zM96Dc%<<@0FDk$#tF8%_F=b{$kL3(X`Y=mtRM}*$3U!Hai{c~`lkhR>R%32UuA%C1 z_VJO3292a*Z#wZ%oOiP}E4cD1^+!pRhXi$%6Qz-&)6rX6MtWZR%(UNW8E5I`SB5-* z2@7PIA*ggEFQ_)+EyX4%rCMQGG6OA}>n=4_&Q4GV79lH6(G4V3KZ+_40FAy_basS2 zJraU2AA#zCfgX@Jx?`)9SvoKg324%+Y)=}UVA&^vG&d&7BuQgU8$LLD6cHDxluepK zUT1znyqBhZ1r-cfCo>}tn{mvhf0 zCa+E{YH3d79e)ZitQ-W#33}zJLs*>A1XUf##d-xWaOo7ri67xZs)Z zQL1}0MA(5S7-rYz`UE=PSX<^MLcALFO_(SC5O9&O9GMVpQ>0{55b0o8?(F3iM#FMA zTHfai7qkbGRk8@=gCnAPYw{uJzA4 zROl%OP^ZK>)Hw*!_v?FiB#*;ZV8QymCY0e2IaE79#H+vB zH)glsZP#t?Q3%87ZvNBSQx1Y>d~X)WIJ*dLb%VMzt|8%ovYDgE_(^kS#KOqb9|G80 zIB)|B3R?ZQ`&BxMVkU0*YHfNJ9-^~lb6}##`0Q4FVS!#8sHLC^%(Nw)c)BO=C)MKx zY+1TWGMDi%c{kfVf#>nVk{qg37u>%<7Z%S&rSAimHjlU{yvk_8@D+KLd$%5*x3y$1 zBgP>Qs5RtvL=N$eBvXY8<|HUtQxuw)f`#P^=hQ9)ICTwfUHDglo@mD%{kK4*7>e4_ z*hvc#9l#i3y*Z{3U}xLM(1r%6P?Ubb<~{e9H5YZuL)(+O^%Zy(W-D$6PtR@lbv55d zjDIxVPLlYlh}0Bu(6`(Km&0EZsKiqesS*Z)6n8XZMtQ;^gqli}cP~>e1%tr7KzHTQ z8ZAw1a#QD)C^coP{^F2NZF@*nutPgy*cBx($z?a8+X?dHCMKi;fjTN2(2t{&qWpn_ z91j%31{2u$D-9?IMQ6DjG=8+V(iS$jKM=PIEuy4)yX$DAqyc7%>^kqys`I_wb7K1Z zbarVeisN7-6)H1fPl-`Dfj||ObYRS=EkEW>>8@y> zFb~X1wE~swY2Yb}52_7{oR7bE-FVNWYttd|t$8f)Ys)<&Q{`?5s|p(6T7B*vPMbSN zzj&kji8+AZy~&YyHXyyI#WS%Z=1r_%&nXO+a=63qVL@87dM_4-ctmf-Yy_vatSoD+ zna5RAoJhna}vdAJ_{>>R!`8zuNLo?jM0;x(eP(Zw% z0OBGMp9RwJEJ^!|!VrFn3Zfc+ZC_t(cpffEC|Q=qL?oxM)*6k2u0c25%UR^08+)kv z+pzcKJGMH;o-Ed8|3`uh)Hp(so0v$b$|ZwF$Yb~LFbaw#LxmtFGZL1<69s@Jkom*?>FrGJ3W?C%7{ z?(}qavd9eB%)@*ssLF=YsH`UA!26p}oG6FEabbv3<+PUX_a0sOl$8|As}&4pLCd?4 z>>T94gM*qZogPcbMYT!}Q8ScLIJB<(M>JU2u65Ja3^`BRm}x!xv?rlzX!tEJ{PsaW zI5;Mcxgihz1n@g9`XOK$I5X~B7fHV9$ z55Bwpfd#zxO#q+!zRT)?8gBa-aGQsI2e>A;{B;15C_an8z8AdregGRcf=NFg9zgXM z0`bFrGq`>hI4i^a2go8f{5T9s2YQ4yw*FJsdJ`imRcuoy8qXd35v0~=V*nDoec3ww zt7rZeumQX>qqFL2X$~LVeTCNM&v|hkG>tOBVeF}4JYXK+{3GpKMTrYTR&*6pTYi3f zzFv``6*J2(Aap_;f_*#J&>o~8X5T7Tf!SGG#357@RwK?N_Eq*5g=G1>GFRm!ZFjzC zwHd6fqWz$;(>CvBdsJZa&1=N;0fX$2;2{Ypo~UDY>H+v?z<3e5dyHm-V^$aKkex7+ z^@#`_a$Ny^3#qY$T8YYaz$-rLx_M^y%M0L8cQ}Mr9^OHXa9TM}4NpL>@s@iX?>ZoB zIj`b$g=;?*tBXVKmhJFj2>j-qyoGJD&yBwZe(Xz|r1l6~d(8Ea1ZUDXZotwBD~8*S z>8{tft%33wPTl4&DqFe;Gb?5c@LEesx>=~I#(?Ax;;Sm2^IQHb_#fW!=Mf+fY~h=3 z4+k&tus|wKu1};iqEe)+lzf}!4j}9INbLPcI2d5tO^au0bXmVgpW9}WsM{F;AK{%< zcN+LDmup!Fe`w=XdRlZK|7pi1<%C!XYHDX2yj6-LPC)C`vt~cYl zQDsC%botO(PcpN^99co@KLpLE({~I4Bihb=<+Ko!Gu{rBGn(;yhQ;P5?UlDHOZxv_ zcbghNN|g1S-j*guNX1*L{{bVOVat2pN*ifgu}W)J-0k-9JMtxs72F-A48ln?razYk!c;~UH)nX4x?MC=YCuUfj(())eHVg>+y8Kk2!$WJ{+1Qkpd(@kRw=V=Y8FcQ=`d>6sgE`D?+? z^Se*Bz}-8y>MlLg@iLr&K|$98RJbmnhnl}5=&>%~vY~6EJOk-gI^Mqq_k>tG;uurW ze7afm(FT*l7xRkPMFPWa^0$>(<|d%Cs3o4-+~&Ht_wILP9XXGi$4L zTKq;((A(ZKVqQyiDx#I3#=0EMYIA?)lU{dHxGf9^+P4#4juV(v_q(sg0R1S?&2NB` zlIs}U5X1A=06p4QfjZ;?apr*whl37fX}|@%+f~mDFr-PO45>ZOu;M56m2z+?pW?$P z%5XLJR)%zWuI7hGQ;&k5<+IP6qDusEs(}TkV5Stn`eFu78G*u0mMOqu)LR*$s=(&s zo;Sughsn{Hv{hG`M18FSU8!M(9?-Cl;NQBXwrJe~8?=ejK6== zVT^B3h^zFTH7!*II1IJf zzAeMvb{@3dobGH3*{+|3szBbI+oH=EH0@vuw!L&5)PG{Jx%I=+bsadcS-TE#vTg5& zlAyG%&JZ}aVs+cncOGP8^*Rk9vSB+9J;HnevRUWXvvqW6vPqZJ8|`fCvjK2+qV0%n z?{&W8B)@>MsU6fhIfbAk%+16I(#CZHp5HhQ2_+BUvaJojQJESEXpZejGK8#OhI(yp z?O;2u2vA77Ijwsx!fx}v60ofu?H-&A+S*frDRDRi%^Dy%qh<~GOOV2b+MrjUpa95f zQNMI>pG3$#EdnwunJ_GnAS&=F8{%y7e5)d#vOvE*!O+AlganNWpu@#DgADtBEFde^ z-%(6|{sZbPo7o-1KSgY^n;*ire?7k9UfrUN=IHa=WV{*O-GXA<9=$I8Xae-h^*<=* z!yVy&r4j~$Unzt$8KZWwjxz-QcsRJ|YUmbi0=3cL?9j@%l^`3gdn{9L=|s^n6{VC* z;;$mhD2vF)V;VThxDz1VPK8{_pl3ynH6D!0xRXC*U_)m2BaN44PlXI)B*=u+Vk+Q5 zzR=L>qrLzWkB;naUss~X_mK|P;>#5Bgra?L)x@H+$@8)C6V-T|KlDSh5an$*oFckl z+p5|W&eY*;@zrB zl#l)+Jgyp7>F4)M@oYBNi`@jM5_~szkhz+KL=v=Q4(J{uOOMIi?f*!i&M(!RzTb{Q zgv~g}OH|D$I31upe*Dn`ChLv}a`qzMuL9b0A-|h%*?z^=AqM}|>vl8Xu8p*pN2%l} zZzgQ%qMbrWPADw0PC7`5cp-8ZWv>`4M0jQNymLsBr8oktQVrgHxMc=iVOOVGhg2(o z108R@m>(@6$%6g`lxNWP=*w$XK6fZt1>vEsDy1qS-q;@QYIX764bK z=u6|CV|1@`%J=yJ@^iY^UA|jq>%+k6mU0K6He@5LQ5ZnbjSu8O07940-aG7iLCJx` zZU4a>(pPXB%ns{>hLuqX!;&E~K+S$d8bJ2ZiQurzmA?oW3EYW;;M&g%ZtcXM3v4Xr z?Nz|kfT2#$k0X-d&Y)1x0Jl}rgmmK*Z2-qVx(eRL4Tf>iB+Cisd;Tuw`*_^c_m^tU zPC>3J4EZxB6X4+}fJ8Dc%DtMjY3xb{2}Uz)Ea70^C6rjGG++%2n-TZxnw|xK_ zN0P$>nP$XzWYk`?T=U z@94VzkZx&?kF=K8&v0}q@6l+kw(yZ1RK}0LI}V2M=#L*`g0$usepmzqMNrEyrG#n~ zFH)nWgd=fqh2nPp0&}?LZUBY60HWy`a(=mee{S3owK;Gt1ra>A`&{H{T?JE>9%+up z&)a!bZQtwcIQ~uTnyRnMk_)`t-qO6j&v%Xx9gD426ZbX;1MXh6AQu;!O;*+oTV{(U zj>F})1TGV1&}94$O-J)^BMl@g$v_2hIH^E2wrpUM#Lti~QT-p8=bdxNVl>bhbXX%+ zpx0Zg4oD@u=VszqPoyRS1L<436*|}IBgxrYjlE8bN!Wwey%Se?E*2b*DZva6`m7$s z3CRX4X+L5Yt`b#iFU+dccXo7xz^idipqH0WMOK?+)Uv z2ctq1x~uFsgvQyQcfJdZ`fR_G9qVVk^EMitoTi%hzkC&XF3i)=bX8SaAmDtLMD*|{ z{gUk#Q$!Y6yg!zne=GQO+bl-{v3xs7TkH1AZaEG8+UKg&*xc&$a`lyzR8p%LC8YtkYeJ3=83*?&QkLywn_;^rxjR$Z68F3whz; zgY>>(zHT3RPPulETBF-Hcr6nwC9Wo@MR=da#R?eL2{FUPv*BVo;F#DK6w#2bcVx$% z0>?jk-8kq<4O z0bNef$mZk>=nm*Vy4E=a0}huSy7d8aa?xWv5kMx04c&9hfHpv!r;6Vidu9R5HK1St zgXuR6h;@e}TK#IU5%Q!}85 zsbA8r_DR9FM9i{_UwzU@b?UAS300@Xt;BK9d~}anHf+ICk7Ukznlg2VKRK)_PhG@N zV;sdc8drqfV@!>X`!iSA?wYjTmNAw`6&*p7v3)E2Dl>s-b(P_(ib76*Xvmv%72zYTgS8j^{U8eFO%}*>F2FXHaE}WCU z^q`uhdUzp7nnNyu*~;M&2HR;pZycn-nr$wZou(J6{HNEi73Jp+Q_V8mAF8Dx=---54cw0$A1=U?A^IAnWP{#h4Bs zlXsz5HaUk7Eoiehb&KuG^pJ&ZjJR`-HpQ9N>bL38V`6f086UvV0J(T^nHvgwdR*F~ zZ9g{ErKiZ&GrC%pk;4!xpjAyS6s}Ol29duKjy)Hp*`vTL@dR+43>llDUj<1ieSiHH zVA_FikRGFK3W)dp7kaiTU3jOWHekE1Z_wKn_Nia)RmLLN6bAW0y=liE7SC*2Im6()w1u9e~sRTJXK9&W!? zYk%J5A9vr)g`%D?zHjCOv9YG66iJdabQsba{BY6*L$Dk~9FB%Ht^7rxNYG9igw}pu zXzM2aTu|ewev}ZA9^hr#6Jw(U+Tx}Bn4iK|0j|(?rVcnR^Wb}}i@9I@2Jh=2o$WES zxj5DypI#`Z9Wl`#Jis8?IyUqeb5YPF5X~GBVjzdVndJdv01Tq=Dr9@OMVWpLdZ%O+ zVrq*z4(*_!6>S5+cWag|32!g&W%_xZGPj5STu6NbI*AI}DAYnZn@O`_?0!`-Xp9hn zU9`mPtt3KhTu60tU?dn1>k1v&FpxoaL=7?9eFpvw1YvNYqU?IyCB07#ozN=poaOzu zlF#39dR|9Ia<9Gjh_5Gk%VlnZnB}1w_C=dDH{5XDo3AT+^rk53-p=HCBJHy<^it6Gkfajw`Ab#-xFB0`Sn zC8=6oYp?AMo|b2U?34z6E2pxxb?Sl~gjl%sLl&Am!Y%JK_Lm5qAVoYIai<6km4mpf zNtV4B^6@wOL?zLf2La@hUn zdB`_S?4+G2OjUoPm@;0r&L8=_ETU2FTuL7CX3!-FC&~nh=e{%}C{ksz(r_Lov)NHm zZM;nvb<(cmLY6*hIy@r*!A~{6&6dZ#+~l}1YR2{0hp~jdd$xky2KI?VYBA*So9D|1 zZ$WbRn|0vFQ6$U&xW+CTIGD zP^<}uLtrd3*qhdtqy9Q4(}7E}>!)2-F4X|KyuQ)bF@Ci>?qW3SFS27 zS6`ERr?#%`s$+bXdsFI?xx7SRwZ;av#;T&YqI3Slz5k1R!nt#eDsgONgPP}#zc2&0 z2IV1sS%Pb+j8%Xb_kK{^1DdrzKU@+|HC zyL?%m{<^)un{`v4nM(Oot{}u!LcW-Q^+JtbUQttXfVdpFAruHvlgR_T%volhCH9p^ zU7b>p6?EufLeX;zbnFEWnQ>g}P5qf-P@ZKYw(9i~k>^c`*ggk6yT86Kb*uJR(mUHf zOWi*k(U0=%iwHPZs3*@q(EvGIj3QwPX01BiSV*LYBrimE>sdgRI>94&u4>(eooY2e zaKST}SV)?hw>EPom|~4%AEFDnz-~20grF{vhO8Ov!TOTkOL5@LZS*O3^4I)rIY z(odA}F-6!DFzvlxnaTL{3tN|;;e2)SgpVf;jTwau!*4Dithbh9YiLg%A6sdGw)H!C zuV1rs9o`=hlrwp~x}Uf28*+%ir+kmo&(hLFe(RBtM$C1j)pA+Un|)?h>wR6M$_F`Q zYQx8xm`H_JA8y?Pz zun0YAE2?DWbIa%u0DR@9V7K04MR3w;q4Hu>#0Kza`K=eJyvMzOelyTk?}NfA^jNTB+ZG0S+XFnFES*U*q#TR~Zz^^VDFWM#8&3AZ z13@?^4hUKM%6Ugf-44Jyy0;|A0sIfPPq!dNU%ZjMx$dOlI|6pyo9^Bx+_+CfGTH{d z)-<@vd6V+okYpi6_LSs=&FFjNH6*v-u}!SE-CY{Za4MC{*INW#g0WVvrJ80!%&8dmDDM*p= zCAXn?9>c3&n2KMG12Z3Y?vphx%@5fL=*BfB|9w6(<4!GOZz4#Amr#d_qEESNd-4^}gIlAaw~9vGV65p>7BG zjOqu?^V+H-D?wYY5#B;K79^6jWddMOK>ggV;xAK zK#EN@#LJsB(2OyxSt^a0fMs#+fHYe)9Am@zw*12iY|wD~6k`~bw)Fe;#JE=-*c|Zk z((SnwDiwXq>M6(OEWPgud*ALHh}C*p#pkQv?~S`Cl1L7)ufRf~&((>SP%G!jOVDi4 z2;sHfg;i_RhSjhAHG8y3s@)1rA!%%oy$r64a>CeI57OqQbCfPFoSNZb0&3B6fwt0$ zP%U|c4&1x5#8BRT!o$DL==C5=KE)Cw9x`b8I=F3*9HbPt)1hj|$<(!hDs0Ojl|r(Z zrI9oO^{`{Gc6ehSkbVG9oULaObyt+gTMQ9!g`XAMlYY|hMAAOP&@v=%lSQxH~& zm)CL0^s_`4qWO?MBO=tR-CPKHF8_=Pty+`r%?+9OHY*8dAmWzwu_U&nR=GNX2tpn$ zECeWUmcvmdU$SpGlyf4gb&HGEsQ$>)~ zDe!uvigw&wrT&iSHoxgQbD6P$<)Sc=B#bkW%0I#i_tD@zb$`{D72D;iY~Jx_=GEsj zqmAbRmx{N0_XPK)x*Z_}eAhdkpo~^dQ5cU3Df<)&Ifj_vlLmy}pH)vR-3y_Tr2;Z8{;eLSX5**jBh=EED#y1tFe7I_{N{Yd3TMz*P$SH7y3&s)dY; zKbeNgSw(FC)$wZ7-LimHxq-JueaYey@bk40n1);kObC$&bi%Gz%OAq6^|z)^s~?oz zIl2V+?03EHPk?botnI#bxGfEnjm4R@YG`fAJjP=*zUgnnSOqoo538%*%F+rh9y%?+ zqFV(tj13>Jp!1D$<}pEk!@C`Pe7t^IXKLP%KT6a}H0)8M@p?YkIt_t!Vav+obBZV0 z&{0Q&XLZXL*;e+dV@-~azY2V!yww`;bX)k9L#DelUG8o*sUJPMZ@J`t+k#+tu z9jJA7t>sqtWHYY}Oc;x5KL>wjb`#e1k0rhks#)y0hHnx54XbNk)*CHB7)j?w?{n(0 zPkPsa%<~gi`F2{PHY5|R<1r@>hXoD-#E3ijeY6mTS?Vw zq%z`h-?p74ur2v2;yxt4-0|yO$V81ntklq;+Lh6O|MLdr8O%$)UEzZltYR0eFU1%l z0V?n0jtTzc*gVbrYH5pfR%yljdWF|8U8i-OZrCOIHs=)Kq2Zwu=@?U={g8&`VJ#3a ztD06Cr6RpBWx=|H_WXJ$5NRK@)j0m4d^qx`tejmk=n!>`ch7WhdykR{k!d_tlvgME zenIMXe&Lz^VtjS^5H9sK;HI5Orv+0fR(x+OU2{+w#iy>|hub?)d$j`W2h{`kr5313 zWRgp)#L^Z3#A3JXvO2hFo^}fWXA^yTS)HgM?btueu_Z`=OnDrFCAJL!tL-dxUKD|} zp}l>lCFpL9+6JI}-(tS3PWg7NAA^E;^Kb*s%c%t!OZ)>kf|RilmE#nN+t^d!Ys_{hG3M=Bz3W86y1g@O!9B4WRkATzjZ(K*-2!*kyGH z)f8*bu%TQLugp|^Wm(DT(;jJ4adrux<;mxY6La;2B@!bR!@)Q`Qs2Hp+iMfOUfe2o}Al^o5m zjdT}1CW&GQXlrg_M+jO_(j z#FXzzm71F+86l)GOO%@*m|C94;w+`@9KA)NQBzw)jFwhcHPw`W_;5C>#cci@=2#|{ zw1|jTGf;VFgZyluqR3;Gh)GdlY++`epv)w=Q?Mtp z+~sJlQ7PBf7!_Uy$Ch|^7r7g3>vAo#(~@7qKD9L0CKD-BC78;&thPnIQ$80+!*NA2 zs+nOC0T+f*(NnCB+*b~3U9ME?P$zc;7e;`Cz75(te zc)x2Uv>Gc99Bzsq*nH8952uI{b7|VK4@t!w3y(}nDN5#N+N*{&T_qG7aPJ-~9Joyq z_x9u z?wz1uy3bg~#i^^k65y=-ah{tG8g9 zf1RW4J0E)Zt?qjjBCCn0txUNH{nnaENyb{;foW!C5oJBXjG^zrXe$XUc3pI=JBYF=olXk z{WcVRUmml}*RSSfR7SQf-Ypq6%RNUNPbA{m=>6Y&g@DP6IcCpB`2i-X60VY8)W@O* z8Uh9jD5dKBY-aq|7r6SFeuF*J=+~gD|D?w|YnHHulW4=c^wc%auGIrl>6YXq9BL+q zcSbW{H07@AN<2fBC-gmtVWID{e*_dK*rgo##%8T(e|KFC?vjqAeSP|BX0hn4n3f!( zYV2Z2M~M`9EUl_xdqskIpw={_2XBOay(QaITLqWZg2{_SI;?B{1-7ac^!rF~?|7BF z1PMV5!GlCPTrao|Qwki)*1hO2o%GY75a;`C5329p^eVhC=L=Hx+vg@gwgIwj`nF6- zee;1{H+-JyXPE(Fj|E29PRO>>a~UUWO}9Ifaa+p$ zfcK>S{%2m^#Lf4U1?Tt4%dD}tYv=Ga-qGjyXVizqCX|S1{&!P6F8~k~_|WDNonzn% zmGByJejWGqB7|=2y^{d)as6GOx&5tG^8C~-s<43^J+hVT>~Q&h#BHq;;JkjD*{NW- z2xi#}>ZUDvPf2SiNhPl(F-pD+2J!)XU3ykSaolxeu0rxI!WlFG)fY9}If3eV4U#Pg zr#yA)D`3@n6v7im$634e+-?V|@br{>MiF}q!_yAZcASqko8~d+RYRxz7D_c)kEAa?X)6hAV@I!85W)ed$csShtrd;&=Uo!?*oTs6pwdTwD@f zsKj;OU0G*nt_{L%YkZBN(S+?6b^M_VtG;7hU^9X5^Dx7!x>waU#)=2vr{^&Dn_FWG zYyPv>TaA5te*gOPWXVB> z4NFVY`RBzDj34b6cTB0E&8W?aE)6qGe%*y>C$XmQ;aexhwD%23yU%e%CiM-3CiV5+ zS!JCrCLL|J4v%jf!14Bi72XD_Zf&vG041*)hjZ@eAKT>AOOxrTz>`CdJg+96R9y;Et6i9ed9h*Cy?n~HDI<;xGds!|ERc1Rk>A5$(eUw!fb zMXY%vbU^JJAmYygQg#HTI~yaStc(%j5Mm%K!t&Y+*`bZB>-|~4=X?1B@2__MSbYO; zKA~oE#A9IiTQ!-QI8qgYT<}etQL=tR-a8nfa3bY@@jLs6GudAb+Kg;g59n?Xl~A^4pJmr($nYbNcT{C6_NMRFB-Y-ydhW zVhB7Y2BK=RcQ9@=25C2xufkjg&Z(?+gsl=@LV3s^#d|oel7by}Xsg=8UWF0x9y1=d zA3@T>_MzTe!d~`>+J$L^-;lX&cARi<`q&&W#aD2=`nWC5rfb8SHECG3lh4W#yw0<1 zFp&W5>rwIO0snOw{hOe{KbH%wyn~+opS7c4>j3zxlwa2l@Mo(2pI42Et)0Dqv99f( z#UP>kKY7-V`L1kYU~g=v&dN+j_z{JUkl`cJ+@F+%h2vAiFMZ&N#CP5A2MtYIDQ&=BlVg+%>9`0Pp>HDf3 z3A6+DQ!*O1q)0n9x18h!#HUT`^NBMbt9R$;pPwWNyx&I7-oRR|j8+_Q32Q!eyqIf$ z!+e`QZ&&{kEqzr9jQTvDe>Mr$nC?$|f+M1lRPpY@xM}v;>O3mI*NEH7<#T(&MG2(u zJRCO(4>_`DqO}Pf8=_0CGCSYHI~d)oH95NU3pTG52tCc9upgkeo5UYmxSe$+W&Xn40&;?o#!>+z&}EBiNW;$I@V2XVbY znD5xqj+=hz#9}MvhuR!4qT(syA)|TZR)oJhjM_wf@izxGi4eFieF^%Mvk!wKJ@)D8 zb_;(~mM{4Ul1MvfmC5%3XQ>lqtC^Bas#nef_kolP?41G#iU6BooqI7wVx~X>kJqd1 zj%VJL)sgyy_7N#$-TPDqQ9viPTFNUvaT;&x1S)8c6`1)(>JYv4MEpVta{;qQDY;w^ z`J$P|$;ndJV6if>WGi|7RL~dr)V$;%Ho8ok< z;kJyL(x)+mL$*qlAVK)+eGgfM6Rnb|W`*2^WN&QCQ!%x^n@vJx9f(*J{Z3ADnEgF= zzGD9ydvbhpz5x=quie0^XuvnOifDzY*rC#IOL@$dfs#bxgBZtvLn_PF9Wv(}EqIZ^ zdv>5tcPepYGW4aZsGnOeFabL@BG+RZZguCYR4T*KPP2%RD7}PX@@FQbcnvB9$*rxr z0T5lA?%$#yUkq8O%W8=*rRuG&SZ7*V*M5lF*i8}7+o8|c#EEKZ%8g5k$?kFB#*l_( z;kVzG!nrnkr0BBauAE7S@=f7k;PmykC)Pg4itjw_#2&BPPYrz?)N5)ZI@DKE=P=wi zX<{NFtqWjL#eV;6%zpKJt|k5(E2cq)7M^Ccc5${c7IF1pHX4I ztHB^?l(eB?Bm%QcWA>^v>6jF+V^4-TkU6^6;ePYCck@kOWTL@cfyG;%%mVo>Lf%+)led?NbQ#W zUQC@s7&E5<@f)Xr!E!rzcl&1BgH=+-U_ACWfT8<@X#j5Z$fllh8uHErX!w~kKA2Re3FI=fMDe=lb5=reGF@eD;r~CT6YQm`CEh>=BcLi%n z|HGGsSR?{`pw8?da|Q$3c!7K)eF&z(F=D4Mk>{(V<+mgexENQ($jv0I*=pP0>b&}r z{W8_^4Qr=x&eO`GRX@x{Gm@FUP!$~;smv4v>;8HwRUa3nN|aK%iPerA0BMpIqd4`f zXF)x&=`qXgZg)+-mz&UUw4G=Z_Uf8 zj5`xY>qvTMmQ2Y2TtE}K&h8BL*L`#QL{8wMm)MW&@)j1lrfBCkJ7n*!V$fU$Vu5dg zbmDman2o^abWpm!CTyt<=L0IxLM%h$&)GHnsfOax3O!_UKL{g9M`aE3m<1X0O!U+H zDnxaN^oj6`x;Zx< zPt9nmzZNq3%sga}{sv$qgw;gFN>(I5ejkC^4g9h0?Bs31GLSzrfe}Yuk)YojXtGDw$fYZ_k}TzDHafC406UH$b72wl1zNXZt$BZRwT;p!gvPSh=Gm z*;(P|2$7g*n*6+2sT5Na(f7qqktvuRUjMG#Tb9Y-1O~JE3F;*jj0B2jw*&7v&_iY$ z%qU_!GhlZ1j=~MigL3Fl!)P3dsT!lEgd)j^T3u~NV6&kS#4S@C&(r8gbVTib&guPi zuicBLm^=Q-mKAzd-|)7{kly7|qKJ7{M#5S6;57C`oNG82?>P+7P+}!O?m! zs@2wI*896oMKOh}o+aM>un1SQ_0^jZmeCF_b#J*osSLHHlx$2Qzo%|~)gHK2;zo^{ z6@GZnL^)81tOCtS0k@PuS#jlBv$xNlk&trDsI17_delYH*$gAOC6-Y&qqKx{AvVXw zZ{bqUmAjl#^L?WpE2$1bM^@PTH(8PfnN!J-yD4~f^OCAkz1e=`(GgQ1__*N&MpD*CDWc3iX_DUdlha&N_3Xdl;KdW?L8w&0E zm9^XRWEDkfo$`gW`JWERV_Z8OiEp1#?$OqgINw9INAX}KLvt-77VpHeox2NJ zLs+?*&JUDNqdr3dG%pWFBN%kgu}Ui$`ixud1shcJe35LuqQ##(ss4>eiX^ z8O_u|FhnR>%PgsMdG7bovtDuNtCnnq=E@_o2z(zJn@hD&Bh?9l6Y35f<4O6i; zQ89A>&jP#a*IHl*fF!DKc8|S0@{4-Kic1DKhgM6(Dwz`bndz=Z`3Wy^iJ}>Nw$S5f)}+eSJBAJL@W%P zHU;eS*HWu>J&!EVQI_7D+jC#fd*p|h*fJnJ933;6l~J#+G#ukb4Xf0yHAyGK7uC$P z%2!F%s3CP;H`Hk)8tIO@sAQd{f7H@w0(@Pig=JVe8uXWFuJvVb@jmcZ)Z3nCs(^)U zm(K2s1XJfwqu{qG?hC);)kX|kWCsGc2FAzjurn+%c5*jn*hlA9fG1pGi`m1L2nXi1 zoZnc_(iWQ)4-5G3Qz>Q@Zzbuk(NS&{O@$@fnWr=peJR10&_k%B!riZz(O)}fICIOb zgd+DN3)Z?GmoVhq2u@+w*)w_RyeMew*D7}=1fC1=zbUJ(r?ma>JfB&EyVk8^u*#g= zyb!4^gZacIBn)!<%b8Fd0pju#n^6N@D^yY0$b-;$sI5z{nopbQw02u`i!q<+ooj^_ zMJZ;>eoV`gGVj5;Qz4I5;Kd8A_VP7&Dhnn@;e__69R#RZhA{L9u+c|D+6f(b-%xGjO(L3$CB6!gwz9ry& zT1J4G$fz^hk7x+0_bjHq6+X>wkS{ck9lq;}LvXjB-nop$qh9C0lr$IbziypjWQ#3uL7w^ryNq4F z0;LWe?tC~DuHSsYQhwaTt2`=?aktlgxdUxj*}zR!BCqedl+3wiAq0v+Qk6_5=_%Ln z+z*GRH6+qhn1iDsFy%y~@7->CTz%yk!KW1f|hh*QKRiJK^ z{8V(id%Z|~wsL;XPqOa4_j)xazkC>KZ!(}vOI}gVq*g6SF zZ`jYlT4&nUGz5m=s0?A9+Y%Au)9WXrcw`yrF=LEv1}ep57mkphq+WNmTv;^QB?7M* zLG6PJ50nf??e&mO!~=e=QMJI`7=hclfngJfXr||M{JOZJU$JvLI-C(aN-XBo&RrRf ze{L^uZqk7cCy#*NcaQ6f6^IDuD61P$(?`PyAr#YVB3G+bx}+euoH(i+Nm_+$qTaAh z6{P$4dY5uPNw8T9ibXJjO{|Yn1826k-=7^uDB+xe&*=9wQrH{I)tjsGBvYRh=MIe2 z;z(H|bvablDu1dG0p7jIvjRQ0`rJse3CV8X>#j=)^xyVCBMf&rB2;Q=#tr zl!gcdT7N0et_l$PQB)AOO|K$ygFVX2_;v%~Yv*q|B#7Ibj6Z3Hsm;c+I%Lo|E7S;v zu|b}RF@Q!dze1cj^*OaHRh@ai4q{2`6t=nY49-E5U8d}b(i?6_hx2vHIxOw5fpdGT zpD+2by%Sy0Z?()n`!~Qh7$!^sM}VRfgf+aRGSPM6UO`28^&}qVc+>SE00xH;3P)k# zGy0bzYe*rR2AH&8KiGJm*Nf#gxzSj<87A|)(5*u(cA!ne{qZnzDZ=Trw`FueY?&1) zsJi4NYhcWDn)Zay=6uEN)B+r2id|#_Zmne*%eo*{N?%#gSonR$%DS++XdNgO7QiVZ zgwV$PPx~Aw%mcam&WkD`5)BWIb6avl4sK&AQQ=8_<;Yp=b=aC)Xo;xdsbeUHDTne4 zRLq^c1b>IYA@m0Ng&3PxGUc9$Rf!e*Nt7axhUV{e%9xndlEo$_aQOLME~$8_m`Z^^ z=Vm)x${5h$VkL^@QTmtv$Y&Q*C+@Zps-P+(*K`$)3`wA?s-3|Fn`}glNAB*lHXvjJ zDu>=`on-S1IdmUpomZ4S3kf6Y?F?^|H znDBRk&$-amlNh-0f#fQvRmS9Feth)Nfxdnua9_KtvOlxCSjZof@Yz!04LFy2F(L0y z`NfE^jUgiykle)~ORf-vodU!UBjDoPHU+f@alPF1{h;L{L_4jM=OlbW1B4(|Ldm;A zu=ahkH!&{*pZuV!84zht#lHnAB_y1#x3@DD8IlN!ekU0QX!nTYVultKV;U+!KB<4d z_M_N*Hc(+m1o zf~|YP1{^;=^89VPRWGx$*kACoVYeDB$-fMz5Mlz9rjCiuG+L1Dky$?56p;Y4%vkKs zpGAqmkAqQ&Gx)aXB%#HO-K+9x_r$ym3#c`|@=$7v;ww+6JT=`JmL`m-rI{UHa|d57 zs%jypcPlY{gkV|_uf@Fa)V=u@8+M`5AA+)}lB^D>ZxP9f6R)$AM6UwRvWOP9cuU7x zHty3pvoeS@2wpZc6IG8yS}E-FL&(apnSZR^v*@u)ea!$WC zg^nsY7V9_1%d+yOLl1l1flh0P>gK~Ar<*rKV=pqjlZg=1W{b)@f}90@nIaRaHla<|CS=)0Zx(tSJd6{M>Ahh%y4s?#Vu|rrq!~OM;XLKri zzwX(V_G~yWb+rb;Rg&9i?TwXL!AEo^ZTy&l#hD zQQuhboP3KEblev9xax>(fwY2aY<~eapwLXJAp_ltH)7~8ha@614nSrmwdN(K&mA%( zDsH*`N_HXq?e3xqkg0$AGxIr;=E{BFID20U+q(9-h|ck*JGbkVdK&*&GqVN!m^xG4 z-)cp6r|J6mXXdgM_0@_{H^*iQqN8LFDZG?~wDA(DOv=ERS?yXVE32aG**gqAcJf{L zWRB3_+vf=I2)2l7FlMMF_~2(f{BfDMSroI>bDQiM%J!kf{0ih2`@AbZ5DfWyNxb7dtvi%8me~ zq(uJmV$>ErVzplED#`E=sGp~+AV7VDdWW+k)cCR9-UzY%7YO@dN0zhG2f6+jcpG_j zpTZ0w&*fMaq6u^hlrg~{| zgfGN-1%r%A%9<;32C)gz)-c`QJw2uXiM|{=_}Tk=WRbZcF?F;Ko$w%b%69XCxV76? ziL9{4=<9`_dNvoMO*8E2?+{;Cl)s5e-o?yXLR)s*zBJm=)cgne{lu` z{HstA9|i#3e^Lji8UL@z0}Sl{JMzF^BJ}?O27VA0 z=m`IiBK`#iGSbuk7a;K8p+C(SNlQOE#DM$su3>v5A5nf^|7bbnZ|JYGCI~-Hh<;M^ zF^u^x&ojo=%VGSoN_H9Vw$orP?EAvw=@4hy8Rkj1)XBA)4r=3btV5gv!%gm0aZuJb zCS)^FKYXHVF2RfT6SX~H?PQf$Ntj!6gD6xx9g;Pue;G!dphEX{pny6f8PWkZX@VEImc5#~4 zrxOj#1YIW4`eg=dF`#q|Yfp;c8iUaQXJ+%Hh>>Tbq6DB<>euyq>F@r}>w37(+Pw6z4t6wx5=ml< zdcXaA*4-N7exh-&^YJBR{kN&c_9raZ|NQm;Ij8;)!218i)cUXRI{n9t_&0d{53Kx8 zX!-;C{sTk*x&DI3KhnRU=0EA5>u>n^!|pG5{ZHB7(Di?Tq5oPba{mEC|2572leY2! zoBwm{|B!YjWM}&mqv-z#Lo7QwGv>;&oyqBwSUjqzK^?ZW+Zow9p8Z!oo#0- zC22`ZT@TvP|0&Pblt|!f-9Bn?xY2v9Q$Y$vC^9}7O;luM45uf{@+?NYL7erY$p4zc`DNeoCp3}+)@{CvQSAd1 z#(R>*yku&n2VT!tR4xDgO^X9RR>Cj%3$T_Kow978GzWn+)?IEF!Vlm)-mn)`FJBTj z71N8tqtcVubt5nI zJM}mf(`LH8I<}9LvL+ne&lT(6o_NmzB?cwmsDTXJM)FJCI@+Th@~KJ`flaH1jd zST|^RFuo7*SoL!l>?YmT_p_;iT*;A>u~qRgVoq+H5H?K0@ZO9PjO?+|=vhsZLQiQF zO514?sVgY|YzfN)J6Xf#imXm!@)CgJPy_*6`dH;xN}$f#wtxN02?Z{ilpvMkG%qwe ziRF=QVxLIxRChW4Ei`t{bezlQOy!}Jm{h~VP4lRup{Y{wi6%C-;~t5bey~#cZTPu( z=mNiE2dP58a-$DjshOaf6!MYL?^8poG|gIsPLmTI$=!n@Z1F$&JjzSM44y z5VN;!qd4ST4f>u`WO@jEErn_#{p*H_c2)9F#j~y9?)4p-DnE)X0|F%%P>=q+X|avp z88~}Z%gS~-W*LHgyMv~$l=3j1wpzgK{j|WY&kyDwI zgr;V<7taAzr|e?37f&SvqvhAqY6fMs{rg5uml%$(;Sr7RorH!WBnRt=0R4yJ6lJR8Xozy_k^JP>EO)j_rLZu9Su=Z#r^jv z${lEj)>^U%j9Zq}JeEz(epBzI9)aZrA{;0QrfM^%Wx4d3x0$qpf9+$Zzg$^4+C3~xms3@HzIfH|>wjtaAp!+7aP3q8b@UFT z07#=ORt%KccGt`4nH0r(YFW9@NaHhlPD(EwXhsj&U-^Yo}az+P>-Ui%N;y(V2m^bOFe zEx0{Z+n5(sLbOgW2pVV)Xj66{37B@&p^Ys_f~M+0$&Nt$?+U5|>oE1ak`#RsdK6v0VRDk4q%vjhGLolF-c=71D6d zvs}HOfLgqGY4e9N<`fAcv;~Yy8mV`O@}u>aYd`3Iv96Pw_wR zZ_`T_b|2*>Rz*O91%a+6FRa~6DD^J%WDEHGxK|n#;i^ZRmaA3%@YM$Xwjw7K>+|!- z^#e&oK%G)Qj8097C^nIhF06Y<|9xD)V=jTZu}~eeAOvMN+sGp6hGOC|sT6!B@Ux$Z znK-4df5b(VTfe;0T7&-QUh$Ocb*51d%Mpp^(+>;;DBX}rx zWn9z`1rG^nL2S0hz807Y$%34IMY*7ti1@1zJ&wk{L1#nskSNK6b}o0T&O+eBzB*#r z>tPZ$?qn=YPcmj3=!rH+IK9gtQERC-oUSDYv7u}=!R4WAH=*VYg`+qDs4UAr2dD< zRP<}n+(7@0T^ma>S@k0pCQs(jn3qiP5GnItJudZ~bL`K_fY9PEr^-x@lYdRoCFm7f% zNRuGL)Eo(Uzk@7E`~CQ@pU!`Wvt(fY_mCoN|F_I;(SMxMq^$v#@-7y7R_1>n%l?DV zP5(iRq-LaN_&AV#e6O-Iu>R+v?B9-L3@rb~=l-zxcRn}!pUVGA=l<&>`2X=;{QstN zGq5oJf1Svp$EA7*5&Qnoxo<0ds!h$Nm?l@vr~JJ1R-t~;m3>41oFCNI3Z}_?`RNgk zk$`c%Qs2$AEaZfmZI&<3uj+qM_Ks1SG;P{$RhMn6tIM`++wQV$+pg-eZQHhO+qS;y z=bLx$nLY2?v*t&xxFa(n?)VXrE3eG!JWlrR^TceQM_Nn?NWKQS8_WX@sad3;RjUjF z$qF1zEu_b&7Pg>-OWcODouKNaY?;c=gdFj+3GxX~$;}e~IV9K(` zioyEOGh8BX5WF%layw0nJklcFM|r*&Ct!K|&FNPUD{$2h8WqbhFWD^m--f;k>3GsG zwZoL9{lSrVh+9U~S%_QsP;w#tPiyXriEHjD&En&M!yi={vxKHfJg_C|{JhStSu4u) z29)oW>l|5%FCIXm)1JfscA5MyQoW*juHYt22^a;0Ds0J9}8X+oIH$=mv;9DWHV6i z1hFkhl5L6{pO7&&j_$fJ4))=LkPeFc%Vb4qKsW0h_tcYzcju|%g4QJ0(|X;8y_NGX zEeWhx1V;kD{?|rXlA{`e=1pPnwbLY_0J#S+V*VFo{_)kq$pOnJyv|cfehUWvRsV1e z6~@^8A!B?4NnsN~XM6qPoIQI_X8uo0pS)}g%ukJ05vT_wSs81qaLu=xgW9W{Pljy+ z4USU*A}H^aFxgMn%VN?%Mev>%f zH;y(;jx!$56#rIm#tmpobnbh4emQ|NXkE6y_BhwV-}X3>H7htZlg-Zo{rUTU6qB~4 z@A8ceqR>;AM$x4;gnFyaWw0)3)a1vPRfKUmHC zW6j8@2G3RFc}8~zrr?33a`O#+XEssuYiC<62Y!WZ@u&Gdns2+JXKI*I+yR~HGUquR z64YWIHscJ=^WNbd;74zR$hJWk6{^6P3F0Kdx1cJ&kgB`tg3PL{pZb0Y7v6zQPuN|d z&if_WSQCuB%=_ZWa=$Uri;+wt?D{njIEdobyV=w;^Hv&V>L!1-W!FMb1#txMfRZo8 zi&guHYx-UB>13mvyYF*dfS*98LfDTBz?jesAN_2BOqpq*9qTB5^hP)%N-|=41_65m zD-{636D{+3?DDzK1hT?Ls#2xpQPpB9vU3u8DNkW2OwwYbvJo;JnJ0@U2^~P9$+B5_ z&b18$(I1L@) z7wH%o7yorqF?u@qNJUY=^+QocHpGi2$#~e1S)npHd)KKCJcV4mLKcxqYjIsc9*l9< zvt2jLSUeA(1nYv~T6RAN8Rz6=Jy=A#-_939jou5--+`E&s=S_X9-gYIm^vkO-wDjV zwn%6qv&0T9^;cemS)pJ9y?9PwT+|}OTW$2?`i!wq_-XqfsEojI=_x5h&oZw3?3}#@ z;~>_=tz@K8#XCK&@+SJkqa;qt0kG>p0QOeu|Ay<=_7D5;X55P?z_+IrO?1kju z!4pw3216eyjMFD*m+a=xe2Mp1>K>pkKm@D{icqow4oVR}A9M*K#R|(R7y-ZI&+5dI zTG~8r8RPk#6iz}dab+Q@1%GjMe@Iokf&?M<1$Z!3X99AO90O+#fqivLThGz(QoF>t_^ zPOO$D8}tHji$b+0-_ZYZg(Pe~Ic-RRFw+!#UKS)ctaoq&C94I zwV1kIeGqzRUm%dA3ek!sJQ%>S8WRw6e91>2dJZ#Ne=;%e1J88hMd?im!p9r`g3qNB zhRGZpk=tZQX+)cQ)GN>uSZm16T@KZCVHxh^3@ZVpEOzo2gABDMdQj~uii7l1IH~bU z0K%pa4)K7nB?w;61^HngQh*@|Ujp+Bi~KS7SFYnbS}=3Og!Q7wGEbjy&vC|sW+76 zu9eARxXqXbcSoE{=@4mx$F~a%M8|>c)V88GgCPkx%W_?pEChvmMH;?z@Zbs|gY9HM zH-u@yj~!mGF5@bDCMb5mXP|U^J-95ZIRnqdD;c|lwf8gxK(LG4dz)SZE4(K*hP^|l zUt#=<8kn9*{Ywx#$;e0#N7`H4*V4j^_-+D7M#tIi%JB(GFm3SsK%SBZw|t(cb`CdH zzRPQ-SxKU@%ialw<8DCY>*vP$l4ksj0A-W*h!+iry}8*@Wtq$K&@{~1WzSq?+ohXp z$4?3?%;8ahTnrN8JEII~YhpJ&XOoxJY~?Zrbc+T)pqVpX2QOEAp&RZhavpJS1ftAH z$7;1?m+B3w{(WP&b%V*RYBhG^4@xB+Pv9Zs?X;UnxJ??a@d|FQ<2n0}ESs`7n!dm> z>-?3aXWzN>VM{)OnO`-e_?s~)X8I5{hJ$r^wf&0cq5~e})bzi@0n?Th1t`O$Dxru8 z`+t;~`~T9Iq^Ar&FJ_%;l0|KmDXaxYm!kQ}B#plygE3K15KSsM&^=M}(&8dW&A`mF zkufxAYF{G~64;I$Q|TwXnWA3TDD>!Mt_WdLOwY*rl1B3C5v8Zqq&IQ zgrmGIHfIt#q%C{wJlwilWR_1f&cU(@yY8Z>>U2#P?CD&dsK||b*}>t2Qdj7eq`1l z-VjSs+Y0D2F(6^$-59i7)rpHI}nS)_86#%^z1NPuM5wo8oxuiCNq@ym4=6 z;~uu~BGrx`Ra=?eBAHvQ7XgeAnUGz{4Cj*5qhmrzv3m{eJ=rs6mQHE@a~PpY`i7(a z%4I#d3;pr~*ak?CV~Lfw5W{1NYKjpbkp8>L&UN-0P6ds49;7{uYkks}neiM!=ggk3 zE?;W~dNNBoi}k4}Ui&|I?0kYK6+=$@-)B5D-$|h;BH(vjoit-tG!P6NjqKwpIbk(+ zX=QeIzP z9CsD_RTcOY>Xqx*#Zt&CYxhDiA+X^v62npkOHR~NjgHuhLv>9MI>^wd+!vw}JI6`E zbap71gDQ0S=eB_Lz4dYP1+{7Bi?Y^}I9}RXSKGU6oC0BQ%aYC}yFjemP`4?}j|`@s z@$5Q?exski~v6JEy(%WOzchH;nHy>{WU~nBzBifu_ z2l`nfjhhgSo!~A;f=GhCg<0yt=DU%?b-z(34i2pt%=cZXh$BFB)m)Xd<)mLMOH=%P z-F*b4(Wog&fl)Kwu2YV%9zdDtj2SPzB5}58q$4A6G!!PMLEEhD>k7J#;iSDoc3Sgn)__stBA*YSdPMr!^{-nB7Hmo_f3Pq|Y*LM=KpC-GW*NsKqO(IbI@6|S!by_arZCZjfkrnKM9MluIT zWjpH!nIuNPiH(<1(IrU${_(`-++$-`h9pxElQQ{(glzrbeR0IXcK6p2qw#c0?+AOw zGaAX~@JmCysqgEBv^;O@sA@#bjqikXL|cZcsm;xy&w$#wK|MU{arexbo=dO!1A7eX zbqpj9u=csiMK8$~I=W66`1}sO!7PHi|!ZEY&0W(I{1 zc!$beAInf#h4(yz>8(ePljd*U%8&CcKwEVxew~CpxUu59j&yEytwqE|{l#k~bJ%4| z1W+)rf4Fv8oaD>DU0aBDZ}-ulUv~I8Hb2)m$gVHhU1Ca-WBljzS-R#9QojapkQ zs)zJuEa%TG0|*Io1{YtX4R%<_;0*!J)IN2lKlyT<#NEE| z1csOQd+JHIOy=5``L#Nc&^Q4sz5;^TlUdps%M#w7gXw^;Xu(44&IOt?D^E~~n@4G( zC&c%1;?G_KRDwiJ2j887dLndc{;FhIgT$ZZ@7GUY0X?iLbN$y#a+Joiox{@p9OV0N^xr0_(cS$rYC1Rml ze^VM71@W9evP{*;Vi=q|emGe&c-K??}R^k>Lr zc09S~te^t~&V6&aT1r%(c#%5GcI(cNh3ngOVDBb^Ib%&onCfQt6HG|%%j;#g`8&j?MCSPs9it-;k{YgRKJvf`jus$Ev>I-c=j2y6 z1DGqM1n%xl24`pJko_|#cW?X%=j0Jx-`X={rpHLuK}xhsdzN>gG475nnm1Bc3JE0t zUim1%7>CPYIlI55xZ2N*tUiX2rrYs@rr`+@A>+>g-XcFd;sVl<3^Nt^Fb>+(+5PP~ zS39UG*(oRaANx7N65YLRE_iSySVP>+J_2p1Ho*NPWy}^7*|plGz1pQ++QT8{!DkLh zvydDSDl11^+dw@VKHb!9R<3%Ehh-y;Bl*@B4_#}D?oHz=R@;m(Ayfhc(~`D-lnGcR zN$Kzb*%;4js7I!%1*HAJ6zV0} z1Sqbd?EDf787Pak>zNlW9qa%Eawe*y+prDxmA6g zgN=ipjIdN=c;E7UAvMRBd_T**M70!s=^F`tDShA)C1(7f)5Kk-n&`UiCxi-Hz}GT^ z6mKY`r`C(`m7N$JNCIo=@v*$7)Qz!^sI~ky0qs7mS7w6n7xdM=8@>8em@?O?b$<7F z{+P;qdua?la<0cC|G2yVIw2@09LAJNhwf1Cq*Z-IQy z6Uq|=Gg1{US~!K!V@tgJfL4|P`8gmbPva=?u)GmyMU~?HSWqW#NA7M;{H9mSY|n~^Ps1qi5 zydxEo?PL51fjb&kraXK!yn%>TtFrEadF*GR$>-)!!y>Nw^vnqZZPs90#--~DdHSLg z6PeSHvW&9y(HI_WJ7^%cXXI+#AN};4rDz-M{pPHtuGrxXpxSvPZt)9*$>=kRR_unq zh*u8nsiAy~>_AcL)W09@&Wz4MHWYtJoEPxzZ7U1$Fsc*Q`mL7u(O0#TY}|r!Q+>Se zjx`@@jf5jzL(M7@r_o73UFUrmziok~_*%tTAH4ti85J?tqp2J|85d(xp9H3*Y|(&O z5mH0%2u+6+w8NTTdh&Y_3bkvRgYy0dv++L4Af1(KTJ~!xCM%Np0A449@fu{w)p1+e zBxl2!bC751A_$9BTHEaz-E6q`=SEud>&`|8L{8#bK9BVuuRr!#U3G1|S-Y~tE_vk+ zyP|aPbufB8=vXz8=%(SJOlk0z^S>%&ap%?L-a&}aotRlT86zk#Av=+8-~D&+BVk2+ zq_kKMyVL$KuuTW;uYh?=&hTK2Nx7TU=7LeMj8}w$^z321rkdmS!e!M}WnEZfv4^h_ z;%HM*016*mCx>tYW<(>w+^_!;ayk1E@Mn)%?V*Px$zA8c>vm*2MV_*p127>3Hy(5) z9oE>Qd?Uw}kceGBHgbumx?h*&SU9IkmyGCnGj+{2!1kvUn`%qiGU$eKAQ+DYy7WKm?RYA!P^N*Hx z^n%f?@1-mS%E?88@~Sz2bKBVQGOu0E?64PubR_7;xgXQKO9WeX#&@r>CZuFAxX#mn)m|6T7p9lq*x{6DyaI0mh2Ln}Q+* zK#jEM&{3u6pj~8HRiqXB30nC=TjpmnR)9?rT>km|UKy9==Wm+qL}IhAr@>lq)Slse6>ez@-{iP-mSP_~57 z=nK0;l92?Y6qc(u zyT0Ut+@&c?>eTDK+(vAGX|FjwP`p{IyI5~?r)+ZkoO)B<9Mj7L%+VA4Hh~+5)mDab z!_tl7T;^Hm$#_))aPfoWg+sM>_Mb4yrZb63&fxa|mC;OGz&x7%*32XGzhky>(J|05 zU`t8@I}U>iN%8hx&n@*ZxCkx<(+J|0f)0-~fE4Yjf>8wTfCTE>-z>j7w3ULx3$g9( z7v*A(&k$^#cR)4KBy_$X^jT-Qy72)SJ#D!?O_VKKv~U@&Wo~M?!EFs~c)Fb7RI#Z& zeOwGpeR_Q*>Ju!FyQ5yY*LjZ(GKH^NX*IaKv<@{oRJz?(Mqw4hB=)iw`C`ZamZ^lV zi;pFf0-6-l|CLvp46O?7pRP=jMK z;p#wrw~vSVMAg#tC4CZKF+10F*^W4LsHhdVG46+w_I1BIs*&b2_h2C2wOd!sbJkOY z970A6v;)6rlgt1gp2A|G(XGLH-~S_Vtg;&sg)`!_N_+m_=yJVVXIOuF% z2vg|6^q8`hm+ev^AzV1E<(a?uav)H$XGeenGwDifjR*H`is!2+DQl3$TKi_fbEB$4 z+J%tGZR7PqLs=(FJdSy*rrOak_@za_ljG8zElSE`yA?~jqtMNG?RfaL&HB9EDs9{! zPWQ_N&LavIB~*-(FS#$^m`S|?kdt}F7TRBpzkA=qwf5+dLd5hrS9YBMjLmEO+=YzN zu`B2mVTl$l!yCu|3sgJUcPTVxV*L9%#9o}9C^p6j7PMN_y$x-Uk#cqk z>~Lp{vN@~(vA?|U8N^p<$!AZMFm?JS?I~Fa;ufs|X>z~+AxTm1WD<`zc2P(3f#H-s zgceG)M+VQ%bsULI`Ab{9p5;<&=RpP(Uh}ALr1vY$yNK!D>V25miNZP{=<*jCrzVadvMJ-@Z2&xlgwl7$ z;KmC^o)k01_UIDhO@z0FI-|CF@D5~dzV;g!DY)U&;ALx#!>ME`X@q1Lp@(=)%zEG< z`JvG{JdUzY=J~6f#Vl2*xNJLYfcJ4YLvY4(5-u?dpg^Z9bD(1`nUf27s!_1^lB?dl zvv|vIK0+lmdM^m=H!hC8+ND>{xDyZQvidf2gjRAD{8fWy?7>fH-v~Z_q`lcL141iz zfJ;r{pZjF2SK;`!U2{QfiHmef#T=R@Rel^3-Q_i2pza~7uuDFXK}(VjYE`gY!e(U&!)~?L*5wVmv<0Oo;B*idiYcwiXkvW>JIKv+;~W$VP>(WI>2xk%zcl7+GW}c#7;;;3?r(M9J zjCn&!WYQMRHh~NbK6>bjdWILprO`Yd6!+02J(9Z;GtL5^?tboGYd)y^^xn36pL>|C zSYJD;a)n3|?fi82xinAtFo1n#WJo16!lZ=OCvr3B7w!n+mE{aCJ5aX8VoOBIfB*zu z8OO6v!?4v%PXvQYmm5al+3Rh^J~=Z^vR-L?7dlD99>-d$ zy+hlgzgPk=0+ro9GHufKuk#7=RBSQmVwbPi1vcdzI&NUk;2VRN9y$I%TTgD^Y1K`+ zMS~j8tCG0tx@|RvVR&F|dTqZRquED}G&d=?PSE!R6Zb7%Gmi?DnjWgIAx0{jsjF0! z3R_8+$6_p6E=s}2Vi;Him15p6hMDc@>r3qsc+II$&?f&F>>eG#mqH!97XejEZeFN@ z^O>7<|024$Xi;%fcy<5M_CTTTdze)_nZ~m{daJVP(pVj@*mQ5YA276qqj|fwr-x*q zNndkb3Nqhk_*rkT&G^Lq{ADm~SvMhl4P8RkUcr1^`%D=z&|62kl1fRKM6#9APN1ew zI5HAII1d{7v9;gi%E;?GOrhoYF&YgO)M-e$Z?s8@!(}V_YP<2~a2hv$}GeV6Dt8~e2NzNY0|x;0gvbCfbHU9rXw&7K?X zczn^o$2Egt=Fh%n?Y(vKTlF_`wd7~wTzHE0HS79wr9)pdVlSP(?QNOM{NtU@dv`@5 ztOSXS1Y9SGn9{rQx$8lEU3VUIi1+AEmW4crnZleNxM0^lA^fT70JH&i4wH0-Q>7l} zltI=kPPsOr!xxC^t&duq2t=HF2|B2vIW=ATB|$%Rm_mHd%s4)1vR@0meu9*3${|MA zzG$_$UmzrzUrd4R=^l1Zt7XO=ksLP*F1Ma(1v)%jpF1oLnW!G=Etx04ME0R{!187h znQ&G^L$rH+)y~iR(_ji|jX?hGKgquGw1m=oHUALv0Q!NRL4z_ruQ0hWZYt)si_Le*NppJHn>sSZ* z07i8Y@;Z9#Jg^y14V9oeNa;3TE90nPPkeEP2W++kJ6W^%JAW>8bReEy6qr-Rm8Q&~ z%|#tQG6-@IvMTR30bZ7W0m)OuRhq`clYl`vLz6vkNEw z1U>^xg9^Ao*<=Z5W3%?dB35bM8Nu{ESj{GD%#BH+6$*DhRexx53ucD4@Hv@r8pRJ% zh%1D46z2dv>hd}z@5eor`YxBR9;^o2IBy6k-ZbhP-NrcDs9ml|5X!QX;44^@IvW9L z>|sshIrMZLLa}na(J+sJsAKX3svbs4f>7+yGmx6yGkg+u^;#UIk%UF5N5Fn!bPS@` z9XNyn2Px*e`f;xe2Pjcn*|gC*m)z_bF_Oq zd{eingKjl_G>YZ6Rl6OLf3sR$b`QyB^?LcfBEJJ&0YnvLTSMZ&>5raplEcPxil9e= zG}lSabmPcU`?Mi%)9-L$9>2nG>UQ(J@dUZ!-X{QbGRFB;27Y?de^_S|A(Px20=z?H zcY)X}_OwNLB5w4b=pnEUuL163P>zb2E-G>z7O>q)Al;nEkSl}(6H zb$pX=ugYB)VHWomb@WU1Gs9jcjp`CsF)fzXaBDtRqRt5}>MleKF=Y7nx_=?d=n8Q= zpjh-R#chNnxGUJUz3NDTPblS6@KDM2osz@L#cNNQ`uK%Su2fUP6v_9 z*P>Pk(v%wF*lqJSl#3WG6aA?LY}(FNKa``t8=dx6JD|@hF+{?Yh%j4;KpY{=2Cj1} z<`P3KHjI#0t57$JiJg!g13swJpQjJ6T@h{=&k=NrS6|GQJI8G(7cyRfTc8)@Ue_>F zi;ipgk{<&-^o$gvx-&_?%vWd5ExWfhTM4LK3|^?kI5_*FZ!ol#$Tu|9_n(Fj3kZ0P znncl}3Qr^G9e$<6x4uuF=|#c83D>|1B*W3lz|qPPl@M{S)EzDO?b>U>ivTWE8)$m* z&@!ii%0ynxZ&=L5Nrh-;S(1fZX>DO`a*k*hAn{650txxPK3GX>IXZ?DpXLo1z`sul z-#6G05Eui00?EYK7}#2gz@AD?EP8CFxsDjc=)|Wl(I%UqkwWn&_*diw0{;Bw&v6V) z*0Pe4f=)TBa_jT30DxwKS!h9>j`}j9^=Ww-W2ht83PW@aa)QV)%s`AB(R{k~8E!V@ zpcbE6F)b=foR!|&!^Br3T~|^{M#dlw)Fy$WT$J7cec)r59`)5Vjzqvw!^jn0X9X4g z=9U7_8u-F;2o|RX#uCy1QF~H;mCZ%;6SESyhQ>+&z(&X3X`!Dr2UM{}?C!;m&XxQi z)ddjAdWeVjQ#)47R@iQwBNu#SPJzG~eyiLce;(A&P#7-mys zYO4z~E8v2YZF;XDygwy$4Vv>D)$~<^tgJ08z!mryyAd^X;U(8sXKZ1##1%x)VwT`d zCozPr6-3;DgPg!~fX|NOQtlLPKTZt^`ZI#cSn2?+Ch3`alcOb4S0U>U~@^JwdxXt^r&p^%- z2`~wi`3Uoyqqg5on=pb}0crut;!JNr?tv_CvIBG~cm)}>;}qi@@NY95cn>6k6|9h> z0J=Ib|0(QwcI&3a8Km;t+;IU>glKR=1|=1@r>I}@KZEV7Ls-Q!Z~;7+2D`4QQ_U zXA+5(6hK-UkVbLnFZ|cXVu|=qtpAkc7Q~zbqV|L+yW$2$8L5%**9u}OL5LWbfwjzM zSBA+ilQr%0vNkDZ)+r217$<{$>b+X)DK;}{5|j|C8@l!N*))yKGY?zh2&5OtR-8(X zhG`gfIZVVTrW#NwG%x+sAA4bWw~TW|k~6-DAv5!d{$(tb$Nu|VUd=2Fg^V5h1#L3W z;M1vik3A=NvS50aSVO3;+&RO96F7xCJIc$>@B+(<;-R!)zm)Oqvua4LmE8~)wkfO< zUwzeQ@T7F232tR|R#%yWG*tYWbIy=vrsPznWRz_O5qe&k`XN={pvv`z9NE&s*G;gH zgz}DFMY~V$I17Y9vgn2}x9A#(CYS1%rBZA!1{aMWB3u?Fv$&H)AAv0fO2)4VYBLF+ z2N&*QZyV;L7;Dxj;**TWxaZEa8N)%ilEQP~7HLEV!F=Z=E^CdBVscRA?Pl%+{XxI4 z++LM6*qajXh;~@fI0D<^@VzCSkBmyLaT+E*+SVxR-;kyz+JE38?Za#ky1)>{I(e3%B(3 zG0nQPv#0pf8c^|p3Df4|;5J@~gs$ZE+)n<148ul^yFU>QjN1T|yMIk)8*VdeoBbBj ztA%q;=}G=bVuJ>urmC{4E_#}fbJ=)|q5+$ldt4P38IRT8=lCo)L+)_$ILd@ky!C0b zC26IGr8P;d0qklSXJg{o$?;r|vd!pXwexJBI&rIJ;|#IsOkaFP`b^rWy}8bV1Zl(7 z;pirV-buG8M*DSp(P0V5#@fHlgQC;ftJ`rZ(P8O^s;H3`z`-V*tZ;rd7-m<~qQ!k- zL(*fzN5TgX`!vuS^tWc#(C)wg4)(zQ@o^E&6={oqPHQf(b~;zE>_Bz8OCBZ zBrT3X+}R?+${@;$v-4(NxK`J*#QfgPmTRs9*SS5wl-wbV8!SpM&!vm4Q1KXJqp!TB zV7{T%vU>rBlB4l{f0jXFB&C2Ak=iNHS4FEpUrS;em4l&9B5-mhLlSI$bw|4YMhW8c znYvw_ z6blm$1qr9dgyX+|Fq9gZke?ksGw|5@hHX9gYMrHM_KfOm4tAV6+-wX@@MhISn8-5>DA5VD~9agZOAVHT1UY!JcDuslsiwLI@;^%4adfp$ws zPy8$_rSmKW_9OX2$Si!+v^x4Gc-SbOB}}ks8QRG9P63nbLvE@Ka4;azxCT%NsT)n8 zfWHH@)-CX6Dy<|x*hqe$E;Muw_;wgHY-knV7g#8;kIKKz+y9pcpN@|0KkGZ#X#Zc; z@c*Nj{&y;Tp?|Bw|Nm3qGcz-OYdvTgzTy4MwBLdcI;Q_B_V`~Y@aeuqB>!IT@!u8r zZ2w(>&qT}gKj}Tb@%^iR@%>(qcr3vQTpOP&3Gj$e;r;kLkZEAFkGzy1YxIZRYsRJK zaiVNKW^SeKomTUI@%^;-5|5U+Yk4}e_B;-CU6D^M4<{o!ulTlcPM&T3@t#dfM&h+G z?jGx?-dxZ}whiL7S38%DTaoiuvxP31!S%o^Er@=%M@ek}5 z?`-og>ykRDWmA-AFVlf%Uap+Mf4qaDhxQd}>IlR+oIaVEDzegccH@;YtL7HGx}@Ky zKb%!iB-t|7vL>+0sa5aVmn;2I=N2gH<)IvOTgP)G%mOQqU4tv7%3QT2!%tM^8ou3} zuClk#o0=L8mIbcRtFpIFXmXw+miXGzp^Hz3b^7*(br*_G##3BHynmUMO7t zy!&Yqd7I+iqWxC>K4fpvj#Wlzk}HJ0-nGTOYMe)Oa&?HhvUMW=lKHb~h`KQ0UZDD+ zZkHxe39Wu8gS5RHgUmg0Pw9SG>{wn^+kR|+eUeD-1yH`dgOcw6TK>D8!uG#p2>cHl zzWdrWp#qKkGmw)Sj`2l|wG5_@c zKL3r||G&Tgp8Ia|cdWnH{-XBj|D)YMegC8XH;3T=;`RS^?Yr$i|MOk`i&5~evHuz8 zU-SCz|M&Xe{{OW5uK(p9{A=!i=k)jZ*BJkr|3BroMC)()ul|3>{Wr{mf9^~FRn7Cy z#{RF`F1CNeJor`){SRs$Hdea-$~<6oRmED$=wiu(!jEb0$Nw#ix=j2t0D;*lBJzi* z4?drd7$FBUbR4f8Zyb^CkX75^*bUJ@PYsLdEVfR(OI=6Ys{e(hO)9h1>LqcS1H0?g1To0P6&DOThe(%o*M~Kj(dJd>)|_Zbzals^EevP#k9c_xC21#a zfOcTsTc9`j-JLT^Eci}yWOnX7mJNf%lxGFo1D#pL4Li8iUf)&@?o_az&j868@Xmw(Yc#tiI$+0n8pAHw^fB z+4Manvq5t#2zUi+xhL((gRB5~7l5B1!~=<$;a%$IQe9u(7=cz0 z&%e?G+_#OdpCB&*X#}?!MAck9u`)$kK8EjlVV_TjQauq5V`XS)BD$#<-&D5dgUB?RV`hEo{RD*fJZV4Q(MyS53T+_aXj0FxrMu;l{ z?|Ic&T-~kbRY&I8zX8~_M=XL`5`w_Ri%j>$9z! z%=PKy90DU&2A$;q4dQoR17%J=s|@4Yp{rngD%aR?&C@(mf8shDp>+knu@6zL`_Jna z+d~ujp&S~$m>2&%5>2BmyW$tXL>)r&+y}WuD$fM-5GaWadoAeGCUucPrkuP5u7(Te&B z+X=mWy57=vg|*7fI(>D~cDcHlX}O`5f$J>dzQ$C!SfQcLtkYqte;4#{hKc>~*xF#O ztfI1_tQHv8%Nb9{LZXpXFlRPTo=G4}GHTFIb+@3GDN@^FDWB9K?T{3}aqei9W-N$G zBsVD3u)4S~Aj&L;DkA90L_G_68*pwq|*O-_Zekc)tQ}L_k>8 zFmN=yS`h%auKu)Ok9}-ctT8@M1!8F3HMOBzqyF*OYQ?s+*rPfj6qro1G>?!6(x&{r->f-$GvX&dCM40nsD#FSyx=EakdEc@zzOvi&->!VvOHc z1@oD3IFq&7;G3;QckOT6>Rx3Es=ggpw1{87WS-vWo5AxE6}Ii>Uk$AS>?Wyf!-7bS z-9qcix%K)sAE95343r$5rw<3i@Dle=gkx{)89nG7ntL-NUZFhQ_4f+9Ki^3 z%e5ng_$v}1Sy>bf2m52zd5jX9D35}2n%iUtG5W!TJ5(Eu!fI$z*Edi(Cj}iuLBA%4%P5Yv)eIqJk@{ zm4{ZgFHl*d=~G6A8Ut1~puw+Ct}R-ut!=g==}Vfaq*&gNu&@<2KEp`Q8MF-J>mF`1 z%qBQrO*Ymw2Hcot=5!ZAvNCPVF+S9!ZcXV^Q6Ol%+>WrEUh2)i;e3fW`1z0k$CYpF zp4I^y-Pp*6)l%m@DRhawzQbYO`_#+P^d@Z^V2)>cH>HF><*eKf2P1qynt(|5OFlpy zlUHzPpUPMZU@oFe4>$dZ0| zSiJ#t$7+GSVGFb-tZ@p#9|uS>nLT3njiz|-vcHu^LsU0i7-PNRU=938R?fB*%Z1C zqoJ^b!mWMnoi4D2>8sK)z#0HZ@%huZ1#>&WO^eFw*PK7-iUkEmNLd#T8cais(WWku zK`a7gb2VkC;x-tY9c9ckc+B4~F-h)yn;52ADt(d7EXo!cIl?JI>uf#ePMIDIJm)}- z^=lRzjT$Ty3X7*BC@;rbuEw!TYK{_Mn%?zP2pQc@q1^FGo%S1};3BNDAfsb?-=Zx) zqNfs^HowEQc(3l9!j~nsl=bfj&S5vN=D9dBUwHUTiwbAnsRIh~pPcrZFL* zB3fF4xVy-gj_F;cG;>Nu=M8p?qzDav6STAiap`Wy(SZo8pqLLLgg#uM&7q6z6R8r3-+5v~k zv$1Kd%X1Obv9MI2Q4TL`elbSi*j0|FGZQlyfYf81(J+xFjg6V%EDdMB4Y|yR-8u{LT{@|a0PecMZ2xS3 zxo@dLOK!Wpz1Gk%&&x}+L?sfzW)G^}r(a=HW3ik7ZVHKAPOVU1=f+YGji;I1P33N~ zl@Y7!n*?!$+WOiY0WPQG;U-pKOSH0uoZTI%MS33J!uxjds^-dQzSjx%IDl^Uea8J8P8x;8ZA)S10Hnutz}PZ}F>V7mm7 zrTZPxq`ZP%|G3bCP9Ux6l~6aMIbNrgArU4yIcTIk_Z7{77k~BZJ$6zg?R=tead#Gqhk%QP^Wz!fS9&ocO{aJ6!|?9W96T`U9rJro1DbwiFi@rWxU8lH85x}-M#Lbc z)WoV1vxZ|rVQJ5f+0Q}HxQQjjMJ3qhGfDH(w|DahB_SfApmOf69PrzhcR(I%^;H&! zboG_^-GD_-d%+pMx?BpwA@B85jhbavQB2$?2|ygm)VRbZEzmuTY(qbf{JoLR3;D(6 z3bk+^Y?{tdZD-nSI1k(M`bjw!u2hugU7$CIe$7iZ+X|UoFAAJ?GJ{J^RyngHPO$UG z!;2;>b=DzQtA>@dk6>o%^t~bRizyJRsGW5#|Aykhs|M7N=G3t48015IIPAIs z`JAy4va0H2s7TjAU2g;vdwiBQ!ssPaQE8{iYMq1(xRktcF&Wqc!O87<@05u;4Jldc@4?!0C9{DVSc=%ZsL~1)BVa=qyc1+$EaF<0}$0?N$+)%~`yT@cPX{61ZcY zsSjP<*mBwDPrrA zenzvp#4tv`QpIvoipLG+IE?IiB%6~`&gF=i^oX??Y^fmpQZx(pMw-K9_fZ(w zh6Hg9JqWM#mNq3+^jrBtN5XSXTVQXV?CYdevoUwyrH z>|e9Ap3dCw)1|)F8TRXHGt+0bx|$cqQa>1<$Sp5>DU%G&$QzR+02P~bv+i{3%IGP0 zbS(Fwc+059r$)yxACC?X56*a@2)r5+RfrRCL(cn>G6T>l-2JO7dXcJs+W%liV|6uW z@P2-I3gTGDdI>q1deT|{Dr&7ZUdqaFEnR~07H!o0>M^Lv?B3nk==QST7soTv)^K^N zt~t6v$@6X&eEnba&UYM^f22|CE)^pmw+k@@L1LHw>*>?7}m zI{LD5f93*rgL1+GZ>{tNWTEgu{t-bQTBluV646U0FBTQY!Up$**d?b_6ju9O+mrLo zJn9RvgEe!hY=!iHD0`pe}vhQu%w!3fJwr$(CZQHhO+qP}n?%tlA{m0Ji{5EE{ zBI=;#8@otpVx%qZ<;+G#gsAk_Zx!%ciUrh> z)rC&o0|#F2=X-7bdtu9Ct-MP)O6&zuNh;_0XRLQkcDk$eQ^K0-rTy{c zPH-F?@)z*A74{^$bGP##GpsdzQ=+L0f6hg@$9|=l- zU$shA*F63id?HgFLK=cde>6fyl)RBXtrE6G{;mQ$`s?FmMMB)-?`oQRQNHt_6n|AIfk z7g6)D_khgjN(L{7@xpIn+=t%`Euz4n$>bdAuGjEi+~sVL+97vhg)H8ienlb#=^hoDR8eC{GElC z1CS18DM{?4dZk1o>QuSA!* zE8dSUT5?1X1S_gXe4&9qVH(#Co}(MCJHF?KACpZNyoPxT3aQAyBN%Z%lgr6xu@`L{ zT&5X%7n}+h-cd)o0@dxr3L;z;uF7`MjMWSIO#&t zOq&4{_QYKH$Ua1`TCO5HmMDyEg2d6fra7B{SGf2H!pY~(Gp}FlPhpbqZ0J9fp{d6) zo)1lZl3K=`lrGC@M4zoox+FF6g>LYWTxJ@p*5D&KHKJ-IAHISXK^E$h7Hwio5!|j& ziJSJ7n0CAv@{hFceHf{W)xNYwk}|>4CvXjDc+cGP$5Geuu_k+JZ(Ive_F1wEq2a)% zO5`BC0it>nH|$82gl<^d=tU&OWot3~t79>Yk2Ao1%?)1Vc%(p4y0ic97L!VL?!_v& zyBkWHStMSz{vDAT)rA_&!RU78jkxrNuc3>N!%<2ueoBk#RH7-$?gLCCu>p?qUnz??hf}L0OgxklJ`M*vVoElBb4$B(EjoiOe zvEnn?_`?YUqz0t8Y-Qm&soZvtKs4E=tb6Qt_hFEv)Y-G1&_>z#ZmQIX$y1Kw^ZqdQ zT2D-$v3EA12dr%$tYWyNgd+zdB{2^=V=|CB#|!-h)1P@Eau0cZD0_ESRFe*K2Fw3u z2xGE5BR${>JaskHTVdH|Vj<)sYe@f+vvH{sHgZR);*vXC9dNtYMCf+D%ywxmb8S=g z>l}DNRoFgOQ}u5(F!jf+QT?5apX#S*jK4%pU2z;`bQwQ2=30p8B((zRXc}9VD)sAf1SdqqvN;32}PETi#g8O z;J9k=cn76`vB{h)4joKd<}iM=E@md}A#HI~<{Yafr{Q7LEW~DGTIm=k8+(gaZF94U zb_ULATtg>^k$s6KmuOD)H+KE8GM5*{h-gsC1s=1<7iX>w_9QV4k0MKt(-2# zABCYz^!3j%!*XVaxI-i@T?p`wgvkEeb%|f7s6Zy+R~CteC}Z3@Mhx7@G1S@`OSDMO znnveKJx1Kok+2BGAe7vQt`R3TAF+Ot zK(wqv{sR3;q3v#VYmL*OduRrcY4o+Cu4ZA-=kuydyjecXBfaK`6kZRsCVU~Wq~tyA zJu1>Yu-_*@vH&Hk&@GkVpHVy06NfoLYd3imsUm#&l%Y0q_PcGc!# z?-gEI)d%IKV}6Hj(%xcSQ{EC^=^ohbxE&H+eLZ=v=pLBvz};fj9gG*5(=ZvGU1BMV zvA+dN?C-dThlLEb6BRLEzaUMt|EZGu-z}8?NZROrkMMtywqIiP z-zXL1@9O!l_kVrI3J**wV!_%9A6F?BflM~e^vCM}?Kjup{0Lf>YK&Opves?{6O%$l_D zR0g86xjO&(S}r7=HU^dhYXV?rd?HXRD&9mjdd1YqJz$P#FpWw%V{6Z`jq474dyrbo zOJAPF$6nn01&7N6c;3Cl#PE3x;(6+N#fNvgmoK0OGoAt(o7r=4wDaOYWQ*2)auss~ zIWmXVZvK#50dnkzhUOc{$A7brhETdb)LZ**9|QqZjaT%8jo9T)A^ZI&88YkLDYcXL zIU!5MS2=?jNqQs zvMr1=I(#15fAyS7?v(U!$|AvkW>3l+)JK%W)CoOvBK*XsyQh+hDKeu@G6tF?BG!W*PwKB? zrH^OnskbvEzXt=24Bq?RLk`|HJM`@f6(cMr;QDL=%^iWu1uq^M^#euAM@%%XDr#6p6kiAr5jci3%Tl6On~OmlhLd93WH|m#>spCAAm=G@FWYVNn~6ocAr;)X{cU z&jjJG^6SOl-yi2yVq!jg>T4UA8K^0E3_$gm-m&1&reRo! z62Fl`sJCfJdi|2ua2N13#TS>*40Bv+|sP%F!p8`UiFf{ za?$eD<=V>ji;0D!Ei;Q5f*2D(A3!d3iWVcTAOpW)xQpL66c8PrpXDCgMfyrsYw_zx06AQm8A|WiF zYyNo>E}J*aOKZhlsBOxpKVipmW@AG=)<#`@O7E~uzwsyEliuR^Fov4e_>Ahxk=6B13@%XCw$rcG#L2rxJIE>aIjz>I<(GE=_6J zX$b~TrHXf~*Uw`~>n+?!&hAM`W~*LKc3s=2kMAl5g}D~`h$NyM8M;sYMiF`+&JH~j zBey`NR>;7)lYt~IuhX@F1{5(DTo)`2Z|)5hXbtg)eQ{>*tx+_tNJP%PZdPXx_KjjF zR8h9{Q3@V5$zBmn@p!H--BGAIp;lIs2)wT@l3-F)yLUsaHSWT!n=r!%*;NsWlKK3z zfRy>);Fp{~5F0KsemH~#V5RmsBvQb0!3{E%>HK0YCah?@{$vs$GQqF3AnH3TD1e;# zJ%OXMh1_aw)D(@&O!bD*(P{wZRqyE)5TP=gwdxifa@f9t6dA|R7hRj3(h(0`FK8w- zP_!{oPCSX9nD8HZ&^*xODOvXmdRQz7#F6QrsTs?^{1c9Kze3gww5G{?=0tJKc(4FC z=^#-$OPC2qb2UJ!f*L?U_%y>^;;h0H$;e(;SYLTZIEn0`RR!3?Sa6_QoL+TAQ#(XP ztXTvD zAR%r)GOKqh3I7X}E}FYnvN60S5++bXW2qOE@Qm*@byXfXcjBDTle->^Oi;!=JX8%> z*3FUhh-VtJma5M_{6}qtJ&=8v^3|R=(|vgST?GURH7ptUfnkOongo?B$S`9ODJWp+ z%%FlmpW#-;TuoGH$sB($2Ik0Ezz760on!c7}@qLGvArg!v5+K!-mf(KDfn4{QZ z2P5Z=IFY7s`Mq!P)pfDo#L5Iq2BE@n)a16A(KhPGWZGHRu`v7-`AQHu>DP(3vG;FElFtbpt1zh3J z zoLOK~VQ^xBkdF;q@ahP81-2#xizNJY@9j^^?d|OG8OYdu6u~rO>nc|WFnT-Jebtd1 ztUw)C_Udby+AKlIHtdya5f{wC*!QFP0WtJ4Tl76QeOFc&t6?;c`wRBNODMRkbIE@1 zioOPCBXx`jENA#^mKccU38dOKFd>iX%jht5cSI`azPzNwz>o(w!>Uxxg_M|>5}*y1 znLjB%-!Jz&{Em@w|8^+Br}kSb8fOIwqsyEpuW#MVntpxN*G=XX$v4z_DU`Xl%G$M3+i&fQ z_@CZq&to08R*Kkgyv;*G-n=iYFKH;#=(jg@A*Y{dn4h+Ud?>>}Q&nb?UqZwo4aQzwJz!$wFu(VQcBLd^1A(K$G0+hyJ#|QAyzx zO(n)(Tmrgu;1nZ4H>^*@nSBie@_@j1PSKtagkgUOV&EQN+WjYM`j~O3*hqS5aE_ckd_u{H&o_ zZ=r$NdCO^$`7u%Y(#qgY@X>NVN#{u3KHF)wo(hNN%+zVsott;Fs-n2o^a=SqV;6E3vQ0-HS=6`jichM=f<0`Tg<%Dj1ObSR z+}BVV8e03uF{TEDy7xGpReo)Tmgx3ZGIrWS)L$r6B2?nB9weqO(jg}xs=-P$Fllip ziL^gd@H7KVpMVu%kKoB~1W^xFs8l9!UNBVEd>YEpY z`dV1ExMERjva;M5zPC@|lQXIMKYWA8SqD1)0)s$m;{G+Xs$fA~bF&Y5fe6jKC#}=l4~xd#5U5)}{Q_TyHMmn)J_;V8 zosy1DyQEHUUWAFOE+9xOatv&B+bh`1ZYxX}rABefhwbxpRCUt333UdLt)-?BLh0u$ zos|5Z^ziq~KDLQqj4s~s1`VclSAI#7s-!0pQ$`@AW;~+7gGr2-1phT9IC_moOFq#X z_NyRcn#;$25E@3;yk*EDZL(YbVpQv{%_NJ`4$=db_i8dnAC`ndX`=k4wJd3Cbz9C> zyY2SZE2H~s$Q0@?Om45`&b?}64aVDr1{db*FwqVi^+#J_*eUnWQ@s!zjNc6Dt=?`~2xJy7$5SmI z>;YNn>v>;<6qDQw-$2V{Zo-gu6`SWPEzR}Div=Xh?Yzb4LgKT-rQ6|{Po$u?bnjW_$T8HLGwxBQ-kP(KoBye&g|%Do#%{ZZ{bm zU?0Dm<8g^M#44jmJd;K%(&L|j*&Lu6%~mz+^S`9#dy+0a`mbec%4n|}qdAzX%zne)lC4i; z6LmZfF!zz&IbM)Q2r|ZEgkih27LDp1y(F$w*Z#3Hb&GY|cEf#aSSS&tWlM~v(iZBB zoO7y-MT{Gf!0KGViXec}U?3?o5(nzUN~xT9~WoiY{gbH`-LW;6tB-#(HYJU5#`qJ>ol~hg!_1e zMTUKQwCPjs(GF|}uGkP;p&$nOPw~@}tBFnm0Td|Cq?v-x{&aovGg(EoDgJsY%}Y7h zm$;4~S>6@>RzAflrLQ$Em6O`9!eze^E7<(OImBbKo>7KF-dHWQ@CY&I68&CK^m z4p2#$TNJg+2M)(MhRQ*K0WV9gV2~oYjnd;Vr)1}y$SlM|U?9CHh#}cZ%WlBK2HTzH zPVXW7eB+#<#74WvP!Sf)((Q8Esk`ieR4N_L#x*ABEBj5vyLTF8h4X|_^lmt zJdr#8*+CK}OW{fcol$|ZZ^?~%J*Ph&(H}sgWkLz2`$z?Ts_Kj8e(@B`5}!xx1L~B< zcD!MI(zptKXjh4JUxAs`IN<4bF20n_CSZXv!6LvJ^RlH6CcUbT&kvdi({P=)u@4n!sfCeMK+p0m(C5AFs6!q>1@5E4Ie5z^Nx{ zsoJ)-k&(S>&q1wVQMb1oO8Lc-rD=sJ1eF>qgURp^fQdP^xk#=@IYDQPtNeV9YyA7q z_@sb%5ubF$Qt`ri;~n^EjcUg77zAsdx-==T!(Ty!-M?R!GQP<`r(~OH08QX3Z*b+J z&6%4NS)z^&y*p-@f40DdHCLcL52Hs9WM2MdbvjP$4XEp;Y;ijL=&aMHmYkcv3*(q- zOy|U=Xtr$TPD9fMM&EgwaYjJO2vKCBx|;6oLBURO3c9ZL2>`-2alX3JKG^0Vnv%j| zx}uE;a8%i+C%fSNY}3Z7_7=6C=QiEZ`s}ZCGhQp`uhG6U@Qe|?h$;+bb2X`(WU^%$ zO-%z)SID5wyvm}ch*qv=9|)*dB^?g?u~m~q)76)zD=$h^1QDSIhE}jaIve)|Q<{$Y zuTzpu`TJ9j76xVYJ2EAPwQ*z?(6cAEW>G2cC6-*YX@*wWTZx4~mIc_!TL|NBb6J3C zhD>OK5aO+Vk5V(T>L8p{y1sLT7kjJbfD1nE-Fu_GL6Ip@@l0>VTR%1e;6|`I@F|$QUZ5&C z>)t4FS%RlNo`u>RUBB4f%I~PBWd2ZhSlMX4%mk{W0j6ks*v|->t56)3p}oWqTgO*k z&bWonlrNlxaWf5#v!OfrOdBq{rCB@rP$Szb=n4E=EcT~CURTH?Mow4wartnV8{(C3 zx%O5WDK2hUc-F+y+|K!Mf|$Wx<^)FDF|pQp9=4#_bUvYquvf8BYf@dy_0WE)#oA|z zc{zBWtWQCmKs}P_adlg-qr&Zc`gb*h)EMx z2|xhZBARao{3kQ;P04Q2A2NvERsdH(TXKLCvm=k_=UC_y9!^BJuF_fU)oZ2(ltf z%~uZ@Raw)@8*9BaMvHU`)8SW7Cz{$s3LVp7SAUAM4Q6@_E_QGO8Vtp)T$l1r`E_@T z*&j9lN+b{eA6wFU*bhF(}^$bsr7JP3T(OV{|xL%v-CwLlde{wdK=j?9$hv`#& zAXk2^M&f-i7`kYrCx@HV0qB6IlXi)%%ERF|Cb(YY9Y=S2WW^WLGO~I_ z^4U>wwR-(b=>l!1sAXV(=~DL35*{iYrgj^fpHcjqIuQ+#IuVu4X1g}CDC(QydgMl# z)45epJD9}*sIsI!S5VccXa)>M$`G%;$y}w%tY2epza1eKb3ZkqC1bxh;UZ?wSaIgUPrd+^~L>#^L$BXCP90zs}bMRYLs9FL;}nZ@SxLmfTz{R=Uc zvG7rLZ4+7qZ>XeuB7T9geDi-|YP7Dt&E2p7IC@P$$UHT|dCGGjLA>Z5Z)_|!| zZK+#N{e4<@TOncEbyFaj+jNzn9Ds%fePs{)%W<`CgCMtE`Yfnf`R|n5bF=fEi%Y}g zIQhq{3J=RQX^Dkl;HTSn1=fl7IgkCBs7oFGB+fG@kShRE&lg84U_du!%~6jQ>K>jT z0ADGN9z?dT0v{#1>!7-7+4?cxHbcTJ9IMEiRzspiK+=9HVwsHHSQ~1!87O^rh_ig9 zzl*udY>f}kKI&W4u9`cXkX3x>j&QfqBITlv?fdC(gB4W@bInK3_e-KEy@7s>#IW7 z5Vp=PnW<$g4JHOklDLoBM9d;z0=G{N2APm+jT;Xtr!U@}fSjHCrAPNyQ<07oXVwzc zi9yu3&zd);N?uJ@{WxsIhv*pC^BBK3A)g(5U>Q%!kdpK>w`sOf^nQ`r?c2A(b~4zT zi&Q%NIk7g{aZ6$xt7=fE(o%)YxNLEiLdnV^_2lOZZGn?hdl4POBN-?&3?&)>NhcXY z+nB{ZwHvEtK*xy3Cq$ndv&Bc3UKngL$lzHmIp$z4E1-+qS;sZN^eEZVVf{!k{{781 z?TyyPS;jR<_to69(dstUFI3UY$PSQ{dB)O|fARI1>yYx^H>cHtL?^J#VYfe-GV)XW zn6}=we-OqyU*zfsm-PpfVA_(=l7c>6DPpHso%5_y{lfA|*%4cA!slp_+5EjE)v81~ z4_9rRnU9<6;7NiR`W-uK+H}?|j-Ue+_tGozxH9t1it6a82hweVY}_{9@%@C;nWcik^5hrr*+NyEoqlbc|MIBNY$F3^WI- zoxXtf99<<2EsDY?h?(J*2(W3Kp`5C&n*0LOL95$BRIo*yNVj-$y+P6&80LAz%H28E zj*i2q9M3G?B_b+U_MNtpbk`M5F)J5xK9L~)?IQ_XLZ3_RCNs)Xl&6~M2&#$*`We?0 z9X_w=9NK589ydje?_yfMCrs?Z0~oaKWZ-{p)v3a^iRk}fmSow$4^;x&@)x^=X3}Of zHF>*4ezCkLZ46ym)!a`sm%SvNVnw}IWez!|TvjSiz)RO0yjlri<-+@?y@y9mE6{KW z7BIX})YP_QvM;>@q+<(%6|B>kZ=bBd6Vf5loJso|mM3P3wwvuwlH`SOadB@`r!om9 zY^^Mvh>q@?|EmYO&4@4n&e(P#8a&SkUq$+CrqB7dRdtNw;=-LFv z{!u1vHuV8(v(s!aVbJmIXf~_-+!sQfwRX1~eYN4jIf@!X^$&xmy41G62-2WfiiWJ! z?A(?0b&iMU=kYSFX5IYFs5p6s`}vvNfq;eK6BK#WX*!YmDX9fhi3sa`Vx ztcW0#K(-0u-^hy!?zr=ML5qf{JW9zm5n@FU8RqjE+K?JkW{(Cv1E#s&f8s;LJ`*TzVq3mdrFYhZTc2otu@PiXr#TM$(&gG z-z|_W=`Ay@2x$}jJ32F3klF~9>~CK02l!OL0q&5;i=68Rx|fR2?9Yl#k{$?h796)bfXH{O;eq(kgaFjvEMhIx$1VIb zel$_6Bza#M10wbv35HywaP&iBAgc#p*Qo5L$4fl>Yn>StQ88-Zk7mDK6=PSiM4Qh9a56D3as-KDWk0Q4x?Oy|)0C3w8#QTOEKa}~yo_yg?q8{+BGV7gH z@8}4TZTHwT`Do<>DMx1p_<5?K_|mz@%Ow3KRjMcaiji(lO7C9P2IQ{trEzyJZW-3Y zh5C2e_tMu>w=nl6QKfU<%jwOgXlYHc$3r53HEfXsY?hc)Ax!G;6CcmjYc~|a%q5Lq zU#7+Iu*kJ$-LCh-LUfL{_fN(YX0u45haXLs?w8Zj_-(z_#JRPWorctA0!PXe67-c zbU%<4DF;1%RpX^uiQc9AHoepDjAAt7Lv7b%G)c#Qvty00%HUcL)wFnHV|r^hmoqWn z(~3;T=*BueaeJwF$yK%&12ZGuT%4XXNWi#ZW^%C3nBl_FeE^>{sZ0a1Ts5NR85#Q+ z;rOsKGrG9&9+R<6ZtLEAY>z_($H=j--ghfLz!}? zv21Tx$skSU2=s7c+4@PC7wDj|t=H?(EThxnXIlZ3naB0?{iu;9Nlr^nf9)^%>`*x! z`WEYtnW|4cQ(qh{&7p0ryBF5;SmX8}nrnjgM0iRKEeOpHZ`-(4sk^kx3KHUC@jtP0 z*!5`_g#DhM-45m1+*Z=-3GT<;Y;Mqj8c!$3g>qtzpH9O!VOBSguRSQmXLD65pX-g1 z%@vA&ZLfRDBiB05qi0`=I~Au{Y)9VOG-G}XcruUf`Us)hxizrpjF};h-1kbJY4uxr zx|!Y)QfiV8#XUGsTtCRE>yej)n{IERn`Abg!279VwkOG_nbZpJ35ArAu%UiS`VoI? zD8Q>u_SA4t?krq~Cj+8~hW(_UDd#94t>sP~>FC&Zht7>^qLI0>?v_kgRyv-znJb=X zE{!vz=eB#!uvIeh+pNwJLO54{E+L1F1lp#-27ly7cU9Ajb%lZ`hQZ{&=t zrf`3KD$HE@+y|9tvre+&flGIKsY@sHB=^KE>~Q=c?F)I766LW?T{XtCR%5bp0;-njwc)J!G)oY1s*K>5aN^*}hZ6D?FdN_aCkIQs;xpsfNmXok2M7NaRfVk-_k^TX) z$uT4Sz_IK8RVrt7%zrTOSjUA(cZ9|%bH9Ihe`4&5z$OYDi@A9@bp;xF__K^z-0bVo zYniEm@R34c9gd$*YqZC}7NJvqrA<=fP~-dU==vE$rc$+`2+yd$ejf;QM!Y5t>5br% zE=6d}>5;F9IM`RaiB7p(RBwyd7CLqhoZ7!!+zivWUn56kZwjDkt`0|9&iDxxWK?jo zgDND@$6RlJPR`MoM{ly}R!$g6WZ4()GZYHK)JUzA_m&{1KhyOe`# zW`tZ$Z9JalC{Np@JKrxFpaS-MdIcX*qqdOsm^#aC-CtssG;x1ErQNfjR$a)P2)@Cv zle*8+9E*=}Yj9R0tg&L|#Ggx2g0r=?TBA{qtVOW~VPeYjDZ5Jhu8=Bh*i~&KMi6Am*~BM`q26m z8&D$4USd1WSFm>lo2cp=x=rV@m;)uKpi$9U1f2xh03{=0@$2XX_HJ>Ck)bL>U9-WL(C zM9B9AI25c_!WZNZ)~aS#F9~EqZP&mmN)2Nde8yodhCraCpIUBEkgxS(1dc-_FP zyL60a2J`rc?rHMW!BNPO72I|Y;xg9{%rE5i7}=(d zHrZWiN58MN)%c*HZ_#|(8s++6s%DF#6@#FUMOv57_Es~R&ohme=$4{saRNNyf^%dtAp zbFIDzW?)iBm@7epZg^cThg` zR9?~#^0ErZMX8%k@Vg9#iiu|A&S0-PvHOyHQknt!x9t@=UZyVc9mtAZH#eY!;lVMX zThoo9W|t(owP*)J7;;e_0wAQL|nby@&x^B+y|mKgOytpcM-^;xqf z_jV-Yq&>OLP3iL^^RrQ;S-P`9s;&8=9))%$+a{4(lDQ9Nv2Y$Tiv=u>;ZOHSwH1`( zl%^{Kl03p(&U~8LYJQx9JSFp&!HdL+7nmw!N0eH1RzuLpN@d#9r@tqmCtctcUAtD@ zUS{6WsP1m~+mIkMpZh^IUAJ|p+xPqlsLQS`t}m`@LE5GF{k%8O+h*F$C8!9Uy7&A> z8K~24dkQp}xBZaXuKkc3oxX}TFa1>7tz(b{U9_u^e`tu@`%Z(DX*>^tdOY^5XgF~P zNH02T7a<+GWcP#Wv`24`-P5SGX+8d&<&-?i$i07b-NvFWQ?$CcrV)g5jY4+SVQRy5 z((cBic0cu#YO|gtneVdEaGnKKY4?JlEPx1mM085R7?EYuKSCOvDvZaj`-PZ-Ugu(y z6=SzfLy80Epr#_+$lt)+(A}Whbf^e)=02#ha$Udy&5~;)k3jGsRq)v?+a(;Ri@^7^ z<-!YeEI-BU>{5XF!3Zc^ljPSSqf+3Ola8F09*pMaOi9a72Lk}T`DAyUiphvt^H8L8 zZ7*{yC43yr;ev#^+px@bO;cw*+I=-I+dIBZIOA4=L}zWe|A@f84!qQZDt#er%+!r@ zM+O~=b*T#DqM8`0R!kXEf~Tqa`^60YogQ_L!%-`BxfOg`-oD84uED z6meDXwtaPICMHgTJo@P!o57MjsnF@}j>B%NTJpKaJk%qb=8Ku-8pSO1jn->&ry8*Z zIr6V_cfnMdY<2vj0m#)uStODg51*e=m=c4{k;CyExY|efGFo(X*|_|0xl$EVXR+*{ z&|KB^m}>9+(xy4YG`_P-d7Aim9yDwskc)*~&Vr#kT5x>^tEL594VAU`p3(28hMN zI|#r5T{{QR1VYB*Yv|jJw4?{1?^_-L!ip)tW$CL0va0I~0=S5oy9fXbf~E%$r%$LS zDBONCa(bQbctO4;mgq=AEJb!~CvHwGlqz^eG;(@as^~0dYgO4jp0W;gzeov8F7Xc@ zxmuY=!h%NxT-T~NkvY;Yd<`I_<@Lwb=jS}&n5VHJURvXO946d;-^I;eHd&Q%n^#Ao zghKg8e*^WVKjC(;L(*FVF=6JoF^P`j^p%7TG>sW+hm~G#oE~1e-~^h}&S<*L3g1Um}d0n99nq6+aLPc74U0f zgHE%vUXLLpi*@4IaMa=XN0;bT`A1i$eUD3nW)pU^u+8f~r|~hpYjAZm=#mq`Z zN{ZBH+TQdugkU-|w4)bPnczoU^SqvCYE7hvkkkCsYlkwP(<@Ku;%_Lw?0W`|>l8@6 zm#^9k@+8u}?hoA@&NFUeW2dGSJH%IqR&xnLzWY2!mWfB^H3S6r=f{tPDX(|arZH-h z@R<`yW;)NE%U4PVWmd;>QqD!h*Cj5!yyqJA}n@!l0IPS459jt2delrDEDPbbgH*wZH#>Ikk2jV`VQ6NWGh|tY^VB! zHHc&b@Uc<;s!8^;>syf85O7k!aEcc4i?q~flpp7r_i&e-$wb4UnD(minUs&G85nlD z0;!PeyRujlg$QehYcyU-*TdI2sB9vrD|yiq?wygQbF_eN{wpXPA7wzdy*W^Hbsr?-mAzC zE%&5ru=IHjLCM)gT0{T|lxU#H!D83poF$?H!k55|7F0YS9^Msrb2Q-|?Y#ixiFJ2e-4M(tYpkl7x0x zmhM+DYDAyz!YNypG_J|Q29mbrDCBve)T%;Z!`F=48EfqkhrFa%%XUODYBwbhHb*~I zw+#}#LydiW$070(4p?XZ5}kpp#E0k>Siz_D{aP%#iccFYOe@r9x!;#9$gHXY;M=&N z!&^$Ca-&2wjJ8^XaFG%p&f$Gqm!JTM#MWHAYNqw7WOcH|t}2ZEn0!6X#@wwjNlKZX zGi?c4HvS#@P~WbYV()%s>DbH6@`2`QWiQ(;-SY%!3m)ha?D&GrcQdr|0KAd-#1iFF zMx+4OPw`{jew+kc}kDd-- zTz1*8gs|qgeP?J<7UxB+P9u1Jch>WL-)<_Q=iwIi|4f(MuSBh^{_MCro6<)Jgx zgx=pt`5pDaJqR{Jv`+iuk~#V2e1Y?Vvpf5Xx#Q&$owva5Q#5!I?}$Ac8!Ku$*l)kr z#hiFK@YjBAPCebI*5Mv@sm@fMJNmTo-tvQD?|wGP>i-oEh& z^M&=LHvnc(b_cCcW}9%UzR6|xu^&C+W%a#IKR9prmclgs-c7Z{Jls6kJVCv#vccmZ z8ts8qHH|;5MIBX&{?510k8T^GHe(E5TJ}Un5M%(XGW| zr5dq)`s_W`CfO$ECO;J~8a^e|2SKMG9f1H4Tt*Sr93TCVMDkL9c9*P?Leb@PVG(AF zzheMP(86r2(lnhI+|ZhF>h~+>7-fL!$m}L{$MiiJqiyh*G7B?LdxZtHP$KiYy%r#~c-IErW0X|Uw+?cM5f}CbY z6iXeFZ2A1|ezP*>4n^esJO^ElsiVC6ygA&yuCuaRGE+^VqqN%G*{EyPz*vTkqCuwE z)k|vXk_~zPHobj4y}kauJpJ5pj`q{MlhW?*{3uO@45EnAj3llCQvtsa3Td)Z2&v*^ zHcLsRwW+JIkdvEG)~ZG)#9sMjVt9LP{IvK@!uAXO<-f`DT2+$em82wVKNrObTXHncIC{q;is#HK{uI(Nq;RHDD`>uoRF68l!8o?d5GuX8Zo*r@G$F}>Xqz(B4&I_UPbfnYnfeV|4_-2)ySmk%&o1oraZ^B zZ*C{s!^6!jODa1pg_knR-3#T^lvS7!gMtt$($S0idC^0gjF!4YrYkDSs(49Cw0Vx{ z3H}e#-T}InZr}DzR&1@$oR#kJR{=NTtT_Gfc7Ne<;aEgJds?yKUM1Qg&n#mrC<*SUeG|it?<7K6S52I(4 zp02yDD$>r}DwPOhqhqyGWF={-w}%vhL5Ni`^r|fNRiOHfj-#h>qw97a#@^oNzak?+ zpil~ug++}?U?n&dCZ7n^-t$(&kLBjcl@2G-0||92BUiaN8YD`g%Y~o!@f{7m z<4Z@L7-iq_%#g@MDmUKm+}SN;+@-axpzqxb#v&Aij}I2(WUtZXkdYGb7^l$o%}Xf= zT8t1Vh}KfnDk;Ifh|9iB5~LQu@es7))LOvvfSpCK4J_jMP`^{Ukvbw;lDW$gUiCnsGyx^?k?IA#=v>7Rlb~pU9)-LZ z(zU*7SD*lqGXF+($cskcjQm21Dm(B}SY9$c;znLG6QQvXWS)VN^CkL8eB*dnCn>m$ zx<0Rse0EktYDsR>aP~}ERA{F=z@e~Uw4`wA7lxx5Ck1Yz66xsi4;3NNmMjO%1O@j7 zRmjlBh5}Y}@kajIi|`Vn;yhh6N9pjg1`f*t21G})?j4zia`NVbhKeG=I>^NgGf9h> zBe_pU$)S?*JdGlW>I{Xmcg~wkVPi#H>&6fVrD$8{4CSb@p0?ZLl2Vm|Q@eLtB2|$C zO{7Xy$xb=%pUJKB6cnYK3kGDV{+A$knKF&l^_An18WJ8qk0L+!JRo%&l>#y=^Qr=q zTZi{jN+wiYmsdMvR4_5a!j9bsGQ#EaW>3SoWGX3~gKzpOrHKlpuRje`DkYTG|n55U;k;D~q*>1b$ zz17=Il0Eima<7#q)u1D(Yg3bASY1KaU=6?wk;v;73 z-r-)X6M~us_Nqf6cF+B30H^!PC^xONHb31@0TyyD-BiJ~HM5?-7rlt3?cp>u^Df%> z1&s8xJL(zcU-W`!;ev@P?s;Q69uIYZ%jE565n>Ta5i4MK;OI5^J+(3Q+l%3bXzp$Q zgfunMyY)2%TbA#3bIvo>-gEI%pW$KtH+xgDH(ax|WnHx%<-ApZVY;584(b*V<_6EL z$kt#X=8~<|*0AX&<;ED(I#lBs<{~5JqTubz+*zuX>RXjV@aZpS60c1o!W7$pbQ3 zeF0(ELgmr8(7vPa6L)eU zSg=x<=;6^e3aqo~IP$2;!hfBLjS3woV(?Pusbk|O6eAtEe~AiUu^sOHja?AB3AmQ zj(A^qV-Z^$r~m5KXQZS5a_iImXSe>BL7U&v(AdTakNxYm{m)+gFX#S0dG%S@|2wb# zzc9eR4&z@T;4E|u|C3q&=S0;i9enVkdpMOXs%pO>=Z*w;*jP+|9xp{R96X{RVImQv ze$U#HY4nNV@oB30ASM(yR{K(o1-jQ%98_Lj^J4_6V%{*m4J%edI4%S49C z%hviSy=MRV+$~S&T5UIUxpLDJPWQ&qNou#%>JAoHo5AuVrHaSIRk;I(Q? zu+L2wS4%tqyT zYDeXL`kBF9@0V*1BR_8opVejQ=liGgt_ChiGAxI6adMElFGzi^&~8+>>G!MU z=3={rxB8GNqt+t$lYN&(9dJkOwW>cUtP!6vw{p8;b?s;cd}iMJtC>eGf8p&{E0KQgg!$=00}mj!^VSmyI~)7 zqVQA2aG3V%A=>3mnB*mHE6sJEX7Up=&via(@@C9n!d8Bl@Z{4YNEpFV%l5&m$# zzt;aX#y=R~e|X}5vAqAm5dTk{ab}jk`u`d4FBbUMwtxEmgZ=#%Bm8eh`TrW@pT_%| z^Dn+Q+ZVOr5BL1fKL53Rz5n|-{`vLKSbz5K?|uCG8}d)TKka`X?_cwM&GGkG>|Zp9 zKgaMl{o$`MzUE{8;*@{w6Xc)QKXd%^xPP^MwbOr5%Ky4${wprxA9vFKL@@uyZRtN@ zMZVhpm0|wX_&-9-=^0p==y-S_9i1GE^{pY@GB!NS-ISD@j#rN|(kPh=84v_A^TYrc z;|chfVu8dH{ei)Q#2|wT#FWM06>7@>_^vg^#=3ayynOdiW;dLWD(|S)SfZS4Q_vVrhxMZ{}u zV#b07*(x6fv9spK+S9Ptv%JKien7yDG}A`urtV`9`1L{jdx<8B39Q?iWeO0UcvTmr zqcUHxWUn^niQfv22FlmzkOy)Upa>Z|PR$E;y$WDIDlZUw#%?H>T9;M78m zWGFHx>4E*rIQIt@VI)(hX6+(c$4Jaf&21=lI9>4te&b$eB;W-5_ zA$^5YBUFKrRsbJ!%6fVqy<#BMFsP=!e#S$2=ea}Z1asE_ZSo!SI9p(^LrnFAl_%kb zvhIK^1BmKVS_ReeMm&J;s`uqkPe0wxkI?-1WnF`GvKjcK;~!iQaWxHW-vZ?k>ry#Q zouOc{&FBCig8;NH zk;R^w%?r|e$}iK1hpHdkQji89cd^{=;A(CgumwB!AkdV_Rrdl^aZ7dhI8i_^Nt*@1vwb7=25y+YS95bT;bt z2n6HwXnrC~nbUFbF74D@vE1hFm4dQJDruBdnyP*0Wfo#@C^3?pf@*jQlbM0kGsv`M zE%BmZts;piVJ2tEocY@n!Z4EY?0&+t)yxH)hgX)KvQO5rq;2K+)UErQbRF7vW2+!6 zS!HC*8(`yF@t=-05U?0F@x)py4iggOwF($&;#LOeKjjf|1KNIK-Fj+wH;j!W}4Ij6TB`X>^fp#M-0>A!UV^Q?kJ}M34eVg7)RJqHP!~ z5cL6AM_s*H!Cr_YP>AnA1Rc&RKy{6a*06`C(kV2#60IO9&?M9~@z2mCYNP64&jv0! zkhC#9tZGWgm#}Vv0$5pxz2F~RuDhzLz>GYrxKae5`d>g7Hy|!whR7WwOukCVa)m zalD#>HnF--H!V2BXxGJZGw)yL4laQmObQ=sOP1(!v8>!k7p=`5)I<~p12(A$RTYJ- z3aKXqO7v<6vgT|}Q){y<)_NtF@k|MQV|NKvJLPBk9y7IPsqm@NP(=6*0a-gS-7bh7 zrcNo$@4FK9;Ta7@KXwlZlbR+mW0BVJNo-~oInZLE)${5p#xja?`tOR^+*0)oV$>Hk zt+1}DqETR|@5!cL&v&mLGS6@*O>piE2;h`v2TGBTjoG`ZLgXTTTZ}^MuQ&dHNwraj z%n1g{3bFHR!?rNHYn3|00z9O2#3(!CTBtu{mXbpkmy&Z5Xu8B;$_g0=#&F_O&#pwp zY?0#egR*ABdqKF8BJXRi7+c&k6b!DHKW$MQ?FWsAcrTBGac?+=QY||(`=ltqIF&(G zeqU~Ah;XAQW7q(6-A%|I+G!|39K`l0n=ktymr`WQ75%IzF%VQrKAArm0F_-vx@rio zQ(EIQ&Og=HP)Y1@s#>*}RPN*-6=3$qEPmxwO0DB%b*ynXz*P6m(R7};oBuGcmAovi zI?Eg8rV!wpEFR_4R!h^HGHUe$Z2)tuHtUNu0o+)i7H3M)tS%PgQWVtAY71d#!nhs5 zPAw;=22)BnWmmkprE8Qvd5CqcZzHa&veD^7z+Ch?J7mJz23MV7BA({{c7zfA!_BNl zK011qe-*(z)F3Sin_Dy6UFh4fQT;bez4t?$Z&p%UydpWRp^}j+h(Qi$_z-Lv2#Aad zpB8{acVV?MEQ357e99!~%<(!5VkR_UW4}q9jsc=OBALtlfAKSl6QpjmSh8SV;Ad`t zk~7xkA*qT%z%DK5;%oC(@8qD{VR{nglHUbh#BYWV4jK-ShLq%2Ks2~8gP7IuQ>1}@ z{*dBIn3l>CAO5jOg~`1`UN^!R9GyIOebe8P6n!==EKbpLo@w@~ktzq5vb8-J`#rQH zb;bBKLxaLkym0J6oQI(qMfSbD12gL*lj1Zm(c}`oVwBTe3M>S zr+sa*{rsYl%QZPbvlXfn)+TkgAQ)rO5KqZ4GYwW*!GeOXO()q(Qld^Re(o6`Jz&I0 z`r?EWKb88S%&3!RVN~-M;K9Jb=B$7%%|J}hEE<0MQhLr&Qw%k!2KMESqX@|ww~MWV zg$BF$!|L+}7j3Hx&r^qCNX_0YA$hRiP4wFrv7V0j&ZUzf>aA+q@*pO;+1yJ)W5nMb zb9k%UH#pJbjyOXE$2k_*dDfXEniXl<;?4umi9-jz0tI_VO3Uz<6~n|_f(7@CC38m( z!>M+S-!8NjfwP$mxw`{EI zLmX#fJ9F2iE&^;6S2^&oYQ=D{=IbOBCDSb)a<4+`hRNKi(}^BSabe(q$xa1mvcKf4 zT1FIL`v!qulNhDB`}CrPtC{gR`#Evt;<#laD9{!f9g(1WK;K|6lnwPG%Hg+fP>8=7 zbV?1vCU&TCSb3rxBlMbE2aL1_ZTBT4!Wco6?zJUej5KfNlN~c##y+MFw?oY0Asvc=2r`VrhAu*Dprsj0lP)@` zawPwxQD@Xb*MiKB>%oLxRQr{)r)U7k1GEzCWV8ZU77?eyE7_v7RX%5vtvm+Lo=<*9i52mL5v)4jA$hla z7HJ>E7TBogsOYF`|IMB2RxWS9cpzOe@08ak$qA_cF&+O2On`~*FAAX`>E5rpYYuuZ zR6Jp$1YQlToREb$(g~gbbr%Qyw=H4}N_=2QRH_zaV)AiebO*2jDTgr5;BBNM-nNVZ z-+orBmAqd`)DZ2m!oD3~?=t|zv+(>==x*4>jA>2*B4*HLZm{pw^n6%l;wzfM(t$=& zGiC|`>p%T8TaH3~cOpFJo)VI`4g=GJ@YfbUukiEfkuE`XnampF zOzV1vJxGXuF84Z9WmSnLn#pPwmweD3TM~MQLE?HiE1GYXU3(lwS=m7NP*lH1o7o|! zO5czH$r2;aF9)AFcA7?;zQ#~8 z>MoXN6m|qF5D5Ey@tyVX3*V!?KDn75bK4BnjyyEiiEHk)Mz$d{Z^(Rl&7p=bjl=#; zn~Ttq2O5JI$XytLE{zm>5|A<#M>;3l$ST>tf9&I*{ z`~1gyW_cNE%$CZk$6kD5Ibo7FsqR-D&b>sB*N?$>O#5)k;scp#nhIGxK0Y!du6~s* zKQ86hI41DB!>zZ8Of_=~$cDxo36d!Tu{noRCK+jUpVcR4V5>y2LQ34NrW@shIWGf-Y9tq$F4xmX z<)E{`GTY)!Unq2G?~L_=@dMi-PisWz-xyqHZQxSZVyd zPL1gLOLqI;{kE=I94-cMM{+!>6jRxx)!Psjq@lE#suXI_`Yn)>(??Wv{G$>KmSJ%z z?y$R{<09zx0*$~a4aPG%G!Jb*BPk=qD~dn3Ppzm^wT{}4?C ztvi#ii?CEUjO~nx?HtVzgVZ-st$Ci^L_E(j1$CFm>@!Dy+b5Wis)3G$nR0XPKu z@OgBEMND%uUfk$S)-5&oc%3|bsKZh3HKc0tc(4HHC^*5l?W&w~bMxZxqs41Q7e~X> z$!5Qa)28wAxetQ$wmk~-MB4dk zEc?rLbFba5!)t%4K3VEjw(j@1QyHah}`dS)CUyHgN2Ru)B$iF3S|V3^V- zt!Zx_`TAuHIgfrt&1-0D?}athrI36Uz-dHiZhWd8S2&s36Eu|&(x?Kl7@-d0fh4S! z&rm7*V`s|t9{5e1zh|Z#Q6YquL*1O2Lz;p@=HU0tMi#u|8X8e1ourd$thPI|9*VKj z+vwYH^nOFrLD^c*Xe@>+YhO|*xW<7+D_?O(4Rvq9CG>-=O@WK6HcvR~^NkP`4hFeQ=XD3_Y&rOldjl7!v zq%nR+zv*Ilht?g5+hp!MSnuCdT(?~BoR;-Pon7i98j%)1Z3JfDjs&Hq<)>x>)Rp;c zO+O9_;-p)VcUvIFDjawK93cnNxwy|Co&JjG2+Q6n^YCn;sA_&((qbH(gTA5hC0+9W zh{I3yM`Z%mf&ES*5g!ymh@n9^z8yZ?&gmle@er%nYgYyOSRgUjpG64hpd?LK7*=Ks z=ZndHza8lGu1N-`|3Z}*Vlk8L?B>pZHZC5Z6N(%@*^~Zj9*xgyNr~c=d=L`fqiZ+N zee4~DSI0f`r?yYRPx9)$=a;@O<`0B;7{wtynm#H)}p>(rUa`Xb{>q-jI{0xGJh?^TA2l z|hASu2^(Wsj%liWwTK9MTC_mivgx?OPe9p2!qIx6*EFG;vo z<$d1qjqC2{GCbdi;oVff{RMr|a?^41>!mW4LHyNZli`@t@gY0>YCN5`YO7((m9xGF ziA*t(V$Q2{na3&x#a75XMNHI)GwxA@6tH+=1l_$DY0Mo;h1Bn1&4NqqVU#zA#e=jfJi%GT5KTDq%JMa9R$i8d8Z)UhI|x(r1U zgImXqIXjREPy+g`LT8ea#dV$JUaZbFC?bA4HFAE!c2smhQ50s3{L^7KSsQEEJ_UNB zC`o7OwYHA;oMp_$#Mad0@8YZR%|H%{M6GXj8q=p&55x8y%D=X0L&0?#-D9!HmECG5 zwdEp5s+EyyeBz*^;YC8Q&?JmQ8l@2ESsuy`lYV;ti)Lz%lan_KLE z=Sgjw7bH$u{N^GL-gD0sk1$Q00p{q0ooh~##B~ZvB#}_Ekg4&siZ+6_$Ja%7zdNJ# z(0(J?IoJ%@gmSBgM69p@-$@*55hOxY#+P8h0SCjH;9Wa}GCK1b?mShJaoKy>=+Eg0 zOUJp?b|{2>HdsR_}ZMW)h=i^=!;E}T%Q`pN9S#%}vtEm4 zf1~r!nEGoy-2U;4Z_N3-^l10Fhug#)$X+WiZ^d}#qq?sSR6S#l%o$>Y9|#~@JhM2J zslGD-n@=50F1vVt9uaBsvbi*($|M;s1zg;<5k)E6^~ZqnRF-#oLZaZPN|Y>nMTgMc z=hKd)fz-UfD0XipRkUzPtjHA#l+o(Fxth(2`=gzyh~Y1CwGe%ABXJh<^lwol6=w^c zy1b<35E~_+gAS3K&x6Hgr9KWVxT;d!yj(9IS5I{yUzsfwzL&PVRT&?W?j)C!X0z|5 z?OPH9XRUWg#NVf!7D}@K`*Kt;j7J-$eG9}z@{96TwerZ_#cpB;`5fwUX4q0d8LMaY zdVi_XD4z0?$nhgKt3m_MM63Iv;Txt}3>YmMe4uh9Lg|v{53@L!-==NhsL*g-_k;No zyVt`GCx_X8IvPz#+UAtSRBWd1u<`M<8F$SVtRr_yqj!Z5z@BpNjmXZSXfK&jzhY>G zZOLwxsJ*XIcK;%G1bJDbdACng3J#do57Jz#=W)F;^t z;oQ-5K-!estx261fLhFwuXsf%X)|Ujo<^}gZiW6>#H^L1NbE*>KCL?lF5_lh-u3bdzIoGHd7vT;e0-G z0rMW|4(28K4i$P1x*ctZ5Fgh~EMuRAEGQlDiLe8E==e9?EDzq2G!O$~jX_LFyA!;M zK2FFl1!NSviFb+${%$v^;6^u6PnBTj8Vn=k#lQru;$G02SaAv~B6@}VUJ|rXY}_YZ zFpzamiVR@l4*pK)*(BPe+m;dg0A@nC5>{!d&AtB`aU6l9qI;t*mAEC1S% z`b6u9wO#A-K79J`kzfOdVnbzSYrBgrY-R2ZYFbQ1Vjc8|>K#l}DnfbKab|RzDCV?u zDq8IoU;mwwl?7aL*;{xz@=LGf*%?%_anItUV(WBxnbUEwFJjri1?L-dxlIIEwy_51 z(?g=7Mv|j>8egO(TGP{$4d(aAxvA56M4*|srh(C8=&Ykegyyp?FVZZc&LjV5>~U-1 zrU6|O+|BThV${@FP3yC&VaJLBv$rSO47Z|D$FYtGUQHu!RO)=2|^u8C#e2%6txqJ()` zRmna$AFv9~8F2pGbuc3)ik6z`X*iJ>Jgg&7SUWt6yo08>fdd1v#f9ZT2GRW*UH%X3q54Ewu113OfA6! zmf;BIBaL;yDtfV`R2#os;Q4k=OicrFz=l@{J0e=hJx?R^;yN_xB_>|E${5Q^$qdLO7m4u*x{Ri#4EE+F=#ew@S8 zCq#S#h3IB=hE4Q?4o1Y~(?3PNk9c=S*27%?km|E%5p>rYeCh%jB5=!kkH-ccuh|Qc~xa$T%Sk!Qayt=m#u0A zq(w8p3RvlOThSN18E$+w$j;MWsL-X&t+1UBEw6w7J*3o%$dS*M#Q5I4$F?veu^%#P zV{8|D!qiVE_i3T(N-Ge9+n*y&!uikR5=vQgd+`GND6bKALkc3SJ*t$q33&AmYK@G^{3E4 zr9em6`;aJ<=sP>@F4iJ4t~547zDZ5uJG;?l!`>S;t!@e(`XOl*;Ao;YG4@2bhIv$E zbXxfkND&z?C+)nP)pi2DHc;am!a23+IRK(Vv3RjPeBX{lEfb?RS(WiZ@f>wd*Rz;l0l{^DMr*zwxB^0qT|ZDlQ_O#$kvy9ve06%wTU| zSQuwg@`!!U^n+*V^Mh^ZzBz`pjpx}dW$cB1lJJF1wVcrj}?CYz{w;jo1x8sS=PrWR@F zDcUe|i0w>%NxtgJ?0IJROC80_R>odOJ4F2O{eJ$z>CWlF?D(?-Z8d>w)s|DLzppWr z6K*UtcvA2Nf6}AoZF?Zl3r;-V;ZdoT<6we;bc}T0)ws*f_u0p0h{qk*)nKdrwWYW7 zz_az7HWtZqbE8jMhCqdk1m!2tm35ye(H(;UF$;O{yp84RVr`V~%{A6i^&5Lt9%%t7 z+y2h>Ua8>wPt?9Wl=jb5YU3*G1eks><6}eCvdZkI0(tx;!&GmYv!r*;Xxp7aYIVc6 z*`#?XuhdGPv;5$gB;K}%nTQyR3R)yap&#mqt)eW4EjU$Yj@~t?->pfiCW6yjhYuUm z*_Vyhh-`Mr0S-ZvcWl2Ie7%dJiJ3#J9Ul@&Kk{DNHQ$@kHogv^EkIhuNnCqh~e&OGgJ@SR(J=Q zao60JNl-aYnS-iP!`<(k-gCzpk`qZq#X!Y*<#yveYQ!-QF7ZXkF%c%KCY-c07FZ(^ zOcJH8BKLEAqZ+*_`LP45A7c;yXp5woGf zi76#)0rI?FKlq)A8F6o0V2J=g6nJcyB4w}0#VT@z)(h$?pVyM!?{6KkQ=Uy^pn*0P z98ABc{X-L8kg8`4z!u67LdNj@`wA)c_9p;2ZKTk@m#O>_BK*;Vu`w{S|Fcf)|1{o3 zAn6#C&t7^|0mVuOPayN@UNjR{~;4&`-++Q51H6khyNrK`|l!M z{vovZui}e;4Rv8;WBZ?UV(}9;fppM*mt4ZpYqHJcKzZ<2R<=%Q{ zS-fh&!7D5jS-rdP(qih~Bwux@!G|x#E2q^4k1WEptghpU<&zUsfpigHC4srmzTD*PSkt;*ojEp+^YLe%6_jj-M~U^4uj`2%<0 zBP=gM$M$Z$#5c0 zX}^I&m=TTw`x6>#NbZ7SYUy?=bR-Fw&;ZG?CT{N;>h@x|*)~bfhu`Gt-wMyOnra{0 zT}7f3K-t<&KhF~{GcUcnmpU=n6Vf92c%*>f6wCxct_|8sXoqgnHIdvoR|%p*Ohn+z*d_HDz4No?&C4l?cxI1uE5H8Ki3}+ zJkZrS3$C$Ek0M1a0$L*IY;EB$j&46WAv{}j2^~Tl*jP>dZF>#(@iZp&GKy6QHa}EF zV*0#W9t6J^!J7zn@6qxGW*ltkD?Rq$xB(|>@`({V>y<@2olVKN-tb1acWk>E=#eg}GQccRB6-`2IlWrN!#MTJx4(=$X{};{8Heqj3aK@bE4O__@vJt6N=d zy0v*x#hrN@tySCVIzo?mZ+SFocS;lI;F6UnFrWib@V$hfZ1$E=# zDD@RZGvo+d1`-U+4XI16)>(Iqa1fnl(PJ3Vw4mfEWGjbY#NQKY6SzFnBbHYI&do>0F$?cS?C{1xb6`=-Mw)s2;1EA0G`3D$YBElm69TA3I?LJ-D+Thn z39VEVmaT2@$-HAq>O8tz&tG=^ zlD0aMam?Ylvp1eOIlYY(1yj2Gp&JpcS*h3I0j?x$gj2M#F+T!?Gg8NaQ5Ya zG5RQ|6p7ZfU*rWNP)qFK{zl%Fic>ao0ZXay({Tm*JhDlkp zi;^G_wp^#6eVRnNcxg(JmZmUU#z$9RPHqFosTyEPvRu^0XC2o0ag?L)ZeJx|qig0T z0^T6MQ>XH~4kioT*Gu|TSqmZ$jW1Ga3vx!i*Hgh0MNeYE@Kz98t;P(bR{wo5!CaWQ3dX+Rg4Z5933Cw2W z_H9y^VTpW9iNx)&26Kn+-Ge1rO^TMHi)sFOX2p$tItV3lqSDNvR{U#d%u-CH*y<=c ziorfwp?A8k!%-LltBc_khx0%&HLrxg^VR5iyk#ANO!#rK6iV?WuUx}dYr zu6QR9s+gA%Q`*tpKaPOkX7!Y!70BZVz6qBU@(4*uZGL0`(@nH+i0HYQWdY=;)-ip{ zb(bkrpO0dxi6YvL%~xbsP|*lwN{~o5VPZM-E0P*rkR%}&9X*0%d&SBvD2}_~>KZzP zZ;6$K{NWAT_=4u1B{g**=AvwXK}@vJhZLyVjDvNfJ3M4-%Bg9ekHS%-Z6!~|;#27s zL}&fe6KEz?&ku)%tZ#N3SN=x}(iqW&kSO%CL=~F3{7pZK#Fp?$yHcC~Y}9gIL1fMg z)8b|^{3_t7CyhUWr($PWSjKTLv zFId~34lp@K_a^|h2{#b?2?JgZEZM-f5P4vBSRBCZS}JBW=Nhl?JAq&o!UZd<({jy) z3c4CIO6Ci!$}D!~3Qhyk;mMmMLzvzVMI`N$l&tRo9~5Y6J_)b%pO97oe)DSjRO*@l z#Bz^fh<+E&q5}q;$Ex>79+XN{l!sSbrAr@lI$hi)F2)JA-nw>ACv+ z4$)j)>Ato4vbwl-a)#VuM?UK+h|{&9?SnwEFVjIqkKLURwQf)SNa!Q>Xi zVNBv$m2yh+Q+ydDZQ9 z8)B>m?OmVCewsDa`RJ(ylc{L-&a$hj_Mv~SR6T5a1mcb%9J9TFeCa}$5$jA3r=T1g zi^%B6t$~N$F56VnQquYf+Y%veUppMwxBJTs3szn$9rlL^4=uJBMsZZeiddwGPn1%W z?Tt}wT1F*Fk41nPOBv{+KhRx6RrHv*ANGcoefa3gY6bJDNLTKoqpl{53nhABSVPux_fmX(rIS#JX3C#dQ)5Bgs}G0FPa&6@Y_#xHda=_9|P z_S311iM_;a{b+$OSIAd}Q7{p#`V9z^t@o8N*)0j@SOV^DSs1JcHC)TIQ!CB;7I^x{ z>SBKcBx*~jc#!LJxv6f9UY2`0n4K(sKAl|GH@CeoN?!V0;NsxecD06ge3gMF3wgPB zbi%tH5+OY<<#e+}bRB2bjtb%On{&YKnx;|d)LRgB{U`;&X4Zr;ujzf2O;J<3p;+?h zs!db(#4#Zl9+eZAC2`hylmrl#^%Pm?=X!8Y^u!a(I9q5p2UbqY@sgYMWN0v)A zCe)lhP70%!d~On!KJQJZ-X;QZQ@P%DVq_AsY1NZAKc>3hu3dTEpPvUPxIId-1z5{hy~Md8>A20l)ykOY@%eCM_?s)#it%UD;>*v&&jJ zZ_CS=*E7tA>M{HK5NvUr+>~1FzCWi*(6BS_(Jl0ZU$wv$bT(F9KLe<5JkL(NwWwdFEMe3Y|#)d}@%%+M#hSj#v zsjcZ!KJ7~pWg+alsiCRK|3=4-3MPm|3ol?`fFxy*zq_j%QKG_*4nDRySxp2`G0x{j zN(~41Jdh%Zm+9BsXSxW^g6ZE4b856>!+;VF?sL!p7oDxGWn&PH246Y_A5NrCa^s>8 zCMhOZIDRyvh>srJH55n-sW691Ey>8`mla|tRTIO(LK=u7B{0|5 z-LIKWPKn*qty0$RS&uZ330@XrNK7%{Su7AN6(fpHAJKOwV!;{9X)MWz7fhl5s2Uf*eeObj3GsIopTdG zB6niS2wSYU@nS-l%CQiL?bCNLB9+p+#x!HD;(;2nF|x%70Qcf;|3pYefaL!cZwIU(MG>w9 z=(`-01DSna19EByIUTJ4u^*G)1yBiIEEiG5P@nF{Hou!Jdj_UaE?Odcn-^%VN;n_( zg5NM5CZLR9(BNDd5EXh2ihxi^FSBE)Ug3O;vmjIswdIYxeg!gd{Em3WEI#bP& z5yd+HhSyHtKvW}TiWcg@(bLh5X$~>(+3f{RhN{0HNl4mTLsu_h4VNdxn{Y!fofZbY zMm<>oYExqfcfl6^g0C`CVf16A2s>9p1`lh&!2|V>bASt+vD3=ReEqqa(r$0_*mP66 zmiv)`V_+_FDZou5LULjS;FiE&DJ`P!7-EBUR4?^_alFAiW`KDD;Wx*Q_ag$6wtBf_ z#yNeVySQ^%qgPBF^Tb2c9?rL0*~*(nPbex`hOst{6Nr726f5wPy(jj(%sPni@V2EN zF43^{is%ajS$ZxYUfN-Jp)SG!3)DLHNafcH6(!z`W%s4OoD#rE)xNKAE!M0~ixG?~ zLXQ02kI5NiThqL!9&HmeX^b*!oU8$_dxo@(Q>adeQ~<(RM7`?}ZOGX4e-wIzp)Nz$ z+DLC8*&E-wqgb;)w00vFVO~?R&{`9Z`Z9!xx>nDd{=835o1v>$xy50}HEta-YbQw& z)qg8NR`sOxZ%e4aIdxZPXTMcVO;GniO4EtokU*bEhH&A@s{l%((U4v=F!$}bBFM_Edr8Ooz{&u zq>h9Rhv!JFrBA|spKaKE)IjB=?nMjRQv`N3T(5BC@7<(`u829*#E6%OAY89ZT1O3( zpkQjKk>HbHRa6vI8rqa1-3;%z*HtK+;%AT}sEk{Iso<~DSdU}B*Q9&&EjNbO&vfs| z6kJE1L!ZdcyHt&%RF}}(gcvI)8Xkvd1REdsonAr^l}o6CP^UiF@trQHx4PT63xzt= zK8C&1{*%F#Kt}&tCYi4f?OmA+n^|h>gV4{ceQqn?<@+mcxNI-AY%jZ)o)xg?6T|wU zmRm(yX?t_sL`DQx_Pz7;OiK)_z(G)-X}`7Y3xy-G0}@+1H3!)I>5p9M$=nADQ+vUg z92}s<+?-U`oAxIho}TPO-QB1np6tGr2*(-Ml_Bx246o|ep_RRhoug#bLNQekjkSbz z#?H{oI~8`$)n<-~^GO%iSGYCbl@FD6{gzCwXy47-&E$@b{YnQ<;_Cd~_NqP}wM97& zGvY&j$w2p5LbYR1G^h0BiHsF4tFEo_bbVC2Ib$K&!;#2!VJ?9zG%&j|Hy(ckbs{!&rSqj>ouDJrl6o6VcQC_e?Q8 zRh_D8y9WV^5=9P($V5>tQWWRGyjV(<0FotcRsureA&O#42@eLOkQ+}yi69R_BKfV$ zK4zVDoU_WAy*w%z`!cAazf+H0@9?rZIT@6S{}|JVNHXMgus{)d12|Na;M_ka5F zum1br_$xpE-~Yq^=3oEo|KT6_%|HCde(B4<|7ZWn@BD}V+<(yj`7izQuh&2Q`~KSh z_WS>(4}a}9p8wdt`Innt`Y*rpH~#)Npa0fB^-F*CFa5>e^ml*9|ML%i_vhdJy?+H4 zCH{r~^AG0Lx1a6{)ON8%1`~X z-~5mM)8F({-~7h^`mg@^um9KM@A+^4`R4n6d3yfszxOM@{ri6DpZ$|ZzxYFc^GiSS z@BG5A|I7c%^k4m%-}~ZE|B3(NcmCnO{qyhtgWve?e&J95qrdp8U;Pt*`_KNrAN@}! z+-dW>{_{WgWB>RU|I#o1FMss!{MKLpcc1?JkNny%|MXw~g}?A`{MvsqeEKmO^@fA#zRqrdrY{ke-oQ|&AWze*z);}@u;4)F`Bh^C6?235{fbxnT`|Fv2T zU88E8#xBJZn2JqdGZTb~tyNKB^SfyLfT_->CwK2saF5oCKZ0td5FUSSPt&Bs9S!T# zJ%;s<1BMw(c$!F^haWvc@L}m+QH6LV`d1JY(<=lA;C=7K^N-%YfAs-MW8S^{+WqIR zzLC7Dan8{9;=K>Qb$|EXhcCD>#UOw^xqtcmvlk!Tzof6yL{IL1{Ql#oAHMng^AG4~ z_keDga036}i|3zxiZ8u?_q7*ji}5La=A-Z3z4bm0;Lkq&=>EwceDm%{Pp@8lcK?;H z+`R=bG0V#nPZF&rS_-$~I0Vug&z?Ph_40#9y-rQL`dhuj3( zcH;OGSMU?Geb1YYU*<~q)qfud|M+)ZRWCb+zw_qfm$wVQ3^sl_0ES=v9(bp`&)<90 zkNQ2tq5U;eJ&8})mmeou%J&*}GY#`t-33Xos@o{;*fpX9ybUEpb=U2r1i zCfhJ6x+g{Vr06aNTlhr`cf>4iNbI$uzftrzivEVr+Nnpg2;P=Px3kghY;-#tC67k8 zv(fLh`n^`ahl~aO4%jDtAN8$%uhs9h`n^`a*Xs9L{T|pYzu)QiI{jX!@OApVPQQnS z6!N@&ujB7M>O1{juirydil6KCd%b?I*YEZ6z4CqJ@5K8^fZd!8OlaUi>zMTTm&42W zis2=MJpjB1@mll#MR20?$%DWtbWn`Xn&~NqlNSB}_!PP=hm+|ihLaA=1HdWgtQ<~0 zzY(0wupR(T;SZDYhhlhzkH+v4LERo+kjJ+C&EPCUp7;@Bpl&Kl3W2f$ zV|W;=My=UNt=ZzUD$bP%iR@ju+0HIJMXZKNt?_brtpH)K&jY}F(0ULjRE*b$v2xVw zQI1b*ys$Ql^y-bsOnTqi{S!;)VzBj{f8Izi<*nyA# zL3Ukzcg5I)Zy#_yiMG9pd$iupJ2|Ph@c^XkzDXdxsW@6FR5;V5{?bYPr3WClBCFy` zlh;h6mBhAUgu1ZYA%}X|(WxYam4NjieztBBiP=t=LN7fZ9E4@0pD})!GvQah*GrTSB~8p6Fs|Q|eLz4>{nrxq!`}tIUZQXK zyMC|I?^Oa{U+MQM{hs(!PkpW5V|Ob2^y0t7I3FbZ>i25>UajA&<$LAyE&wJwNS}P| z^ll|_#Ta_sV9EBx*y0U(?O-u=Bw!JJymqjdIAgFl-1WM_l2}^;7M%*rK!fy1|k_XABmHI$t|j)*`FeHht}2vDiqk^+n+F;+TxV;yCl`#+LZY6R>V- zUll4_5`IX)`XX?73Gv5ZaghIYZ=ysH6R^GrTwW3!60qoOzIJRmF3%Y?uNy2$=ZUe! z`BSeQEXU?wHdU^!i$9Tl$~EXU>9PjWM`7Pp+ZGm703HM?NreXZTSWUs;BRg2pw zIt4X5j&6@Y_3KQUCpu}K=mCUU*-*!Ab&mUv%XHdW{Aw{m;}VYJUh*%^&YHf4tND@lNu`A9b2P-f8}L$B|dS zt@-1f=8t!pKTbEt@w!+B(sSZ)>@E1uPa zGHxoKXUb4lY^Sc+PF=B``1($rx?($Z#dhk7?bH?9sVlbABireb?exfYn%doIYIi50 zibtJ>Dmo3epd?FnK!a|b2HiRhx^h0x9j)%^)r0xkAVZSVVd^11p@YNl!>Q50ImkK>7vn zJ=SuvW3c#aKL7$*jXX`ta>@}YJSTye`1=DuEQ;Tx%yUxac>r>!w=iFP0LTyKWYof^ zV;nQ5zCENGL!4A_mE%?J zn)Sfj?}^5T4?t>TWmM_<5GPb4+>=DOakn{7d_c;H<{VQI>&_2=V^MS_joIT?b|C0L zp=d3-eFFKz2tv&|D5nmwHWEm0DhOwhEp|7k;-~>Hc2Ep4TS7OdicvE^M$P;fHS?n! z*J7z9kUxm595t6^)LfSFXvu9YwqyeN7a+=4izyp}#m4Ldkb)5Hs5a=RNkiqNAjWnA z`GW|^QLX3$kUBxf4uIR^Sp5Q{`UOVy3ykU)7}YOuU?olvvdiKDRwBxEIi%u3iK&B~ zC=URs(zW_(M)lPkfSi|}K>i?tZ&dHosNSbhy-x=qw;t@83GVhd*FFrR`q9cEmZKfx zn%UC>KrE?^qk0BM^$d>c89cB8*1M7w+*BYIx-mptCSZLLq@Cy=5m*iDQV+1-2UWC2 zw9*99hmmgT(;n5QJsxe+(TL`sKz>utWKf64qir1;v94lBAEpt?s0H(*#v4YBH;fu@ z7&YE7YP_MC8#Jy%O2bzC?de-1E2BnMMvbf-fZR&GhW!i=0J&%uqsELzjTwzc>%|-K zha}W=Q!}uP6F06YNW<>G+ap$kccTXHMh)JL8oV1dcsCv`bZ=bykcM5b53nK?+8V?e zHHb565NFgN&Zyzba^e?Xd`vnVue$w;G+Z@mxN1CFlh;T*Er$HIy+;a(-gg+`fZhWj zls(|5QR9N>hkMNJ)kwfGLFmIs&!c5zjVv{W^tNqBW;uVfY^)I~PawT%sBeK(8HN_T zl`{m_e57Gs^8oaFR8JM&m*DoMQg6ns#w$mS=#LuFA2p&s9!G-^m_)R54qL9kJSV54Sll%EGt(vlV3)SR5D zOam^XhKxoHj*S`|8#OpKYH)1S;Mjqc(P@cu>6(XWl`?8k<){IgQ3EuihMYzXIhC)( z^-^irytzHk(lE%VVUY1?0H<*cR~j}gZw~pOVUXcy7^D%SJw6W)(~f1(u*aZ*oO0@L zeOa2@Hf9MYc+kMjpn;nM5Ic*M-Hs1H6{0l^Mv~57YW(&`8Ljk&r?2aLXZgySI~+=ldRxD?9@U1%!7K+2aN#?8Ur}6 z0xL6HRxfYQYt)lIs3(0;Px_#q^aCrfG0c`tfd^QDq%;m18z_fZOq7^v*hslO#7Eod zwqi6Tklr*_Ir9?r?GNhPAJn%$Xw>2Wu5H3=%ckxF;9C4LgF4Lzb(#-a@p51VR+hH6 z?cFl(fjY$p4GRn!78o=vP`(0jo5WOf+cq!D3d9dH9Ie%8#i5fx{2)HvLEZU-R-X(S zxEPMMGHk`!7O#NaZMUa;^`j5!M;|m`F=)V|oN8QOnUBhfdg-L1PGm#t_OWTojHNk*sn&z!?><*8xbaW!kcucY8=R ziZN&uW6=1`0mz-DdfTQvGgauZ9Q0TYdMpP$mV+M4L67C2$Fh87V$8(U!v@;z_eA3~ zgEFK+8PcE(>A(t{1y}u59x1}HZV!wk5D1+*UQ^18};q8s5Ou7zV`IhC-+}|_nmj&J)c`NlJC*UsK=k- zlRCr0aK>NH=;U$6J)Y-&!dN3??c4Y}J^zk8%YT0BD||8Xs}Dr=xcehN`BSH^e>~uJ z&fzh+p}!F>g4Lxyx%)%7K9-hdU2qtRj;*ZaoIs2IC+8ke_HPL!1TFtvp>FB#SV<3v zX*E4TOuqy%{Tp44OTSnZKljch=*PzuddmR%6nNQ*0KC;*0emD&E&;zEI7K@xCM;Zm zr$r3SHQ*6#cnn}-%nR`Ey}18b!n{?PbTgDQ3GmHAgre~WG7=xGAtS&@>#Koq+N739 z3x6h3YH70w;rI)$gEoQwJk9X4-JU}_VFAfrxU8rO^DdG~mQ&4#LhP2X8u^=94IPFa z5YvGmNa@eC0{Z(fLoGls!4t`VdpstOON@3V@j&p-V+%ORzn!2xCHU*O6WpSKPeRyy zgcrJ4ARNw*Atlja>M;ccA`oS76OIxm#tZVg1$nYn!jI14P)d;(Kw`wv*;5c1G$50a zxPT}a%0QxSz0#r{L+6kMN(sU>lmecfjuFU`xF2!4uAet`fk#l*_nqBU*~fWTt)&DI zB0cFMCx}77^et$ss{;u7c|wVR0I_2^sXh~MBAXI$LINdDr2{}Tl#3G(I{`$b*LE{d z{82ulxj->qW-Ku&resD#1whe;wIHkrW6X?q0Vm4|81wv)DLWT9!W1#QnX1KAybGWU z_;K>2ZkKZ?bgJi2yjAHrY_X3l10nmu8C>KZ{%wI)c525NWS>>oT9;-EdL!sEut(>Q z`2w9sU=X`1GMX4I9TNPu^o!?M=94HP9zuVo@izl~N>m`i_@#3zWTKny8YJPO8YeXj zH`a5@AQ31eCjywX1RR@TKF1Qni9ot^js>J}j%8B=fE@cwj!axsvc^~#KmZr?9u~Xw z_gPyL5B?tD1Ycp(U1bTdM^urs>4dS1z+tmz?1?9P7l4ef89?TVDfTiY!*%Qdz*$m= zPkR@D$+2;9EMPEGZnQ8=Sd4<^SWzcz&c|7p!7jiO`Qb`$09dB{NC4A=G4mb(xf~8j zP1prwB2OfYm~L;TJYh42Fh(bK7I2aiu?wI?hRA780ot%;n9cwM14OK24BSlo$Gd=G z`7skevy~JWCrvK%HfF)JRoK2jTci#ME13aYM8AmMGw4FhjuPL~3hD>G(b762EZ zX8>8G@4}#fs{pzPXLaVG9R8*NvNUJ|K;rz}1yCXlT=5nF+A<#K1QLA_Z7I_w#fdd@ zlA_6p6rb%L09A$rj4^jhwloe3uZk;`r7YHorzz_opc!z&D4p2ZTo+I7E?^Vs;3CDq zX0CJ~tdX7qOwyrXvz{7fRGILRoH$lP-A@$LdzSbShVUZSvumcg(CyCI-iQzjaP z?~^PjwwQ=L&5DA!aCZTkNETOLS;6ed)0~5Ag#iU!8gGwyt9L<`h#1!-5s+nyn9GC+ z#Ssg8vIio;PS9gq76u^7v@%kNa;dPAQ0Oj*S+FFhg)QQQ@D`W6WUdD9qo~2ga1U;F zl72x<&)U6Q^(i>**4>W5s$}v@0o)KL?5ZWkM?!aT(@K^>gq#aTws-^P4P?%j&b=Wy zL~YW!XPH__4o5Wi1#4R8)^)qinIIk~1e(RQDcR9sXGDmbol(1s(W0RR_QYeCh|}RG z$J;GwC%lx6NQtgQA|(N*u9ybv+L9lnvk*56+F#&o^!LS~Ede3{>tNt2%EFOBg~T&rZYi=sSDv}XpEFG+7UfFtl}<&t1kaF50@@1 z&`u&-TsjXhPD@FSxG|>)NRlV|o3oh3BPSP$#*FjQNlV0v>tza7mLpbJtrj=~vmsC0 zUU)O?LA9_0hP}LIG$%N%mZ*(Xy3D7O6=p*_7x|_vr6zF>8rnl!L~C_KLqZZeXeikq zmlA{h*$`zt01m|7(LRwL0(zp84A^*&R-Xa=(LSy|vv61m=0qI!0?nyoLUk_Jg%)et zu%cFBS%jQA8&_i>3X9T{(no-d=`mqUaTWe0WArLyKq38GzhFxGnnakoAd3uii9O{C z?SZ!~sd$AJ*oMa*GfhMgibB5!e~AI*y7U4zFj1Z3PS(3u0BYe= zODmy00L^dgfm%2__CS53%DY`dYph_Wq)hgJPASnot>jHW?^YE2CY4$Mdm#759}D_K zi&;zzDej(?7$&`AO3b{PNcm-N5S1|Bn77g{Bb;u{)lBji^K&vP>146vv#EUfOJa$X{sy>84{DriI8<~(4Al^K$C>3T&EpCvt?u{G^|>a`mrdd(u`&oG;C@I z^+MiHsccIM5Ckf8W4wsUxXvk3yd*}HOZo?1wu~s^q6A5b6KUhL3nz)OX8^s9zqGfQx}DR{%gGCWGSnnLAnY(QLK!`-*v z5R{99_dzKqHbCjsV-|~RxFfd!8PtSBD6zBALE4ZSAi>K^GOL?8ty~to3))Lqbew*e z=B!IShgyvxDJ@2SCzV$%4i>ACU|@Zm#2DF9#DYkL3eVD?XJ=zA^_xtzc_D(tFJE0S zq2d}Jk+q9&Rb#K}mzTepWfA6eXIQ_YKhqMhQ%eA$mcjx7`$_;oq8CA&NWpt@xOn;% z0=bSo@pkgzBf_DBM^+GlxDZJMq9`u7UHCB-LPk09vdt+}PP8n!xY8VQ*8BJbr05GU zG3p}XX4r@VQW!PIofzshOHI+J8iUfMoI0%AIWZW-HKYPjoP~~42Us}2y2XiGG`>0l z>Z-;k+c|Hp*Pr92X%{sq&TUfxuwzW32>r5{!I8HCu@|jFB!VKpkoOWV@60Rp_^(h z3qsKl(V5bHC6#I=bT8+YLNr8r%n^yTkV=GK76SAe*bg>g@oLnPt(wDf0yV^%QRPda zWLe3Yjn$+y%J>I{m|lratDvvNKwUd4dP?=IAZ6a3SsBWOLur5*O*<#W*U~;{l?DPF zf}OCZfs^oAODST*_Mmh)!U$uBC=}a9|1o61QgnVKrEwQ@u`PnMDUY)aTO@{#^dTa+ z3ui|%@OD8K+a?GPd&rysxlUCK8J%X3eLLH3axLt-eq(ntwo?#B@KDjv8jV3!5h(CW zyQe#f>r~D){tZ7;D8!JOXXv1AJ+p9A&HP#8>vna?NtWgXDXnhUI9%dnAqU`(h8|jJd#PU6;tJ;-Qr@a1AQLYfJ^J&n+v^K=qy#$eNWWi)oPH zo`?3Xz|inT=u;Y&u=O6Us5RjMaxdfJ7M+*$!D~=u;U3WQa}n-^7IxrX4Y9BSFAuq= z&>HSR-?R#ri3=neE!YD|BKxF;QA!0HvX3P20tx<%lZMXYGmpOb?_f&JT=G;)++Y_4 zByv$Q-%_YIH=+R!HWTle({bef z*9~e_m{bqfeNqU0k$%NPYnTEgj2(gw(4^4K*it{jDjzbCCDKSTD-+yp_B1e%5l_0X zk7_yZfJ{9U0cT#?_{Ii?x-4Yim=qIB%PVT}AgrI#6la=$8X)shWV30(DrDGQK+1GS zG)ez~9{KMyKHGzG%j+&WOnMzu(pE9u?G33DQoqQI=hH#>Bx^O`mCX8g13flk)9u1- zB4J#QVI+=kNSFjdf`%Xiw0yQn8zn~ser0TdR5ao}^qEK?ciABz-H<@+`Xoq{3o;G~ zI{G`#_)?_OMBR9V3;Gl;^?lqa#}Uj0Jz0`L)1BV1ruZD=|Itp9otN6n1$+3V_9jtTB&o~^jm8bZ zFWO`glwCf*)Oq*dGqHGlzl3V5UjpquyN|&$dAG64D?C$X*oDhP_V~sL)mGyK!XHB! zq~RQ>YP4W}555xl;yWZ%JhVoC4jSN#cAMnOx@M8lPsE(ENuu3+S|8hy&(eQs(q3)OVD)q z6pjr!avhEoB^eSk`XAnaBv=C!yNvlduNm%E^(EoL!JI27^7~nv~wt6CLLbvQ}Mq?I(yQDut z<@+PZP$}IJ?v|a+=)z*5OXP}g3|RTj2&o4y#vRLG;?krc;Oz35jc}I{%Sm~kN^j-R zzCA$2Lz%d{1Re3erKY9H=)+?1m)H{`*As1lhe{!&-CgjP(Qw5=m&gu@A*aw0Q#=5j z#h-Ao9cNcHp|HdJehQ(pFm}@4d^)hz+Yu;3e~HZSy%Q=PD#ah!ZbW|(ghEYw@R!I9 zx#%#(--g|>dVUk`A~#}g`2P(461m|U9#mTm54NDQ_}eWz1Y<#G5gjtY9}ng3Fm!02 zb=YP!LNVu7YwPq>Nd7?z6)D=eP?2%15u2rCyN!C9T=h4nyO~rMR=$;h3>86zQ!x8T z3vORLa;Vd~3;jSxnA)qYc)>L3MBI@rB5eMhEQ@8>VOsNQcP;F zP97}6s@98h#Df4O+X-Wf3tVnpR4iVu&k4Y)yVn;L3qWgl!||q&Ij5Ww5zxj5A|SUQ z{hh|=AXW_4RhM{DUXL4ch`FXn+z=*YJ~BE8K7xnPL$E9gb4KTiO5q6jNrZ_ntFN}o z>JzAl;>hvLn>iosjIIr<(f8J5WWUqi6HSU zB`O}ugp6^AoeZpG35>TH?Her45+Ne#g$aFa7SogZM7)9MYsQt15&xk7=-&yS^i1B_ z$Y}LoSCR-FUv^(@mfhbF`V12)rI1UQcS32L*`sDm2KLCuF=dZ)3IOpQTAA`A{B_wU z+7sQo8mEwXzy6)~EBqV1L%f5&qkBr<oz-|aK z%G+iQi*^uyroV^&3PHee{Efz!3qK;zt_oT8_=fFeW}VU@4Xtf23slUDt)s0ZM%d2T zeQief3E8VBAuCOHCqU#y*;c0j&P$@r!?C>tkqD$!ADLn$>{uegMrLp+j%a8FM{H*k zo`4%7@e5E16|UPr2C77S`MUOsht{AXaikQ5?7>{|q?N~e@aHkM*%N?RH|=4>!$e8K z7{QHyV|E@AKuArY=LyT$cm6ke4qgr(BTZSwHLIp{QWid__1v_kJofFZiz#kc_O&pMU-V$mV?N;olozyx_LXAA9=o z%MVT*QaSOnCni0-iszo3^fqg~yjpMPmK?j2B(I$$JM1K>S0~ADI*B{vB$){(30t2e z68uO)g(r!WoWz}u8g!md9Cj!1>YT)Jf*Z>C-^5NhiCPZ$c~H=D5<)#mmyeSOx05y* zkY?&wkuFKE4AoLajLVm_`!jC9WC4#~0ZIGho-{ETzltGoz5qq+EWi5JIf*U(IRRO;WpD^2#s9JbW7$1HWJ{2>S z9G_DqB!^#tPuqi>v;hZxWxd)L;#3Rm;8(t<#rdb2^T?mzSK!kU^;0d$i1-!wv@rNl zEvYi6T9Pa9tKX9_BgjbbS4*%5e^>a#MS7~m{fJ+MPh1?QT68-6>i0ye13l{Zgsnf) z!iZBX);fL_KD~%l6V^|f7LH%}o~Ad0u;qJ=9s*5>JvDj^8a)S1I0)e+$WeHtNp?6H zLVt~(hDMG9#$~;Y9*9OygeJ3`8a)$@9*Ra!g(ei>s40AUFd97>jU0_fjh>B04~K>f zPmLT8{K|SECHO?OdOkFGf-@}eX;9##Zg~94eyDr-q|RIX>i6V)JZklPw0b_&#dT6= z5`JYrTJdt6)KbTKoR5>- zO#B4DLeF4|k~xC|7|Gl=ZkxdDmhT|Gd;haLq^#N#s-lZ__%?#v&siW9o^uA zYzgm2fKos+4s_XePz4(7M>R|0>oL|C1955gem*EO&Hx~c26zG^z8->3064@4WyS>n z2&M%C*Q4_Z0EhTs%QG$jG);^Fwy3s5QCv^Ge+yt1#WVmTAjUwJLL6TKUjP8lxL|;E zgqa4er@SOvaEK4KJmUfYY@&q*u4e)z0F?1TJ%(h3!PygzVLMDQ2G}RINdsm2U;uz; zTmYD=2m{)k;eyvQ!9W=&3;^(qGXUMWjxcaN-7W#(m`2DmE&x<*jDbZXCCSmj5lHaC zw2lE_H$yQi?s&!pfVzt?;O?Tk48S2y*zt@D0L>6#;QCF02?h>v!j5NL0BFY;16iCf zuIAm(h&rBe0iZv}7|7y;aglBT06gOYz)&q1Q193lABbyk3jp957XZd)!GOByHUT)q z2|J!~0bpul3}kUa_V||{L!NO4pg;E!2E=i>iGf3$P-a{Js7OOojYvJHn*bc*ggwu= z08mFdp}KOn0Eo+C_Y+~yGcEwMkxr;SlI)zCyWbS3oyVl zE&%kAPN-h?O$;2ejeDMP0bq!9!j<~L1Ota`_XGlzgaS>(#26)B=fU%1X!Sxm@2>^!} zAu@y#5}1bQ5M1vvlK^mt5mr3oi~$7aBMe+`$ddqYh!M(+3jp;w!oc;uMF{|h7$Ncv z;!{vJRg8fw(=e`e+)soujH~c=%&#h8!xJv^PmxNf32$3F;L=6& z@|OYtJmU;NdyZ7Xl}6d|DU6HZ_G3V1TmYydm2jnJcmlv7Mu@z(_z)n?Ejk2RU$Wt> z=ghQXStK(q7-%AuP?IA!Y2XkeYWQVBJacN2g^UP7d4 z#x&5KBbBh$&P5wEz=^TN$53XRG0<^NQ&0!4U+NPxBF<1Q2VfbfxGl;m;*tmKkv7WyU)9%6*uN-pWjjcv&e9AbpsN-nA9=Wk-*5F_kXa!FTi z@k=mJ#s~uqt|U>#09>cRxL9dFAM93gsNyRsMI*hKOBz=s?EpX#u$D_21F(XCvaoSR zF6s5FMPmZswDV#nu;w0GxurD$po|NuM!e=8TDjCV0pO5fyyhNSx%)Q(;1C;Ja}Q~i z(H0kq@9Nxf2ErDsxQDddX%m1$Y!HS=Y!isHMs)$LyV?Yxj12}1thk4y9P?t|r-%kn z?sz1nd(Azhm1r9n==qAzVm`3u9tvga>-u2N_hOaK{dthk3lZ<%EaE_r8qzRYqz04fXD+(R({S7jlxKMoy&74J~!yRabO@(vu* z2iM#~RaRj|&()v%cR=}2v*I4oLe|YgaEKAExrel(b_;-Gr6p_bAua8V0JwMv;wu(+ z2tz#tYwn>Kfa`}Kz9@0W{7M3A-XX1Vju3G15XAQ!767o~9nxa!O#lvQglpa*t@_>s z;E+bR<{i@V^GyH_F+$YX#`=)>YJxr#6;`Z>qQcUWK!hvaA-x%469b1d!Zq)Zb_Uo4 z;1DAef7Ifh;)=Jh1zD99XgYL67_NDTv{%9w2IAZO_VWQLZeB1Dmm15}Q=2+5m-ZJ6 z!!`Gic8`cKa8VQ#)|RL!SaT1>09+RZ$4X1qyhGYXBSOGMQNS4{#Q?1AK$$|Q^RIb_!u_nIk*>^N#s)LIL)u`4Hvo?hryjXZwyXo$$VZsa zTK1AQdWi_&A_X3+D_L_-X~&refQuB!X=eM6fKtGkdnyLtIt6e)m;LjrBwq7QY3rQ` z0hf2+kXgLyosu3Wn*bbA2kSNOlr&q}1mKW5xaOUbrZ1cGmodRW0xQm`>o-HhzNuqH zC2PJZX%V%#{xT-0>tAzCW!1FwT#8$K1lJOmq$$wW`j1tVtU0EnInn0)heE|`X-m>1 zX>FKsP{~`Xj=9H2q zTATA9;(u#CDZRH~!z&nHKepcxT60P1%@|wrAL4&&9x3Vfw~7BlO5mDDN^kMmSbt$1 ziJt$pbS1qfYHR*O{BO-4B~9nH@PDj~WX&BV&F?nnKcoS!d84Em-{$;>_}^NplHM1x zwf~3s-%$NkwE@yPN-%6>*UY< zz{_kzO}zZB9UhZNj5}-etfTCoKgR{N%)heyGUk`#fg-UY%fIe`;&yQRSFh8f z+bZ?@483Kj;nLFZ^J??wg!m6R0A<2?{uaFsn^3f(ol#l%t)Rb5_tV{%377fNZfRLR z=fNxflPhA9^_S^>iht_w1RFQtzeTIVX#Gp|;Pw4KRxlzHF7u<=(z5=X9&3GJ!AQVA zPq@s_?Pt~Y)K0q_`(Icu5_+s@!`pcSc6Yq(3+qJ!0(im&0pocgfUF|!o@+YxGk`EZ zPq@sFPD?WZWK|5I7X!Fd`TRWLJb!ma>$|`JvXZoWc2N}1FB2~FqtDW^evUA1F@X45 zqaDVt;-4BjMGT;;`)K{r(tPUxlrcbMKr-R7esoz{*3X$9TLLJ)rl?^3JmE5bJ1y(a z%ZVy16bbm}377fNV`*N0UOGyAg;2rzdBSD>p^nxcwYR%201L}R!uol_Wqx#6TGr12 z?k)N+tP%Mggj{xah?&_7Q&&rki8mi0%i<*p0h!Xgn}zf8EyUy(i* z@*twdZY%3AbN+?-dBSCWbXS_!pJn`VPx4~+OWm9z_Sd(O{ulKwSXq4;_Y14%`IgnA zv(mi!sB^)}^oO*+p66Sp?<4I`u5%FHe>M7CSR4{o&+{$QqpQ-g`lX>AuO8PdJO-*0 z!|PyW2v4`nj%KqFEv@AM*K4)E!`+U79KB zsn-iOc;{)OF87n{IWoEb+@T^1_ZfxO!lVV$#T9+hVm-=$yUzCbdXoL~2lT`40RjLG z-7`@#eHqu&<*U{omcRd=3*>?nX}!Aq8XeR|TrtzYn=#;O7zn*@+`aMTFW-p*@zJZN z&!64BfA{q#KT7|7>D#Yfefsi;@9uu?=YH<-cc1_9r=NWC;p68ozIAv1?1#So{@sti z_tm@l@%iotVV1_0DPJ73e}_<`{kWrR5YWy6#Md#zt zfN+Hixl;hL;xf3_s%VoMBqLH;3>k$$0P!h80P-ZxK{V^_KpTg2D6APlm3j<7jcip9 z0L5HHH@nUykgrmN0aV64u4fFOWc&gEa(_~UflI#0fiqb46Crp0CIHY-s>ZD}=pjHD zfTw;4-T_xKa(VtT?GQJTJ|^?KLoWf`ih~T1kx3B0JLfO6j$2ykvVN4Y5~GOMulGAe z_`j5#G!#~hsD^-CWJuo%(t%C@vCBRzKXMKU{ar?X8JpDUTNnouPfMBkEmZZuf%G<| z&DED_hZWc~T}OnwpRoHC&5Px?SpK~GS$9yNEo0H~t17U(Wqz=sn${oBkH2Re|H4|4 zfPPs%y6!h_dOB8{+^4Wor0u}|aQJXV7AK~li3=$yEt+mFT_p5U^YzH&P*^Jx2mswo zp?9K4ls5qVZ68;G{ ziVgA?$@oaS#rC($;adVD1nFfBd0+!>zvw|VCJSGtLR=q+UhZ`GA^m6Gmv{IJOGI!( zC#ydcmWOVLGl&~JMGyws%iQ}i=10}R1BpJkB1foy=f@MxPl9mg{KuGI1JOk-Mv)$X z%MB6t3$y28zpy$aP(Do_=suo2>*k%IurdS*=A?Ny=(7&72hS+!y$yumEcP;|FVp&T z?Rwz_^3R#_ucZ|XRViPfO-BUCc47Wb>yp{s4!f;cKETX0eH zFDwhGAaB|GfVj*^mkkREqJ>&u0eO7{hr+TDQuaGCyl@mi0yRt@7QeXoVJ3lG2+BN! zHza{FD1khQY%#W^w1P+?NWbhp00%bbj?MR@E4c?3d z3M)fyNCJGV_*oDdqZQ-?A);5M8P?l`XwWkOKK2~!dv zBi+futj5+uVVy_~PZ)&*IQ(*|d-2N@Fadyl3t1@M=#&X$xnm0pMJy8lPx7)ba|g=w z!9W49%Mo@2`{#HNYd!lUVPUCAm|x9uc!tO`m#SkuNtjJJR9Gu=GZH*jD6pgn`QgpecBiBXyfL77=>&j79& z00zt%$nwr{QS*LX=yqqIP!~*fF(l4XR5m4ny!DqcK}Q1c)H!uL>w1CVV9|)OLHMaD zIFph97Xxl`fx@bhn^~o$RU;`0fDMu$N=P7c{e@gG*o475301(6Kqdrb+MwkE<&qGd ztrBI(0B}GO6&8-%js|a{4MH0<i3BwVw?;HdHQ&j+KrCWdxc*sU#|_9Wly4xg;p8 z9dTPwE(wlRkAy8aAPEY~M{afs$1*->NT6I2Ajnk01}zD|F;glD#$)=RBxzxC$rebG zwAkgbsSFgBkjx~&Iiho@GRhIn3{`TItNn~HNTM4cpim(UHqlW894jNyG`%AfP*_QF zGYa5j!s8U62{Y*t$chobyHvylZbkuRT+kkY0|+Q&gEvFKF(xP$5w0^4CYS^$vTpkt z3JXf+BXBfdqp(^ePypg%6skt40!L_2*0&_AWZgD4lvaztAx=4Co#yP|UV17i>h|aC zjD_VQ6%zC~TN_#1lrf?Sqs#i69M9lbTq}a=5L&;aYoeT-y%JHnX5M9MV_~U?RYcIx zf$^U>rZO>5#smWia-J|}ZBm@HB|t*XXr3Z47TzyHO+;GCSB4hYBTXMUtK=LV;HFmZ zbng6xOb}PQ5CIAaRPYVZ8H_V_YtBO0QpCo>Vi8=R^BA>kbIugsvjPAT63B$0)Fu`T z^r&4!VPZf*kLDI_pn+T*lsN})NQ7m|;LV7zux6x%BZ8CmId_vtk+T)z+|4`^C@dPO z!Xe;_tqSa)e3Koe5rz;^R>j&_S~3z`bBEJ4#?qpZ0D(FOku&3C^_e&*QwPHygkz|i zkRHQK2+CMtIEI=+4P}5!m)Jy`c`+TZOgm z!eimhA{B{#Y(J&$*PJ~*fc&VQC6w*v&VNW1l<9*p5>H=e*&<_M{Ya>v;29AYljLZ=2!l|W zAKD27Jv?{*G9555Kbe1Ke#!iK=r2ufK&YK1OSmSBc-H=M z{IMh7Kvq0`8!GrDQ!lCDtJ%@EDgO(v6rq3|xgu2mL%uRwVX^*^Ie!@o3_Y#I1fddA zpQ4hLvpyEyDN@1p%FZ~FIw!hZhuvWj4{D;uUPLaJtH;OE$`QDosB?<&K=RIt8NA4# z%mYwZH`2ft!wNWUIhcU1#km$_Yf)IM}s|15{hlW%=yb~;5jtS9^q<`9Z1}P zne&&$L~3~5*aj6Q(17+hLnUzsWMy7 zxJc&wWsK0C0*#ENPVr0#${3+J1t??X+M)CmNW6B9D@`?m~EKeQe zdvNx%Vm$=`06hg=3_$KFDC30{I=OKpH7;kb&!P|}38R@ba1%~=ga*nuq2WXD36Mo( z_z=N2;IW?#l4C5g3Xz;qXcZP-He$}e0jsdEbR=*gm`PuIvblRJNzU0mbv$svF<pz#i!g=0dcH=)q z>#R-&V`0$N zGZMC+EFw_9gh!fT3bY?xxwEqQh4msjc}K2E2p{Cfkr@VsC@?;By3aX!h2F$lWyDR5EZ!f=0{R_+I=_^F1$OjQm-!NXc zr!QlCI(>z653!@zuYiS_?`6_{nIDi^hLF%FBLI6)OBbUGEyV)gY5A&%?d6y8y|8?q zz5)ZFa7a9T!#rhc`l+-=1PO5?={#V+Eh~LwfH&|*%$$$Eygh$eG(?v#(^r%oVy4GM zuo;|hDl8Id$n}r2N4G7ar#Rg>Oq>t0Fr587m3JzG(XWh)czW~Kw_8jm1n!7 z;Y!@?4Jb5zRqiST6}UUK@iGwPSUwXR7$uQ;k|zraf(s-CfD7`sQBcMJt6mz*S1@=X z=4*Au*Pw~T5zS2*wjn6vffd*eS>Osm1to;cPXj@Y?J=Fp*kITMK>-KIND8DV$gw`A z!mC9TfR=utfI$p#Co6>N=k~@eXTNUlL1CRp0D$u`<`iX#Q>zk~mm@rt7K*^&ib#O(3MQjHnrouvzfB>=o5R&8!xyb&@Q-h|$Dv=gG7vcjFmtT@(qaN#7 ziojHrF+$GG#u?Ne^Hje}N_dZQBbf>}!k%nAeEQ+z?@B&<#pLTW||A#nWU_h#hv@ru}vaXk#3QI&N z`awy$tbHI7ttBFqEEUdwR*BNYf%{@7EaGv@f#Hu30;Gd5Gr+7JI94MTbfhw!7HSB&qO?kjl=GeQ zmuZ5EfF6N(Mu3zl^;EkxAAzhK(W&sF5e0xe(G(8`OC&vz%)%ueoRua#72Y&L8Yr1O zEu;aQ5irL&CxgPnx&u{o3oC(p*$X>yGWGr=KGJ#)B}k5I94S zAxsPi_TYT}sw`*7R9GbvawBE_3guet1ditCj`7>rFH-?^^L2JmBB!Rtvu7z_$4W$q z>me6to*hboo;=R{-(LG6)<<_a;)*E}gmmtZB^b_q=In(Aa3DN*<4~We^)U_Zy9&xD zCt7YVzD)O<>5iulbQe#bNq1#Fz(990yY754dlualR)z$Y2lW%~Z`d1r=CB391;*jj zP1G0Gg@oCW@YzSUB{MuNgK^VMRzFJf58tZqECNX3z6Ivqn%L>k(z+#RCjPeDzwp_%_e19PFv^ z7Ll-cnH@Qxym;7qA>N$ldFFdY_Aj0y4V-{Y20p?q&@_y>op+J)#0tUw`E~VrlkgdA zmn403ldr4Bx|DA-6dIyT~e^DV}_t(z>r@Zykwew{xcAelc);PIuS`!|5B z3XV7+_@bFkMErEA;hgV=3eg!h1t>eknOy$RA`e&!0#B9FyA5 z0t5LY(TzG%kdKu#UogbECq|yPy|DCy%qvdzMA>1-iVq9HbI`l<;=P4s9}U%B)9Hhk z3^`^%Idm_CJj2P$Gj4)FC{{yd{KmX*V1+uVkq=9FYbM^_YrKJy|Mj)UEfU+#RhDs_($fMZ- z<(I*vCoKaMzq!>fvDe>v`s&-Cee>~0&%b;3)qvK!_uhYYK7aH5w|~qa5)zCwrg*#G z`ta3^mg|XpS}9z z=`&1$ayqt_9|7KH-}=)1vmg5U`#%_yB!G;$HGSsG@4oZyyXSNJ*7@8ciK?&9=kARE z8vOa4^BF(n8e#3zPkU?+dqsR(GbbLyCFYzyLH~GqCS&wxGDhitmNC?dfO_Jw275-jU_1s;xn*2B*1^M@ zK8JVFA2}VvX0{Z|PT%cY$}fq>@NQ25$9N2ALpaxtjXkA?#LwYfZf+ZoozG)W{_}Kf z8i`ZIV+fIR&%$`@e4a)+hsjt4`@*dkZhng^JV(`@>APsrgfkV7Vcwn+Qsc2R99b0d zO2^Q8)r{fYfzrtBa}-ob$9g1Yrek<_A~&CXj@&fq7@Aa?v8L-_@wn%3Snb%g&0f6&h0cg zKGfk58d#8Ta<=>cG9K<)^F4?Z%6UlVMY~Q5GoG_+J9l7;4(72X4^;d;dXC(p=@`Ve zfdw!FYX6+2-81x8a-GND!@C0+l<^onN2W$H*4OTw<6X}Ev(MSH3XP(*^w)GqT(xHq z&ru~|`aPHh4rZX=ZFIm?^QL&M&;cn-Wv zy&BBC4VnhnvCiphc(-?FVd%g*?7KbJJD7O~0^!!gJ(nNWX{pk(mSU zc2=&Q$9i&S5bVYBKfF6Q-2%@!9E{Lu{CY>rch7i^S^}gnlVy^QL3@Upo{m9i!R)eQ zxLDTh5w6!VW9M9X&_*W+-7zOa_A#>wLf8O0QcjMo8}A-K{p7(ec;o{@)TX&3L3 zt10;&o|~w=G@j!OZP(Kk3bQUe=jaMPlMC~5a(+5T#~szvF)#$fJ5dLFwr2~6qax>P z`tCSb`G$8<)aIYF_6#g(XzA&5co*nO$LKjr2eAAH%ZKo8N6C6IeDoZJHPW$qw7N3h zg;MCBvpk}Lf<@^*@%QlVNPdWTjGnXmR>8?&b!xmjS)PsOTB_+lgHYlOT~%Pa zR<}T;srBn6WzWt5R9XB1`Ia}qh3;%gXp_jPG2cT>&C&thh1TGoYb@>|Whl-P;{fjt zRwiSLo)R|V=PHOdXAkyBF*WBG&rO#9ArT5L`Sg2D4+Gf2*CA6peXgoNfQEy9^nzFy!sKsCY4Sk9SAPLQm&_9%k@@s!tfZ>2omO zoQ%SAz4bv=@ZwvX;@!&H2K1cc8|d@l&(Q$WJB0;_z_r6Y8mLnicDyz+IjydYjsl#9 z96tw*u(mkByUt#v=dA3;F+!g*H}7O+BRyx&8$2W4-tTdxjio<4=jKIg0E<5uB$Pap z-~e6~r<);jy0Lm9-gW$so^$JHd#5|%UCM_x^TLidJfb4h8~Ve$lyzXV5b9@)-nw!yZwa+&)S!Gcd+~(-5@&4 zo3KHx(^UqPt6BI4L{HopvN|l^7$B)F-4EcW?p^Rnhv&+lnE^Vc#UHquJ#V;x1V*R9 z6`r#=g|+2;uXq>n5c@7{si3eVZ|28=qp z5in1VhVYzQFB%5;^+Hrw`onW>y(qA=zBJ@5K+2o-;yK6vCfEUnPVp{kPVKwkFIJ|2 zGMukqAT7zhi(_v02vXJQghRt!BNLv8=bTK2No@6O^lgM|%FgR!BH*yNY9M_M@1h5F zI!4b~UI#2==hEl!ZhPT5Zod$(qb9eRp+CIq;w1E(#@m9?Ybxxw`h>2rAZ!rD*_Zt(|J?EDM^9A^gi5DJr} zQJ4PFq zj$z*3##eFUFqdh^IK`OrH{spM>Spwu!vPB7t!X7xH z;%n+u??&5BA7SW@8R9i;RVlGyBh&qxY$zo z;Ei>0CVI~D2y%T{e=**Lcuc=X&pCR57s=W^co)e>_Fbe_Se^r|-P$gA7YQ)tT|DRb zBrHEGEAXz<|7tvE;{kBPA-a>!fp=XTf}V5y9_Eo<8y1U%vGjZJMz|OYn$C}&u0U$; zUE~2c9E>hrfqB6t?7R>kZfu&YFB0z}$;-S8Ez!y?ICDlj2i_eVZ^DSBAvn?oyIyEb z&fcO(f<5OLL!w6tAIA6+vY5YM42;M=N6s`i265}gkXq%&Ts#>8SC_wrvBB;e#++S& zF(h2rIiNNL4+d0V7~_kf?J387vo(QBgGi3UH3gWWZjtamBI_>e9aiEt(}K4ut590 z2_9KDhDe5ig%qYjxl(2-1kOD_b@gb-NO)YbdT&}NB2E!`L-zZ-M53!>sKFAZZ(C&XA|^$3i?;biAP7~ApxOKEkN{D+7iCS*V>FAgPUK#fsHyTg*21J>|^T_>z%yZ8E0QGU3UGp5W z^6k9HS9UOua00mJxD8wSJ%mjik3i0y!!yLMTL)a+4$l)ZmhHUofjXEc7mG&W7njZ_ z@WDgtU_p+x%~3*OL1S$zjJe!0jCGDTA;a47rUtf^-Cuaf9B;x2ba(-)^RQ6#*x&`O zb+<>bdK}M&_TqFEinCiDL8iEy139Ud4q%Ggyc?M3&Xx7;`ZKj5)t8#=LEX%nFZZT>IqcrSrBGl69R-K|-sw zr%^)b{3RFz)D{Pj3l8^4?s2&9kr3kEMRAZD^EwF3Mr)fQi4n?=eHU`U&4I*RHwS!u z4p)#1{(H`Ei{vmwckH}yj<|P6NKyBkv+eOcC z7;|}0h>4M-0d&CqHcc?&U5>V ztV4IE;ZksC8fk}4?!!uPItZK;&PPFx0V`|C$hN$g3|7mF$sn|J0E5P_?Sfo@g70)1 zDBsqXi6DZtOXE;#oUR9^!T-=`i5U+6ii}Vsd=50TiDNfgeRB-YQ zS=>&)0?1CjA!_A#6EZ`ct_K&HKbIh92QzX${TKqpc8}mdb@)SxqB{#n=W=5}v*p>y zd~D0_U}r3q%@zjPC+V^k-x!IX(_o zq{qwXYJx$2aPru7AdSr74@n(v-_Y*T;R>mPehk5FH;4BPBg4VgGa>5%Mud46)|=B` zI+*(wK1g%Ncaa6<{8FGkXA?sWb2=*>K?e&GzAgTcsq1`XT zydZvb0Tz^@+wUQV%JQ|2vIE?6wc8^~!La<4+|+)|<({`F9lijI%bNqcLW!A$g#yZM z41Lnwn9I|`_n^qS=b#k2F&6{EyQu82&%q?|V+e!0=TL6x#$4_oSh0(>5qow%6y%!v zJ;Gsd^a8@Nyb0N-?o4CXobHYE631WQMsmCkHPw#S!K`q0EkugbPf-``^iz~~JKYQ% z%*i8E$a+|i_T}~ifi*`jNd9&E0XM%pTgY2?_=8I5&N-ShyFEv;kee5-a6jhqh9PQQ z3>=~s%BZCw1Q-37%g@2PNa%9!dOry2T%CQ?!E|xBg8SZ$fxS5Tn~)-5=SAJD!!z7I zZXF1xIG87wlMi(RjxI9?NHVPOS0UI%T+@jBFQx^o0;)yYPf#LmV+ z4W+{iqKHmTLv3<+!I5!zq54LPD@4kj?;4(^3$VCa1rUp?v%#3l*~XanGf)kn-Csyh z7azniw=rRS&+}cR*f<#gtK099&o6=V&*kZ3%++CF%=PZTn9J3`n9F~`nD;*;^yzF8 zc+DIihsEUA2Cc@P8Cdb2{$Rpdp3}G9_M^T#Za)wvw&$%!@q_!G&j&&CYwu_1!JsW) zqkMkLBjDzDG6gOkXYYfHJ3SE^wcm3>sy+Jv(47T@VjPd4;&t~f3Ono=QV|`lD51eU z2gSsVL4|f>uHJw;!uUNxjM=U2LW~*9aI%)lyc{f)q;6pWYj?Efb8z9Y^tK-)nUl3J zx14-~sCBUzSRc+;fbhPH3n87=pM?u@0qLwB&yWjtFOkFIWH+k2U7QIfqSNnDdhK}o zg}M#|x8U3~c&2(1OD`xzakzr#)$t8zr_SF#T(B3YJlWC<>N=dQi+T-*D=N>kv;h)# zG;<%3aWWKXv>q0u##=f?O@lihP|cj4gVYaqJ}%THAY;ep zgTT}5bbe%8IGRMwfURGE){fRk7BA$SGh^_KSpGt}QC2TTHMWZ<)0pK$7#l5oNc?p^ z6pT5!3I@y9q{aRN8ng6FofE8&0%I<39b>Mi1cmtQUecKLxna!7JdF7|Af%;PSP*`5 zdDk>%ZF`K-t&X(ZxrZ9Y;DEMc@G+Xb1XaP=XP<-GZs;D*!C7UVgFDvc%p$MF>O;_8 zKt<+Vj9EPq&$-@IaK1o;vG0N*7ZT&F`OjxJ(#PO{t(`Bwa65rviy(3 zR)%k&4VBBM!59=1GcUTTS(?OiuGa=~5uJaH#;h)i%t0hFnmLf+Wqpx&&gD^H%=K=g zOhn7Gk*w!(!7%3XOEBhgnJ`B8pAyk5bPCaJ&k>$;{#cB;ye|$F*}a5!&CwMq6s^CB zIGyz^Va(O=BAAT6kQQbbDsCOVj-E1WtzCw(3%SJb`MQ1cd4dRF_&!A=T#S~k5K*`G z5#Dt*0~m8YBaAtDj$~@*Q@|J)zQqe_8XR7LeE*z_&Ek7b_E0#_%6*KX#L>=+oDO>i zku7C;G2V6coESqQviTl5idkKcN)@c`jWJi#k1^*5#+cL5G3I#*R7|VyB2?+m7D_3s zJjZj+XM{0dn+q4WwcijaLS~x90rVV8lc;jAenPzKYc3FZvN|ThtIlshAy+HoG3I-p zKyq8%2hVx=F##I4mpBT3%%2&ELB}U4{A+0!u74*RQPpwbIoE>@4jEU&hB22Tf-z@r zVa)RlM9}3#YrBe41;o^v&=7;`og#++V) zF`p-hx_7GsQ&iIGIT-W)KSXRCUQlN3{AOsqW9dD`E;yzzIyTD(@*YSJVJZ?_n-dpdv30N_vHEWSM(>G^Aq~*|LC)y zc}{I6%9)17!zw;CCKKlOwM22Fi literal 0 HcmV?d00001