Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-09-05 00:51:28 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-09-05 00:51:28 +0400
commitcb89decfdcf5e6b2f26376d416633f4ccf0c532d (patch)
treea299a5c8729dd0cb4359d57501fd9e6970141e5d /source/blender/gpu
parent2167e5c341f656b2f664b1052d181e8aa32fe698 (diff)
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with scons, make, but not cmake, that seems to have an issue not related to these changes. The changes include: * GLSL support in the viewport and game engine, enable in the game menu in textured draw mode. * Synced and merged part of the duplicated blender and gameengine/ gameplayer drawing code. * Further refactoring of game engine drawing code, especially mesh storage changed a lot. * Optimizations in game engine armatures to avoid recomputations. * A python function to get the framerate estimate in game. * An option take object color into account in materials. * An option to restrict shadow casters to a lamp's layers. * Increase from 10 to 18 texture slots for materials, lamps, word. An extra texture slot shows up once the last slot is used. * Memory limit for undo, not enabled by default yet because it needs the .B.blend to be changed. * Multiple undo for image painting. * An offset for dupligroups, so not all objects in a group have to be at the origin.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/CMakeLists.txt34
-rw-r--r--source/blender/gpu/GPU_draw.h116
-rw-r--r--source/blender/gpu/GPU_extensions.h144
-rw-r--r--source/blender/gpu/GPU_material.h169
-rw-r--r--source/blender/gpu/Makefile37
-rw-r--r--source/blender/gpu/SConscript11
-rw-r--r--source/blender/gpu/intern/Makefile53
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c1439
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h87
-rw-r--r--source/blender/gpu/intern/gpu_draw.c1167
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c987
-rw-r--r--source/blender/gpu/intern/gpu_material.c1460
-rw-r--r--source/blender/gpu/intern/gpu_shader_material.glsl1543
-rw-r--r--source/blender/gpu/intern/gpu_shader_material.glsl.c1026
-rw-r--r--source/blender/gpu/intern/gpu_shader_vertex.glsl12
-rw-r--r--source/blender/gpu/intern/gpu_shader_vertex.glsl.c13
16 files changed, 8298 insertions, 0 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
new file mode 100644
index 00000000000..4d376f47d91
--- /dev/null
+++ b/source/blender/gpu/CMakeLists.txt
@@ -0,0 +1,34 @@
+# $Id: CMakeLists.txt 14444 2008-04-16 22:40:48Z hos $
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Jacques Beaurain.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+FILE(GLOB SRC intern/*.c)
+
+SET(INC
+ . ../blenlib ../blenkernel ../makesdna ../include
+ ../../../extern/glew/include ../../../intern/guardedalloc ../imbuf)
+
+BLENDERLIB(bf_gpu "${SRC}" "${INC}")
+
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
new file mode 100644
index 00000000000..2399e7b6a8c
--- /dev/null
+++ b/source/blender/gpu/GPU_draw.h
@@ -0,0 +1,116 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This shader is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This shader 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this shader; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef GPU_GAME_H
+#define GPU_GAME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct MTFace;
+struct Image;
+struct Scene;
+struct Object;
+
+/* OpenGL drawing functions related to shading. These are also
+ * shared with the game engine, where there were previously
+ * duplicates of some of these functions. */
+
+/* Initialize
+ * - sets the default Blender opengl state, if in doubt, check
+ * the contents of this function
+ * - this is called when starting Blender, for opengl rendering,
+ * and for switching back from the game engine for example. */
+
+void GPU_state_init(void);
+
+/* Material drawing
+ * - first the state is initialized by a particular object and
+ * it's materials
+ * - after this, materials can be quickly enabled by their number,
+ * GPU_enable_material returns 0 if drawing should be skipped
+ * - after drawing, the material must be disabled again */
+
+void GPU_set_object_materials(struct Scene *scene, struct Object *ob,
+ int glsl, int *do_alpha_pass);
+int GPU_enable_material(int nr, void *attribs);
+void GPU_disable_material(void);
+
+void GPU_set_material_blend_mode(int blendmode);
+int GPU_get_material_blend_mode(void);
+
+/* TexFace drawing
+ * - this is mutually exclusive with material drawing, a mesh should
+ * be drawn using one or the other
+ * - passing NULL clears the state again */
+
+int GPU_set_tpage(struct MTFace *tface);
+
+/* Lights
+ * - returns how many lights were enabled
+ * - this affects fixed functions materials and texface, not glsl */
+
+int GPU_default_lights(void);
+int GPU_scene_object_lights(struct Scene *scene, struct Object *ob,
+ int lay, float viewmat[][4]);
+
+/* Text render
+ * - based on moving uv coordinates */
+
+void GPU_render_text(struct MTFace *tface, int mode,
+ const char *textstr, int textlen, unsigned int *col,
+ float *v1, float *v2, float *v3, float *v4, int glattrib);
+
+/* Mipmap settings
+ * - these will free textures on changes */
+
+void GPU_set_mipmap(int mipmap);
+void GPU_set_linear_mipmap(int linear);
+void GPU_paint_set_mipmap(int mipmap);
+
+/* Image updates and free
+ * - these deal with images bound as opengl textures */
+
+void GPU_paint_update_image(struct Image *ima, int x, int y, int w, int h);
+void GPU_update_images_framechange(void);
+int GPU_update_image_time(struct Image *ima, double time);
+int GPU_verify_image(struct Image *ima, int tftile, int tfmode, int compare);
+void GPU_free_image(struct Image *ima);
+void GPU_free_images(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
new file mode 100644
index 00000000000..d3faa81ebb1
--- /dev/null
+++ b/source/blender/gpu/GPU_extensions.h
@@ -0,0 +1,144 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This shader is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This shader 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this shader; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef GPU_EXTENSIONS_H
+#define GPU_EXTENSIONS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* GPU extensions support */
+
+struct Image;
+struct ImageUser;
+
+struct GPUTexture;
+typedef struct GPUTexture GPUTexture;
+
+struct GPUFrameBuffer;
+typedef struct GPUFrameBuffer GPUFrameBuffer;
+
+struct GPUShader;
+typedef struct GPUShader GPUShader;
+
+void GPU_extensions_init(void); /* call this before running any of the functions below */
+void GPU_extensions_exit(void);
+int GPU_extensions_minimum_support(void);
+int GPU_print_error(char *str);
+
+/* GPU Texture
+ - always returns unsigned char RGBA textures
+ - if texture with non square dimensions is created, depending on the
+ graphics card capabilities the texture may actually be stored in a
+ larger texture with power of two dimensions. the actual dimensions
+ may be querd with GPU_texture_opengl_width/height. GPU_texture_coord_2f
+ calls glTexCoord2f with the coordinates adjust for this.
+ - can use reference counting:
+ - reference counter after GPU_texture_create is 1
+ - GPU_texture_ref increases by one
+ - GPU_texture_free decreases by one, and frees if 0
+ - if created with from_blender, will not free the texture
+*/
+
+GPUTexture *GPU_texture_create_1D(int w, float *pixels);
+GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels);
+GPUTexture *GPU_texture_create_depth(int w, int h);
+GPUTexture *GPU_texture_from_blender(struct Image *ima,
+ struct ImageUser *iuser, double time);
+void GPU_texture_free(GPUTexture *tex);
+
+void GPU_texture_ref(GPUTexture *tex);
+
+void GPU_texture_bind(GPUTexture *tex, int number);
+void GPU_texture_unbind(GPUTexture *tex);
+
+GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex);
+
+int GPU_texture_target(GPUTexture *tex);
+int GPU_texture_opengl_width(GPUTexture *tex);
+int GPU_texture_opengl_height(GPUTexture *tex);
+
+/* GPU Framebuffer
+ - this is a wrapper for an OpenGL framebuffer object (FBO). in practice
+ multiple FBO's may be created, to get around limitations on the number
+ of attached textures and the dimension requirements.
+ - after any of the GPU_framebuffer_* functions, GPU_framebuffer_restore must
+ be called before rendering to the window framebuffer again */
+
+GPUFrameBuffer *GPU_framebuffer_create();
+int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex);
+void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex);
+void GPU_framebuffer_texture_bind(GPUFrameBuffer *fb, GPUTexture *tex);
+void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex);
+void GPU_framebuffer_free(GPUFrameBuffer *fb);
+
+void GPU_framebuffer_restore();
+
+/* GPU Shader
+ - only for fragment shaders now
+ - must call texture bind before setting a texture as uniform! */
+
+GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, GPUShader *lib);
+GPUShader *GPU_shader_create_lib(const char *code);
+void GPU_shader_free(GPUShader *shader);
+
+void GPU_shader_bind(GPUShader *shader);
+void GPU_shader_unbind();
+
+int GPU_shader_get_uniform(GPUShader *shader, char *name);
+void GPU_shader_uniform_vector(GPUShader *shader, int location, int length,
+ int arraysize, float *value);
+void GPU_shader_uniform_texture(GPUShader *shader, int location, GPUTexture *tex);
+
+int GPU_shader_get_attribute(GPUShader *shader, char *name);
+
+/* Vertex attributes for shaders */
+
+#define GPU_MAX_ATTRIB 32
+
+typedef struct GPUVertexAttribs {
+ struct {
+ int type;
+ int glindex;
+ char name[32];
+ } layer[GPU_MAX_ATTRIB];
+
+ int totlayer;
+} GPUVertexAttribs;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
new file mode 100644
index 00000000000..560421f7edf
--- /dev/null
+++ b/source/blender/gpu/GPU_material.h
@@ -0,0 +1,169 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This shader is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This shader 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this shader; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __GPU_MATERIAL__
+#define __GPU_MATERIAL__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Image;
+struct ImageUser;
+struct Material;
+struct Object;
+struct Lamp;
+struct bNode;
+struct LinkNode;
+struct Scene;
+struct GPUVertexAttribs;
+struct GPUNode;
+struct GPUNodeLink;
+struct GPUNodeStack;
+struct GPUMaterial;
+struct GPUTexture;
+struct GPULamp;
+
+typedef struct GPUNode GPUNode;
+typedef struct GPUNodeLink GPUNodeLink;
+typedef struct GPUMaterial GPUMaterial;
+typedef struct GPULamp GPULamp;
+
+/* Functions to create GPU Materials nodes */
+
+typedef enum GPUType {
+ GPU_NONE = 0,
+ GPU_FLOAT = 1,
+ GPU_VEC2 = 2,
+ GPU_VEC3 = 3,
+ GPU_VEC4 = 4,
+ GPU_MAT3 = 9,
+ GPU_MAT4 = 16,
+ GPU_TEX1D = 1001,
+ GPU_TEX2D = 1002,
+ GPU_SHADOW2D = 1003,
+ GPU_ATTRIB = 3001
+} GPUType;
+
+typedef enum GPUBuiltin {
+ GPU_VIEW_MATRIX = 1,
+ GPU_OBJECT_MATRIX = 2,
+ GPU_INVERSE_VIEW_MATRIX = 4,
+ GPU_INVERSE_OBJECT_MATRIX = 8,
+ GPU_VIEW_POSITION = 16,
+ GPU_VIEW_NORMAL = 32,
+ GPU_OBCOLOR = 64
+} GPUBuiltin;
+
+typedef enum GPUBlendMode {
+ GPU_BLEND_SOLID = 0,
+ GPU_BLEND_ADD = 1,
+ GPU_BLEND_ALPHA = 2,
+ GPU_BLEND_CLIP = 4
+} GPUBlendMode;
+
+typedef struct GPUNodeStack {
+ GPUType type;
+ char *name;
+ float vec[4];
+ struct GPUNodeLink *link;
+ short hasinput;
+ short hasoutput;
+ short sockettype;
+} GPUNodeStack;
+
+GPUNodeLink *GPU_attribute(int type, char *name);
+GPUNodeLink *GPU_uniform(float *num);
+GPUNodeLink *GPU_dynamic_uniform(float *num);
+GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser);
+GPUNodeLink *GPU_texture(int size, float *pixels);
+GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex);
+GPUNodeLink *GPU_socket(GPUNodeStack *sock);
+GPUNodeLink *GPU_builtin(GPUBuiltin builtin);
+
+int GPU_link(GPUMaterial *mat, char *name, ...);
+int GPU_stack_link(GPUMaterial *mat, char *name, GPUNodeStack *in, GPUNodeStack *out, ...);
+
+void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
+void GPU_material_enable_alpha(GPUMaterial *material);
+GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[4]);
+
+/* High level functions to create and use GPU materials */
+
+GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma);
+void GPU_material_free(struct Material *ma);
+
+void GPU_materials_free();
+
+void GPU_material_bind(GPUMaterial *material, int lay, double time);
+void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4]);
+void GPU_material_unbind(GPUMaterial *material);
+int GPU_material_bound(GPUMaterial *material);
+
+void GPU_material_vertex_attributes(GPUMaterial *material,
+ struct GPUVertexAttribs *attrib);
+
+/* Exported shading */
+
+typedef struct GPUShadeInput {
+ GPUMaterial *gpumat;
+ struct Material *mat;
+
+ GPUNodeLink *rgb, *specrgb, *vn, *view, *vcol, *ref;
+ GPUNodeLink *alpha, *refl, *spec, *emit, *har, *amb;
+} GPUShadeInput;
+
+typedef struct GPUShadeResult {
+ GPUNodeLink *diff, *spec, *combined, *alpha;
+} GPUShadeResult;
+
+void GPU_shadeinput_set(GPUMaterial *mat, struct Material *ma, GPUShadeInput *shi);
+void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr);
+
+/* Lamps */
+
+GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Object *par);
+void GPU_lamp_free(struct Object *ob);
+
+int GPU_lamp_has_shadow_buffer(GPULamp *lamp);
+void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]);
+void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp);
+
+void GPU_lamp_update(GPULamp *lamp, float obmat[][4]);
+int GPU_lamp_shadow_layer(GPULamp *lamp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__GPU_MATERIAL__*/
+
diff --git a/source/blender/gpu/Makefile b/source/blender/gpu/Makefile
new file mode 100644
index 00000000000..b9bde147115
--- /dev/null
+++ b/source/blender/gpu/Makefile
@@ -0,0 +1,37 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+#
+# Makes module object directory and bounces make to subdirectories.
+
+SOURCEDIR = source/blender/gpu
+DIRS = intern
+
+include nan_subdirs.mk
diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript
new file mode 100644
index 00000000000..8ccd4b7b24c
--- /dev/null
+++ b/source/blender/gpu/SConscript
@@ -0,0 +1,11 @@
+#!/usr/bin/python
+Import ('env')
+
+sources = env.Glob('intern/*.c')
+
+incs = '../blenlib ../blenkernel ../makesdna ../include'
+incs += ' #/extern/glew/include #intern/guardedalloc ../imbuf .'
+
+incs += ' ' + env['BF_OPENGL_INC']
+
+env.BlenderLib ( 'bf_gpu', sources, Split(incs), [], libtype=['core', 'player'], priority=[65, 20] )
diff --git a/source/blender/gpu/intern/Makefile b/source/blender/gpu/intern/Makefile
new file mode 100644
index 00000000000..733ee3f764c
--- /dev/null
+++ b/source/blender/gpu/intern/Makefile
@@ -0,0 +1,53 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+#
+
+LIBNAME = gpu
+DIR = $(OCGDIR)/blender/$(LIBNAME)
+
+include nan_compile.mk
+
+ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
+ CFLAGS += -funsigned-char
+endif
+
+CFLAGS += $(LEVEL_1_C_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+
+CPPFLAGS += -I../../blenlib
+CPPFLAGS += -I../../makesdna
+CPPFLAGS += -I../../imbuf
+CPPFLAGS += -I../../blenkernel
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I$(NAN_GLEW)/include
+CPPFLAGS += -I../
+
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
new file mode 100644
index 00000000000..b6285915484
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -0,0 +1,1439 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "GL/glew.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_customdata_types.h"
+#include "DNA_image_types.h"
+#include "DNA_listBase.h"
+#include "DNA_material_types.h"
+
+#include "BLI_dynstr.h"
+#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_heap.h"
+
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+#include "GPU_material.h"
+#include "GPU_extensions.h"
+
+#include "gpu_codegen.h"
+
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef _WIN32
+#ifndef vsnprintf
+#define _vsnprintf vsnprintf
+#endif
+#ifndef snprintf
+#define snprintf _snprintf
+#endif
+#endif
+
+extern char datatoc_gpu_shader_material_glsl[];
+extern char datatoc_gpu_shader_vertex_glsl[];
+
+/* structs and defines */
+
+typedef enum GPUDataSource {
+ GPU_SOURCE_VEC_UNIFORM,
+ GPU_SOURCE_BUILTIN,
+ GPU_SOURCE_TEX_PIXEL,
+ GPU_SOURCE_TEX,
+ GPU_SOURCE_ATTRIB
+} GPUDataSource;
+
+static char* GPU_DATATYPE_STR[17] = {"", "float", "vec2", "vec3", "vec4",
+ 0, 0, 0, 0, "mat3", 0, 0, 0, 0, 0, 0, "mat4"};
+
+struct GPUNode {
+ struct GPUNode *next, *prev;
+
+ char *name;
+ int tag;
+
+ ListBase inputs;
+ ListBase outputs;
+};
+
+struct GPUNodeLink {
+ GPUNodeStack *socket;
+
+ int attribtype;
+ char *attribname;
+
+ int image;
+
+ int texture;
+ int texturesize;
+
+ void *ptr1, *ptr2;
+
+ int dynamic;
+
+ int type;
+ int users;
+
+ GPUTexture *dynamictex;
+
+ GPUBuiltin builtin;
+
+ struct GPUOutput *output;
+};
+
+typedef struct GPUOutput {
+ struct GPUOutput *next, *prev;
+
+ GPUNode *node;
+ int type; /* data type = length of vector/matrix */
+ GPUNodeLink *link; /* output link */
+ int id; /* unique id as created by code generator */
+} GPUOutput;
+
+typedef struct GPUInput {
+ struct GPUInput *next, *prev;
+
+ GPUNode *node;
+
+ int type; /* datatype */
+ int source; /* data source */
+
+ int id; /* unique id as created by code generator */
+ int texid; /* number for multitexture */
+ int attribid; /* id for vertex attributes */
+ int bindtex; /* input is responsible for binding the texture? */
+ int definetex; /* input is responsible for defining the pixel? */
+ int textarget; /* GL_TEXTURE_* */
+ int textype; /* datatype */
+
+ struct Image *ima; /* image */
+ struct ImageUser *iuser;/* image user */
+ float *dynamicvec; /* vector data in case it is dynamic */
+ GPUTexture *tex; /* input texture, only set at runtime */
+ int shaderloc; /* id from opengl */
+ char shadername[32]; /* name in shader */
+
+ float vec[16]; /* vector data */
+ GPUNodeLink *link;
+ int dynamictex; /* dynamic? */
+ int attribtype; /* attribute type */
+ char attribname[32]; /* attribute name */
+ int attribfirst; /* this is the first one that is bound */
+ GPUBuiltin builtin; /* builtin uniform */
+} GPUInput;
+
+struct GPUPass {
+ struct GPUPass *next, *prev;
+
+ ListBase inputs;
+ struct GPUOutput *output;
+ struct GPUShader *shader;
+};
+
+/* Strings utility */
+
+static void BLI_dynstr_printf(DynStr *dynstr, const char *format, ...)
+{
+ va_list args;
+ int retval;
+ char str[2048];
+
+ va_start(args, format);
+ retval = vsnprintf(str, sizeof(str), format, args);
+ va_end(args);
+
+ if (retval >= sizeof(str))
+ fprintf(stderr, "BLI_dynstr_printf: limit exceeded\n");
+ else
+ BLI_dynstr_append(dynstr, str);
+}
+
+/* GLSL code parsing for finding function definitions.
+ * These are stored in a hash for lookup when creating a material. */
+
+static GHash *FUNCTION_HASH= NULL;
+static char *FUNCTION_PROTOTYPES= NULL;
+static GPUShader *FUNCTION_LIB= NULL;
+
+static int gpu_str_prefix(char *str, char *prefix)
+{
+ while(*str && *prefix) {
+ if(*str != *prefix)
+ return 0;
+
+ str++;
+ prefix++;
+ }
+
+ return (*prefix == '\0');
+}
+
+static char *gpu_str_skip_token(char *str, char *token, int max)
+{
+ int len = 0;
+
+ /* skip a variable/function name */
+ while(*str) {
+ if(ELEM6(*str, ' ', '(', ')', ',', '\t', '\n'))
+ break;
+ else {
+ if(token && len < max-1) {
+ *token= *str;
+ token++;
+ len++;
+ }
+ str++;
+ }
+ }
+
+ if(token)
+ *token= '\0';
+
+ /* skip the next special characters:
+ * note the missing ')' */
+ while(*str) {
+ if(ELEM5(*str, ' ', '(', ',', '\t', '\n'))
+ str++;
+ else
+ break;
+ }
+
+ return str;
+}
+
+static void gpu_parse_functions_string(GHash *hash, char *code)
+{
+ GPUFunction *function;
+ int i, type, qual;
+
+ while((code = strstr(code, "void "))) {
+ function = MEM_callocN(sizeof(GPUFunction), "GPUFunction");
+
+ code = gpu_str_skip_token(code, NULL, 0);
+ code = gpu_str_skip_token(code, function->name, MAX_FUNCTION_NAME);
+
+ /* get parameters */
+ while(*code && *code != ')') {
+ /* test if it's an input or output */
+ qual = FUNCTION_QUAL_IN;
+ if(gpu_str_prefix(code, "out "))
+ qual = FUNCTION_QUAL_OUT;
+ if(gpu_str_prefix(code, "inout "))
+ qual = FUNCTION_QUAL_INOUT;
+ if((qual != FUNCTION_QUAL_IN) || gpu_str_prefix(code, "in "))
+ code = gpu_str_skip_token(code, NULL, 0);
+
+ /* test for type */
+ type= 0;
+ for(i=1; i<=16; i++) {
+ if(GPU_DATATYPE_STR[i] && gpu_str_prefix(code, GPU_DATATYPE_STR[i])) {
+ type= i;
+ break;
+ }
+ }
+
+ if(!type && gpu_str_prefix(code, "sampler2DShadow"))
+ type= GPU_SHADOW2D;
+ if(!type && gpu_str_prefix(code, "sampler1D"))
+ type= GPU_TEX1D;
+ if(!type && gpu_str_prefix(code, "sampler2D"))
+ type= GPU_TEX2D;
+
+ if(type) {
+ /* add paramater */
+ code = gpu_str_skip_token(code, NULL, 0);
+ code = gpu_str_skip_token(code, NULL, 0);
+ function->paramqual[function->totparam]= qual;
+ function->paramtype[function->totparam]= type;
+ function->totparam++;
+ }
+ else {
+ fprintf(stderr, "GPU invalid function parameter in %s.\n", function->name);
+ break;
+ }
+ }
+
+ if(strlen(function->name) == 0 || function->totparam == 0) {
+ fprintf(stderr, "GPU functions parse error.\n");
+ MEM_freeN(function);
+ break;
+ }
+
+ BLI_ghash_insert(hash, function->name, function);
+ }
+}
+
+static char *gpu_generate_function_prototyps(GHash *hash)
+{
+ DynStr *ds = BLI_dynstr_new();
+ GHashIterator *ghi;
+ GPUFunction *function;
+ char *name, *prototypes;
+ int a;
+
+ /* automatically generate function prototypes to add to the top of the
+ * generated code, to avoid have to add the actual code & recompile all */
+ ghi = BLI_ghashIterator_new(hash);
+
+ for(; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
+ name = BLI_ghashIterator_getValue(ghi);
+ function = BLI_ghashIterator_getValue(ghi);
+
+ BLI_dynstr_printf(ds, "void %s(", name);
+ for(a=0; a<function->totparam; a++) {
+ if(function->paramqual[a] == FUNCTION_QUAL_OUT)
+ BLI_dynstr_append(ds, "out ");
+ else if(function->paramqual[a] == FUNCTION_QUAL_INOUT)
+ BLI_dynstr_append(ds, "inout ");
+
+ if(function->paramtype[a] == GPU_TEX1D)
+ BLI_dynstr_append(ds, "sampler1D");
+ else if(function->paramtype[a] == GPU_TEX2D)
+ BLI_dynstr_append(ds, "sampler2D");
+ else if(function->paramtype[a] == GPU_SHADOW2D)
+ BLI_dynstr_append(ds, "sampler2DShadow");
+ else
+ BLI_dynstr_append(ds, GPU_DATATYPE_STR[function->paramtype[a]]);
+
+ BLI_dynstr_printf(ds, " param%d", a);
+
+ if(a != function->totparam-1)
+ BLI_dynstr_append(ds, ", ");
+ }
+ BLI_dynstr_append(ds, ");\n");
+ }
+
+ BLI_dynstr_append(ds, "\n");
+
+ prototypes = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+
+ return prototypes;
+}
+
+GPUFunction *GPU_lookup_function(char *name)
+{
+ if(!FUNCTION_HASH) {
+ FUNCTION_HASH = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
+ gpu_parse_functions_string(FUNCTION_HASH, datatoc_gpu_shader_material_glsl);
+ FUNCTION_PROTOTYPES = gpu_generate_function_prototyps(FUNCTION_HASH);
+ FUNCTION_LIB = GPU_shader_create_lib(datatoc_gpu_shader_material_glsl);
+ }
+
+ return (GPUFunction*)BLI_ghash_lookup(FUNCTION_HASH, name);
+}
+
+void GPU_extensions_exit(void)
+{
+ extern Material defmaterial; // render module abuse...
+
+ if(defmaterial.gpumaterial.first)
+ GPU_material_free(&defmaterial);
+
+ if(FUNCTION_HASH) {
+ BLI_ghash_free(FUNCTION_HASH, NULL, (GHashValFreeFP)MEM_freeN);
+ FUNCTION_HASH = NULL;
+ }
+ if(FUNCTION_PROTOTYPES) {
+ MEM_freeN(FUNCTION_PROTOTYPES);
+ FUNCTION_PROTOTYPES = NULL;
+ }
+ if(FUNCTION_LIB) {
+ GPU_shader_free(FUNCTION_LIB);
+ FUNCTION_LIB = NULL;
+ }
+}
+
+/* GLSL code generation */
+
+static void codegen_convert_datatype(DynStr *ds, int from, int to, char *tmp, int id)
+{
+ char name[1024];
+
+ snprintf(name, sizeof(name), "%s%d", tmp, id);
+
+ if (from == to) {
+ BLI_dynstr_append(ds, name);
+ }
+ else if (to == GPU_FLOAT) {
+ if (from == GPU_VEC4)
+ BLI_dynstr_printf(ds, "dot(%s.rgb, vec3(0.35, 0.45, 0.2))", name);
+ else if (from == GPU_VEC3)
+ BLI_dynstr_printf(ds, "dot(%s, vec3(0.33))", name);
+ else if (from == GPU_VEC2)
+ BLI_dynstr_printf(ds, "%s.r", name);
+ }
+ else if (to == GPU_VEC2) {
+ if (from == GPU_VEC4)
+ BLI_dynstr_printf(ds, "vec2(dot(%s.rgb, vec3(0.35, 0.45, 0.2)), %s.a)", name, name);
+ else if (from == GPU_VEC3)
+ BLI_dynstr_printf(ds, "vec2(dot(%s.rgb, vec3(0.33)), 1.0)", name);
+ else if (from == GPU_FLOAT)
+ BLI_dynstr_printf(ds, "vec2(%s, 1.0)", name);
+ }
+ else if (to == GPU_VEC3) {
+ if (from == GPU_VEC4)
+ BLI_dynstr_printf(ds, "%s.rgb", name);
+ else if (from == GPU_VEC2)
+ BLI_dynstr_printf(ds, "vec3(%s.r, %s.r, %s.r)", name, name, name);
+ else if (from == GPU_FLOAT)
+ BLI_dynstr_printf(ds, "vec3(%s, %s, %s)", name, name, name);
+ }
+ else {
+ if (from == GPU_VEC3)
+ BLI_dynstr_printf(ds, "vec4(%s, 1.0)", name);
+ else if (from == GPU_VEC2)
+ BLI_dynstr_printf(ds, "vec4(%s.r, %s.r, %s.r, %s.g)", name, name, name, name);
+ else if (from == GPU_FLOAT)
+ BLI_dynstr_printf(ds, "vec4(%s, %s, %s, 1.0)", name, name, name);
+ }
+}
+
+static void codegen_print_datatype(DynStr *ds, int type, float *data)
+{
+ int i;
+
+ BLI_dynstr_printf(ds, "%s(", GPU_DATATYPE_STR[type]);
+
+ for(i=0; i<type; i++) {
+ BLI_dynstr_printf(ds, "%f", data[i]);
+ if(i == type-1)
+ BLI_dynstr_append(ds, ")");
+ else
+ BLI_dynstr_append(ds, ", ");
+ }
+}
+
+static int codegen_input_has_texture(GPUInput *input)
+{
+ if (input->link)
+ return 0;
+ else if(input->ima)
+ return 1;
+ else
+ return input->tex != 0;
+}
+
+char *GPU_builtin_name(GPUBuiltin builtin)
+{
+ if(builtin == GPU_VIEW_MATRIX)
+ return "unfviewmat";
+ else if(builtin == GPU_OBJECT_MATRIX)
+ return "unfobmat";
+ else if(builtin == GPU_INVERSE_VIEW_MATRIX)
+ return "unfinvviewmat";
+ else if(builtin == GPU_INVERSE_OBJECT_MATRIX)
+ return "unfinvobmat";
+ else if(builtin == GPU_VIEW_POSITION)
+ return "varposition";
+ else if(builtin == GPU_VIEW_NORMAL)
+ return "varnormal";
+ else if(builtin == GPU_OBCOLOR)
+ return "unfobcolor";
+ else
+ return "";
+}
+
+static void codegen_set_unique_ids(ListBase *nodes)
+{
+ GHash *bindhash, *definehash;
+ GPUNode *node;
+ GPUInput *input;
+ GPUOutput *output;
+ int id = 1, texid = 0;
+
+ bindhash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ definehash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+ for (node=nodes->first; node; node=node->next) {
+ for (input=node->inputs.first; input; input=input->next) {
+ /* set id for unique names of uniform variables */
+ input->id = id++;
+ input->bindtex = 0;
+ input->definetex = 0;
+
+ /* set texid used for settings texture slot with multitexture */
+ if (codegen_input_has_texture(input) &&
+ ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL))) {
+ if (input->link) {
+ /* input is texture from buffer, assign only one texid per
+ buffer to avoid sampling the same texture twice */
+ if (!BLI_ghash_haskey(bindhash, input->link)) {
+ input->texid = texid++;
+ input->bindtex = 1;
+ BLI_ghash_insert(bindhash, input->link, SET_INT_IN_POINTER(input->texid));
+ }
+ else
+ input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->link));
+ }
+ else if(input->ima) {
+ /* input is texture from image, assign only one texid per
+ buffer to avoid sampling the same texture twice */
+ if (!BLI_ghash_haskey(bindhash, input->ima)) {
+ input->texid = texid++;
+ input->bindtex = 1;
+ BLI_ghash_insert(bindhash, input->ima, SET_INT_IN_POINTER(input->texid));
+ }
+ else
+ input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->ima));
+ }
+ else {
+ /* input is user created texture, we know there there is
+ only one, so assign new texid */
+ input->bindtex = 1;
+ input->texid = texid++;
+ }
+
+ /* make sure this pixel is defined exactly once */
+ if (input->source == GPU_SOURCE_TEX_PIXEL) {
+ if(input->ima) {
+ if (!BLI_ghash_haskey(definehash, input->ima)) {
+ input->definetex = 1;
+ BLI_ghash_insert(definehash, input->ima, SET_INT_IN_POINTER(input->texid));
+ }
+ }
+ else {
+ if (!BLI_ghash_haskey(definehash, input->link)) {
+ input->definetex = 1;
+ BLI_ghash_insert(definehash, input->link, SET_INT_IN_POINTER(input->texid));
+ }
+ }
+ }
+ }
+ }
+
+ for (output=node->outputs.first; output; output=output->next)
+ /* set id for unique names of tmp variables storing output */
+ output->id = id++;
+ }
+
+ BLI_ghash_free(bindhash, NULL, NULL);
+ BLI_ghash_free(definehash, NULL, NULL);
+}
+
+static void codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes)
+{
+ GPUNode *node;
+ GPUInput *input;
+ char *name;
+ int builtins = 0;
+
+ /* print uniforms */
+ for (node=nodes->first; node; node=node->next) {
+ for (input=node->inputs.first; input; input=input->next) {
+ if ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL)) {
+ /* create exactly one sampler for each texture */
+ if (codegen_input_has_texture(input) && input->bindtex)
+ BLI_dynstr_printf(ds, "uniform %s samp%d;\n",
+ (input->textype == GPU_TEX1D)? "sampler1D":
+ (input->textype == GPU_TEX2D)? "sampler2D": "sampler2DShadow",
+ input->texid);
+ }
+ else if(input->source == GPU_SOURCE_BUILTIN) {
+ /* only define each builting uniform/varying once */
+ if(!(builtins & input->builtin)) {
+ builtins |= input->builtin;
+ name = GPU_builtin_name(input->builtin);
+
+ if(gpu_str_prefix(name, "unf")) {
+ BLI_dynstr_printf(ds, "uniform %s %s;\n",
+ GPU_DATATYPE_STR[input->type], name);
+ }
+ else {
+ BLI_dynstr_printf(ds, "varying %s %s;\n",
+ GPU_DATATYPE_STR[input->type], name);
+ }
+ }
+ }
+ else if (input->source == GPU_SOURCE_VEC_UNIFORM) {
+ if(input->dynamicvec) {
+ /* only create uniforms for dynamic vectors */
+ BLI_dynstr_printf(ds, "uniform %s unf%d;\n",
+ GPU_DATATYPE_STR[input->type], input->id);
+ }
+ else {
+ /* for others use const so the compiler can do folding */
+ BLI_dynstr_printf(ds, "const %s cons%d = ",
+ GPU_DATATYPE_STR[input->type], input->id);
+ codegen_print_datatype(ds, input->type, input->vec);
+ BLI_dynstr_append(ds, ";\n");
+ }
+ }
+ else if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+ BLI_dynstr_printf(ds, "varying %s var%d;\n",
+ GPU_DATATYPE_STR[input->type], input->attribid);
+ }
+ }
+ }
+
+ BLI_dynstr_append(ds, "\n");
+}
+
+static void codegen_declare_tmps(DynStr *ds, ListBase *nodes)
+{
+ GPUNode *node;
+ GPUInput *input;
+ GPUOutput *output;
+
+ for (node=nodes->first; node; node=node->next) {
+ /* load pixels from textures */
+ for (input=node->inputs.first; input; input=input->next) {
+ if (input->source == GPU_SOURCE_TEX_PIXEL) {
+ if (codegen_input_has_texture(input) && input->definetex) {
+ BLI_dynstr_printf(ds, "\tvec4 tex%d = texture2D(", input->texid);
+ BLI_dynstr_printf(ds, "samp%d, gl_TexCoord[%d].st);\n",
+ input->texid, input->texid);
+ }
+ }
+ }
+
+ /* declare temporary variables for node output storage */
+ for (output=node->outputs.first; output; output=output->next)
+ BLI_dynstr_printf(ds, "\t%s tmp%d;\n",
+ GPU_DATATYPE_STR[output->type], output->id);
+ }
+
+ BLI_dynstr_append(ds, "\n");
+}
+
+static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *finaloutput)
+{
+ GPUNode *node;
+ GPUInput *input;
+ GPUOutput *output;
+
+ for (node=nodes->first; node; node=node->next) {
+ BLI_dynstr_printf(ds, "\t%s(", node->name);
+
+ for (input=node->inputs.first; input; input=input->next) {
+ if (input->source == GPU_SOURCE_TEX) {
+ BLI_dynstr_printf(ds, "samp%d", input->texid);
+ if (input->link)
+ BLI_dynstr_printf(ds, ", gl_TexCoord[%d].st", input->texid);
+ }
+ else if (input->source == GPU_SOURCE_TEX_PIXEL) {
+ if (input->link && input->link->output)
+ codegen_convert_datatype(ds, input->link->output->type, input->type,
+ "tmp", input->link->output->id);
+ else
+ codegen_convert_datatype(ds, input->link->output->type, input->type,
+ "tex", input->texid);
+ }
+ else if(input->source == GPU_SOURCE_BUILTIN)
+ BLI_dynstr_printf(ds, "%s", GPU_builtin_name(input->builtin));
+ else if(input->source == GPU_SOURCE_VEC_UNIFORM) {
+ if(input->dynamicvec)
+ BLI_dynstr_printf(ds, "unf%d", input->id);
+ else
+ BLI_dynstr_printf(ds, "cons%d", input->id);
+ }
+ else if (input->source == GPU_SOURCE_ATTRIB)
+ BLI_dynstr_printf(ds, "var%d", input->attribid);
+
+ BLI_dynstr_append(ds, ", ");
+ }
+
+ for (output=node->outputs.first; output; output=output->next) {
+ BLI_dynstr_printf(ds, "tmp%d", output->id);
+ if (output->next)
+ BLI_dynstr_append(ds, ", ");
+ }
+
+ BLI_dynstr_append(ds, ");\n");
+ }
+
+ BLI_dynstr_append(ds, "\n\tgl_FragColor = ");
+ codegen_convert_datatype(ds, finaloutput->type, GPU_VEC4, "tmp", finaloutput->id);
+ BLI_dynstr_append(ds, ";\n");
+}
+
+static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const char *name)
+{
+ DynStr *ds = BLI_dynstr_new();
+ char *code;
+
+ BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);
+
+ codegen_set_unique_ids(nodes);
+ codegen_print_uniforms_functions(ds, nodes);
+
+ //if(G.f & G_DEBUG)
+ // BLI_dynstr_printf(ds, "/* %s */\n", name);
+
+ BLI_dynstr_append(ds, "void main(void)\n");
+ BLI_dynstr_append(ds, "{\n");
+
+ codegen_declare_tmps(ds, nodes);
+ codegen_call_functions(ds, nodes, output);
+
+ BLI_dynstr_append(ds, "}\n");
+
+ /* create shader */
+ code = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+
+ //if(G.f & G_DEBUG) printf("%s\n", code);
+
+ return code;
+}
+
+static char *code_generate_vertex(ListBase *nodes)
+{
+ DynStr *ds = BLI_dynstr_new();
+ GPUNode *node;
+ GPUInput *input;
+ char *code;
+
+ for (node=nodes->first; node; node=node->next) {
+ for (input=node->inputs.first; input; input=input->next) {
+ if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+ BLI_dynstr_printf(ds, "attribute %s att%d;\n",
+ GPU_DATATYPE_STR[input->type], input->attribid);
+ BLI_dynstr_printf(ds, "varying %s var%d;\n",
+ GPU_DATATYPE_STR[input->type], input->attribid);
+ }
+ }
+ }
+
+ BLI_dynstr_append(ds, "\n");
+ BLI_dynstr_append(ds, datatoc_gpu_shader_vertex_glsl);
+
+ for (node=nodes->first; node; node=node->next)
+ for (input=node->inputs.first; input; input=input->next)
+ if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+ if(input->attribtype == CD_TANGENT) /* silly exception */
+ BLI_dynstr_printf(ds, "\tvar%d = gl_NormalMatrix * ", input->attribid);
+ else
+ BLI_dynstr_printf(ds, "\tvar%d = ", input->attribid);
+
+ BLI_dynstr_printf(ds, "att%d;\n", input->attribid);
+ }
+
+ BLI_dynstr_append(ds, "}\n\n");
+
+ code = BLI_dynstr_get_cstring(ds);
+
+ BLI_dynstr_free(ds);
+
+ //if(G.f & G_DEBUG) printf("%s\n", code);
+
+ return code;
+}
+
+/* GPU pass binding/unbinding */
+
+GPUShader *GPU_pass_shader(GPUPass *pass)
+{
+ return pass->shader;
+}
+
+void GPU_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
+{
+ GPUShader *shader = pass->shader;
+ GPUNode *node;
+ GPUInput *next, *input;
+ ListBase *inputs = &pass->inputs;
+ int extract, z;
+
+ memset(inputs, 0, sizeof(*inputs));
+
+ if(!shader)
+ return;
+
+ GPU_shader_bind(shader);
+
+ for (node=nodes->first; node; node=node->next) {
+ z = 0;
+ for (input=node->inputs.first; input; input=next, z++) {
+ next = input->next;
+
+ /* attributes don't need to be bound, they already have
+ * an id that the drawing functions will use */
+ if(input->source == GPU_SOURCE_ATTRIB ||
+ input->source == GPU_SOURCE_BUILTIN)
+ continue;
+
+ if (input->ima || input->tex)
+ snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid);
+ else
+ snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id);
+
+ /* pass non-dynamic uniforms to opengl */
+ extract = 0;
+
+ if(input->ima || input->tex) {
+ if (input->bindtex)
+ extract = 1;
+ }
+ else if(input->dynamicvec)
+ extract = 1;
+
+ if(extract)
+ input->shaderloc = GPU_shader_get_uniform(shader, input->shadername);
+
+ /* extract nodes */
+ if(extract) {
+ BLI_remlink(&node->inputs, input);
+ BLI_addtail(inputs, input);
+ }
+ }
+ }
+
+ GPU_shader_unbind(shader);
+}
+
+void GPU_pass_bind(GPUPass *pass, double time)
+{
+ GPUInput *input;
+ GPUShader *shader = pass->shader;
+ ListBase *inputs = &pass->inputs;
+
+ if (!shader)
+ return;
+
+ GPU_shader_bind(shader);
+
+ /* now bind the textures */
+ for (input=inputs->first; input; input=input->next) {
+ if (input->ima)
+ input->tex = GPU_texture_from_blender(input->ima, input->iuser, time);
+
+ if(input->ima || input->tex) {
+ if(input->tex) {
+ GPU_texture_bind(input->tex, input->texid);
+ GPU_shader_uniform_texture(shader, input->shaderloc, input->tex);
+ }
+ }
+ }
+}
+
+void GPU_pass_update_uniforms(GPUPass *pass)
+{
+ GPUInput *input;
+ GPUShader *shader = pass->shader;
+ ListBase *inputs = &pass->inputs;
+
+ if (!shader)
+ return;
+
+ /* pass dynamic inputs to opengl, others were removed */
+ for (input=inputs->first; input; input=input->next)
+ if(!(input->ima || input->tex))
+ GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1,
+ input->dynamicvec);
+}
+
+void GPU_pass_unbind(GPUPass *pass)
+{
+ GPUInput *input;
+ GPUShader *shader = pass->shader;
+ ListBase *inputs = &pass->inputs;
+
+ if (!shader)
+ return;
+
+ for (input=inputs->first; input; input=input->next) {
+ if (input->tex)
+ if(input->bindtex)
+ GPU_texture_unbind(input->tex);
+ if (input->ima)
+ input->tex = 0;
+ }
+
+ GPU_shader_unbind(shader);
+}
+
+/* Node Link Functions */
+
+GPUNodeLink *GPU_node_link_create(int type)
+{
+ GPUNodeLink *link = MEM_callocN(sizeof(GPUNodeLink), "GPUNodeLink");
+ link->type = type;
+ link->users++;
+
+ return link;
+}
+
+void GPU_node_link_free(GPUNodeLink *link)
+{
+ link->users--;
+
+ if (link->users < 0)
+ fprintf(stderr, "GPU_node_link_free: negative refcount\n");
+
+ if (link->users == 0) {
+ if (link->output)
+ link->output->link = NULL;
+ MEM_freeN(link);
+ }
+}
+
+/* Node Functions */
+
+GPUNode *GPU_node_begin(char *name)
+{
+ GPUNode *node = MEM_callocN(sizeof(GPUNode), "GPUNode");
+
+ node->name = name;
+
+ return node;
+}
+
+void GPU_node_end(GPUNode *node)
+{
+ /* empty */
+}
+
+static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
+{
+ GPUInput *input;
+ GPUNode *outnode;
+ char *name;
+
+ if(link->output) {
+ outnode = link->output->node;
+ name = outnode->name;
+
+ if(strcmp(name, "set_value")==0 || strcmp(name, "set_rgb")==0) {
+ input = MEM_dupallocN(outnode->inputs.first);
+ input->type = type;
+ if(input->link)
+ input->link->users++;
+ BLI_addtail(&node->inputs, input);
+ return;
+ }
+ }
+
+ input = MEM_callocN(sizeof(GPUInput), "GPUInput");
+ input->node = node;
+
+ if(link->builtin) {
+ /* builtin uniform */
+ input->type = type;
+ input->source = GPU_SOURCE_BUILTIN;
+ input->builtin = link->builtin;
+
+ MEM_freeN(link);
+ }
+ else if(link->output) {
+ /* link to a node output */
+ input->type = type;
+ input->source = GPU_SOURCE_TEX_PIXEL;
+ input->link = link;
+ link->users++;
+ }
+ else if(link->dynamictex) {
+ /* dynamic texture, GPUTexture is updated/deleted externally */
+ input->type = type;
+ input->source = GPU_SOURCE_TEX;
+
+ input->tex = link->dynamictex;
+ input->textarget = GL_TEXTURE_2D;
+ input->textype = type;
+ input->dynamictex = 1;
+ MEM_freeN(link);
+ }
+ else if(link->texture) {
+ /* small texture created on the fly, like for colorbands */
+ input->type = GPU_VEC4;
+ input->source = GPU_SOURCE_TEX;
+ input->textype = type;
+
+ if (type == GPU_TEX1D) {
+ input->tex = GPU_texture_create_1D(link->texturesize, link->ptr1);
+ input->textarget = GL_TEXTURE_1D;
+ }
+ else {
+ input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2);
+ input->textarget = GL_TEXTURE_2D;
+ }
+
+ MEM_freeN(link->ptr1);
+ MEM_freeN(link);
+ }
+ else if(link->image) {
+ /* blender image */
+ input->type = GPU_VEC4;
+ input->source = GPU_SOURCE_TEX;
+
+ input->ima = link->ptr1;
+ input->textarget = GL_TEXTURE_2D;
+ input->textype = GPU_TEX2D;
+ MEM_freeN(link);
+ }
+ else if(link->attribtype) {
+ /* vertex attribute */
+ input->type = type;
+ input->source = GPU_SOURCE_ATTRIB;
+
+ input->attribtype = link->attribtype;
+ BLI_strncpy(input->attribname, link->attribname, sizeof(input->attribname));
+ MEM_freeN(link);
+ }
+ else {
+ /* uniform vector */
+ input->type = type;
+ input->source = GPU_SOURCE_VEC_UNIFORM;
+
+ memcpy(input->vec, link->ptr1, type*sizeof(float));
+ if(link->dynamic)
+ input->dynamicvec= link->ptr1;
+ MEM_freeN(link);
+ }
+
+ BLI_addtail(&node->inputs, input);
+}
+
+static void gpu_node_input_socket(GPUNode *node, GPUNodeStack *sock)
+{
+ GPUNodeLink *link;
+
+ if(sock->link) {
+ gpu_node_input_link(node, sock->link, sock->type);
+ }
+ else {
+ link = GPU_node_link_create(0);
+ link->ptr1 = sock->vec;
+ gpu_node_input_link(node, link, sock->type);
+ }
+}
+
+void GPU_node_output(GPUNode *node, int type, char *name, GPUNodeLink **link)
+{
+ GPUOutput *output = MEM_callocN(sizeof(GPUOutput), "GPUOutput");
+
+ output->type = type;
+ output->node = node;
+
+ if (link) {
+ *link = output->link = GPU_node_link_create(type);
+ output->link->output = output;
+
+ /* note: the caller owns the reference to the linkfer, GPUOutput
+ merely points to it, and if the node is destroyed it will
+ set that pointer to NULL */
+ }
+
+ BLI_addtail(&node->outputs, output);
+}
+
+void GPU_inputs_free(ListBase *inputs)
+{
+ GPUInput *input;
+
+ for(input=inputs->first; input; input=input->next) {
+ if(input->link)
+ GPU_node_link_free(input->link);
+ else if(input->tex && !input->dynamictex)
+ GPU_texture_free(input->tex);
+ }
+
+ BLI_freelistN(inputs);
+}
+
+void GPU_node_free(GPUNode *node)
+{
+ GPUOutput *output;
+
+ GPU_inputs_free(&node->inputs);
+
+ for (output=node->outputs.first; output; output=output->next)
+ if (output->link) {
+ output->link->output = NULL;
+ GPU_node_link_free(output->link);
+ }
+
+ BLI_freelistN(&node->outputs);
+ MEM_freeN(node);
+}
+
+void GPU_nodes_free(ListBase *nodes)
+{
+ GPUNode *node;
+
+ while (nodes->first) {
+ node = nodes->first;
+ BLI_remlink(nodes, node);
+ GPU_node_free(node);
+ }
+}
+
+/* vertex attributes */
+
+void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *attribs)
+{
+ GPUNode *node;
+ GPUInput *input;
+ int a;
+
+ /* convert attributes requested by node inputs to an array of layers,
+ * checking for duplicates and assigning id's starting from zero. */
+
+ memset(attribs, 0, sizeof(*attribs));
+
+ for(node=nodes->first; node; node=node->next) {
+ for(input=node->inputs.first; input; input=input->next) {
+ if(input->source == GPU_SOURCE_ATTRIB) {
+ for(a=0; a<attribs->totlayer; a++) {
+ if(attribs->layer[a].type == input->attribtype &&
+ strcmp(attribs->layer[a].name, input->attribname) == 0)
+ break;
+ }
+
+ if(a == attribs->totlayer && a < GPU_MAX_ATTRIB) {
+ input->attribid = attribs->totlayer++;
+ input->attribfirst = 1;
+
+ attribs->layer[a].type = input->attribtype;
+ attribs->layer[a].glindex = input->attribid;
+ BLI_strncpy(attribs->layer[a].name, input->attribname,
+ sizeof(attribs->layer[a].name));
+ }
+ else
+ input->attribid = attribs->layer[a].glindex;
+ }
+ }
+ }
+}
+
+void gpu_nodes_get_builtin_flag(ListBase *nodes, int *builtin)
+{
+ GPUNode *node;
+ GPUInput *input;
+
+ *builtin= 0;
+
+ for(node=nodes->first; node; node=node->next)
+ for(input=node->inputs.first; input; input=input->next)
+ if(input->source == GPU_SOURCE_BUILTIN)
+ *builtin |= input->builtin;
+}
+
+/* varargs linking */
+
+GPUNodeLink *GPU_attribute(int type, char *name)
+{
+ GPUNodeLink *link = GPU_node_link_create(0);
+
+ link->attribtype= type;
+ link->attribname= name;
+
+ return link;
+}
+
+GPUNodeLink *GPU_uniform(float *num)
+{
+ GPUNodeLink *link = GPU_node_link_create(0);
+
+ link->ptr1= num;
+ link->ptr2= NULL;
+
+ return link;
+}
+
+GPUNodeLink *GPU_dynamic_uniform(float *num)
+{
+ GPUNodeLink *link = GPU_node_link_create(0);
+
+ link->ptr1= num;
+ link->ptr2= NULL;
+ link->dynamic= 1;
+
+ return link;
+}
+
+GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser)
+{
+ GPUNodeLink *link = GPU_node_link_create(0);
+
+ link->image= 1;
+ link->ptr1= ima;
+ link->ptr2= iuser;
+
+ return link;
+}
+
+GPUNodeLink *GPU_texture(int size, float *pixels)
+{
+ GPUNodeLink *link = GPU_node_link_create(0);
+
+ link->texture = 1;
+ link->texturesize = size;
+ link->ptr1= pixels;
+
+ return link;
+}
+
+GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex)
+{
+ GPUNodeLink *link = GPU_node_link_create(0);
+
+ link->dynamic = 1;
+ link->dynamictex = tex;
+
+ return link;
+}
+
+GPUNodeLink *GPU_socket(GPUNodeStack *sock)
+{
+ GPUNodeLink *link = GPU_node_link_create(0);
+
+ link->socket= sock;
+
+ return link;
+}
+
+GPUNodeLink *GPU_builtin(GPUBuiltin builtin)
+{
+ GPUNodeLink *link = GPU_node_link_create(0);
+
+ link->builtin= builtin;
+
+ return link;
+}
+
+int GPU_link(GPUMaterial *mat, char *name, ...)
+{
+ GPUNode *node;
+ GPUFunction *function;
+ GPUNodeLink *link, **linkptr;
+ va_list params;
+ int i;
+
+ function = GPU_lookup_function(name);
+ if(!function) {
+ fprintf(stderr, "GPU failed to find function %s\n", name);
+ return 0;
+ }
+
+ node = GPU_node_begin(name);
+
+ va_start(params, name);
+ for(i=0; i<function->totparam; i++) {
+ if(function->paramqual[i] != FUNCTION_QUAL_IN) {
+ linkptr= va_arg(params, GPUNodeLink**);
+ GPU_node_output(node, function->paramtype[i], "", linkptr);
+ }
+ else {
+ link= va_arg(params, GPUNodeLink*);
+ gpu_node_input_link(node, link, function->paramtype[i]);
+ }
+ }
+ va_end(params);
+
+ GPU_node_end(node);
+
+ gpu_material_add_node(mat, node);
+
+ return 1;
+}
+
+int GPU_stack_link(GPUMaterial *mat, char *name, GPUNodeStack *in, GPUNodeStack *out, ...)
+{
+ GPUNode *node;
+ GPUFunction *function;
+ GPUNodeLink *link, **linkptr;
+ va_list params;
+ int i, totin, totout;
+
+ function = GPU_lookup_function(name);
+ if(!function) {
+ fprintf(stderr, "GPU failed to find function %s\n", name);
+ return 0;
+ }
+
+ node = GPU_node_begin(name);
+ totin = 0;
+ totout = 0;
+
+ if(in) {
+ for(i = 0; in[i].type != GPU_NONE; i++) {
+ gpu_node_input_socket(node, &in[i]);
+ totin++;
+ }
+ }
+
+ if(out) {
+ for(i = 0; out[i].type != GPU_NONE; i++) {
+ GPU_node_output(node, out[i].type, out[i].name, &out[i].link);
+ totout++;
+ }
+ }
+
+ va_start(params, out);
+ for(i=0; i<function->totparam; i++) {
+ if(function->paramqual[i] != FUNCTION_QUAL_IN) {
+ if(totout == 0) {
+ linkptr= va_arg(params, GPUNodeLink**);
+ GPU_node_output(node, function->paramtype[i], "", linkptr);
+ }
+ else
+ totout--;
+ }
+ else {
+ if(totin == 0) {
+ link= va_arg(params, GPUNodeLink*);
+ if(link->socket)
+ gpu_node_input_socket(node, link->socket);
+ else
+ gpu_node_input_link(node, link, function->paramtype[i]);
+ }
+ else
+ totin--;
+ }
+ }
+ va_end(params);
+
+ GPU_node_end(node);
+
+ gpu_material_add_node(mat, node);
+
+ return 1;
+}
+
+int GPU_link_changed(GPUNodeLink *link)
+{
+ GPUNode *node;
+ GPUInput *input;
+ char *name;
+
+ if(link->output) {
+ node = link->output->node;
+ name = node->name;
+
+ if(strcmp(name, "set_value")==0 || strcmp(name, "set_rgb")==0) {
+ input = node->inputs.first;
+ return (input->link != NULL);
+ }
+
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/* Pass create/free */
+
+void gpu_nodes_tag(GPUNodeLink *link)
+{
+ GPUNode *node;
+ GPUInput *input;
+
+ if(!link->output)
+ return;
+
+ node = link->output->node;
+ if(node->tag)
+ return;
+
+ node->tag= 1;
+ for(input=node->inputs.first; input; input=input->next)
+ if(input->link)
+ gpu_nodes_tag(input->link);
+}
+
+void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
+{
+ GPUNode *node, *next;
+
+ for(node=nodes->first; node; node=node->next)
+ node->tag= 0;
+
+ gpu_nodes_tag(outlink);
+
+ for(node=nodes->first; node; node=next) {
+ next = node->next;
+
+ if(!node->tag) {
+ BLI_remlink(nodes, node);
+ GPU_node_free(node);
+ }
+ }
+}
+
+GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttribs *attribs, int *builtins, const char *name)
+{
+ GPUShader *shader;
+ GPUPass *pass;
+ char *vertexcode, *fragmentcode;
+
+ if(!FUNCTION_LIB) {
+ GPU_nodes_free(nodes);
+ return NULL;
+ }
+
+ /* prune unused nodes */
+ gpu_nodes_prune(nodes, outlink);
+
+ gpu_nodes_get_vertex_attributes(nodes, attribs);
+ gpu_nodes_get_builtin_flag(nodes, builtins);
+
+ /* generate code and compile with opengl */
+ fragmentcode = code_generate_fragment(nodes, outlink->output, name);
+ vertexcode = code_generate_vertex(nodes);
+ shader = GPU_shader_create(vertexcode, fragmentcode, FUNCTION_LIB);
+ MEM_freeN(fragmentcode);
+ MEM_freeN(vertexcode);
+
+ /* failed? */
+ if (!shader) {
+ memset(attribs, 0, sizeof(*attribs));
+ memset(builtins, 0, sizeof(*builtins));
+ GPU_nodes_free(nodes);
+ return NULL;
+ }
+
+ /* create pass */
+ pass = MEM_callocN(sizeof(GPUPass), "GPUPass");
+
+ pass->output = outlink->output;
+ pass->shader = shader;
+
+ /* extract dynamic inputs and throw away nodes */
+ GPU_nodes_extract_dynamic_inputs(pass, nodes);
+ GPU_nodes_free(nodes);
+
+ return pass;
+}
+
+void GPU_pass_free(GPUPass *pass)
+{
+ GPU_shader_free(pass->shader);
+ GPU_inputs_free(&pass->inputs);
+ MEM_freeN(pass);
+}
+
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
new file mode 100644
index 00000000000..53b52f24f16
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -0,0 +1,87 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __GPU_CODEGEN_H__
+#define __GPU_CODEGEN_H__
+
+#include "DNA_listBase.h"
+
+struct ListBase;
+struct GPUShader;
+struct GPUOutput;
+struct GPUNode;
+struct GPUVertexAttribs;
+
+#define MAX_FUNCTION_NAME 64
+#define MAX_PARAMETER 32
+
+#define FUNCTION_QUAL_IN 0
+#define FUNCTION_QUAL_OUT 1
+#define FUNCTION_QUAL_INOUT 2
+
+typedef struct GPUFunction {
+ char name[MAX_FUNCTION_NAME];
+ int paramtype[MAX_PARAMETER];
+ int paramqual[MAX_PARAMETER];
+ int totparam;
+} GPUFunction;
+
+GPUFunction *GPU_lookup_function(char *name);
+
+/* Pass Generation
+ - Takes a list of nodes and a desired output, and makes a pass. This
+ will take ownership of the nodes and free them early if unused or
+ at the end if used.
+*/
+
+struct GPUPass;
+typedef struct GPUPass GPUPass;
+
+GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
+ struct GPUVertexAttribs *attribs, int *builtin, const char *name);
+
+struct GPUShader *GPU_pass_shader(GPUPass *pass);
+
+void GPU_pass_bind(GPUPass *pass, double time);
+void GPU_pass_update_uniforms(GPUPass *pass);
+void GPU_pass_unbind(GPUPass *pass);
+
+void GPU_pass_free(GPUPass *pass);
+
+/* Material calls */
+
+char *GPU_builtin_name(GPUBuiltin builtin);
+void gpu_material_add_node(struct GPUMaterial *material, struct GPUNode *node);
+int GPU_link_changed(struct GPUNodeLink *link);
+
+#endif
+
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
new file mode 100644
index 00000000000..3ff8e7fa559
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -0,0 +1,1167 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <string.h>
+
+#include "GL/glew.h"
+
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_view3d_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "BKE_bmfont.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_node.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
+
+#include "GPU_extensions.h"
+#include "GPU_material.h"
+#include "GPU_draw.h"
+
+/* These are some obscure rendering functions shared between the
+ * game engine and the blender, in this module to avoid duplicaten
+ * and abstract them away from the rest a bit */
+
+/* Text Rendering */
+
+static void gpu_mcol(unsigned int ucol)
+{
+ /* mcol order is swapped */
+ char *cp= (char *)&ucol;
+ glColor3ub(cp[3], cp[2], cp[1]);
+}
+
+void GPU_render_text(MTFace *tface, int mode,
+ const char *textstr, int textlen, unsigned int *col,
+ float *v1, float *v2, float *v3, float *v4, int glattrib)
+{
+ if (mode & TF_BMFONT) {
+ Image* ima;
+ int characters, index, character;
+ float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance;
+
+ characters = textlen;
+
+ ima = (Image*)tface->tpage;
+ if (ima == NULL)
+ characters = 0;
+
+ // color has been set
+ if (tface->mode & TF_OBCOL)
+ col= NULL;
+ else if (!col)
+ glColor3f(1.0f, 1.0f, 1.0f);
+
+ glPushMatrix();
+ for (index = 0; index < characters; index++) {
+ float uv[4][2];
+
+ // lets calculate offset stuff
+ character = textstr[index];
+
+ // space starts at offset 1
+ // character = character - ' ' + 1;
+ matrixGlyph((ImBuf *)ima->ibufs.first, character, & centerx, &centery,
+ &sizex, &sizey, &transx, &transy, &movex, &movey, &advance);
+
+ uv[0][0] = (tface->uv[0][0] - centerx) * sizex + transx;
+ uv[0][1] = (tface->uv[0][1] - centery) * sizey + transy;
+ uv[1][0] = (tface->uv[1][0] - centerx) * sizex + transx;
+ uv[1][1] = (tface->uv[1][1] - centery) * sizey + transy;
+ uv[2][0] = (tface->uv[2][0] - centerx) * sizex + transx;
+ uv[2][1] = (tface->uv[2][1] - centery) * sizey + transy;
+
+ glBegin(GL_POLYGON);
+ if(glattrib >= 0) glVertexAttrib2fvARB(glattrib, uv[0]);
+ else glTexCoord2fv(uv[0]);
+ if(col) gpu_mcol(col[0]);
+ glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]);
+
+ if(glattrib >= 0) glVertexAttrib2fvARB(glattrib, uv[1]);
+ else glTexCoord2fv(uv[1]);
+ if(col) gpu_mcol(col[1]);
+ glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]);
+
+ if(glattrib >= 0) glVertexAttrib2fvARB(glattrib, uv[2]);
+ else glTexCoord2fv(uv[2]);
+ if(col) gpu_mcol(col[2]);
+ glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]);
+
+ if(v4) {
+ uv[3][0] = (tface->uv[3][0] - centerx) * sizex + transx;
+ uv[3][1] = (tface->uv[3][1] - centery) * sizey + transy;
+
+ if(glattrib >= 0) glVertexAttrib2fvARB(glattrib, uv[3]);
+ else glTexCoord2fv(uv[3]);
+ if(col) gpu_mcol(col[3]);
+ glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]);
+ }
+ glEnd();
+
+ glTranslatef(advance, 0.0, 0.0);
+ }
+ glPopMatrix();
+ }
+}
+
+/* Checking powers of two for images since opengl 1.x requires it */
+
+static int is_pow2(int num)
+{
+ /* (n&(n-1)) zeros the least significant bit of n */
+ return ((num)&(num-1))==0;
+}
+
+static int smaller_pow2(int num)
+{
+ while (!is_pow2(num))
+ num= num&(num-1);
+
+ return num;
+}
+
+static int is_pow2_limit(int num)
+{
+ /* take texture clamping into account */
+ if (U.glreslimit != 0 && num > U.glreslimit)
+ return 0;
+
+ return ((num)&(num-1))==0;
+}
+
+static int smaller_pow2_limit(int num)
+{
+ /* take texture clamping into account */
+ if (U.glreslimit != 0 && num > U.glreslimit)
+ return U.glreslimit;
+
+ return smaller_pow2(num);
+}
+
+/* Current OpenGL state caching for GPU_set_tpage */
+
+static struct GPUTextureState {
+ int curtile, tile;
+ int curtilemode, tilemode;
+ int curtileXRep, tileXRep;
+ int curtileYRep, tileYRep;
+ Image *ima, *curima;
+
+ int domipmap, linearmipmap;
+
+ int alphamode;
+ MTFace *lasttface;
+} GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, -1, NULL};
+
+/* Mipmap settings */
+
+void GPU_set_mipmap(int mipmap)
+{
+ if (GTS.domipmap != (mipmap != 0)) {
+ GPU_free_images();
+ GTS.domipmap = mipmap != 0;
+ }
+}
+
+void GPU_set_linear_mipmap(int linear)
+{
+ if (GTS.linearmipmap != (linear != 0)) {
+ GPU_free_images();
+ GTS.linearmipmap = linear != 0;
+ }
+}
+
+static int gpu_get_mipmap(void)
+{
+ return GTS.domipmap && (!(G.f & G_TEXTUREPAINT));
+}
+
+static GLenum gpu_get_mipmap_filter()
+{
+ return GTS.linearmipmap? GL_LINEAR_MIPMAP_LINEAR: GL_LINEAR_MIPMAP_NEAREST;
+}
+
+/* Set OpenGL state for an MTFace */
+
+static void gpu_make_repbind(Image *ima)
+{
+ ImBuf *ibuf;
+
+ ibuf = BKE_image_get_ibuf(ima, NULL);
+ if(ibuf==NULL)
+ return;
+
+ if(ima->repbind) {
+ glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
+ MEM_freeN(ima->repbind);
+ ima->repbind= 0;
+ ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+ }
+
+ ima->totbind= ima->xrep*ima->yrep;
+
+ if(ima->totbind>1)
+ ima->repbind= MEM_callocN(sizeof(int)*ima->totbind, "repbind");
+}
+
+static void gpu_clear_tpage()
+{
+ if(GTS.lasttface==0)
+ return;
+
+ GTS.lasttface= 0;
+ GTS.curtile= 0;
+ GTS.curima= 0;
+ if(GTS.curtilemode!=0) {
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ }
+ GTS.curtilemode= 0;
+ GTS.curtileXRep=0;
+ GTS.curtileYRep=0;
+ GTS.alphamode= -1;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ glDisable(GL_ALPHA_TEST);
+}
+
+static void gpu_set_blend_mode(GPUBlendMode blendmode)
+{
+ if(blendmode == GPU_BLEND_SOLID) {
+ glDisable(GL_BLEND);
+ glDisable(GL_ALPHA_TEST);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ else if(blendmode==GPU_BLEND_ADD) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE);
+ glDisable(GL_ALPHA_TEST);
+ }
+ else if(blendmode==GPU_BLEND_ALPHA) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* if U.glalphaclip == 1.0, some cards go bonkers...
+ * turn off alpha test in this case */
+
+ /* added after 2.45 to clip alpha */
+ if(U.glalphaclip == 1.0) {
+ glDisable(GL_ALPHA_TEST);
+ }
+ else {
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GREATER, U.glalphaclip);
+ }
+ }
+ else if(blendmode==GPU_BLEND_CLIP) {
+ glDisable(GL_BLEND);
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GREATER, 0.5f);
+ }
+}
+
+static void gpu_verify_alpha_mode(MTFace *tface)
+{
+ /* verify alpha blending modes */
+ if(GTS.alphamode == tface->transp)
+ return;
+
+ gpu_set_blend_mode(tface->transp);
+ GTS.alphamode= tface->transp;
+}
+
+static void gpu_verify_reflection(Image *ima)
+{
+ if (ima && (ima->flag & IMA_REFLECT)) {
+ /* enable reflection mapping */
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ }
+ else {
+ /* disable reflection mapping */
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ }
+}
+
+int GPU_verify_image(Image *ima, int tftile, int tfmode, int compare)
+{
+ ImBuf *ibuf = NULL;
+ unsigned int *bind = NULL;
+ int rectw, recth, tpx=0, tpy=0, y;
+ unsigned int *rectrow, *tilerectrow;
+ unsigned int *tilerect= NULL, *scalerect= NULL, *rect= NULL;
+ short texwindx, texwindy, texwinsx, texwinsy;
+
+ /* initialize tile mode and number of repeats */
+ GTS.ima = ima;
+ GTS.tilemode= (tfmode & TF_TILES) || (ima && (ima->tpageflag & IMA_TWINANIM));
+ GTS.tileXRep = 0;
+ GTS.tileYRep = 0;
+
+ /* setting current tile according to frame */
+ if(ima && (ima->tpageflag & IMA_TWINANIM))
+ GTS.tile= ima->lastframe;
+ else
+ GTS.tile= tftile;
+
+ if(ima) {
+ GTS.tileXRep = ima->xrep;
+ GTS.tileYRep = ima->yrep;
+ }
+
+ /* if same image & tile, we're done */
+ if(compare && ima == GTS.curima && GTS.curtile == GTS.tile &&
+ GTS.tilemode == GTS.curtilemode && GTS.curtileXRep == GTS.tileXRep &&
+ GTS.curtileYRep == GTS.tileYRep)
+ return (ima!=0);
+
+ /* if tiling mode or repeat changed, change texture matrix to fit */
+ if(GTS.tilemode!=GTS.curtilemode || GTS.curtileXRep!=GTS.tileXRep ||
+ GTS.curtileYRep != GTS.tileYRep) {
+
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+
+ if((tfmode & TF_TILES) && ima!=NULL)
+ glScalef(ima->xrep, ima->yrep, 1.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ }
+
+ /* check if we have a valid image */
+ if(ima==NULL || ima->ok==0)
+ return 0;
+
+ /* check if we have a valid image buffer */
+ ibuf= BKE_image_get_ibuf(ima, NULL);
+
+ if(ibuf==NULL)
+ return 0;
+
+ /* ensure we have a char buffer and not only float */
+ if ((ibuf->rect==NULL) && ibuf->rect_float)
+ IMB_rect_from_float(ibuf);
+
+ if(GTS.tilemode) {
+ /* tiled mode */
+ if(ima->repbind==0) gpu_make_repbind(ima);
+ if(GTS.tile>=ima->totbind) GTS.tile= 0;
+
+ /* this happens when you change repeat buttons */
+ if(ima->repbind) bind= &ima->repbind[GTS.tile];
+ else bind= &ima->bindcode;
+
+ if(*bind==0) {
+
+ texwindx= ibuf->x/ima->xrep;
+ texwindy= ibuf->y/ima->yrep;
+
+ if(GTS.tile>=ima->xrep*ima->yrep)
+ GTS.tile= ima->xrep*ima->yrep-1;
+
+ texwinsy= GTS.tile / ima->xrep;
+ texwinsx= GTS.tile - texwinsy*ima->xrep;
+
+ texwinsx*= texwindx;
+ texwinsy*= texwindy;
+
+ tpx= texwindx;
+ tpy= texwindy;
+
+ rect= ibuf->rect + texwinsy*ibuf->x + texwinsx;
+ }
+ }
+ else {
+ /* regular image mode */
+ bind= &ima->bindcode;
+
+ if(*bind==0) {
+ tpx= ibuf->x;
+ tpy= ibuf->y;
+ rect= ibuf->rect;
+ }
+ }
+
+ if(*bind != 0) {
+ /* enable opengl drawing with textures */
+ glBindTexture(GL_TEXTURE_2D, *bind);
+ return *bind;
+ }
+
+ rectw = tpx;
+ recth = tpy;
+
+ /* for tiles, copy only part of image into buffer */
+ if (GTS.tilemode) {
+ tilerect= MEM_mallocN(rectw*recth*sizeof(*tilerect), "tilerect");
+
+ for (y=0; y<recth; y++) {
+ rectrow= &rect[y*ibuf->x];
+ tilerectrow= &tilerect[y*rectw];
+
+ memcpy(tilerectrow, rectrow, tpx*sizeof(*rectrow));
+ }
+
+ rect= tilerect;
+ }
+
+ /* scale if not a power of two */
+ if (!is_pow2_limit(rectw) || !is_pow2_limit(recth)) {
+ rectw= smaller_pow2_limit(rectw);
+ recth= smaller_pow2_limit(recth);
+
+ scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
+ gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, rect, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
+ rect= scalerect;
+ }
+
+ /* create image */
+ glGenTextures(1, (GLuint *)bind);
+ glBindTexture( GL_TEXTURE_2D, *bind);
+
+ if (!gpu_get_mipmap()) {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else {
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter());
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ ima->tpageflag |= IMA_MIPMAP_COMPLETE;
+ }
+
+ /* set to modulate with vertex color */
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ /* clean up */
+ if (tilerect)
+ MEM_freeN(tilerect);
+ if (scalerect)
+ MEM_freeN(scalerect);
+
+ return *bind;
+}
+
+static void gpu_verify_repeat(Image *ima)
+{
+ /* set either clamp or repeat in X/Y */
+ if (ima->tpageflag & IMA_CLAMP_U)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ else
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+
+ if (ima->tpageflag & IMA_CLAMP_V)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ else
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+}
+
+int GPU_set_tpage(MTFace *tface)
+{
+ Image *ima;
+
+ /* check if we need to clear the state */
+ if(tface==0) {
+ gpu_clear_tpage();
+ return 0;
+ }
+
+ ima= tface->tpage;
+ GTS.lasttface= tface;
+
+ gpu_verify_alpha_mode(tface);
+ gpu_verify_reflection(ima);
+
+ if(GPU_verify_image(ima, tface->tile, tface->mode, 1)) {
+ GTS.curtile= GTS.tile;
+ GTS.curima= GTS.ima;
+ GTS.curtilemode= GTS.tilemode;
+ GTS.curtileXRep = GTS.tileXRep;
+ GTS.curtileYRep = GTS.tileYRep;
+
+ glEnable(GL_TEXTURE_2D);
+ }
+ else {
+ glDisable(GL_TEXTURE_2D);
+
+ GTS.curtile= 0;
+ GTS.curima= 0;
+ GTS.curtilemode= 0;
+ GTS.curtileXRep = 0;
+ GTS.curtileYRep = 0;
+
+ return 0;
+ }
+
+ gpu_verify_repeat(ima);
+
+ /* Did this get lost in the image recode? */
+ /* tag_image_time(ima);*/
+
+ return 1;
+}
+
+/* these two functions are called on entering and exiting texture paint mode,
+ temporary disabling/enabling mipmapping on all images for quick texture
+ updates with glTexSubImage2D. images that didn't change don't have to be
+ re-uploaded to OpenGL */
+void GPU_paint_set_mipmap(int mipmap)
+{
+ Image* ima;
+
+ if(!GTS.domipmap)
+ return;
+
+ if(mipmap) {
+ for(ima=G.main->image.first; ima; ima=ima->id.next) {
+ if(ima->bindcode) {
+ if(ima->tpageflag & IMA_MIPMAP_COMPLETE) {
+ glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter());
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else
+ GPU_free_image(ima);
+ }
+ }
+
+ }
+ else {
+ for(ima=G.main->image.first; ima; ima=ima->id.next) {
+ if(ima->bindcode) {
+ glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ }
+ }
+}
+
+void GPU_paint_update_image(Image *ima, int x, int y, int w, int h)
+{
+ ImBuf *ibuf;
+
+ ibuf = BKE_image_get_ibuf(ima, NULL);
+
+ if (ima->repbind || gpu_get_mipmap() || !ima->bindcode || !ibuf ||
+ (!is_pow2(ibuf->x) || !is_pow2(ibuf->y)) ||
+ (w == 0) || (h == 0)) {
+ /* these cases require full reload still */
+ GPU_free_image(ima);
+ }
+ else {
+ /* for the special case, we can do a partial update
+ * which is much quicker for painting */
+ GLint row_length, skip_pixels, skip_rows;
+
+ glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
+ glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
+ glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
+
+ if ((ibuf->rect==NULL) && ibuf->rect_float)
+ IMB_rect_from_float(ibuf);
+
+ glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, ibuf->x);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
+ GL_UNSIGNED_BYTE, ibuf->rect);
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, skip_rows);
+
+ if(ima->tpageflag & IMA_MIPMAP_COMPLETE)
+ ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+ }
+}
+
+void GPU_update_images_framechange(void)
+{
+ Image *ima;
+
+ for(ima=G.main->image.first; ima; ima=ima->id.next) {
+ if(ima->tpageflag & IMA_TWINANIM) {
+ if(ima->twend >= ima->xrep*ima->yrep)
+ ima->twend= ima->xrep*ima->yrep-1;
+
+ /* check: is bindcode not in the array? free. (to do) */
+
+ ima->lastframe++;
+ if(ima->lastframe > ima->twend)
+ ima->lastframe= ima->twsta;
+ }
+ }
+}
+
+int GPU_update_image_time(Image *ima, double time)
+{
+ int inc = 0;
+ float diff;
+ int newframe;
+
+ if (!ima)
+ return 0;
+
+ if (ima->lastupdate<0)
+ ima->lastupdate = 0;
+
+ if (ima->lastupdate>time)
+ ima->lastupdate=(float)time;
+
+ if(ima->tpageflag & IMA_TWINANIM) {
+ if(ima->twend >= ima->xrep*ima->yrep) ima->twend= ima->xrep*ima->yrep-1;
+
+ /* check: is the bindcode not in the array? Then free. (still to do) */
+
+ diff = (float)(time-ima->lastupdate);
+ inc = (int)(diff*(float)ima->animspeed);
+
+ ima->lastupdate+=((float)inc/(float)ima->animspeed);
+
+ newframe = ima->lastframe+inc;
+
+ if(newframe > (int)ima->twend) {
+ if(ima->twend-ima->twsta != 0)
+ newframe = (int)ima->twsta-1 + (newframe-ima->twend)%(ima->twend-ima->twsta);
+ else
+ newframe = ima->twsta;
+ }
+
+ ima->lastframe = newframe;
+ }
+
+ return inc;
+}
+
+void GPU_free_image(Image *ima)
+{
+ /* free regular image binding */
+ if(ima->bindcode) {
+ glDeleteTextures(1, (GLuint *)&ima->bindcode);
+ ima->bindcode= 0;
+ ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+ }
+
+ /* free glsl image binding */
+ if(ima->gputexture) {
+ GPU_texture_free(ima->gputexture);
+ ima->gputexture= NULL;
+ }
+
+ /* free repeated image binding */
+ if(ima->repbind) {
+ glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
+
+ MEM_freeN(ima->repbind);
+ ima->repbind= NULL;
+ ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+ }
+}
+
+void GPU_free_images(void)
+{
+ Image* ima;
+
+ for(ima=G.main->image.first; ima; ima=ima->id.next)
+ GPU_free_image(ima);
+}
+
+/* OpenGL Materials */
+
+/* materials start counting at # one.... */
+#define MAXMATBUF (MAXMAT+1)
+
+/* OpenGL state caching for materials */
+
+static struct GPUMaterialState {
+ float matbuf[MAXMATBUF][2][4];
+ int totmat;
+
+ Material *gmatbuf[MAXMATBUF];
+ Material *gboundmat;
+ Object *gob;
+ Scene *gscene;
+
+ GPUBlendMode blendmode[MAXMATBUF];
+ int alphapass;
+
+ int lastmatnr, lastretval;
+ GPUBlendMode lastblendmode;
+} GMS;
+
+Material *gpu_active_node_material(Material *ma)
+{
+ if(ma && ma->use_nodes && ma->nodetree) {
+ bNode *node= nodeGetActiveID(ma->nodetree, ID_MA);
+
+ if(node)
+ return (Material *)node->id;
+ else
+ return NULL;
+ }
+
+ return ma;
+}
+
+void GPU_set_object_materials(Scene *scene, Object *ob, int glsl, int *do_alpha_pass)
+{
+ extern Material defmaterial; /* from material.c */
+ Material *ma;
+ GPUMaterial *gpumat;
+ GPUBlendMode blendmode;
+ int a;
+
+ /* initialize state */
+ memset(&GMS, 0, sizeof(GMS));
+ GMS.lastmatnr = -1;
+ GMS.lastretval = -1;
+ GMS.lastblendmode = GPU_BLEND_SOLID;
+
+ GMS.gob = ob;
+ GMS.gscene = scene;
+ GMS.totmat= ob->totcol;
+
+ GMS.alphapass = (G.vd && G.vd->transp);
+ if(do_alpha_pass)
+ *do_alpha_pass = 0;
+
+ /* no materials assigned? */
+ if(ob->totcol==0) {
+ GMS.matbuf[0][0][0]= defmaterial.r;
+ GMS.matbuf[0][0][1]= defmaterial.g;
+ GMS.matbuf[0][0][2]= defmaterial.b;
+ GMS.matbuf[0][0][3]= 1.0;
+
+ GMS.matbuf[0][1][0]= defmaterial.specr;
+ GMS.matbuf[0][1][1]= defmaterial.specg;
+ GMS.matbuf[0][1][2]= defmaterial.specb;
+ GMS.matbuf[0][1][3]= 1.0;
+
+ /* do material 1 too, for displists! */
+ QUATCOPY(GMS.matbuf[1][0], GMS.matbuf[0][0]);
+ QUATCOPY(GMS.matbuf[1][1], GMS.matbuf[0][1]);
+
+ if(glsl) {
+ GMS.gmatbuf[0]= &defmaterial;
+ GPU_material_from_blender(GMS.gscene, &defmaterial);
+ }
+
+ GMS.blendmode[0]= GPU_BLEND_SOLID;
+ }
+
+ /* setup materials */
+ for(a=1; a<=ob->totcol; a++) {
+ /* find a suitable material */
+ ma= give_current_material(ob, a);
+ if(!glsl) ma= gpu_active_node_material(ma);
+ if(ma==NULL) ma= &defmaterial;
+
+ /* this shouldn't happen .. */
+ if(a>=MAXMATBUF)
+ continue;
+
+ /* create glsl material if requested */
+ gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma): NULL;
+
+ if(gpumat) {
+ /* do glsl only if creating it succeed, else fallback */
+ GMS.gmatbuf[a]= ma;
+ blendmode = GPU_material_blend_mode(gpumat, ob->col);
+ }
+ else {
+ /* fixed function opengl materials */
+ if (ma->mode & MA_SHLESS) {
+ GMS.matbuf[a][0][0]= ma->r;
+ GMS.matbuf[a][0][1]= ma->g;
+ GMS.matbuf[a][0][2]= ma->b;
+ } else {
+ GMS.matbuf[a][0][0]= (ma->ref+ma->emit)*ma->r;
+ GMS.matbuf[a][0][1]= (ma->ref+ma->emit)*ma->g;
+ GMS.matbuf[a][0][2]= (ma->ref+ma->emit)*ma->b;
+
+ GMS.matbuf[a][1][0]= ma->spec*ma->specr;
+ GMS.matbuf[a][1][1]= ma->spec*ma->specg;
+ GMS.matbuf[a][1][2]= ma->spec*ma->specb;
+ GMS.matbuf[a][1][3]= 1.0;
+ }
+
+ blendmode = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
+ if(do_alpha_pass && GMS.alphapass)
+ GMS.matbuf[a][0][3]= ma->alpha;
+ else
+ GMS.matbuf[a][0][3]= 1.0f;
+ }
+
+ /* setting do_alpha_pass = 1 indicates this object needs to be
+ * drawn in a second alpha pass for improved blending */
+ if(do_alpha_pass) {
+ GMS.blendmode[a]= blendmode;
+ if(ELEM(blendmode, GPU_BLEND_ALPHA, GPU_BLEND_ADD) && !GMS.alphapass)
+ *do_alpha_pass= 1;
+ }
+ }
+
+ /* let's start with a clean state */
+ GPU_disable_material();
+}
+
+int GPU_enable_material(int nr, void *attribs)
+{
+ GPUVertexAttribs *gattribs = attribs;
+ GPUMaterial *gpumat;
+ GPUBlendMode blendmode;
+
+ /* prevent index to use un-initialized array items */
+ if(nr>GMS.totmat)
+ nr= GMS.totmat;
+
+ if(gattribs)
+ memset(gattribs, 0, sizeof(*gattribs));
+
+ /* keep current material */
+ if(nr>=MAXMATBUF || nr==GMS.lastmatnr)
+ return GMS.lastretval;
+
+ /* unbind glsl material */
+ if(GMS.gboundmat) {
+ if(GMS.alphapass) glDepthMask(0);
+ GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
+ GMS.gboundmat= NULL;
+ }
+
+ /* draw materials with alpha in alpha pass */
+ GMS.lastmatnr = nr;
+ GMS.lastretval = ELEM(GMS.blendmode[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP);
+ if(GMS.alphapass)
+ GMS.lastretval = !GMS.lastretval;
+
+ if(GMS.lastretval) {
+ if(gattribs && GMS.gmatbuf[nr]) {
+ /* bind glsl material and get attributes */
+ Material *mat = GMS.gmatbuf[nr];
+
+ gpumat = GPU_material_from_blender(GMS.gscene, mat);
+ GPU_material_vertex_attributes(gpumat, gattribs);
+ GPU_material_bind(gpumat, GMS.gob->lay, 1.0);
+ GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, G.vd->viewmat, G.vd->viewinv, GMS.gob->col);
+ GMS.gboundmat= mat;
+
+ if(GMS.alphapass) glDepthMask(1);
+ }
+ else {
+ /* or do fixed function opengl material */
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GMS.matbuf[nr][0]);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, GMS.matbuf[nr][1]);
+ }
+
+ /* set (alpha) blending mode */
+ blendmode = (GMS.alphapass)? GPU_BLEND_ALPHA: GPU_BLEND_SOLID;
+ GPU_set_material_blend_mode(blendmode);
+ }
+
+ return GMS.lastretval;
+}
+
+void GPU_set_material_blend_mode(int blendmode)
+{
+ if(GMS.lastblendmode == blendmode)
+ return;
+
+ gpu_set_blend_mode(blendmode);
+ GMS.lastblendmode = blendmode;
+}
+
+int GPU_get_material_blend_mode(void)
+{
+ return GMS.lastblendmode;
+}
+
+void GPU_disable_material(void)
+{
+ GMS.lastmatnr= -1;
+ GMS.lastretval= 1;
+
+ if(GMS.gboundmat) {
+ if(GMS.alphapass) glDepthMask(0);
+ GPU_material_unbind(GPU_material_from_blender(GMS.gscene, GMS.gboundmat));
+ GMS.gboundmat= NULL;
+ }
+
+ GPU_set_material_blend_mode(GPU_BLEND_SOLID);
+}
+
+/* Lights */
+
+int GPU_default_lights(void)
+{
+ int a, count = 0;
+
+ /* initialize */
+ if(U.light[0].flag==0 && U.light[1].flag==0 && U.light[2].flag==0) {
+ U.light[0].flag= 1;
+ U.light[0].vec[0]= -0.3; U.light[0].vec[1]= 0.3; U.light[0].vec[2]= 0.9;
+ U.light[0].col[0]= 0.8; U.light[0].col[1]= 0.8; U.light[0].col[2]= 0.8;
+ U.light[0].spec[0]= 0.5; U.light[0].spec[1]= 0.5; U.light[0].spec[2]= 0.5;
+ U.light[0].spec[3]= 1.0;
+
+ U.light[1].flag= 0;
+ U.light[1].vec[0]= 0.5; U.light[1].vec[1]= 0.5; U.light[1].vec[2]= 0.1;
+ U.light[1].col[0]= 0.4; U.light[1].col[1]= 0.4; U.light[1].col[2]= 0.8;
+ U.light[1].spec[0]= 0.3; U.light[1].spec[1]= 0.3; U.light[1].spec[2]= 0.5;
+ U.light[1].spec[3]= 1.0;
+
+ U.light[2].flag= 0;
+ U.light[2].vec[0]= 0.3; U.light[2].vec[1]= -0.3; U.light[2].vec[2]= -0.2;
+ U.light[2].col[0]= 0.8; U.light[2].col[1]= 0.5; U.light[2].col[2]= 0.4;
+ U.light[2].spec[0]= 0.5; U.light[2].spec[1]= 0.4; U.light[2].spec[2]= 0.3;
+ U.light[2].spec[3]= 1.0;
+ }
+
+ glLightfv(GL_LIGHT0, GL_POSITION, U.light[0].vec);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, U.light[0].col);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, U.light[0].spec);
+
+ glLightfv(GL_LIGHT1, GL_POSITION, U.light[1].vec);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, U.light[1].col);
+ glLightfv(GL_LIGHT1, GL_SPECULAR, U.light[1].spec);
+
+ glLightfv(GL_LIGHT2, GL_POSITION, U.light[2].vec);
+ glLightfv(GL_LIGHT2, GL_DIFFUSE, U.light[2].col);
+ glLightfv(GL_LIGHT2, GL_SPECULAR, U.light[2].spec);
+
+ for(a=0; a<8; a++) {
+ if(a<3) {
+ if(U.light[a].flag) {
+ glEnable(GL_LIGHT0+a);
+ count++;
+ }
+ else
+ glDisable(GL_LIGHT0+a);
+
+ // clear stuff from other opengl lamp usage
+ glLightf(GL_LIGHT0+a, GL_SPOT_CUTOFF, 180.0);
+ glLightf(GL_LIGHT0+a, GL_CONSTANT_ATTENUATION, 1.0);
+ glLightf(GL_LIGHT0+a, GL_LINEAR_ATTENUATION, 0.0);
+ }
+ else
+ glDisable(GL_LIGHT0+a);
+ }
+
+ glDisable(GL_LIGHTING);
+
+ glDisable(GL_COLOR_MATERIAL);
+
+ return count;
+}
+
+int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4])
+{
+ Base *base;
+ Lamp *la;
+ int count;
+ float position[4], direction[4], energy[4];
+
+ /* disable all lights */
+ for(count=0; count<8; count++)
+ glDisable(GL_LIGHT0+count);
+
+ count= 0;
+
+ for(base=scene->base.first; base; base=base->next) {
+ if(base->object->type!=OB_LAMP)
+ continue;
+
+ if(!(base->lay & lay) || !(base->lay & ob->lay))
+ continue;
+
+ la= base->object->data;
+
+ /* setup lamp transform */
+ glPushMatrix();
+ glLoadMatrixf((float *)viewmat);
+
+ where_is_object_simul(base->object);
+
+ if(la->type==LA_SUN) {
+ /* sun lamp */
+ VECCOPY(position, base->object->obmat[2]);
+ direction[3]= 0.0;
+
+ glLightfv(GL_LIGHT0+count, GL_POSITION, direction);
+ }
+ else {
+ /* other lamps with attenuation */
+ VECCOPY(position, base->object->obmat[3]);
+ position[3]= 1.0f;
+
+ glLightfv(GL_LIGHT0+count, GL_POSITION, position);
+ glLightf(GL_LIGHT0+count, GL_CONSTANT_ATTENUATION, 1.0);
+ glLightf(GL_LIGHT0+count, GL_LINEAR_ATTENUATION, la->att1/la->dist);
+ glLightf(GL_LIGHT0+count, GL_QUADRATIC_ATTENUATION, la->att2/(la->dist*la->dist));
+
+ if(la->type==LA_SPOT) {
+ /* spot lamp */
+ direction[0]= -base->object->obmat[2][0];
+ direction[1]= -base->object->obmat[2][1];
+ direction[2]= -base->object->obmat[2][2];
+ glLightfv(GL_LIGHT0+count, GL_SPOT_DIRECTION, direction);
+ glLightf(GL_LIGHT0+count, GL_SPOT_CUTOFF, la->spotsize/2.0);
+ glLightf(GL_LIGHT0+count, GL_SPOT_EXPONENT, 128.0*la->spotblend);
+ }
+ else
+ glLightf(GL_LIGHT0+count, GL_SPOT_CUTOFF, 180.0);
+ }
+
+ /* setup energy */
+ energy[0]= la->energy*la->r;
+ energy[1]= la->energy*la->g;
+ energy[2]= la->energy*la->b;
+ energy[3]= 1.0;
+
+ glLightfv(GL_LIGHT0+count, GL_DIFFUSE, energy);
+ glLightfv(GL_LIGHT0+count, GL_SPECULAR, energy);
+ glEnable(GL_LIGHT0+count);
+
+ glPopMatrix();
+
+ count++;
+ if(count==8)
+ break;
+ }
+
+ return count;
+}
+
+/* Default OpenGL State */
+
+void GPU_state_init(void)
+{
+ /* also called when doing opengl rendering and in the game engine */
+ float mat_ambient[] = { 0.0, 0.0, 0.0, 0.0 };
+ float mat_specular[] = { 0.5, 0.5, 0.5, 1.0 };
+ float mat_shininess[] = { 35.0 };
+ int a, x, y;
+ GLubyte pat[32*32];
+ const GLubyte *patc= pat;
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_specular);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
+
+ GPU_default_lights();
+
+ /* no local viewer, looks ugly in ortho mode */
+ /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
+
+ glDepthFunc(GL_LEQUAL);
+ /* scaling matrices */
+ glEnable(GL_NORMALIZE);
+
+ glShadeModel(GL_FLAT);
+
+ glDisable(GL_ALPHA_TEST);
+ glDisable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_FOG);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_LOGIC_OP);
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_TEXTURE_1D);
+ glDisable(GL_TEXTURE_2D);
+
+ /* default on, disable/enable should be local per function */
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+
+ glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
+ glPixelTransferi(GL_RED_SCALE, 1);
+ glPixelTransferi(GL_RED_BIAS, 0);
+ glPixelTransferi(GL_GREEN_SCALE, 1);
+ glPixelTransferi(GL_GREEN_BIAS, 0);
+ glPixelTransferi(GL_BLUE_SCALE, 1);
+ glPixelTransferi(GL_BLUE_BIAS, 0);
+ glPixelTransferi(GL_ALPHA_SCALE, 1);
+ glPixelTransferi(GL_ALPHA_BIAS, 0);
+
+ glPixelTransferi(GL_DEPTH_BIAS, 0);
+ glPixelTransferi(GL_DEPTH_SCALE, 1);
+ glDepthRange(0.0, 1.0);
+
+ a= 0;
+ for(x=0; x<32; x++) {
+ for(y=0; y<4; y++) {
+ if( (x) & 1) pat[a++]= 0x88;
+ else pat[a++]= 0x22;
+ }
+ }
+
+ glPolygonStipple(patc);
+
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+
+ glFrontFace(GL_CCW);
+ glCullFace(GL_BACK);
+ glDisable(GL_CULL_FACE);
+}
+
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
new file mode 100644
index 00000000000..d900f9c63f2
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -0,0 +1,987 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "GL/glew.h"
+
+#include "DNA_listBase.h"
+#include "DNA_image_types.h"
+#include "DNA_userdef_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_image.h"
+#include "BKE_global.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "BLI_blenlib.h"
+
+#include "GPU_draw.h"
+#include "GPU_extensions.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Extensions support */
+
+/* extensions used:
+ - texture border clamp: 1.3 core
+ - fragement shader: 2.0 core
+ - framebuffer object: ext specification
+ - multitexture 1.3 core
+ - arb non power of two: 2.0 core
+ - pixel buffer objects? 2.1 core
+ - arb draw buffers? 2.0 core
+*/
+
+struct GPUGlobal {
+ GLint maxtextures;
+ GLuint currentfb;
+ int minimumsupport;
+} GG = {1, 0, 0};
+
+void GPU_extensions_init()
+{
+ glewInit();
+
+ /* glewIsSupported("GL_VERSION_2_0") */
+
+ if (GLEW_ARB_multitexture)
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &GG.maxtextures);
+
+ GG.minimumsupport = 1;
+ if (!GLEW_ARB_multitexture) GG.minimumsupport = 0;
+ if (!GLEW_ARB_vertex_shader) GG.minimumsupport = 0;
+ if (!GLEW_ARB_fragment_shader) GG.minimumsupport = 0;
+}
+
+int GPU_extensions_minimum_support()
+{
+ return GG.minimumsupport;
+}
+
+int GPU_print_error(char *str)
+{
+ GLenum errCode;
+
+ if (G.f & G_DEBUG) {
+ if ((errCode = glGetError()) != GL_NO_ERROR) {
+ fprintf(stderr, "%s opengl error: %s\n", str, gluErrorString(errCode));
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void GPU_print_framebuffer_error(GLenum status)
+{
+ fprintf(stderr, "GPUFrameBuffer: framebuffer incomplete error %d\n",
+ (int)status);
+
+ switch(status) {
+ case GL_FRAMEBUFFER_COMPLETE_EXT:
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+ fprintf(stderr, "Incomplete attachment.\n");
+ break;
+ case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+ fprintf(stderr, "Unsupported framebuffer format.\n");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
+ fprintf(stderr, "Missing attachment.\n");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
+ fprintf(stderr, "Attached images must have same dimensions.\n");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
+ fprintf(stderr, "Attached images must have same format.\n");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+ fprintf(stderr, "Missing draw buffer.\n");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+ fprintf(stderr, "Missing read buffer.\n");
+ break;
+ default:
+ fprintf(stderr, "Unknown.\n");
+ break;
+ }
+}
+
+/* GPUTexture */
+
+struct GPUTexture {
+ int w, h; /* width/height */
+ int number; /* number for multitexture binding */
+ int refcount; /* reference count */
+ GLenum target; /* GL_TEXTURE_* */
+ GLuint bindcode; /* opengl identifier for texture */
+ int fromblender; /* we got the texture from Blender */
+
+ GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
+ int depth; /* is a depth texture? */
+};
+
+#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
+static unsigned char *GPU_texture_convert_pixels(int length, float *fpixels)
+{
+ unsigned char *pixels, *p;
+ float *fp;
+ int a, len;
+
+ len = 4*length;
+ fp = fpixels;
+ p = pixels = MEM_callocN(sizeof(unsigned char)*len, "GPUTexturePixels");
+
+ for (a=0; a<len; a++, p++, fp++)
+ *p = FTOCHAR((*fp));
+
+ return pixels;
+}
+
+static int is_pow2(int n)
+{
+ return ((n)&(n-1))==0;
+}
+
+static int larger_pow2(int n)
+{
+ if (is_pow2(n))
+ return n;
+
+ while(!is_pow2(n))
+ n= n&(n-1);
+
+ return n*2;
+}
+
+static void GPU_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, int w, int h)
+{
+ void *pixels = MEM_callocN(sizeof(char)*4*w*h, "GPUTextureEmptyPixels");
+
+ if (target == GL_TEXTURE_1D)
+ glTexSubImage1D(target, 0, x, w, format, GL_UNSIGNED_BYTE, pixels);
+ else
+ glTexSubImage2D(target, 0, x, y, w, h, format, GL_UNSIGNED_BYTE, pixels);
+
+ MEM_freeN(pixels);
+}
+
+static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, int depth)
+{
+ GPUTexture *tex;
+ GLenum type, format, internalformat;
+ void *pixels = NULL;
+
+ if(depth && !GLEW_ARB_depth_texture)
+ return NULL;
+
+ tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ tex->w = w;
+ tex->h = h;
+ tex->number = -1;
+ tex->refcount = 1;
+ tex->target = (n == 1)? GL_TEXTURE_1D: GL_TEXTURE_2D;
+ tex->depth = depth;
+
+ glGenTextures(1, &tex->bindcode);
+
+ if (!tex->bindcode) {
+ fprintf(stderr, "GPUTexture: texture create failed: %d\n",
+ (int)glGetError());
+ GPU_texture_free(tex);
+ return NULL;
+ }
+
+ if (!GLEW_ARB_texture_non_power_of_two) {
+ tex->w = larger_pow2(tex->w);
+ tex->h = larger_pow2(tex->h);
+ }
+
+ tex->number = 0;
+ glBindTexture(tex->target, tex->bindcode);
+
+ if(depth) {
+ type = GL_UNSIGNED_BYTE;
+ format = GL_DEPTH_COMPONENT;
+ internalformat = GL_DEPTH_COMPONENT;
+ }
+ else {
+ type = GL_UNSIGNED_BYTE;
+ format = GL_RGBA;
+ internalformat = GL_RGBA8;
+
+ if (fpixels)
+ pixels = GPU_texture_convert_pixels(w*h, fpixels);
+ }
+
+ if (tex->target == GL_TEXTURE_1D) {
+ glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, type, 0);
+
+ if (fpixels) {
+ glTexSubImage1D(tex->target, 0, 0, w, format, type,
+ pixels? pixels: fpixels);
+
+ if (tex->w > w)
+ GPU_glTexSubImageEmpty(tex->target, format, w, 0,
+ tex->w-w, 1);
+ }
+ }
+ else {
+ glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0,
+ format, type, 0);
+
+ if (fpixels) {
+ glTexSubImage2D(tex->target, 0, 0, 0, w, h,
+ format, type, pixels? pixels: fpixels);
+
+ if (tex->w > w)
+ GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w-w, tex->h);
+ if (tex->h > h)
+ GPU_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h-h);
+ }
+ }
+
+ if (pixels)
+ MEM_freeN(pixels);
+
+ if(depth) {
+ glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(tex->target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(tex->target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
+ glTexParameteri(tex->target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
+ }
+ else {
+ glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+
+ if (tex->target != GL_TEXTURE_1D) {
+ /* CLAMP_TO_BORDER is an OpenGL 1.3 core feature */
+ GLenum wrapmode = (depth)? GL_CLAMP_TO_EDGE: GL_CLAMP_TO_BORDER;
+ glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, wrapmode);
+ glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, wrapmode);
+
+#if 0
+ float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
+#endif
+ }
+ else
+ glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+
+ return tex;
+}
+
+GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, double time)
+{
+ GPUTexture *tex;
+ GLint w, h, border, lastbindcode, bindcode;
+
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
+
+ GPU_update_image_time(ima, time);
+ bindcode = GPU_verify_image(ima, 0, 0, 0);
+
+ if(ima->gputexture) {
+ ima->gputexture->bindcode = bindcode;
+ glBindTexture(GL_TEXTURE_2D, lastbindcode);
+ return ima->gputexture;
+ }
+
+ if(!bindcode) {
+ glBindTexture(GL_TEXTURE_2D, lastbindcode);
+ return NULL;
+ }
+
+ tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ tex->bindcode = bindcode;
+ tex->number = -1;
+ tex->refcount = 1;
+ tex->target = GL_TEXTURE_2D;
+ tex->fromblender = 1;
+
+ ima->gputexture= tex;
+
+ if (!glIsTexture(tex->bindcode)) {
+ GPU_print_error("Blender Texture");
+ }
+ else {
+ glBindTexture(GL_TEXTURE_2D, tex->bindcode);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BORDER, &border);
+
+ tex->w = w - border;
+ tex->h = h - border;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, lastbindcode);
+
+ return tex;
+}
+
+GPUTexture *GPU_texture_create_1D(int w, float *fpixels)
+{
+ GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0);
+
+ if (tex)
+ GPU_texture_unbind(tex);
+
+ return tex;
+}
+
+GPUTexture *GPU_texture_create_2D(int w, int h, float *fpixels)
+{
+ GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0);
+
+ if (tex)
+ GPU_texture_unbind(tex);
+
+ return tex;
+}
+
+GPUTexture *GPU_texture_create_depth(int w, int h)
+{
+ GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1);
+
+ if (tex)
+ GPU_texture_unbind(tex);
+
+ return tex;
+}
+
+void GPU_texture_bind(GPUTexture *tex, int number)
+{
+ GLenum arbnumber;
+
+ if (number >= GG.maxtextures) {
+ GPU_print_error("Not enough texture slots.");
+ return;
+ }
+
+ if(number == -1)
+ return;
+
+ GPU_print_error("Pre Texture Bind");
+
+ arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + number);
+ if (number != 0) glActiveTextureARB(arbnumber);
+ glBindTexture(tex->target, tex->bindcode);
+ glEnable(tex->target);
+ if (number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
+
+ tex->number = number;
+
+ GPU_print_error("Post Texture Bind");
+}
+
+void GPU_texture_unbind(GPUTexture *tex)
+{
+ GLenum arbnumber;
+
+ if (tex->number >= GG.maxtextures) {
+ GPU_print_error("Not enough texture slots.");
+ return;
+ }
+
+ if(tex->number == -1)
+ return;
+
+ GPU_print_error("Pre Texture Unbind");
+
+ arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
+ if (tex->number != 0) glActiveTextureARB(arbnumber);
+ glBindTexture(tex->target, 0);
+ glDisable(tex->target);
+ if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
+
+ tex->number = -1;
+
+ GPU_print_error("Post Texture Unbind");
+}
+
+void GPU_texture_free(GPUTexture *tex)
+{
+ tex->refcount--;
+
+ if (tex->refcount < 0)
+ fprintf(stderr, "GPUTexture: negative refcount\n");
+
+ if (tex->refcount == 0) {
+ if (tex->fb)
+ GPU_framebuffer_texture_detach(tex->fb, tex);
+ if (tex->bindcode && !tex->fromblender)
+ glDeleteTextures(1, &tex->bindcode);
+
+ MEM_freeN(tex);
+ }
+}
+
+void GPU_texture_ref(GPUTexture *tex)
+{
+ tex->refcount++;
+}
+
+int GPU_texture_target(GPUTexture *tex)
+{
+ return tex->target;
+}
+
+int GPU_texture_opengl_width(GPUTexture *tex)
+{
+ return tex->w;
+}
+
+int GPU_texture_opengl_height(GPUTexture *tex)
+{
+ return tex->h;
+}
+
+GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex)
+{
+ return tex->fb;
+}
+
+/* GPUFrameBuffer */
+
+struct GPUFrameBuffer {
+ GLuint object;
+ GPUTexture *colortex;
+ GPUTexture *depthtex;
+};
+
+GPUFrameBuffer *GPU_framebuffer_create()
+{
+ GPUFrameBuffer *fb;
+
+ if (!GLEW_EXT_framebuffer_object)
+ return NULL;
+
+ fb= MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
+ glGenFramebuffersEXT(1, &fb->object);
+
+ if (!fb->object) {
+ fprintf(stderr, "GPUFFrameBuffer: framebuffer gen failed. %d\n",
+ (int)glGetError());
+ GPU_framebuffer_free(fb);
+ return NULL;
+ }
+
+ return fb;
+}
+
+int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex)
+{
+ GLenum status;
+ GLenum attachment;
+
+ if(tex->depth)
+ attachment = GL_DEPTH_ATTACHMENT_EXT;
+ else
+ attachment = GL_COLOR_ATTACHMENT0_EXT;
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ GG.currentfb = fb->object;
+
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
+ tex->target, tex->bindcode, 0);
+
+ if(tex->depth) {
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+ }
+ else {
+ glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glReadBuffer(GL_NONE);
+ }
+
+ status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ GPU_framebuffer_restore();
+ GPU_print_framebuffer_error(status);
+ return 0;
+ }
+
+ if(tex->depth)
+ fb->depthtex = tex;
+ else
+ fb->colortex = tex;
+
+ tex->fb= fb;
+
+ return 1;
+}
+
+void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
+{
+ GLenum attachment;
+
+ if(!tex->fb)
+ return;
+
+ if(GG.currentfb != tex->fb->object) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
+ GG.currentfb = tex->fb->object;
+ }
+
+ if(tex->depth) {
+ fb->depthtex = NULL;
+ attachment = GL_DEPTH_ATTACHMENT_EXT;
+ }
+ else {
+ fb->colortex = NULL;
+ attachment = GL_COLOR_ATTACHMENT0_EXT;
+ }
+
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
+ tex->target, 0, 0);
+
+ tex->fb = NULL;
+}
+
+void GPU_framebuffer_texture_bind(GPUFrameBuffer *fb, GPUTexture *tex)
+{
+ /* push attributes */
+ glPushAttrib(GL_ENABLE_BIT);
+ glPushAttrib(GL_VIEWPORT_BIT);
+ glDisable(GL_SCISSOR_TEST);
+
+ /* bind framebuffer */
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
+
+ /* push matrices and set default viewport and matrix */
+ glViewport(0, 0, tex->w, tex->h);
+ GG.currentfb = tex->fb->object;
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+}
+
+void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex)
+{
+ /* restore matrix */
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ /* restore attributes */
+ glPopAttrib();
+ glPopAttrib();
+ glEnable(GL_SCISSOR_TEST);
+}
+
+void GPU_framebuffer_free(GPUFrameBuffer *fb)
+{
+ if(fb->depthtex)
+ GPU_framebuffer_texture_detach(fb, fb->depthtex);
+ if(fb->colortex)
+ GPU_framebuffer_texture_detach(fb, fb->colortex);
+
+ if(fb->object) {
+ glDeleteFramebuffersEXT(1, &fb->object);
+
+ if (GG.currentfb == fb->object) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ GG.currentfb = 0;
+ }
+ }
+
+ MEM_freeN(fb);
+}
+
+void GPU_framebuffer_restore()
+{
+ if (GG.currentfb != 0) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ GG.currentfb = 0;
+ }
+}
+
+/* GPUShader */
+
+struct GPUShader {
+ GLhandleARB object; /* handle for full shader */
+ GLhandleARB vertex; /* handle for vertex shader */
+ GLhandleARB fragment; /* handle for fragment shader */
+ GLhandleARB lib; /* handle for libment shader */
+ int totattrib; /* total number of attributes */
+};
+
+static void shader_print_errors(char *task, char *log, const char *code)
+{
+ const char *c, *pos, *end = code + strlen(code);
+ int line = 1;
+
+ fprintf(stderr, "GPUShader: %s error:\n", task);
+
+ if(G.f & G_DEBUG) {
+ c = code;
+ while ((c < end) && (pos = strchr(c, '\n'))) {
+ fprintf(stderr, "%2d ", line);
+ fwrite(c, (pos+1)-c, 1, stderr);
+ c = pos+1;
+ line++;
+ }
+
+ fprintf(stderr, "%s", c);
+ }
+
+ fprintf(stderr, "%s\n", log);
+}
+
+GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, GPUShader *lib)
+{
+ GLint status;
+ GLcharARB log[5000];
+ GLsizei length = 0;
+ GPUShader *shader;
+
+ if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader)
+ return NULL;
+
+ shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
+
+ if(vertexcode)
+ shader->vertex = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
+ if(fragcode)
+ shader->fragment = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+ shader->object = glCreateProgramObjectARB();
+
+ if (!shader->object ||
+ (vertexcode && !shader->vertex) ||
+ (fragcode && !shader->fragment)) {
+ fprintf(stderr, "GPUShader, object creation failed.\n");
+ GPU_shader_free(shader);
+ return NULL;
+ }
+
+ if(lib && lib->lib)
+ glAttachObjectARB(shader->object, lib->lib);
+
+ if(vertexcode) {
+ glAttachObjectARB(shader->object, shader->vertex);
+ glShaderSourceARB(shader->vertex, 1, (const char**)&vertexcode, NULL);
+
+ glCompileShaderARB(shader->vertex);
+ glGetObjectParameterivARB(shader->vertex, GL_OBJECT_COMPILE_STATUS_ARB, &status);
+
+ if (!status) {
+ glValidateProgramARB(shader->vertex);
+ glGetInfoLogARB(shader->vertex, sizeof(log), &length, log);
+ shader_print_errors("compile", log, vertexcode);
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+ }
+
+ if(fragcode) {
+ glAttachObjectARB(shader->object, shader->fragment);
+ glShaderSourceARB(shader->fragment, 1, (const char**)&fragcode, NULL);
+
+ glCompileShaderARB(shader->fragment);
+ glGetObjectParameterivARB(shader->fragment, GL_OBJECT_COMPILE_STATUS_ARB, &status);
+
+ if (!status) {
+ glValidateProgramARB(shader->fragment);
+ glGetInfoLogARB(shader->fragment, sizeof(log), &length, log);
+ shader_print_errors("compile", log, fragcode);
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+ }
+
+ glLinkProgramARB(shader->object);
+ glGetObjectParameterivARB(shader->object, GL_OBJECT_LINK_STATUS_ARB, &status);
+ if (!status) {
+ glGetInfoLogARB(shader->object, sizeof(log), &length, log);
+ shader_print_errors("linking", log, fragcode);
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+
+ return shader;
+}
+
+GPUShader *GPU_shader_create_lib(const char *code)
+{
+ GLint status;
+ GLcharARB log[5000];
+ GLsizei length = 0;
+ GPUShader *shader;
+
+ if (!GLEW_ARB_vertex_shader || !GLEW_ARB_fragment_shader)
+ return NULL;
+
+ shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
+
+ shader->lib = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+
+ if (!shader->lib) {
+ fprintf(stderr, "GPUShader, object creation failed.\n");
+ GPU_shader_free(shader);
+ return NULL;
+ }
+
+ glShaderSourceARB(shader->lib, 1, (const char**)&code, NULL);
+
+ glCompileShaderARB(shader->lib);
+ glGetObjectParameterivARB(shader->lib, GL_OBJECT_COMPILE_STATUS_ARB, &status);
+
+ if (!status) {
+ glValidateProgramARB(shader->lib);
+ glGetInfoLogARB(shader->lib, sizeof(log), &length, log);
+ shader_print_errors("compile", log, code);
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+
+ return shader;
+}
+
+void GPU_shader_bind(GPUShader *shader)
+{
+ GPU_print_error("Pre Shader Bind");
+ glUseProgramObjectARB(shader->object);
+ GPU_print_error("Post Shader Bind");
+}
+
+void GPU_shader_unbind()
+{
+ GPU_print_error("Pre Shader Unbind");
+ glUseProgramObjectARB(0);
+ GPU_print_error("Post Shader Unbind");
+}
+
+void GPU_shader_free(GPUShader *shader)
+{
+ if (shader->lib)
+ glDeleteObjectARB(shader->lib);
+ if (shader->vertex)
+ glDeleteObjectARB(shader->vertex);
+ if (shader->fragment)
+ glDeleteObjectARB(shader->fragment);
+ if (shader->object)
+ glDeleteObjectARB(shader->object);
+ MEM_freeN(shader);
+}
+
+int GPU_shader_get_uniform(GPUShader *shader, char *name)
+{
+ return glGetUniformLocationARB(shader->object, name);
+}
+
+void GPU_shader_uniform_vector(GPUShader *shader, int location, int length, int arraysize, float *value)
+{
+ if(location == -1)
+ return;
+
+ GPU_print_error("Pre Uniform Vector");
+
+ if (length == 1) glUniform1fvARB(location, arraysize, value);
+ else if (length == 2) glUniform2fvARB(location, arraysize, value);
+ else if (length == 3) glUniform3fvARB(location, arraysize, value);
+ else if (length == 4) glUniform4fvARB(location, arraysize, value);
+ else if (length == 9) glUniformMatrix3fvARB(location, arraysize, 0, value);
+ else if (length == 16) glUniformMatrix4fvARB(location, arraysize, 0, value);
+
+ GPU_print_error("Post Uniform Vector");
+}
+
+void GPU_shader_uniform_texture(GPUShader *shader, int location, GPUTexture *tex)
+{
+ GLenum arbnumber;
+
+ if (tex->number >= GG.maxtextures) {
+ GPU_print_error("Not enough texture slots.");
+ return;
+ }
+
+ if(tex->number == -1)
+ return;
+
+ if(location == -1)
+ return;
+
+ GPU_print_error("Pre Uniform Texture");
+
+ arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
+
+ if (tex->number != 0) glActiveTextureARB(arbnumber);
+ glBindTexture(tex->target, tex->bindcode);
+ glUniform1iARB(location, tex->number);
+ glEnable(tex->target);
+ if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
+
+ GPU_print_error("Post Uniform Texture");
+}
+
+int GPU_shader_get_attribute(GPUShader *shader, char *name)
+{
+ int index;
+
+ GPU_print_error("Pre Get Attribute");
+
+ index = glGetAttribLocationARB(shader->object, name);
+
+ GPU_print_error("Post Get Attribute");
+
+ return index;
+}
+
+#if 0
+/* GPUPixelBuffer */
+
+typedef struct GPUPixelBuffer {
+ GLuint bindcode[2];
+ GLuint current;
+ int datasize;
+ int numbuffers;
+ int halffloat;
+} GPUPixelBuffer;
+
+void GPU_pixelbuffer_free(GPUPixelBuffer *pb)
+{
+ if (pb->bindcode[0])
+ glDeleteBuffersARB(pb->numbuffers, pb->bindcode);
+ MEM_freeN(pb);
+}
+
+GPUPixelBuffer *gpu_pixelbuffer_create(int x, int y, int halffloat, int numbuffers)
+{
+ GPUPixelBuffer *pb;
+
+ if (!GLEW_ARB_multitexture || !GLEW_EXT_pixel_buffer_object)
+ return NULL;
+
+ pb = MEM_callocN(sizeof(GPUPixelBuffer), "GPUPBO");
+ pb->datasize = x*y*4*((halffloat)? 16: 8);
+ pb->numbuffers = numbuffers;
+ pb->halffloat = halffloat;
+
+ glGenBuffersARB(pb->numbuffers, pb->bindcode);
+
+ if (!pb->bindcode[0]) {
+ fprintf(stderr, "GPUPixelBuffer allocation failed\n");
+ GPU_pixelbuffer_free(pb);
+ return NULL;
+ }
+
+ return pb;
+}
+
+void GPU_pixelbuffer_texture(GPUTexture *tex, GPUPixelBuffer *pb)
+{
+ void *pixels;
+ int i;
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
+
+ for (i = 0; i < pb->numbuffers; i++) {
+ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->bindcode[pb->current]);
+ glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb->datasize, NULL,
+ GL_STREAM_DRAW_ARB);
+
+ pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
+ /*memcpy(pixels, _oImage.data(), pb->datasize);*/
+
+ if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
+ fprintf(stderr, "Could not unmap opengl PBO\n");
+ break;
+ }
+ }
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
+}
+
+static int pixelbuffer_map_into_gpu(GLuint bindcode)
+{
+ void *pixels;
+
+ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
+ pixels = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY);
+
+ /* do stuff in pixels */
+
+ if (!glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT)) {
+ fprintf(stderr, "Could not unmap opengl PBO\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+static void pixelbuffer_copy_to_texture(GPUTexture *tex, GPUPixelBuffer *pb, GLuint bindcode)
+{
+ GLenum type = (pb->halffloat)? GL_HALF_FLOAT_NV: GL_UNSIGNED_BYTE;
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, tex->bindcode);
+ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, bindcode);
+
+ glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, tex->w, tex->h,
+ GL_RGBA, type, NULL);
+
+ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0);
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
+}
+
+void GPU_pixelbuffer_async_to_gpu(GPUTexture *tex, GPUPixelBuffer *pb)
+{
+ int newbuffer;
+
+ if (pb->numbuffers == 1) {
+ pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[0]);
+ pixelbuffer_map_into_gpu(pb->bindcode[0]);
+ }
+ else {
+ pb->current = (pb->current+1)%pb->numbuffers;
+ newbuffer = (pb->current+1)%pb->numbuffers;
+
+ pixelbuffer_map_into_gpu(pb->bindcode[newbuffer]);
+ pixelbuffer_copy_to_texture(tex, pb, pb->bindcode[pb->current]);
+ }
+}
+#endif
+
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
new file mode 100644
index 00000000000..47400f61c25
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -0,0 +1,1460 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include "GL/glew.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_listBase.h"
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
+
+#include "BKE_anim.h"
+#include "BKE_colortools.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+#include "BKE_scene.h"
+#include "BKE_texture.h"
+#include "BKE_utildefines.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_linklist.h"
+
+#include "GPU_extensions.h"
+#include "GPU_material.h"
+
+#include "gpu_codegen.h"
+
+#include <string.h>
+
+/* Structs */
+
+typedef enum DynMatProperty {
+ DYN_LAMP_CO = 1,
+ DYN_LAMP_VEC = 2,
+ DYN_LAMP_IMAT = 4,
+ DYN_LAMP_PERSMAT = 8,
+} DynMatProperty;
+
+struct GPUMaterial {
+ Scene *scene;
+ Material *ma;
+
+ /* for creating the material */
+ ListBase nodes;
+ GPUNodeLink *outlink;
+
+ /* for binding the material */
+ GPUPass *pass;
+ GPUVertexAttribs attribs;
+ int bound;
+ int builtins;
+ int alpha, obcolalpha;
+ int dynproperty;
+
+ /* for passing uniforms */
+ int viewmatloc, invviewmatloc;
+ int obmatloc, invobmatloc;
+ int obcolloc;
+
+ LinkNode *lamps;
+};
+
+struct GPULamp {
+ Scene *scene;
+ Object *ob;
+ Object *par;
+ Lamp *la;
+
+ int type, mode, lay;
+
+ float dynenergy, dyncol[3];
+ float energy, col[3];
+
+ float co[3], vec[3];
+ float dynco[3], dynvec[3];
+ float obmat[4][4];
+ float imat[4][4];
+ float dynimat[4][4];
+
+ float spotsi, spotbl, k;
+ float dist, att1, att2;
+
+ float bias, d, clipend;
+ int size;
+
+ int falloff_type;
+ struct CurveMapping *curfalloff;
+
+ float winmat[4][4];
+ float viewmat[4][4];
+ float persmat[4][4];
+ float dynpersmat[4][4];
+
+ GPUFrameBuffer *fb;
+ GPUTexture *tex;
+
+ LinkNode *materials;
+};
+
+/* Functions */
+
+static GPUMaterial *GPU_material_construct_begin(Material *ma)
+{
+ GPUMaterial *material = MEM_callocN(sizeof(GPUMaterial), "GPUMaterial");
+
+ material->ma= ma;
+
+ return material;
+}
+
+static void gpu_material_set_attrib_id(GPUMaterial *material)
+{
+ GPUVertexAttribs *attribs;
+ GPUShader *shader;
+ GPUPass *pass;
+ char name[32];
+ int a, b;
+
+ attribs= &material->attribs;
+ pass= material->pass;
+ if(!pass) {
+ attribs->totlayer = 0;
+ return;
+ }
+
+ shader= GPU_pass_shader(pass);
+ if(!shader) {
+ attribs->totlayer = 0;
+ return;
+ }
+
+ /* convert from attribute number to the actual id assigned by opengl,
+ * in case the attrib does not get a valid index back, it was probably
+ * removed by the glsl compiler by dead code elimination */
+
+ for(a=0, b=0; a<attribs->totlayer; a++) {
+ sprintf(name, "att%d", attribs->layer[a].glindex);
+ attribs->layer[a].glindex = GPU_shader_get_attribute(shader, name);
+
+ if(attribs->layer[a].glindex >= 0) {
+ attribs->layer[b] = attribs->layer[a];
+ b++;
+ }
+ }
+
+ attribs->totlayer = b;
+}
+
+static int GPU_material_construct_end(GPUMaterial *material)
+{
+ if (material->outlink) {
+ GPUNodeLink *outlink;
+ GPUShader *shader;
+
+ outlink = material->outlink;
+ material->pass = GPU_generate_pass(&material->nodes, outlink,
+ &material->attribs, &material->builtins, material->ma->id.name);
+
+ if(!material->pass)
+ return 0;
+
+ gpu_material_set_attrib_id(material);
+
+ shader = GPU_pass_shader(material->pass);
+
+ if(material->builtins & GPU_VIEW_MATRIX)
+ material->viewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_VIEW_MATRIX));
+ if(material->builtins & GPU_INVERSE_VIEW_MATRIX)
+ material->invviewmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_VIEW_MATRIX));
+ if(material->builtins & GPU_OBJECT_MATRIX)
+ material->obmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_MATRIX));
+ if(material->builtins & GPU_INVERSE_OBJECT_MATRIX)
+ material->invobmatloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_INVERSE_OBJECT_MATRIX));
+ if(material->builtins & GPU_OBCOLOR)
+ material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void GPU_material_free(Material *ma)
+{
+ LinkData *link;
+
+ for(link=ma->gpumaterial.first; link; link=link->next) {
+ GPUMaterial *material = link->data;
+
+ if(material->pass)
+ GPU_pass_free(material->pass);
+
+ BLI_linklist_free(material->lamps, NULL);
+
+ MEM_freeN(material);
+ }
+
+ BLI_freelistN(&ma->gpumaterial);
+}
+
+void GPU_material_bind(GPUMaterial *material, int lay, double time)
+{
+ if(material->pass) {
+ LinkNode *nlink;
+ GPULamp *lamp;
+
+ /* handle layer lamps */
+ for(nlink=material->lamps; nlink; nlink=nlink->next) {
+ lamp= nlink->link;
+
+ if(!(lamp->mode & LA_LAYER) || (lamp->lay & lay)) {
+ lamp->dynenergy = lamp->energy;
+ VECCOPY(lamp->dyncol, lamp->col);
+ }
+ else {
+ lamp->dynenergy = 0.0f;
+ lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f;
+ }
+ }
+
+ GPU_pass_bind(material->pass, time);
+ material->bound = 1;
+ }
+}
+
+void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4])
+{
+ if(material->pass) {
+ GPUShader *shader = GPU_pass_shader(material->pass);
+ LinkNode *nlink;
+ GPULamp *lamp;
+ float invmat[4][4], col[4];
+
+ /* handle builtins */
+ if(material->builtins & GPU_VIEW_MATRIX) {
+ GPU_shader_uniform_vector(shader, material->viewmatloc, 16, 1, (float*)viewmat);
+ }
+ if(material->builtins & GPU_INVERSE_VIEW_MATRIX) {
+ GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float*)viewinv);
+ }
+ if(material->builtins & GPU_OBJECT_MATRIX) {
+ GPU_shader_uniform_vector(shader, material->obmatloc, 16, 1, (float*)obmat);
+ }
+ if(material->builtins & GPU_INVERSE_OBJECT_MATRIX) {
+ Mat4Invert(invmat, obmat);
+ GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float*)invmat);
+ }
+ if(material->builtins & GPU_OBCOLOR) {
+ QUATCOPY(col, obcol);
+ CLAMP(col[3], 0.0f, 1.0f);
+ GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col);
+ }
+
+ /* update lamps */
+ for(nlink=material->lamps; nlink; nlink=nlink->next) {
+ lamp= nlink->link;
+
+ if(material->dynproperty & DYN_LAMP_VEC) {
+ VECCOPY(lamp->dynvec, lamp->vec);
+ Normalize(lamp->dynvec);
+ VecMulf(lamp->dynvec, -1.0f);
+ Mat4Mul3Vecfl(viewmat, lamp->dynvec);
+ }
+
+ if(material->dynproperty & DYN_LAMP_CO) {
+ VECCOPY(lamp->dynco, lamp->co);
+ Mat4MulVecfl(viewmat, lamp->dynco);
+ }
+
+ if(material->dynproperty & DYN_LAMP_IMAT)
+ Mat4MulMat4(lamp->dynimat, viewinv, lamp->imat);
+ if(material->dynproperty & DYN_LAMP_PERSMAT)
+ Mat4MulMat4(lamp->dynpersmat, viewinv, lamp->persmat);
+ }
+
+ GPU_pass_update_uniforms(material->pass);
+ }
+}
+
+void GPU_material_unbind(GPUMaterial *material)
+{
+ if (material->pass) {
+ material->bound = 0;
+ GPU_pass_unbind(material->pass);
+ }
+}
+
+int GPU_material_bound(GPUMaterial *material)
+{
+ return material->bound;
+}
+
+void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs)
+{
+ *attribs = material->attribs;
+}
+
+void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link)
+{
+ if(!material->outlink)
+ material->outlink= link;
+}
+
+void GPU_material_enable_alpha(GPUMaterial *material)
+{
+ material->alpha= 1;
+}
+
+GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[3])
+{
+ if(material->alpha || (material->obcolalpha && obcol[3] < 1.0f))
+ return GPU_BLEND_ALPHA;
+ else
+ return GPU_BLEND_SOLID;
+}
+
+void gpu_material_add_node(GPUMaterial *material, GPUNode *node)
+{
+ BLI_addtail(&material->nodes, node);
+}
+
+/* Code generation */
+
+static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist)
+{
+ GPUNodeLink *visifac, *inpr;
+
+ /* from get_lamp_visibility */
+ if(lamp->type==LA_SUN || lamp->type==LA_HEMI) {
+ mat->dynproperty |= DYN_LAMP_VEC;
+ GPU_link(mat, "lamp_visibility_sun_hemi", GPU_dynamic_uniform(lamp->dynvec), lv, dist, &visifac);
+ return visifac;
+ }
+ else {
+ mat->dynproperty |= DYN_LAMP_CO;
+ GPU_link(mat, "lamp_visibility_other", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco), lv, dist, &visifac);
+
+ if(lamp->type==LA_AREA)
+ return visifac;
+
+ switch(lamp->falloff_type)
+ {
+ case LA_FALLOFF_CONSTANT:
+ break;
+ case LA_FALLOFF_INVLINEAR:
+ GPU_link(mat, "lamp_falloff_invlinear", GPU_uniform(&lamp->dist), *dist, &visifac);
+ break;
+ case LA_FALLOFF_INVSQUARE:
+ GPU_link(mat, "lamp_falloff_invsquare", GPU_uniform(&lamp->dist), *dist, &visifac);
+ break;
+ case LA_FALLOFF_SLIDERS:
+ GPU_link(mat, "lamp_falloff_sliders", GPU_uniform(&lamp->dist), GPU_uniform(&lamp->att1), GPU_uniform(&lamp->att2), *dist, &visifac);
+ break;
+ case LA_FALLOFF_CURVE:
+ {
+ float *array;
+ int size;
+
+ curvemapping_table_RGBA(lamp->curfalloff, &array, &size);
+ GPU_link(mat, "lamp_falloff_curve", GPU_uniform(&lamp->dist), GPU_texture(size, array), *dist, &visifac);
+ }
+ break;
+ }
+
+ if(lamp->mode & LA_SPHERE)
+ GPU_link(mat, "lamp_visibility_sphere", GPU_uniform(&lamp->dist), *dist, visifac, &visifac);
+
+ if(lamp->type == LA_SPOT) {
+ if(lamp->mode & LA_SQUARE) {
+ mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_IMAT;
+ GPU_link(mat, "lamp_visibility_spot_square", GPU_dynamic_uniform(lamp->dynvec), GPU_dynamic_uniform((float*)lamp->dynimat), *lv, &inpr);
+ }
+ else {
+ mat->dynproperty |= DYN_LAMP_VEC;
+ GPU_link(mat, "lamp_visibility_spot_circle", GPU_dynamic_uniform(lamp->dynvec), *lv, &inpr);
+ }
+
+ GPU_link(mat, "lamp_visibility_spot", GPU_uniform(&lamp->spotsi), GPU_uniform(&lamp->spotbl), inpr, visifac, &visifac);
+ }
+
+ GPU_link(mat, "lamp_visibility_clamp", visifac, &visifac);
+
+ return visifac;
+ }
+}
+
+#if 0
+static void area_lamp_vectors(LampRen *lar)
+{
+ float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey, multifac;
+
+ /* make it smaller, so area light can be multisampled */
+ multifac= 1.0f/sqrt((float)lar->ray_totsamp);
+ xsize *= multifac;
+ ysize *= multifac;
+
+ /* corner vectors */
+ lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
+ lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
+ lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
+
+ /* corner vectors */
+ lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
+ lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
+ lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
+
+ /* corner vectors */
+ lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0];
+ lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1];
+ lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2];
+
+ /* corner vectors */
+ lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0];
+ lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1];
+ lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2];
+ /* only for correction button size, matrix size works on energy */
+ lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize);
+}
+#endif
+
+static void ramp_blend(GPUMaterial *mat, GPUNodeLink *fac, GPUNodeLink *col1, GPUNodeLink *col2, int type, GPUNodeLink **outcol)
+{
+ static char *names[] = {"mix_blend", "mix_add", "mix_mult", "mix_sub",
+ "mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light",
+ "mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat",
+ "mix_val", "mix_color"};
+
+ GPU_link(mat, names[type], fac, col1, col2, outcol);
+}
+
+static void do_colorband_blend(GPUMaterial *mat, ColorBand *coba, GPUNodeLink *fac, float rampfac, int type, GPUNodeLink *incol, GPUNodeLink **outcol)
+{
+ GPUNodeLink *tmp, *alpha, *col;
+ float *array;
+ int size;
+
+ /* do colorband */
+ colorband_table_RGBA(coba, &array, &size);
+ GPU_link(mat, "valtorgb", fac, GPU_texture(size, array), &col, &tmp);
+
+ /* use alpha in fac */
+ GPU_link(mat, "mtex_alpha_from_col", col, &alpha);
+ GPU_link(mat, "math_multiply", alpha, GPU_uniform(&rampfac), &fac);
+
+ /* blending method */
+ ramp_blend(mat, fac, incol, col, type, outcol);
+}
+
+static void ramp_diffuse_result(GPUShadeInput *shi, GPUNodeLink **diff)
+{
+ Material *ma= shi->mat;
+ GPUMaterial *mat= shi->gpumat;
+ GPUNodeLink *fac;
+
+ if(!(G.fileflags & G_FILE_GLSL_NO_RAMPS)) {
+ if(ma->ramp_col) {
+ if(ma->rampin_col==MA_RAMP_IN_RESULT) {
+ GPU_link(mat, "ramp_rgbtobw", *diff, &fac);
+
+ /* colorband + blend */
+ do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, *diff, diff);
+ }
+ }
+ }
+}
+
+static void add_to_diffuse(GPUMaterial *mat, Material *ma, GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *rgb, GPUNodeLink **diff)
+{
+ GPUNodeLink *fac, *tmp, *addcol;
+
+ if(!(G.fileflags & G_FILE_GLSL_NO_RAMPS) &&
+ ma->ramp_col && (ma->mode & MA_RAMP_COL)) {
+ /* MA_RAMP_IN_RESULT is exceptional */
+ if(ma->rampin_col==MA_RAMP_IN_RESULT) {
+ addcol = shi->rgb;
+ }
+ else {
+ /* input */
+ switch(ma->rampin_col) {
+ case MA_RAMP_IN_ENERGY:
+ GPU_link(mat, "ramp_rgbtobw", rgb, &fac);
+ break;
+ case MA_RAMP_IN_SHADER:
+ fac= is;
+ break;
+ case MA_RAMP_IN_NOR:
+ GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
+ break;
+ default:
+ GPU_link(mat, "set_value_zero", &fac);
+ break;
+ }
+
+ /* colorband + blend */
+ do_colorband_blend(mat, ma->ramp_col, fac, ma->rampfac_col, ma->rampblend_col, shi->rgb, &addcol);
+ }
+ }
+ else
+ addcol = shi->rgb;
+
+ /* output to */
+ GPU_link(mat, "shade_madd", *diff, rgb, addcol, diff);
+}
+
+static void ramp_spec_result(GPUShadeInput *shi, GPUNodeLink **spec)
+{
+ Material *ma= shi->mat;
+ GPUMaterial *mat= shi->gpumat;
+ GPUNodeLink *fac;
+
+ if(!(G.fileflags & G_FILE_GLSL_NO_RAMPS) &&
+ ma->ramp_spec && ma->rampin_spec==MA_RAMP_IN_RESULT) {
+ GPU_link(mat, "ramp_rgbtobw", *spec, &fac);
+
+ /* colorband + blend */
+ do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
+ }
+}
+
+static void do_specular_ramp(GPUShadeInput *shi, GPUNodeLink *is, GPUNodeLink *t, GPUNodeLink **spec)
+{
+ Material *ma= shi->mat;
+ GPUMaterial *mat= shi->gpumat;
+ GPUNodeLink *fac, *tmp;
+
+ *spec = shi->specrgb;
+
+ /* MA_RAMP_IN_RESULT is exception */
+ if(ma->ramp_spec && (ma->rampin_spec!=MA_RAMP_IN_RESULT)) {
+
+ /* input */
+ switch(ma->rampin_spec) {
+ case MA_RAMP_IN_ENERGY:
+ fac = t;
+ break;
+ case MA_RAMP_IN_SHADER:
+ fac = is;
+ break;
+ case MA_RAMP_IN_NOR:
+ GPU_link(mat, "vec_math_dot", shi->view, shi->vn, &tmp, &fac);
+ break;
+ default:
+ GPU_link(mat, "set_value_zero", &fac);
+ break;
+ }
+
+ /* colorband + blend */
+ do_colorband_blend(mat, ma->ramp_spec, fac, ma->rampfac_spec, ma->rampblend_spec, *spec, spec);
+ }
+}
+
+static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *lamp)
+{
+ Material *ma= shi->mat;
+ GPUMaterial *mat= shi->gpumat;
+ GPUNodeLink *lv, *dist, *visifac, *is, *inp, *i, *vn, *view;
+ GPUNodeLink *outcol, *specfac, *t, *shadfac;
+ float one = 1.0f;
+
+ if((lamp->mode & LA_ONLYSHADOW) && !(ma->mode & MA_SHADOW))
+ return;
+
+ vn= shi->vn;
+ view= shi->view;
+
+ visifac= lamp_get_visibility(mat, lamp, &lv, &dist);
+
+ /*if(ma->mode & MA_TANGENT_V)
+ GPU_link(mat, "shade_tangent_v", lv, GPU_attribute(CD_TANGENT, ""), &vn);*/
+
+ GPU_link(mat, "shade_inp", vn, lv, &inp);
+
+ if(lamp->mode & LA_NO_DIFF) {
+ GPU_link(mat, "shade_is_no_diffuse", &is);
+ }
+ else if(lamp->type == LA_HEMI) {
+ GPU_link(mat, "shade_is_hemi", inp, &is);
+ }
+ else {
+ if(lamp->type == LA_AREA) {
+ float area[4][4], areasize;
+
+ memset(&area, 0, sizeof(area));
+ memset(&areasize, 0, sizeof(areasize));
+ mat->dynproperty |= DYN_LAMP_VEC|DYN_LAMP_CO;
+ GPU_link(mat, "shade_inp_area", GPU_builtin(GPU_VIEW_POSITION), GPU_dynamic_uniform(lamp->dynco), GPU_dynamic_uniform(lamp->dynvec), vn, GPU_uniform((float*)area),
+ GPU_uniform(&areasize), GPU_uniform(&lamp->k), &inp);
+ }
+
+ is= inp; /* Lambert */
+
+ if(!(G.fileflags & G_FILE_GLSL_NO_SHADERS)) {
+ if(ma->diff_shader==MA_DIFF_ORENNAYAR)
+ GPU_link(mat, "shade_diffuse_oren_nayer", inp, vn, lv, view, GPU_uniform(&ma->roughness), &is);
+ else if(ma->diff_shader==MA_DIFF_TOON)
+ GPU_link(mat, "shade_diffuse_toon", vn, lv, view, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
+ else if(ma->diff_shader==MA_DIFF_MINNAERT)
+ GPU_link(mat, "shade_diffuse_minnaert", inp, vn, view, GPU_uniform(&ma->darkness), &is);
+ else if(ma->diff_shader==MA_DIFF_FRESNEL)
+ GPU_link(mat, "shade_diffuse_fresnel", vn, lv, view, GPU_uniform(&ma->param[0]), GPU_uniform(&ma->param[1]), &is);
+ }
+ }
+
+ if(!(G.fileflags & G_FILE_GLSL_NO_SHADERS))
+ if(ma->shade_flag & MA_CUBIC)
+ GPU_link(mat, "shade_cubic", is, &is);
+
+ i = is;
+ GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i);
+
+ vn = shi->vn;
+ /*if(ma->mode & MA_TANGENT_VN)
+ GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);*/
+
+ /* this replaces if(i > 0.0) conditional until that is supported */
+ // done in shade_visifac now, GPU_link(mat, "mtex_value_clamp_positive", i, &i);
+
+ if((ma->mode & MA_SHADOW) && GPU_lamp_has_shadow_buffer(lamp)) {
+ if(!(G.fileflags & G_FILE_GLSL_NO_SHADOWS)) {
+ mat->dynproperty |= DYN_LAMP_PERSMAT;
+
+ GPU_link(mat, "test_shadowbuf",
+ GPU_builtin(GPU_VIEW_POSITION),
+ GPU_dynamic_texture(lamp->tex),
+ GPU_dynamic_uniform((float*)lamp->dynpersmat),
+ GPU_uniform(&lamp->bias), inp, &shadfac);
+
+ if(lamp->mode & LA_ONLYSHADOW) {
+ GPU_link(mat, "shade_only_shadow", i, shadfac,
+ GPU_dynamic_uniform(&lamp->dynenergy), shi->rgb, shi->specrgb,
+ shr->diff, shr->spec, &shr->diff, &shr->spec);
+
+ BLI_linklist_append(&mat->lamps, lamp);
+ BLI_linklist_append(&lamp->materials, ma);
+ return;
+ }
+
+ GPU_link(mat, "math_multiply", i, shadfac, &i);
+ }
+ }
+ else if((G.fileflags & G_FILE_GLSL_NO_SHADOWS) && (lamp->mode & LA_ONLYSHADOW)) {
+ BLI_linklist_append(&mat->lamps, lamp);
+ BLI_linklist_append(&lamp->materials, ma);
+ return;
+ }
+ else
+ GPU_link(mat, "set_value", GPU_uniform(&one), &shadfac);
+
+ if(GPU_link_changed(shi->refl) || ma->ref != 0.0f) {
+ if(!(lamp->mode & LA_NO_DIFF)) {
+ GPUNodeLink *rgb;
+ GPU_link(mat, "shade_mul_value", i, GPU_dynamic_uniform(lamp->dyncol), &rgb);
+ add_to_diffuse(mat, ma, shi, is, rgb, &shr->diff);
+ }
+ }
+
+ if(G.fileflags & G_FILE_GLSL_NO_SHADERS);
+ else if(!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) &&
+ (GPU_link_changed(shi->spec) || ma->spec != 0.0f)) {
+ if(lamp->type == LA_HEMI) {
+ GPU_link(mat, "shade_hemi_spec", vn, lv, view, GPU_uniform(&ma->spec), shi->har, visifac, &t);
+ GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), shi->specrgb, &outcol);
+ GPU_link(mat, "shade_add", shr->spec, outcol, &shr->spec);
+ }
+ else {
+ if(ma->spec_shader==MA_SPEC_PHONG)
+ GPU_link(mat, "shade_phong_spec", vn, lv, view, shi->har, &specfac);
+ else if(ma->spec_shader==MA_SPEC_COOKTORR)
+ GPU_link(mat, "shade_cooktorr_spec", vn, lv, view, shi->har, &specfac);
+ else if(ma->spec_shader==MA_SPEC_BLINN)
+ GPU_link(mat, "shade_blinn_spec", vn, lv, view, GPU_uniform(&ma->refrac), shi->har, &specfac);
+ else if(ma->spec_shader==MA_SPEC_WARDISO)
+ GPU_link(mat, "shade_wardiso_spec", vn, lv, view, GPU_uniform(&ma->rms), &specfac);
+ else
+ GPU_link(mat, "shade_toon_spec", vn, lv, view, GPU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac);
+
+ if(lamp->type==LA_AREA)
+ GPU_link(mat, "shade_spec_area_inp", specfac, inp, &specfac);
+
+ GPU_link(mat, "shade_spec_t", shadfac, shi->spec, visifac, specfac, &t);
+
+ if(ma->mode & MA_RAMP_SPEC) {
+ GPUNodeLink *spec;
+ do_specular_ramp(shi, specfac, t, &spec);
+ GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), spec, &outcol);
+ GPU_link(mat, "shade_add", shr->spec, outcol, &shr->spec);
+ }
+ else {
+ GPU_link(mat, "shade_add_spec", t, GPU_dynamic_uniform(lamp->dyncol), shi->specrgb, &outcol);
+ GPU_link(mat, "shade_add", shr->spec, outcol, &shr->spec);
+ }
+ }
+ }
+
+ BLI_linklist_append(&mat->lamps, lamp);
+ BLI_linklist_append(&lamp->materials, ma);
+}
+
+static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
+{
+ Base *base;
+ Object *ob;
+ Scene *sce;
+ GPULamp *lamp;
+
+ for(SETLOOPER(shi->gpumat->scene, base)) {
+ ob= base->object;
+
+ if(ob->type==OB_LAMP) {
+ lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, NULL);
+ if(lamp)
+ shade_one_light(shi, shr, lamp);
+ }
+
+ if (ob->transflag & OB_DUPLI) {
+ DupliObject *dob;
+ ListBase *lb = object_duplilist(shi->gpumat->scene, ob);
+
+ for(dob=lb->first; dob; dob=dob->next) {
+ Object *ob = dob->ob;
+
+ if(ob->type==OB_LAMP) {
+ Mat4CpyMat4(ob->obmat, dob->mat);
+
+ lamp = GPU_lamp_from_blender(shi->gpumat->scene, ob, base->object);
+ if(lamp)
+ shade_one_light(shi, shr, lamp);
+ }
+ }
+
+ free_object_duplilist(lb);
+ }
+ }
+}
+
+static void texture_rgb_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, GPUNodeLink **in)
+{
+ switch(blendtype) {
+ case MTEX_BLEND:
+ GPU_link(mat, "mtex_rgb_blend", out, tex, fact, facg, in);
+ break;
+ case MTEX_MUL:
+ GPU_link(mat, "mtex_rgb_mul", out, tex, fact, facg, in);
+ break;
+ case MTEX_SCREEN:
+ GPU_link(mat, "mtex_rgb_screen", out, tex, fact, facg, in);
+ break;
+ case MTEX_OVERLAY:
+ GPU_link(mat, "mtex_rgb_overlay", out, tex, fact, facg, in);
+ break;
+ case MTEX_SUB:
+ GPU_link(mat, "mtex_rgb_sub", out, tex, fact, facg, in);
+ break;
+ case MTEX_ADD:
+ GPU_link(mat, "mtex_rgb_add", out, tex, fact, facg, in);
+ break;
+ case MTEX_DIV:
+ GPU_link(mat, "mtex_rgb_div", out, tex, fact, facg, in);
+ break;
+ case MTEX_DIFF:
+ GPU_link(mat, "mtex_rgb_diff", out, tex, fact, facg, in);
+ break;
+ case MTEX_DARK:
+ GPU_link(mat, "mtex_rgb_dark", out, tex, fact, facg, in);
+ break;
+ case MTEX_LIGHT:
+ GPU_link(mat, "mtex_rgb_light", out, tex, fact, facg, in);
+ break;
+ case MTEX_BLEND_HUE:
+ GPU_link(mat, "mtex_rgb_hue", out, tex, fact, facg, in);
+ break;
+ case MTEX_BLEND_SAT:
+ GPU_link(mat, "mtex_rgb_sat", out, tex, fact, facg, in);
+ break;
+ case MTEX_BLEND_VAL:
+ GPU_link(mat, "mtex_rgb_val", out, tex, fact, facg, in);
+ break;
+ case MTEX_BLEND_COLOR:
+ GPU_link(mat, "mtex_rgb_color", out, tex, fact, facg, in);
+ break;
+ default:
+ GPU_link(mat, "set_rgb_zero", &in);
+ break;
+ }
+}
+
+static void texture_value_blend(GPUMaterial *mat, GPUNodeLink *tex, GPUNodeLink *out, GPUNodeLink *fact, GPUNodeLink *facg, int blendtype, int flip, GPUNodeLink **in)
+{
+ float flipf = (flip)? 1.0f: 0.0;
+
+ switch(blendtype) {
+ case MTEX_BLEND:
+ GPU_link(mat, "mtex_value_blend", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ break;
+ case MTEX_MUL:
+ GPU_link(mat, "mtex_value_mul", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ break;
+ case MTEX_SCREEN:
+ GPU_link(mat, "mtex_value_screen", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ break;
+ case MTEX_SUB:
+ GPU_link(mat, "mtex_value_sub", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ break;
+ case MTEX_ADD:
+ GPU_link(mat, "mtex_value_add", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ break;
+ case MTEX_DIV:
+ GPU_link(mat, "mtex_value_div", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ break;
+ case MTEX_DIFF:
+ GPU_link(mat, "mtex_value_diff", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ break;
+ case MTEX_DARK:
+ GPU_link(mat, "mtex_value_dark", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ break;
+ case MTEX_LIGHT:
+ GPU_link(mat, "mtex_value_light", out, tex, fact, facg, GPU_uniform(&flipf), in);
+ break;
+ default:
+ GPU_link(mat, "set_value_zero", &in);
+ break;
+ }
+}
+
+static void do_material_tex(GPUShadeInput *shi)
+{
+ Material *ma= shi->mat;
+ GPUMaterial *mat= shi->gpumat;
+ MTex *mtex;
+ Tex *tex;
+ GPUNodeLink *texco, *tin, *trgb, *tnor, *tcol, *stencil, *tnorfac;
+ GPUNodeLink *texco_norm, *texco_orco, *texco_object, *texco_tangent;
+ GPUNodeLink *texco_global, *texco_uv = NULL;
+ GPUNodeLink *colfac, *newnor, *varfac, *orn;
+ char *lastuvname = NULL;
+ float one = 1.0f, norfac, ofs[3];
+ int tex_nr, rgbnor, talpha;
+
+ GPU_link(mat, "set_value", GPU_uniform(&one), &stencil);
+
+ GPU_link(mat, "texco_norm", GPU_builtin(GPU_VIEW_NORMAL), &texco_norm);
+ GPU_link(mat, "texco_orco", GPU_attribute(CD_ORCO, ""), &texco_orco);
+ GPU_link(mat, "texco_object", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
+ GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
+ GPU_builtin(GPU_VIEW_POSITION), &texco_object);
+ GPU_link(mat, "texco_tangent", GPU_attribute(CD_TANGENT, ""), &texco_tangent);
+ GPU_link(mat, "texco_global", GPU_builtin(GPU_INVERSE_VIEW_MATRIX),
+ GPU_builtin(GPU_VIEW_POSITION), &texco_global);
+
+ orn= texco_norm;
+
+ /* go over texture slots */
+ for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
+ /* separate tex switching */
+ if(ma->septex & (1<<tex_nr)) continue;
+
+ if(ma->mtex[tex_nr]) {
+ mtex= ma->mtex[tex_nr];
+
+ tex= mtex->tex;
+ if(tex==0) continue;
+
+ /* which coords */
+ if(mtex->texco==TEXCO_ORCO)
+ texco= texco_orco;
+ else if(mtex->texco==TEXCO_OBJECT)
+ texco= texco_object;
+ else if(mtex->texco==TEXCO_NORM)
+ texco= texco_norm;
+ else if(mtex->texco==TEXCO_TANGENT)
+ texco= texco_object;
+ else if(mtex->texco==TEXCO_GLOB)
+ texco= texco_global;
+ else if(mtex->texco==TEXCO_REFL)
+ texco= shi->ref;
+ else if(mtex->texco==TEXCO_UV) {
+ if(1) { //!(texco_uv && strcmp(mtex->uvname, lastuvname) == 0)) {
+ GPU_link(mat, "texco_uv", GPU_attribute(CD_MTFACE, mtex->uvname), &texco_uv);
+ lastuvname = mtex->uvname;
+ }
+ texco= texco_uv;
+ }
+ else
+ continue;
+
+ /* in case of uv, this would just undo a multiplication in texco_uv */
+ if(mtex->texco != TEXCO_UV)
+ GPU_link(mat, "mtex_2d_mapping", texco, &texco);
+
+ if(mtex->size[0] != 1.0f || mtex->size[1] != 1.0f || mtex->size[2] != 1.0f)
+ GPU_link(mat, "mtex_mapping_size", texco, GPU_uniform(mtex->size), &texco);
+
+ ofs[0] = mtex->ofs[0] + 0.5f - 0.5f*mtex->size[0];
+ ofs[1] = mtex->ofs[1] + 0.5f - 0.5f*mtex->size[1];
+ ofs[2] = 0.0f;
+ if(ofs[0] != 0.0f || ofs[1] != 0.0f || ofs[2] != 0.0f)
+ GPU_link(mat, "mtex_mapping_ofs", texco, GPU_uniform(ofs), &texco);
+
+ if(tex && tex->type == TEX_IMAGE && tex->ima) {
+ GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, NULL), &tin, &trgb, &tnor);
+ rgbnor= TEX_RGB;
+ talpha= 1;
+ }
+ else continue;
+
+ /* texture output */
+ if((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
+ GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
+ rgbnor -= TEX_RGB;
+ }
+
+ if(mtex->texflag & MTEX_NEGATIVE) {
+ if(rgbnor & TEX_RGB)
+ GPU_link(mat, "mtex_rgb_invert", trgb, &trgb);
+ else
+ GPU_link(mat, "mtex_value_invert", tin, &tin);
+ }
+
+ if(mtex->texflag & MTEX_STENCIL) {
+ if(rgbnor & TEX_RGB)
+ GPU_link(mat, "mtex_rgb_stencil", stencil, trgb, &stencil, &trgb);
+ else
+ GPU_link(mat, "mtex_value_stencil", stencil, tin, &stencil, &tin);
+ }
+
+ /* mapping */
+ if(mtex->mapto & (MAP_COL+MAP_COLSPEC)) {
+ /* stencil maps on the texture control slider, not texture intensity value */
+ if(mtex->colfac == 1.0f)
+ colfac = stencil;
+ else
+ GPU_link(mat, "math_multiply", GPU_uniform(&mtex->colfac), stencil, &colfac);
+
+ if((rgbnor & TEX_RGB)==0) {
+ GPU_link(mat, "set_rgb", GPU_uniform(&mtex->r), &tcol);
+ }
+ else {
+ GPU_link(mat, "set_rgba", trgb, &tcol);
+
+ if(mtex->mapto & MAP_ALPHA)
+ GPU_link(mat, "set_value", stencil, &tin);
+ else
+ GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
+ }
+
+ if(mtex->mapto & MAP_COL)
+ texture_rgb_blend(mat, tcol, shi->rgb, tin, colfac, mtex->blendtype, &shi->rgb);
+
+ if(!(G.fileflags & G_FILE_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_COLSPEC))
+ texture_rgb_blend(mat, tcol, shi->specrgb, tin, colfac, mtex->blendtype, &shi->specrgb);
+ }
+
+ if(!(G.fileflags & G_FILE_GLSL_NO_EXTRA_TEX) && (mtex->mapto & MAP_NORM)) {
+ if(mtex->maptoneg & MAP_NORM) tex->norfac= -mtex->norfac;
+ else tex->norfac= mtex->norfac;
+
+ if((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) {
+ tex->norfac = mtex->norfac;
+
+ if(mtex->maptoneg & MAP_NORM)
+ GPU_link(mat, "mtex_negate_texnormal", tnor, &tnor);
+
+ if(mtex->normapspace == MTEX_NSPACE_TANGENT)
+ GPU_link(mat, "mtex_nspace_tangent", GPU_attribute(CD_TANGENT, ""), shi->vn, tnor, &newnor);
+ else
+ newnor = tnor;
+
+ norfac = MIN2(mtex->norfac, 1.0);
+ if(norfac == 1.0f && !GPU_link_changed(stencil)) {
+ shi->vn = newnor;
+ }
+ else {
+ tnorfac = GPU_uniform(&norfac);
+
+ if(GPU_link_changed(stencil))
+ GPU_link(mat, "math_multiply", tnorfac, stencil, &tnorfac);
+
+ GPU_link(mat, "mtex_blend_normal", tnorfac, shi->vn, newnor, &shi->vn);
+ }
+ }
+
+ GPU_link(mat, "vec_math_negate", shi->vn, &orn);
+ GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
+ }
+
+ if((mtex->mapto & MAP_VARS)) {
+ if(mtex->varfac == 1.0f)
+ varfac = stencil;
+ else
+ GPU_link(mat, "math_multiply", GPU_uniform(&mtex->varfac), stencil, &varfac);
+
+ if(rgbnor & TEX_RGB) {
+ if(talpha)
+ GPU_link(mat, "mtex_alpha_from_col", trgb, &tin);
+ else
+ GPU_link(mat, "mtex_rgbtoint", trgb, &tin);
+ }
+
+ if(!(G.fileflags & G_FILE_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_REF) {
+ int flip= mtex->maptoneg & MAP_REF;
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->refl, tin, varfac, mtex->blendtype, flip, &shi->refl);
+ GPU_link(mat, "mtex_value_clamp_positive", shi->refl, &shi->refl);
+ }
+ if(!(G.fileflags & G_FILE_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_SPEC) {
+ int flip= mtex->maptoneg & MAP_SPEC;
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->spec, tin, varfac, mtex->blendtype, flip, &shi->spec);
+ GPU_link(mat, "mtex_value_clamp_positive", shi->spec, &shi->spec);
+ }
+ if(!(G.fileflags & G_FILE_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_EMIT) {
+ int flip= mtex->maptoneg & MAP_EMIT;
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->emit, tin, varfac, mtex->blendtype, flip, &shi->emit);
+ GPU_link(mat, "mtex_value_clamp_positive", shi->emit, &shi->emit);
+ }
+ if(!(G.fileflags & G_FILE_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_HAR) {
+ int flip= mtex->maptoneg & MAP_HAR;
+ GPU_link(mat, "mtex_har_divide", shi->har, &shi->har);
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->har, tin, varfac, mtex->blendtype, flip, &shi->har);
+ GPU_link(mat, "mtex_har_multiply_clamp", shi->har, &shi->har);
+ }
+ if(mtex->mapto & MAP_ALPHA) {
+ int flip= mtex->maptoneg & MAP_ALPHA;
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->alpha, tin, varfac, mtex->blendtype, flip, &shi->alpha);
+ GPU_link(mat, "mtex_value_clamp", shi->alpha, &shi->alpha);
+ }
+ if(!(G.fileflags & G_FILE_GLSL_NO_EXTRA_TEX) && mtex->mapto & MAP_AMB) {
+ int flip= mtex->maptoneg & MAP_AMB;
+ texture_value_blend(mat, GPU_uniform(&mtex->def_var), shi->amb, tin, varfac, mtex->blendtype, flip, &shi->amb);
+ GPU_link(mat, "mtex_value_clamp", shi->amb, &shi->amb);
+ }
+ }
+ }
+ }
+}
+
+void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
+{
+ float hard = ma->har;
+
+ memset(shi, 0, sizeof(*shi));
+
+ shi->gpumat = mat;
+ shi->mat = ma;
+
+ GPU_link(mat, "set_rgb", GPU_uniform(&ma->r), &shi->rgb);
+ GPU_link(mat, "set_rgb", GPU_uniform(&ma->specr), &shi->specrgb);
+ GPU_link(mat, "shade_norm", GPU_builtin(GPU_VIEW_NORMAL), &shi->vn);
+ GPU_link(mat, "set_value", GPU_uniform(&ma->alpha), &shi->alpha);
+ GPU_link(mat, "set_value", GPU_uniform(&ma->ref), &shi->refl);
+ GPU_link(mat, "set_value", GPU_uniform(&ma->spec), &shi->spec);
+ GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit);
+ GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har);
+ GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb);
+ GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view);
+ GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol);
+ GPU_link(mat, "texco_refl", shi->vn, shi->view, &shi->ref);
+}
+
+void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
+{
+ GPUMaterial *mat= shi->gpumat;
+ GPUNodeLink *emit, *ulinfac, *ulogfac, *mistfac;
+ Material *ma= shi->mat;
+ World *world= mat->scene->world;
+ float linfac, logfac, misttype;
+
+ memset(shr, 0, sizeof(*shr));
+
+ if(ma->mode & MA_VERTEXCOLP)
+ shi->rgb = shi->vcol;
+
+ do_material_tex(shi);
+
+ if(ma->mode & MA_ZTRA)
+ GPU_material_enable_alpha(mat);
+
+ if((G.fileflags & G_FILE_GLSL_NO_LIGHTS) || (ma->mode & MA_SHLESS)) {
+ shr->combined = shi->rgb;
+ shr->alpha = shi->alpha;
+ }
+ else {
+ if(GPU_link_changed(shi->emit) || ma->emit != 0.0f) {
+ if((ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP))== MA_VERTEXCOL) {
+ GPU_link(mat, "shade_add", shi->emit, shi->vcol, &emit);
+ GPU_link(mat, "shade_mul", emit, shi->rgb, &shr->diff);
+ }
+ else
+ GPU_link(mat, "shade_mul_value", shi->emit, shi->rgb, &shr->diff);
+ }
+ else
+ GPU_link(mat, "set_rgb_zero", &shr->diff);
+
+ GPU_link(mat, "set_rgb_zero", &shr->spec);
+
+ material_lights(shi, shr);
+
+ shr->combined = shr->diff;
+ shr->alpha = shi->alpha;
+
+ if(world) {
+ /* exposure correction */
+ if(world->exp!=0.0f || world->range!=1.0f) {
+ linfac= 1.0 + pow((2.0*world->exp + 0.5), -10);
+ logfac= log((linfac-1.0)/linfac)/world->range;
+
+ GPU_link(mat, "set_value", GPU_uniform(&linfac), &ulinfac);
+ GPU_link(mat, "set_value", GPU_uniform(&logfac), &ulogfac);
+
+ GPU_link(mat, "shade_exposure_correct", shr->combined,
+ ulinfac, ulogfac, &shr->combined);
+ GPU_link(mat, "shade_exposure_correct", shr->spec,
+ ulinfac, ulogfac, &shr->spec);
+ }
+
+ /* ambient color */
+ if(world->ambr!=0.0f || world->ambg!=0.0f || world->ambb!=0.0f) {
+ if(GPU_link_changed(shi->amb) || ma->amb != 0.0f)
+ GPU_link(mat, "shade_maddf", shr->combined, GPU_uniform(&ma->amb),
+ GPU_uniform(&world->ambr), &shr->combined);
+ }
+ }
+
+ if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined);
+ if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec);
+
+ if(GPU_link_changed(shi->spec) || ma->spec != 0.0f)
+ GPU_link(mat, "shade_add", shr->combined, shr->spec, &shr->combined);
+ }
+
+ GPU_link(mat, "mtex_alpha_to_col", shr->combined, shr->alpha, &shr->combined);
+
+ if(ma->shade_flag & MA_OBCOLOR)
+ GPU_link(mat, "shade_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
+
+ if(world && (world->mode & WO_MIST) && !(ma->mode & MA_NOMIST)) {
+ misttype = world->mistype;
+
+ GPU_link(mat, "shade_mist_factor", GPU_builtin(GPU_VIEW_POSITION),
+ GPU_uniform(&world->miststa), GPU_uniform(&world->mistdist),
+ GPU_uniform(&misttype), GPU_uniform(&world->misi), &mistfac);
+
+ GPU_link(mat, "mix_blend", mistfac, shr->combined,
+ GPU_uniform(&world->horr), &shr->combined);
+ }
+
+ if(!(ma->mode & MA_ZTRA)) {
+ if(world && (GPU_link_changed(shr->alpha) || ma->alpha != 1.0f))
+ GPU_link(mat, "shade_world_mix", GPU_uniform(&world->horr),
+ shr->combined, &shr->combined);
+
+ GPU_link(mat, "shade_alpha_opaque", shr->combined, &shr->combined);
+ }
+
+ if(ma->shade_flag & MA_OBCOLOR) {
+ mat->obcolalpha = 1;
+ GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
+ }
+}
+
+GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
+{
+ GPUShadeInput shi;
+ GPUShadeResult shr;
+
+ GPU_shadeinput_set(mat, ma, &shi);
+ GPU_shaderesult_set(&shi, &shr);
+
+ return shr.combined;
+}
+
+GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
+{
+ GPUMaterial *mat;
+ GPUNodeLink *outlink;
+ LinkData *link;
+
+ for(link=ma->gpumaterial.first; link; link=link->next)
+ if(((GPUMaterial*)link->data)->scene == scene)
+ return link->data;
+
+ mat = GPU_material_construct_begin(ma);
+ mat->scene = scene;
+
+ if(!(G.fileflags & G_FILE_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
+ ntreeGPUMaterialNodes(ma->nodetree, mat);
+ }
+ else {
+ outlink = GPU_blender_material(mat, ma);
+ GPU_material_output_link(mat, outlink);
+ }
+
+ /*if(!GPU_material_construct_end(mat)) {
+ GPU_material_free(mat);
+ mat= NULL;
+ return 0;
+ }*/
+
+ GPU_material_construct_end(mat);
+
+ link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
+ link->data = mat;
+ BLI_addtail(&ma->gpumaterial, link);
+
+ return mat;
+}
+
+void GPU_materials_free()
+{
+ Object *ob;
+ Material *ma;
+ extern Material defmaterial;
+
+ for(ma=G.main->mat.first; ma; ma=ma->id.next)
+ GPU_material_free(ma);
+
+ GPU_material_free(&defmaterial);
+
+ for(ob=G.main->object.first; ma; ma=ma->id.next)
+ GPU_lamp_free(ob);
+}
+
+/* Lamps and shadow buffers */
+
+void GPU_lamp_update(GPULamp *lamp, float obmat[][4])
+{
+ float mat[4][4];
+
+ Mat4CpyMat4(mat, obmat);
+ Mat4Ortho(mat);
+
+ VECCOPY(lamp->vec, mat[2]);
+ VECCOPY(lamp->co, mat[3]);
+ Mat4CpyMat4(lamp->obmat, mat);
+ Mat4Invert(lamp->imat, mat);
+}
+
+static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp)
+{
+ float temp, angle, pixsize, wsize;
+
+ lamp->scene = scene;
+ lamp->ob = ob;
+ lamp->par = par;
+ lamp->la = la;
+ lamp->lay = ob->lay;
+
+ /* add_render_lamp */
+ lamp->mode = la->mode;
+ lamp->type = la->type;
+
+ lamp->energy = la->energy;
+ if(lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
+
+ lamp->col[0]= la->r*lamp->energy;
+ lamp->col[1]= la->g*lamp->energy;
+ lamp->col[2]= la->b*lamp->energy;
+
+ GPU_lamp_update(lamp, ob->obmat);
+
+ lamp->spotsi= la->spotsize;
+ if(lamp->mode & LA_HALO)
+ if(lamp->spotsi > 170.0)
+ lamp->spotsi = 170.0;
+ lamp->spotsi= cos(M_PI*lamp->spotsi/360.0);
+ lamp->spotbl= (1.0 - lamp->spotsi)*la->spotblend;
+ lamp->k= la->k;
+
+ lamp->dist= la->dist;
+ lamp->falloff_type= la->falloff_type;
+ lamp->att1= la->att1;
+ lamp->att2= la->att2;
+ lamp->curfalloff= la->curfalloff;
+
+ /* initshadowbuf */
+ lamp->bias = 0.02f*la->bias;
+ lamp->size = la->bufsize;
+ lamp->d= la->clipsta;
+ lamp->clipend= la->clipend;
+
+ /* arbitrary correction for the fact we do no soft transition */
+ lamp->bias *= 0.25f;
+
+ /* makeshadowbuf */
+ angle= saacos(lamp->spotsi);
+ temp= 0.5f*lamp->size*cos(angle)/sin(angle);
+ pixsize= (lamp->d)/temp;
+ wsize= pixsize*0.5f*lamp->size;
+
+ i_window(-wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend, lamp->winmat);
+}
+
+static void gpu_lamp_shadow_free(GPULamp *lamp)
+{
+ if(lamp->tex)
+ GPU_texture_free(lamp->tex);
+ if(lamp->fb)
+ GPU_framebuffer_free(lamp->fb);
+}
+
+GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
+{
+ Lamp *la;
+ GPULamp *lamp;
+ LinkData *link;
+
+ for(link=ob->gpulamp.first; link; link=link->next)
+ if(((GPULamp*)link->data)->par == par &&
+ ((GPULamp*)link->data)->scene == scene)
+ return link->data;
+
+ lamp = MEM_callocN(sizeof(GPULamp), "GPULamp");
+
+ link = MEM_callocN(sizeof(LinkData), "GPULampLink");
+ link->data = lamp;
+ BLI_addtail(&ob->gpulamp, link);
+
+ la = ob->data;
+ gpu_lamp_from_blender(scene, ob, par, la, lamp);
+
+ if(la->type==LA_SPOT && (la->mode & LA_SHAD_BUF)) {
+ /* opengl */
+ lamp->fb = GPU_framebuffer_create();
+ if(!lamp->fb) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size);
+ if(!lamp->tex) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ if(!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ GPU_framebuffer_restore();
+ }
+
+ return lamp;
+}
+
+void GPU_lamp_free(Object *ob)
+{
+ GPULamp *lamp;
+ LinkData *link;
+ LinkNode *nlink;
+ Material *ma;
+
+ for(link=ob->gpulamp.first; link; link=link->next) {
+ lamp = link->data;
+
+ for(nlink=lamp->materials; nlink; nlink=nlink->next) {
+ ma= nlink->link;
+ if(ma->gpumaterial.first)
+ GPU_material_free(ma);
+ }
+ BLI_linklist_free(lamp->materials, NULL);
+
+ gpu_lamp_shadow_free(lamp);
+
+ MEM_freeN(lamp);
+ }
+
+ BLI_freelistN(&ob->gpulamp);
+}
+
+int GPU_lamp_has_shadow_buffer(GPULamp *lamp)
+{
+ return (!(G.fileflags & G_FILE_GLSL_NO_SHADOWS) &&
+ !(G.fileflags & G_FILE_GLSL_NO_LIGHTS) &&
+ lamp->tex && lamp->fb);
+}
+
+void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4])
+{
+ float rangemat[4][4], persmat[4][4];
+
+ /* initshadowbuf */
+ Mat4Invert(lamp->viewmat, lamp->obmat);
+ Normalize(lamp->viewmat[0]);
+ Normalize(lamp->viewmat[1]);
+ Normalize(lamp->viewmat[2]);
+
+ /* makeshadowbuf */
+ Mat4MulMat4(persmat, lamp->viewmat, lamp->winmat);
+
+ /* opengl depth buffer is range 0.0..1.0 instead of -1.0..1.0 in blender */
+ Mat4One(rangemat);
+ rangemat[0][0] = 0.5f;
+ rangemat[1][1] = 0.5f;
+ rangemat[2][2] = 0.5f;
+ rangemat[3][0] = 0.5f;
+ rangemat[3][1] = 0.5f;
+ rangemat[3][2] = 0.5f;
+
+ Mat4MulMat4(lamp->persmat, persmat, rangemat);
+
+ /* opengl */
+ GPU_framebuffer_texture_bind(lamp->fb, lamp->tex);
+
+ /* set matrices */
+ Mat4CpyMat4(viewmat, lamp->viewmat);
+ Mat4CpyMat4(winmat, lamp->winmat);
+ *winsize = lamp->size;
+}
+
+void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp)
+{
+ GPU_framebuffer_texture_unbind(lamp->fb, lamp->tex);
+ GPU_framebuffer_restore();
+}
+
+int GPU_lamp_shadow_layer(GPULamp *lamp)
+{
+ if(lamp->fb && lamp->tex && (lamp->mode & (LA_LAYER|LA_LAYER_SHADOW)))
+ return lamp->lay;
+ else
+ return -1;
+}
+
diff --git a/source/blender/gpu/intern/gpu_shader_material.glsl b/source/blender/gpu/intern/gpu_shader_material.glsl
new file mode 100644
index 00000000000..309cb738454
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_shader_material.glsl
@@ -0,0 +1,1543 @@
+
+float exp_blender(float f)
+{
+ return pow(2.71828182846, f);
+}
+
+void rgb_to_hsv(vec4 rgb, out vec4 outcol)
+{
+ float cmax, cmin, h, s, v, cdelta;
+ vec3 c;
+
+ cmax = max(rgb[0], max(rgb[1], rgb[2]));
+ cmin = min(rgb[0], min(rgb[1], rgb[2]));
+ cdelta = cmax-cmin;
+
+ v = cmax;
+ if (cmax!=0.0)
+ s = cdelta/cmax;
+ else {
+ s = 0.0;
+ h = 0.0;
+ }
+
+ if (s == 0.0) {
+ h = 0.0;
+ }
+ else {
+ c = (vec3(cmax, cmax, cmax) - rgb.xyz)/cdelta;
+
+ if (rgb.x==cmax) h = c[2] - c[1];
+ else if (rgb.y==cmax) h = 2.0 + c[0] - c[2];
+ else h = 4.0 + c[1] - c[0];
+
+ h /= 6.0;
+
+ if (h<0.0)
+ h += 1.0;
+ }
+
+ outcol = vec4(h, s, v, rgb.w);
+}
+
+void hsv_to_rgb(vec4 hsv, out vec4 outcol)
+{
+ float i, f, p, q, t, h, s, v;
+ vec3 rgb;
+
+ h = hsv[0];
+ s = hsv[1];
+ v = hsv[2];
+
+ if(s==0.0) {
+ rgb = vec3(v, v, v);
+ }
+ else {
+ if(h==1.0)
+ h = 0.0;
+
+ h *= 6.0;
+ i = floor(h);
+ f = h - i;
+ rgb = vec3(f, f, f);
+ p = v*(1.0-s);
+ q = v*(1.0-(s*f));
+ t = v*(1.0-(s*(1.0-f)));
+
+ if (i == 0.0) rgb = vec3(v, t, p);
+ else if (i == 1.0) rgb = vec3(q, v, p);
+ else if (i == 2.0) rgb = vec3(p, v, t);
+ else if (i == 3.0) rgb = vec3(p, q, v);
+ else if (i == 4.0) rgb = vec3(t, p, v);
+ else rgb = vec3(v, p, q);
+ }
+
+ outcol = vec4(rgb, hsv.w);
+}
+
+#define M_PI 3.14159265358979323846
+
+/*********** SHADER NODES ***************/
+
+void vcol_attribute(vec4 attvcol, out vec4 vcol)
+{
+ vcol = vec4(attvcol.x/255.0, attvcol.y/255.0, attvcol.z/255.0, 1.0);
+}
+
+void uv_attribute(vec2 attuv, out vec3 uv)
+{
+ uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0);
+}
+
+void geom(vec3 co, vec3 nor, mat4 viewinvmat, vec3 attorco, vec2 attuv, vec4 attvcol, out vec3 global, out vec3 local, out vec3 view, out vec3 orco, out vec3 uv, out vec3 normal, out vec4 vcol, out float frontback)
+{
+ local = co;
+ view = normalize(local);
+ global = (viewinvmat*vec4(local, 1.0)).xyz;
+ orco = attorco;
+ uv_attribute(attuv, uv);
+ normal = -normalize(nor); /* blender render normal is negated */
+ vcol_attribute(attvcol, vcol);
+ frontback = 1.0;
+}
+
+void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec)
+{
+ outvec = (mat * vec4(vec, 1.0)).xyz;
+ if(domin == 1.0)
+ outvec = max(outvec, minvec);
+ if(domax == 1.0)
+ outvec = min(outvec, maxvec);
+}
+
+void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
+{
+ outdepth = abs(co.z);
+ outdist = length(co);
+ outview = normalize(co);
+}
+
+void math_add(float val1, float val2, out float outval)
+{
+ outval = val1 + val2;
+}
+
+void math_subtract(float val1, float val2, out float outval)
+{
+ outval = val1 - val2;
+}
+
+void math_multiply(float val1, float val2, out float outval)
+{
+ outval = val1 * val2;
+}
+
+void math_divide(float val1, float val2, out float outval)
+{
+ if (val2 == 0.0)
+ outval = 0.0;
+ else
+ outval = val1 / val2;
+}
+
+void math_sine(float val, out float outval)
+{
+ outval = sin(val);
+}
+
+void math_cosine(float val, out float outval)
+{
+ outval = cos(val);
+}
+
+void math_tangent(float val, out float outval)
+{
+ outval = tan(val);
+}
+
+void math_asin(float val, out float outval)
+{
+ if (val <= 1.0 && val >= -1.0)
+ outval = asin(val);
+ else
+ outval = 0.0;
+}
+
+void math_acos(float val, out float outval)
+{
+ if (val <= 1.0 && val >= -1.0)
+ outval = acos(val);
+ else
+ outval = 0.0;
+}
+
+void math_atan(float val, out float outval)
+{
+ outval = atan(val);
+}
+
+void math_pow(float val1, float val2, out float outval)
+{
+ if (val1 >= 0.0)
+ outval = pow(val1, val2);
+ else
+ outval = 0.0;
+}
+
+void math_log(float val1, float val2, out float outval)
+{
+ if(val1 > 0.0 && val2 > 0.0)
+ outval= log2(val1) / log2(val2);
+ else
+ outval= 0.0;
+}
+
+void math_max(float val1, float val2, out float outval)
+{
+ outval = max(val1, val2);
+}
+
+void math_min(float val1, float val2, out float outval)
+{
+ outval = min(val1, val2);
+}
+
+void math_round(float val, out float outval)
+{
+ outval= floor(val + 0.5);
+}
+
+void math_less_than(float val1, float val2, out float outval)
+{
+ if(val1 < val2)
+ outval = 1.0;
+ else
+ outval = 0.0;
+}
+
+void math_greater_than(float val1, float val2, out float outval)
+{
+ if(val1 > val2)
+ outval = 1.0;
+ else
+ outval = 0.0;
+}
+
+void squeeze(float val, float width, float center, out float outval)
+{
+ outval = 1.0/(1.0 + pow(2.71828183, -((val-center)*width)));
+}
+
+void vec_math_add(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
+{
+ outvec = v1 + v2;
+ outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2]))/3.0;
+}
+
+void vec_math_sub(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
+{
+ outvec = v1 - v2;
+ outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2]))/3.0;
+}
+
+void vec_math_average(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
+{
+ outvec = v1 + v2;
+ outval = length(outvec);
+ outvec = normalize(outvec);
+}
+
+void vec_math_dot(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
+{
+ outvec = vec3(0, 0, 0);
+ outval = dot(v1, v2);
+}
+
+void vec_math_cross(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
+{
+ outvec = cross(v1, v2);
+ outval = length(outvec);
+}
+
+void vec_math_normalize(vec3 v, out vec3 outvec, out float outval)
+{
+ outval = length(v);
+ outvec = normalize(v);
+}
+
+void vec_math_negate(vec3 v, out vec3 outv)
+{
+ outv = -v;
+}
+
+void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
+{
+ outnor = dir;
+ outdot = -dot(dir, nor);
+}
+
+void curves_vec(vec3 vec, sampler1D curvemap, out vec3 outvec)
+{
+ outvec.x = texture1D(curvemap, (vec.x + 1.0)*0.5).x;
+ outvec.y = texture1D(curvemap, (vec.y + 1.0)*0.5).y;
+ outvec.z = texture1D(curvemap, (vec.z + 1.0)*0.5).z;
+}
+
+void curves_rgb(vec4 col, sampler1D curvemap, out vec4 outcol)
+{
+ outcol.r = texture1D(curvemap, texture1D(curvemap, col.r).a).r;
+ outcol.g = texture1D(curvemap, texture1D(curvemap, col.g).a).g;
+ outcol.b = texture1D(curvemap, texture1D(curvemap, col.b).a).b;
+ outcol.a = col.a;
+}
+
+void set_value(float val, out float outval)
+{
+ outval = val;
+}
+
+void set_rgb(vec3 col, out vec3 outcol)
+{
+ outcol = col;
+}
+
+void set_rgba(vec4 col, out vec4 outcol)
+{
+ outcol = col;
+}
+
+void set_value_zero(out float outval)
+{
+ outval = 0.0;
+}
+
+void set_rgb_zero(out vec3 outval)
+{
+ outval = vec3(0.0);
+}
+
+void set_rgba_zero(out vec4 outval)
+{
+ outval = vec4(0.0);
+}
+
+void mix_blend(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ outcol = mix(col1, col2, fac);
+ outcol.a = col1.a;
+}
+
+void mix_add(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ outcol = mix(col1, col1 + col2, fac);
+ outcol.a = col1.a;
+}
+
+void mix_mult(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ outcol = mix(col1, col1 * col2, fac);
+ outcol.a = col1.a;
+}
+
+void mix_screen(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ float facm = 1.0 - fac;
+
+ outcol = vec4(1.0) - (vec4(facm) + fac*(vec4(1.0) - col2))*(vec4(1.0) - col1);
+ outcol.a = col1.a;
+}
+
+void mix_overlay(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ float facm = 1.0 - fac;
+
+ outcol = col1;
+
+ if(outcol.r < 0.5)
+ outcol.r *= facm + 2.0*fac*col2.r;
+ else
+ outcol.r = 1.0 - (facm + 2.0*fac*(1.0 - col2.r))*(1.0 - outcol.r);
+
+ if(outcol.g < 0.5)
+ outcol.g *= facm + 2.0*fac*col2.g;
+ else
+ outcol.g = 1.0 - (facm + 2.0*fac*(1.0 - col2.g))*(1.0 - outcol.g);
+
+ if(outcol.b < 0.5)
+ outcol.b *= facm + 2.0*fac*col2.b;
+ else
+ outcol.b = 1.0 - (facm + 2.0*fac*(1.0 - col2.b))*(1.0 - outcol.b);
+}
+
+void mix_sub(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ outcol = mix(col1, col1 - col2, fac);
+ outcol.a = col1.a;
+}
+
+void mix_div(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ float facm = 1.0 - fac;
+
+ outcol = col1;
+
+ if(col2.r != 0.0) outcol.r = facm*outcol.r + fac*outcol.r/col2.r;
+ if(col2.g != 0.0) outcol.g = facm*outcol.g + fac*outcol.g/col2.g;
+ if(col2.b != 0.0) outcol.b = facm*outcol.b + fac*outcol.b/col2.b;
+}
+
+void mix_diff(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ outcol = mix(col1, abs(col1 - col2), fac);
+ outcol.a = col1.a;
+}
+
+void mix_dark(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ outcol.rgb = min(col1.rgb, col2.rgb*fac);
+ outcol.a = col1.a;
+}
+
+void mix_light(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ outcol.rgb = max(col1.rgb, col2.rgb*fac);
+ outcol.a = col1.a;
+}
+
+void mix_dodge(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ outcol = col1;
+
+ if(outcol.r != 0.0) {
+ float tmp = 1.0 - fac*col2.r;
+ if(tmp <= 0.0)
+ outcol.r = 1.0;
+ else if((tmp = outcol.r/tmp) > 1.0)
+ outcol.r = 1.0;
+ else
+ outcol.r = tmp;
+ }
+ if(outcol.g != 0.0) {
+ float tmp = 1.0 - fac*col2.g;
+ if(tmp <= 0.0)
+ outcol.g = 1.0;
+ else if((tmp = outcol.g/tmp) > 1.0)
+ outcol.g = 1.0;
+ else
+ outcol.g = tmp;
+ }
+ if(outcol.b != 0.0) {
+ float tmp = 1.0 - fac*col2.b;
+ if(tmp <= 0.0)
+ outcol.b = 1.0;
+ else if((tmp = outcol.b/tmp) > 1.0)
+ outcol.b = 1.0;
+ else
+ outcol.b = tmp;
+ }
+}
+
+void mix_burn(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ float tmp, facm = 1.0 - fac;
+
+ outcol = col1;
+
+ tmp = facm + fac*col2.r;
+ if(tmp <= 0.0)
+ outcol.r = 0.0;
+ else if((tmp = (1.0 - (1.0 - outcol.r)/tmp)) < 0.0)
+ outcol.r = 0.0;
+ else if(tmp > 1.0)
+ outcol.r = 1.0;
+ else
+ outcol.r = tmp;
+
+ tmp = facm + fac*col2.g;
+ if(tmp <= 0.0)
+ outcol.g = 0.0;
+ else if((tmp = (1.0 - (1.0 - outcol.g)/tmp)) < 0.0)
+ outcol.g = 0.0;
+ else if(tmp > 1.0)
+ outcol.g = 1.0;
+ else
+ outcol.g = tmp;
+
+ tmp = facm + fac*col2.b;
+ if(tmp <= 0.0)
+ outcol.b = 0.0;
+ else if((tmp = (1.0 - (1.0 - outcol.b)/tmp)) < 0.0)
+ outcol.b = 0.0;
+ else if(tmp > 1.0)
+ outcol.b = 1.0;
+ else
+ outcol.b = tmp;
+}
+
+void mix_hue(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ float facm = 1.0 - fac;
+
+ outcol = col1;
+
+ vec4 hsv, hsv2, tmp;
+ rgb_to_hsv(col2, hsv2);
+
+ if(hsv2.y != 0.0) {
+ rgb_to_hsv(outcol, hsv);
+ hsv.x = hsv2.x;
+ hsv_to_rgb(hsv, tmp);
+
+ outcol = mix(outcol, tmp, fac);
+ outcol.a = col1.a;
+ }
+}
+
+void mix_sat(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ float facm = 1.0 - fac;
+
+ outcol = col1;
+
+ vec4 hsv, hsv2;
+ rgb_to_hsv(outcol, hsv);
+
+ if(hsv.y != 0.0) {
+ rgb_to_hsv(col2, hsv2);
+
+ hsv.y = facm*hsv.y + fac*hsv2.y;
+ hsv_to_rgb(hsv, outcol);
+ }
+}
+
+void mix_val(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ float facm = 1.0 - fac;
+
+ vec4 hsv, hsv2;
+ rgb_to_hsv(col1, hsv);
+ rgb_to_hsv(col2, hsv2);
+
+ hsv.z = facm*hsv.z + fac*hsv2.z;
+ hsv_to_rgb(hsv, outcol);
+}
+
+void mix_color(float fac, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ fac = clamp(fac, 0.0, 1.0);
+ float facm = 1.0 - fac;
+
+ outcol = col1;
+
+ vec4 hsv, hsv2, tmp;
+ rgb_to_hsv(col2, hsv2);
+
+ if(hsv2.y != 0.0) {
+ rgb_to_hsv(outcol, hsv);
+ hsv.x = hsv2.x;
+ hsv.y = hsv2.y;
+ hsv_to_rgb(hsv, tmp);
+
+ outcol = mix(outcol, tmp, fac);
+ outcol.a = col1.a;
+ }
+}
+
+void valtorgb(float fac, sampler1D colormap, out vec4 outcol, out float outalpha)
+{
+ outcol = texture1D(colormap, fac);
+ outalpha = outcol.a;
+}
+
+void rgbtobw(vec4 color, out float outval)
+{
+ outval = color.r*0.35 + color.g*0.45 + color.b*0.2;
+}
+
+void invert(float fac, vec4 col, out vec4 outcol)
+{
+ outcol.xyz = mix(col.xyz, vec3(1.0, 1.0, 1.0) - col.xyz, fac);
+ outcol.w = col.w;
+}
+
+void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol)
+{
+ vec4 hsv;
+
+ rgb_to_hsv(col, hsv);
+
+ hsv[0] += (hue - 0.5);
+ if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
+ hsv[1] *= sat;
+ if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
+ hsv[2] *= value;
+ if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0;
+
+ hsv_to_rgb(hsv, outcol);
+
+ outcol = mix(col, outcol, fac);
+}
+
+void separate_rgb(vec4 col, out float r, out float g, out float b)
+{
+ r = col.r;
+ g = col.g;
+ b = col.b;
+}
+
+void combine_rgb(float r, float g, float b, out vec4 col)
+{
+ col = vec4(r, g, b, 1.0);
+}
+
+void output_node(vec4 rgb, float alpha, out vec4 outrgb)
+{
+ outrgb = vec4(rgb.rgb, alpha);
+}
+
+/*********** TEXTURES ***************/
+
+void texture_flip_blend(vec3 vec, out vec3 outvec)
+{
+ outvec = vec.yxz;
+}
+
+void texture_blend_lin(vec3 vec, out float outval)
+{
+ outval = (1.0+vec.x)/2.0;
+}
+
+void texture_blend_quad(vec3 vec, out float outval)
+{
+ outval = max((1.0+vec.x)/2.0, 0.0);
+ outval *= outval;
+}
+
+void texture_wood_sin(vec3 vec, out float value, out vec4 color, out vec3 normal)
+{
+ float a = sqrt(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z)*20.0;
+ float wi = 0.5 + 0.5*sin(a);
+
+ value = wi;
+ color = vec4(wi, wi, wi, 1.0);
+ normal = vec3(0.0, 0.0, 0.0);
+}
+
+void texture_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal)
+{
+ color = texture2D(ima, (vec.xy + vec2(1.0, 1.0))*0.5);
+ value = 1.0;
+
+ normal.x = 2.0*(color.r - 0.5);
+ normal.y = 2.0*(0.5 - color.g);
+ normal.z = 2.0*(color.b - 0.5);
+}
+
+/************* MTEX *****************/
+
+void texco_orco(vec3 attorco, out vec3 orco)
+{
+ orco = attorco;
+}
+
+void texco_uv(vec2 attuv, out vec3 uv)
+{
+ /* disabled for now, works together with leaving out mtex_2d_mapping
+ uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0); */
+ uv = vec3(attuv, 0.0);
+}
+
+void texco_norm(vec3 normal, out vec3 outnormal)
+{
+ /* corresponds to shi->orn, which is negated so cancels
+ out blender normal negation */
+ outnormal = normalize(normal);
+}
+
+void texco_tangent(vec3 tangent, out vec3 outtangent)
+{
+ outtangent = normalize(tangent);
+}
+
+void texco_global(mat4 viewinvmat, vec3 co, out vec3 global)
+{
+ global = (viewinvmat*vec4(co, 1.0)).xyz;
+}
+
+void texco_object(mat4 viewinvmat, mat4 obinvmat, vec3 co, out vec3 object)
+{
+ object = (obinvmat*(viewinvmat*vec4(co, 1.0))).xyz;
+}
+
+void texco_refl(vec3 vn, vec3 view, out vec3 ref)
+{
+ ref = view - 2.0*dot(vn, view)*vn;
+}
+
+void shade_norm(vec3 normal, out vec3 outnormal)
+{
+ /* blender render normal is negated */
+ outnormal = -normalize(normal);
+}
+
+void mtex_rgb_blend(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ float facm;
+
+ fact *= facg;
+ facm = 1.0-fact;
+
+ incol = fact*texcol + facm*outcol;
+}
+
+void mtex_rgb_mul(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ float facm;
+
+ fact *= facg;
+ facm = 1.0-facg;
+
+ incol = (facm + fact*texcol)*outcol;
+}
+
+void mtex_rgb_screen(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ float facm;
+
+ fact *= facg;
+ facm = 1.0-facg;
+
+ incol = vec3(1.0) - (vec3(facm) + fact*(vec3(1.0) - texcol))*(vec3(1.0) - outcol);
+}
+
+void mtex_rgb_overlay(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ float facm;
+
+ fact *= facg;
+ facm = 1.0-facg;
+
+ if(outcol.r < 0.5)
+ incol.r = outcol.r*(facm + 2.0*fact*texcol.r);
+ else
+ incol.r = 1.0 - (facm + 2.0*fact*(1.0 - texcol.r))*(1.0 - outcol.r);
+
+ if(outcol.g < 0.5)
+ incol.g = outcol.g*(facm + 2.0*fact*texcol.g);
+ else
+ incol.g = 1.0 - (facm + 2.0*fact*(1.0 - texcol.g))*(1.0 - outcol.g);
+
+ if(outcol.b < 0.5)
+ incol.b = outcol.b*(facm + 2.0*fact*texcol.b);
+ else
+ incol.b = 1.0 - (facm + 2.0*fact*(1.0 - texcol.b))*(1.0 - outcol.b);
+}
+
+void mtex_rgb_sub(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ incol = -fact*facg*texcol + outcol;
+}
+
+void mtex_rgb_add(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ incol = fact*facg*texcol + outcol;
+}
+
+void mtex_rgb_div(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ float facm;
+
+ fact *= facg;
+ facm = 1.0-fact;
+
+ if(texcol.r != 0.0) incol.r = facm*outcol.r + fact*outcol.r/texcol.r;
+ if(texcol.g != 0.0) incol.g = facm*outcol.g + fact*outcol.g/texcol.g;
+ if(texcol.b != 0.0) incol.b = facm*outcol.b + fact*outcol.b/texcol.b;
+}
+
+void mtex_rgb_diff(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ float facm;
+
+ fact *= facg;
+ facm = 1.0-fact;
+
+ incol = facm*outcol + fact*abs(texcol - outcol);
+}
+
+void mtex_rgb_dark(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ float facm, col;
+
+ fact *= facg;
+ facm = 1.0-fact;
+
+ col = fact*texcol.r;
+ if(col < outcol.r) incol.r = col; else incol.r = outcol.r;
+ col = fact*texcol.g;
+ if(col < outcol.g) incol.g = col; else incol.g = outcol.g;
+ col = fact*texcol.b;
+ if(col < outcol.b) incol.b = col; else incol.b = outcol.b;
+}
+
+void mtex_rgb_light(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ float facm, col;
+
+ fact *= facg;
+ facm = 1.0-fact;
+
+ col = fact*texcol.r;
+ if(col > outcol.r) incol.r = col; else incol.r = outcol.r;
+ col = fact*texcol.g;
+ if(col > outcol.g) incol.g = col; else incol.g = outcol.g;
+ col = fact*texcol.b;
+ if(col > outcol.b) incol.b = col; else incol.b = outcol.b;
+}
+
+void mtex_rgb_hue(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ vec4 col;
+
+ mix_hue(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
+ incol.rgb = col.rgb;
+}
+
+void mtex_rgb_sat(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ vec4 col;
+
+ mix_sat(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
+ incol.rgb = col.rgb;
+}
+
+void mtex_rgb_val(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ vec4 col;
+
+ mix_val(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
+ incol.rgb = col.rgb;
+}
+
+void mtex_rgb_color(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
+{
+ vec4 col;
+
+ mix_color(fact*facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
+ incol.rgb = col.rgb;
+}
+
+void mtex_value_vars(inout float fact, float facg, out float facm, float flip)
+{
+ fact *= facg;
+ facm = 1.0-fact;
+
+ if(flip != 0.0) {
+ float tmp = fact;
+ fact = facm;
+ facm = tmp;
+ }
+}
+
+void mtex_value_blend(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+{
+ float facm;
+ mtex_value_vars(fact, facg, facm, flip);
+
+ incol = fact*texcol + facm*outcol;
+}
+
+void mtex_value_mul(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+{
+ float facm;
+ mtex_value_vars(fact, facg, facm, flip);
+
+ facm = 1.0 - facg;
+ incol = (facm + fact*texcol)*outcol;
+}
+
+void mtex_value_screen(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+{
+ float facm;
+ mtex_value_vars(fact, facg, facm, flip);
+
+ facm = 1.0 - facg;
+ incol = 1.0 - (facm + fact*(1.0 - texcol))*(1.0 - outcol);
+}
+
+void mtex_value_sub(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+{
+ float facm;
+ mtex_value_vars(fact, facg, facm, flip);
+
+ fact = -fact;
+ incol = fact*texcol + outcol;
+}
+
+void mtex_value_add(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+{
+ float facm;
+ mtex_value_vars(fact, facg, facm, flip);
+
+ fact = fact;
+ incol = fact*texcol + outcol;
+}
+
+void mtex_value_div(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+{
+ float facm;
+ mtex_value_vars(fact, facg, facm, flip);
+
+ if(texcol != 0.0)
+ incol = facm*outcol + fact*outcol/texcol;
+ else
+ incol = 0.0;
+}
+
+void mtex_value_diff(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+{
+ float facm;
+ mtex_value_vars(fact, facg, facm, flip);
+
+ incol = facm*outcol + fact*abs(texcol - outcol);
+}
+
+void mtex_value_dark(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+{
+ float facm;
+ mtex_value_vars(fact, facg, facm, flip);
+
+ float col = fact*texcol;
+ if(col < outcol) incol = col; else incol = outcol;
+}
+
+void mtex_value_light(float outcol, float texcol, float fact, float facg, float flip, out float incol)
+{
+ float facm;
+ mtex_value_vars(fact, facg, facm, flip);
+
+ float col = fact*texcol;
+ if(col > outcol) incol = col; else incol = outcol;
+}
+
+void mtex_value_clamp_positive(float fac, out float outfac)
+{
+ outfac = max(fac, 0.0);
+}
+
+void mtex_value_clamp(float fac, out float outfac)
+{
+ outfac = clamp(fac, 0.0, 1.0);
+}
+
+void mtex_har_divide(float har, out float outhar)
+{
+ outhar = har/128.0;
+}
+
+void mtex_har_multiply_clamp(float har, out float outhar)
+{
+ har *= 128.0;
+
+ if(har < 1.0) outhar = 1.0;
+ else if(har > 511.0) outhar = 511.0;
+ else outhar = har;
+}
+
+void mtex_alpha_from_col(vec4 col, out float alpha)
+{
+ alpha = col.a;
+}
+
+void mtex_alpha_to_col(vec4 col, float alpha, out vec4 outcol)
+{
+ outcol = vec4(col.rgb, alpha);
+}
+
+void mtex_rgbtoint(vec4 rgb, out float intensity)
+{
+ intensity = dot(vec3(0.35, 0.45, 0.2), rgb.rgb);
+}
+
+void mtex_value_invert(float invalue, out float outvalue)
+{
+ outvalue = 1.0 - invalue;
+}
+
+void mtex_rgb_invert(vec4 inrgb, out vec4 outrgb)
+{
+ outrgb = vec4(vec3(1.0) - inrgb.rgb, inrgb.a);
+}
+
+void mtex_value_stencil(float stencil, float intensity, out float outstencil, out float outintensity)
+{
+ float fact = intensity;
+ outintensity = intensity*stencil;
+ outstencil = stencil*fact;
+}
+
+void mtex_rgb_stencil(float stencil, vec4 rgb, out float outstencil, out vec4 outrgb)
+{
+ float fact = rgb.a;
+ outrgb = vec4(rgb.rgb, rgb.a*stencil);
+ outstencil = stencil*fact;
+}
+
+void mtex_mapping_ofs(vec3 texco, vec3 ofs, out vec3 outtexco)
+{
+ outtexco = texco + ofs;
+}
+
+void mtex_mapping_size(vec3 texco, vec3 size, out vec3 outtexco)
+{
+ outtexco = size*texco;
+}
+
+void mtex_2d_mapping(vec3 vec, out vec3 outvec)
+{
+ outvec = vec3(vec.xy*0.5 + vec2(0.5, 0.5), vec.z);
+}
+
+void mtex_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal)
+{
+ color = texture2D(ima, vec.xy);
+ value = 1.0;
+
+ normal = 2.0*(vec3(color.r, -color.g, color.b) - vec3(0.5, -0.5, 0.5));
+}
+
+void mtex_negate_texnormal(vec3 normal, out vec3 outnormal)
+{
+ outnormal = vec3(-normal.x, -normal.y, normal.z);
+}
+
+void mtex_nspace_tangent(vec3 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
+{
+ tangent = normalize(tangent);
+ vec3 B = cross(normal, tangent);
+
+ outnormal = texnormal.x*tangent + texnormal.y*B + texnormal.z*normal;
+ outnormal = normalize(outnormal);
+}
+
+void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
+{
+ outnormal = (1.0 - norfac)*normal + norfac*newnormal;
+ outnormal = normalize(outnormal);
+}
+
+/******* MATERIAL *********/
+
+void lamp_visibility_sun_hemi(vec3 lampvec, out vec3 lv, out float dist, out float visifac)
+{
+ lv = lampvec;
+ dist = 1.0;
+ visifac = 1.0;
+}
+
+void lamp_visibility_other(vec3 co, vec3 lampco, out vec3 lv, out float dist, out float visifac)
+{
+ lv = co - lampco;
+ dist = length(lv);
+ lv = normalize(lv);
+ visifac = 1.0;
+}
+
+void lamp_falloff_invlinear(float lampdist, float dist, out float visifac)
+{
+ visifac = lampdist/(lampdist + dist);
+}
+
+void lamp_falloff_invsquare(float lampdist, float dist, out float visifac)
+{
+ visifac = lampdist/(lampdist + dist*dist);
+}
+
+void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out float visifac)
+{
+ float lampdistkw = lampdist*lampdist;
+
+ visifac = lampdist/(lampdist + ld1*dist);
+ visifac *= lampdistkw/(lampdistkw + ld2*dist*dist);
+}
+
+void lamp_falloff_curve(float lampdist, sampler1D curvemap, float dist, out float visifac)
+{
+ visifac = texture1D(curvemap, dist/lampdist).x;
+}
+
+void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
+{
+ float t= lampdist - dist;
+
+ outvisifac= visifac*max(t, 0.0)/lampdist;
+}
+
+void lamp_visibility_spot_square(vec3 lampvec, mat4 lampimat, vec3 lv, out float inpr)
+{
+ if(dot(lv, lampvec) > 0.0) {
+ vec3 lvrot = (lampimat*vec4(lv, 0.0)).xyz;
+ float x = max(abs(lvrot.x/lvrot.z), abs(lvrot.y/lvrot.z));
+
+ inpr = 1.0/sqrt(1.0 + x*x);
+ }
+ else
+ inpr = 0.0;
+}
+
+void lamp_visibility_spot_circle(vec3 lampvec, vec3 lv, out float inpr)
+{
+ inpr = dot(lv, lampvec);
+}
+
+void lamp_visibility_spot(float spotsi, float spotbl, float inpr, float visifac, out float outvisifac)
+{
+ float t = spotsi;
+
+ if(inpr <= t) {
+ outvisifac = 0.0;
+ }
+ else {
+ t = inpr - t;
+
+ /* soft area */
+ if(spotbl != 0.0)
+ inpr *= smoothstep(0.0, 1.0, t/spotbl);
+
+ outvisifac = visifac*inpr;
+ }
+}
+
+void lamp_visibility_clamp(float visifac, out float outvisifac)
+{
+ outvisifac = (visifac < 0.001)? 0.0: visifac;
+}
+
+void shade_view(vec3 co, out vec3 view)
+{
+ /* handle perspective/orthographic */
+ view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(co): vec3(0.0, 0.0, -1.0);
+}
+
+void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
+{
+ vec3 c = cross(lv, tang);
+ vec3 vnor = cross(c, tang);
+
+ vn = -normalize(vnor);
+}
+
+void shade_inp(vec3 vn, vec3 lv, out float inp)
+{
+ inp = dot(vn, lv);
+}
+
+void shade_is_no_diffuse(out float is)
+{
+ is = 0.0;
+}
+
+void shade_is_hemi(float inp, out float is)
+{
+ is = 0.5*inp + 0.5;
+}
+
+float area_lamp_energy(mat4 area, vec3 co, vec3 vn)
+{
+ vec3 vec[4], c[4];
+ float rad[4], fac;
+
+ vec[0] = normalize(co - area[0].xyz);
+ vec[1] = normalize(co - area[1].xyz);
+ vec[2] = normalize(co - area[2].xyz);
+ vec[3] = normalize(co - area[3].xyz);
+
+ c[0] = normalize(cross(vec[0], vec[1]));
+ c[1] = normalize(cross(vec[1], vec[2]));
+ c[2] = normalize(cross(vec[2], vec[3]));
+ c[3] = normalize(cross(vec[3], vec[0]));
+
+ rad[0] = acos(dot(vec[0], vec[1]));
+ rad[1] = acos(dot(vec[1], vec[2]));
+ rad[2] = acos(dot(vec[2], vec[3]));
+ rad[3] = acos(dot(vec[3], vec[0]));
+
+ fac= rad[0]*dot(vn, c[0]);
+ fac+= rad[1]*dot(vn, c[1]);
+ fac+= rad[2]*dot(vn, c[2]);
+ fac+= rad[3]*dot(vn, c[3]);
+
+ return max(fac, 0.0);
+}
+
+void shade_inp_area(vec3 position, vec3 lampco, vec3 lampvec, vec3 vn, mat4 area, float areasize, float k, out float inp)
+{
+ vec3 co = position;
+ vec3 vec = co - lampco;
+
+ if(dot(vec, lampvec) < 0.0) {
+ inp = 0.0;
+ }
+ else {
+ float intens = area_lamp_energy(area, co, vn);
+
+ inp = pow(intens*areasize, k);
+ }
+}
+
+void shade_diffuse_oren_nayer(float nl, vec3 n, vec3 l, vec3 v, float rough, out float is)
+{
+ vec3 h = normalize(v + l);
+ float nh = max(dot(n, h), 0.0);
+ float nv = max(dot(n, v), 0.0);
+ float realnl = dot(n, l);
+
+ if(realnl < 0.0) {
+ is = 0.0;
+ }
+ else if(nl < 0.0) {
+ is = 0.0;
+ }
+ else {
+ float vh = max(dot(v, h), 0.0);
+ float Lit_A = acos(realnl);
+ float View_A = acos(nv);
+
+ vec3 Lit_B = normalize(l - realnl*n);
+ vec3 View_B = normalize(v - nv*n);
+
+ float t = max(dot(Lit_B, View_B), 0.0);
+
+ float a, b;
+
+ if(Lit_A > View_A) {
+ a = Lit_A;
+ b = View_A;
+ }
+ else {
+ a = View_A;
+ b = Lit_A;
+ }
+
+ float A = 1.0 - (0.5*((rough*rough)/((rough*rough) + 0.33)));
+ float B = 0.45*((rough*rough)/((rough*rough) + 0.09));
+
+ b *= 0.95;
+ is = nl*(A + (B * t * sin(a) * tan(b)));
+ }
+}
+
+void shade_diffuse_toon(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float is)
+{
+ float rslt = dot(n, l);
+ float ang = acos(rslt);
+
+ if(ang < size) is = 1.0;
+ else if(ang > (size + tsmooth) || tsmooth == 0.0) is = 0.0;
+ else is = 1.0 - ((ang - size)/tsmooth);
+}
+
+void shade_diffuse_minnaert(float nl, vec3 n, vec3 v, float darkness, out float is)
+{
+ if(nl <= 0.0) {
+ is = 0.0;
+ }
+ else {
+ float nv = max(dot(n, v), 0.0);
+
+ if(darkness <= 1.0)
+ is = nl*pow(max(nv*nl, 0.1), darkness - 1.0);
+ else
+ is = nl*pow(1.0001 - nv, darkness - 1.0);
+ }
+}
+
+float fresnel_fac(vec3 view, vec3 vn, float grad, float fac)
+{
+ float t1, t2;
+ float ffac;
+
+ if(fac==0.0) {
+ ffac = 1.0;
+ }
+ else {
+ t1= dot(view, vn);
+ if(t1>0.0) t2= 1.0+t1;
+ else t2= 1.0-t1;
+
+ t2= grad + (1.0-grad)*pow(t2, fac);
+
+ if(t2<0.0) ffac = 0.0;
+ else if(t2>1.0) ffac = 1.0;
+ else ffac = t2;
+ }
+
+ return ffac;
+}
+
+void shade_diffuse_fresnel(vec3 vn, vec3 lv, vec3 view, float fac_i, float fac, out float is)
+{
+ is = fresnel_fac(lv, vn, fac_i, fac);
+}
+
+void shade_cubic(float is, out float outis)
+{
+ if(is>0.0 && is<1.0)
+ outis= smoothstep(0.0, 1.0, is);
+ else
+ outis= is;
+}
+
+void shade_visifac(float i, float visifac, float refl, out float outi)
+{
+ /*if(i > 0.0)*/
+ outi = max(i*visifac*refl, 0.0);
+ /*else
+ outi = i;*/
+}
+
+void shade_tangent_v_spec(vec3 tang, out vec3 vn)
+{
+ vn = tang;
+}
+
+void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol)
+{
+ if(i > 0.0)
+ outcol = i*lampcol*col;
+ else
+ outcol = vec3(0.0, 0.0, 0.0);
+}
+
+void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t)
+{
+ lv += view;
+ lv = normalize(lv);
+
+ t = dot(vn, lv);
+ t = 0.5*t + 0.5;
+
+ t = visifac*spec*pow(t, hard);
+}
+
+void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
+{
+ vec3 h = normalize(l + v);
+ float rslt = max(dot(h, n), 0.0);
+
+ specfac = pow(rslt, hard);
+}
+
+void shade_cooktorr_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
+{
+ vec3 h = normalize(v + l);
+ float nh = dot(n, h);
+
+ if(nh < 0.0) {
+ specfac = 0.0;
+ }
+ else {
+ float nv = max(dot(n, v), 0.0);
+ float i = pow(nh, hard);
+
+ i = i/(0.1+nv);
+ specfac = i;
+ }
+}
+
+void shade_blinn_spec(vec3 n, vec3 l, vec3 v, float refrac, float spec_power, out float specfac)
+{
+ if(refrac < 1.0) {
+ specfac = 0.0;
+ }
+ else if(spec_power == 0.0) {
+ specfac = 0.0;
+ }
+ else {
+ if(spec_power<100.0)
+ spec_power= sqrt(1.0/spec_power);
+ else
+ spec_power= 10.0/spec_power;
+
+ vec3 h = normalize(v + l);
+ float nh = dot(n, h);
+ if(nh < 0.0) {
+ specfac = 0.0;
+ }
+ else {
+ float nv = max(dot(n, v), 0.01);
+ float nl = dot(n, l);
+ if(nl <= 0.01) {
+ specfac = 0.0;
+ }
+ else {
+ float vh = max(dot(v, h), 0.01);
+
+ float a = 1.0;
+ float b = (2.0*nh*nv)/vh;
+ float c = (2.0*nh*nl)/vh;
+
+ float g;
+
+ if(a < b && a < c) g = a;
+ else if(b < a && b < c) g = b;
+ else if(c < a && c < b) g = c;
+
+ float p = sqrt(((refrac * refrac)+(vh*vh)-1.0));
+ float f = (((p-vh)*(p-vh))/((p+vh)*(p+vh)))*(1.0+((((vh*(p+vh))-1.0)*((vh*(p+vh))-1.0))/(((vh*(p-vh))+1.0)*((vh*(p-vh))+1.0))));
+ float ang = acos(nh);
+
+ specfac = max(f*g*exp_blender((-(ang*ang)/(2.0*spec_power*spec_power))), 0.0);
+ }
+ }
+ }
+}
+
+void shade_wardiso_spec(vec3 n, vec3 l, vec3 v, float rms, out float specfac)
+{
+ vec3 h = normalize(l + v);
+ float nh = max(dot(n, h), 0.001);
+ float nv = max(dot(n, v), 0.001);
+ float nl = max(dot(n, l), 0.001);
+ float angle = tan(acos(nh));
+ float alpha = max(rms, 0.001);
+
+ specfac= nl * (1.0/(4.0*M_PI*alpha*alpha))*(exp_blender(-(angle*angle)/(alpha*alpha))/(sqrt(nv*nl)));
+}
+
+void shade_toon_spec(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float specfac)
+{
+ vec3 h = normalize(l + v);
+ float rslt = dot(h, n);
+ float ang = acos(rslt);
+
+ if(ang < size) rslt = 1.0;
+ else if(ang >= (size + tsmooth) || tsmooth == 0.0) rslt = 0.0;
+ else rslt = 1.0 - ((ang - size)/tsmooth);
+
+ specfac = rslt;
+}
+
+void shade_spec_area_inp(float specfac, float inp, out float outspecfac)
+{
+ outspecfac = specfac*inp;
+}
+
+void shade_spec_t(float shadfac, float spec, float visifac, float specfac, out float t)
+{
+ t = shadfac*spec*visifac*specfac;
+}
+
+void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol)
+{
+ outcol = t*lampcol*speccol;
+}
+
+void shade_add(vec4 col1, vec4 col2, out vec4 outcol)
+{
+ outcol = col1 + col2;
+}
+
+void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
+{
+ outcol = col + col1*col2;
+}
+
+void shade_maddf(vec4 col, float f, vec4 col1, out vec4 outcol)
+{
+ outcol = col + f*col1;
+}
+
+void shade_mul(vec4 col1, vec4 col2, out vec4 outcol)
+{
+ outcol = col1*col2;
+}
+
+void shade_mul_value(float fac, vec4 col, out vec4 outcol)
+{
+ outcol = col*fac;
+}
+
+void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
+{
+ outcol = vec4(col.rgb*obcol.rgb, col.a);
+}
+
+void ramp_rgbtobw(vec3 color, out float outval)
+{
+ outval = color.r*0.3 + color.g*0.58 + color.b*0.12;
+}
+
+void shade_only_shadow(float i, float shadfac, float energy, vec3 rgb, vec3 specrgb, vec4 diff, vec4 spec, out vec4 outdiff, out vec4 outspec)
+{
+ shadfac = i*energy*(1.0 - shadfac);
+
+ outdiff = diff - vec4(rgb*shadfac, 0.0);
+ outspec = spec - vec4(specrgb*shadfac, 0.0);
+}
+
+void test_shadowbuf(vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, float inp, out float result)
+{
+ if(inp <= 0.0) {
+ result = 0.0;
+ }
+ else {
+ vec4 co = shadowpersmat*vec4(rco, 1.0);
+
+ //float bias = (1.5 - inp*inp)*shadowbias;
+ co.z -= shadowbias*co.w;
+
+ result = shadow2DProj(shadowmap, co).x;
+ }
+}
+
+void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
+{
+ outcol = linfac*(1.0 - exp(col*logfac));
+}
+
+void shade_mist_factor(vec3 co, float miststa, float mistdist, float misttype, float misi, out float outfac)
+{
+ float fac, zcor;
+
+ zcor = (gl_ProjectionMatrix[3][3] == 0.0)? length(co): -co[2];
+
+ fac = clamp((zcor-miststa)/mistdist, 0.0, 1.0);
+ if(misttype == 0.0) fac *= fac;
+ else if(misttype == 1.0);
+ else fac = sqrt(fac);
+
+ outfac = 1.0 - (1.0-fac)*(1.0-misi);
+}
+
+void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol)
+{
+ float fac = clamp(col.a, 0.0, 1.0);
+ outcol = vec4(mix(hor, col.rgb, fac), col.a);
+}
+
+void shade_alpha_opaque(vec4 col, out vec4 outcol)
+{
+ outcol = vec4(col.rgb, 1.0);
+}
+
+void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
+{
+ outcol = vec4(col.rgb, col.a*obcol.a);
+}
+
diff --git a/source/blender/gpu/intern/gpu_shader_material.glsl.c b/source/blender/gpu/intern/gpu_shader_material.glsl.c
new file mode 100644
index 00000000000..38263efd864
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_shader_material.glsl.c
@@ -0,0 +1,1026 @@
+/* DataToC output of file <gpu_shader_material_glsl> */
+
+int datatoc_gpu_shader_material_glsl_size= 32638;
+char datatoc_gpu_shader_material_glsl[]= {
+ 10,102,108,111, 97,116, 32,101,120,112, 95, 98,108,101,110,100,101,114, 40,102,108,111, 97,116, 32,102, 41, 10,123, 10,
+ 9,114,101,116,117,114,110, 32,112,111,119, 40, 50, 46, 55, 49, 56, 50, 56, 49, 56, 50, 56, 52, 54, 44, 32,102, 41, 59, 10,125,
+ 10, 10,118,111,105,100, 32,114,103, 98, 95,116,111, 95,104,115,118, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,
+118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32, 99,109, 97,120, 44, 32, 99,109,105,110,
+ 44, 32,104, 44, 32,115, 44, 32,118, 44, 32, 99,100,101,108,116, 97, 59, 10, 9,118,101, 99, 51, 32, 99, 59, 10, 10, 9, 99,109,
+ 97,120, 32, 61, 32,109, 97,120, 40,114,103, 98, 91, 48, 93, 44, 32,109, 97,120, 40,114,103, 98, 91, 49, 93, 44, 32,114,103, 98,
+ 91, 50, 93, 41, 41, 59, 10, 9, 99,109,105,110, 32, 61, 32,109,105,110, 40,114,103, 98, 91, 48, 93, 44, 32,109,105,110, 40,114,
+103, 98, 91, 49, 93, 44, 32,114,103, 98, 91, 50, 93, 41, 41, 59, 10, 9, 99,100,101,108,116, 97, 32, 61, 32, 99,109, 97,120, 45,
+ 99,109,105,110, 59, 10, 10, 9,118, 32, 61, 32, 99,109, 97,120, 59, 10, 9,105,102, 32, 40, 99,109, 97,120, 33, 61, 48, 46, 48,
+ 41, 10, 9, 9,115, 32, 61, 32, 99,100,101,108,116, 97, 47, 99,109, 97,120, 59, 10, 9,101,108,115,101, 32,123, 10, 9, 9,115,
+ 32, 61, 32, 48, 46, 48, 59, 10, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 10, 9,105,102, 32, 40,115, 32, 61, 61,
+ 32, 48, 46, 48, 41, 32,123, 10, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,
+ 99, 32, 61, 32, 40,118,101, 99, 51, 40, 99,109, 97,120, 44, 32, 99,109, 97,120, 44, 32, 99,109, 97,120, 41, 32, 45, 32,114,103,
+ 98, 46,120,121,122, 41, 47, 99,100,101,108,116, 97, 59, 10, 10, 9, 9,105,102, 32, 40,114,103, 98, 46,120, 61, 61, 99,109, 97,
+120, 41, 32,104, 32, 61, 32, 99, 91, 50, 93, 32, 45, 32, 99, 91, 49, 93, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,114,
+103, 98, 46,121, 61, 61, 99,109, 97,120, 41, 32,104, 32, 61, 32, 50, 46, 48, 32, 43, 32, 99, 91, 48, 93, 32, 45, 32, 32, 99, 91,
+ 50, 93, 59, 10, 9, 9,101,108,115,101, 32,104, 32, 61, 32, 52, 46, 48, 32, 43, 32, 99, 91, 49, 93, 32, 45, 32, 99, 91, 48, 93,
+ 59, 10, 10, 9, 9,104, 32, 47, 61, 32, 54, 46, 48, 59, 10, 10, 9, 9,105,102, 32, 40,104, 60, 48, 46, 48, 41, 10, 9, 9, 9,
+104, 32, 43, 61, 32, 49, 46, 48, 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,104, 44, 32,
+115, 44, 32,118, 44, 32,114,103, 98, 46,119, 41, 59, 10,125, 10, 10,118,111,105,100, 32,104,115,118, 95,116,111, 95,114,103, 98,
+ 40,118,101, 99, 52, 32,104,115,118, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102,
+108,111, 97,116, 32,105, 44, 32,102, 44, 32,112, 44, 32,113, 44, 32,116, 44, 32,104, 44, 32,115, 44, 32,118, 59, 10, 9,118,101,
+ 99, 51, 32,114,103, 98, 59, 10, 10, 9,104, 32, 61, 32,104,115,118, 91, 48, 93, 59, 10, 9,115, 32, 61, 32,104,115,118, 91, 49,
+ 93, 59, 10, 9,118, 32, 61, 32,104,115,118, 91, 50, 93, 59, 10, 10, 9,105,102, 40,115, 61, 61, 48, 46, 48, 41, 32,123, 10, 9,
+ 9,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,118, 44, 32,118, 41, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123,
+ 10, 9, 9,105,102, 40,104, 61, 61, 49, 46, 48, 41, 10, 9, 9, 9,104, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9, 10, 9, 9,104,
+ 32, 42, 61, 32, 54, 46, 48, 59, 10, 9, 9,105, 32, 61, 32,102,108,111,111,114, 40,104, 41, 59, 10, 9, 9,102, 32, 61, 32,104,
+ 32, 45, 32,105, 59, 10, 9, 9,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,102, 44, 32,102, 44, 32,102, 41, 59, 10, 9, 9,112,
+ 32, 61, 32,118, 42, 40, 49, 46, 48, 45,115, 41, 59, 10, 9, 9,113, 32, 61, 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42,102, 41,
+ 41, 59, 10, 9, 9,116, 32, 61, 32,118, 42, 40, 49, 46, 48, 45, 40,115, 42, 40, 49, 46, 48, 45,102, 41, 41, 41, 59, 10, 9, 9,
+ 10, 9, 9,105,102, 32, 40,105, 32, 61, 61, 32, 48, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,118, 44, 32,116,
+ 44, 32,112, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 49, 46, 48, 41, 32,114,103, 98, 32, 61,
+ 32,118,101, 99, 51, 40,113, 44, 32,118, 44, 32,112, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32,
+ 50, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,118, 44, 32,116, 41, 59, 10, 9, 9,101,108,115,101,
+ 32,105,102, 32, 40,105, 32, 61, 61, 32, 51, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,112, 44, 32,113, 44, 32,
+118, 41, 59, 10, 9, 9,101,108,115,101, 32,105,102, 32, 40,105, 32, 61, 61, 32, 52, 46, 48, 41, 32,114,103, 98, 32, 61, 32,118,
+101, 99, 51, 40,116, 44, 32,112, 44, 32,118, 41, 59, 10, 9, 9,101,108,115,101, 32,114,103, 98, 32, 61, 32,118,101, 99, 51, 40,
+118, 44, 32,112, 44, 32,113, 41, 59, 10, 9,125, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,114,103, 98,
+ 44, 32,104,115,118, 46,119, 41, 59, 10,125, 10, 10, 35,100,101,102,105,110,101, 32, 77, 95, 80, 73, 32, 51, 46, 49, 52, 49, 53,
+ 57, 50, 54, 53, 51, 53, 56, 57, 55, 57, 51, 50, 51, 56, 52, 54, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 83,
+ 72, 65, 68, 69, 82, 32, 78, 79, 68, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,
+105,100, 32,118, 99,111,108, 95, 97,116,116,114,105, 98,117,116,101, 40,118,101, 99, 52, 32, 97,116,116,118, 99,111,108, 44, 32,
+111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 41, 10,123, 10, 9,118, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 97,116,
+116,118, 99,111,108, 46,120, 47, 50, 53, 53, 46, 48, 44, 32, 97,116,116,118, 99,111,108, 46,121, 47, 50, 53, 53, 46, 48, 44, 32,
+ 97,116,116,118, 99,111,108, 46,122, 47, 50, 53, 53, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,117,
+118, 95, 97,116,116,114,105, 98,117,116,101, 40,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,111,117,116, 32,118,101, 99, 51,
+ 32,117,118, 41, 10,123, 10, 9,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 42, 50, 46, 48, 32, 45, 32,118,101,
+ 99, 50, 40, 49, 46, 48, 44, 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,103,101,111,109,
+ 40,118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32,109, 97,116, 52, 32,118,105,101,119,105,110,118,
+109, 97,116, 44, 32,118,101, 99, 51, 32, 97,116,116,111,114, 99,111, 44, 32,118,101, 99, 50, 32, 97,116,116,117,118, 44, 32,118,
+101, 99, 52, 32, 97,116,116,118, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,103,108,111, 98, 97,108, 44, 32,111,117,
+116, 32,118,101, 99, 51, 32,108,111, 99, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,111,117,116,
+ 32,118,101, 99, 51, 32,111,114, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 44, 32,111,117,116, 32,118,101, 99,
+ 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,118, 99,111,108, 44, 32,111,117,116, 32,102,108,111,
+ 97,116, 32,102,114,111,110,116, 98, 97, 99,107, 41, 10,123, 10, 9,108,111, 99, 97,108, 32, 61, 32, 99,111, 59, 10, 9,118,105,
+101,119, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108,111, 99, 97,108, 41, 59, 10, 9,103,108,111, 98, 97,108, 32, 61,
+ 32, 40,118,105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40,108,111, 99, 97,108, 44, 32, 49, 46, 48, 41, 41, 46,120,
+121,122, 59, 10, 9,111,114, 99,111, 32, 61, 32, 97,116,116,111,114, 99,111, 59, 10, 9,117,118, 95, 97,116,116,114,105, 98,117,
+116,101, 40, 97,116,116,117,118, 44, 32,117,118, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32, 45,110,111,114,109, 97,108,
+105,122,101, 40,110,111,114, 41, 59, 9, 47, 42, 32, 98,108,101,110,100,101,114, 32,114,101,110,100,101,114, 32,110,111,114,109,
+ 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42, 47, 10, 9,118, 99,111,108, 95, 97,116,116,114,105, 98,117,116,101,
+ 40, 97,116,116,118, 99,111,108, 44, 32,118, 99,111,108, 41, 59, 10, 9,102,114,111,110,116, 98, 97, 99,107, 32, 61, 32, 49, 46,
+ 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,112,112,105,110,103, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,109, 97,116,
+ 52, 32,109, 97,116, 44, 32,118,101, 99, 51, 32,109,105,110,118,101, 99, 44, 32,118,101, 99, 51, 32,109, 97,120,118,101, 99, 44,
+ 32,102,108,111, 97,116, 32,100,111,109,105,110, 44, 32,102,108,111, 97,116, 32,100,111,109, 97,120, 44, 32,111,117,116, 32,118,
+101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 40,109, 97,116, 32, 42, 32,118,
+101, 99, 52, 40,118,101, 99, 44, 32, 49, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9,105,102, 40,100,111,109,105,110, 32, 61, 61,
+ 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99, 32, 61, 32,109, 97,120, 40,111,117,116,118,101, 99, 44, 32,109,105,110,
+118,101, 99, 41, 59, 10, 9,105,102, 40,100,111,109, 97,120, 32, 61, 61, 32, 49, 46, 48, 41, 10, 9, 9,111,117,116,118,101, 99,
+ 32, 61, 32,109,105,110, 40,111,117,116,118,101, 99, 44, 32,109, 97,120,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,
+ 99, 97,109,101,114, 97, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,105,101,119,
+ 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,100,101,112,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,
+111,117,116,100,105,115,116, 41, 10,123, 10, 9,111,117,116,100,101,112,116,104, 32, 61, 32, 97, 98,115, 40, 99,111, 46,122, 41,
+ 59, 10, 9,111,117,116,100,105,115,116, 32, 61, 32,108,101,110,103,116,104, 40, 99,111, 41, 59, 10, 9,111,117,116,118,105,101,
+119, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,
+ 97,100,100, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,
+102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 43,
+ 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,115,117, 98,116,114, 97, 99,116, 40,102,108,111,
+ 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,
+117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 45, 32,118, 97,108, 50, 59, 10,
+125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109,117,108,116,105,112,108,121, 40,102,108,111, 97,116, 32,118, 97,108, 49,
+ 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,
+123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 42, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100,
+ 32,109, 97,116,104, 95,100,105,118,105,100,101, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118,
+ 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,
+108, 50, 32, 61, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101,
+ 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 49, 32, 47, 32,118, 97,108, 50, 59, 10,125, 10, 10,118,111,105,100,
+ 32,109, 97,116,104, 95,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,
+111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,115,105,110, 40,118, 97,108, 41, 59, 10,125, 10,
+ 10,118,111,105,100, 32,109, 97,116,104, 95, 99,111,115,105,110,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116,
+ 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,115, 40,118,
+ 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,116, 97,110,103,101,110,116, 40,102,108,111, 97,116, 32,
+118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108,
+ 32, 61, 32,116, 97,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,115,105,110, 40,102,
+108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,
+102, 32, 40,118, 97,108, 32, 60, 61, 32, 49, 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, 9, 9,
+111,117,116,118, 97,108, 32, 61, 32, 97,115,105,110, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118,
+ 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97, 99,111,115, 40,102,108,111, 97,
+116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,
+118, 97,108, 32, 60, 61, 32, 49, 46, 48, 32, 38, 38, 32,118, 97,108, 32, 62, 61, 32, 45, 49, 46, 48, 41, 10, 9, 9,111,117,116,
+118, 97,108, 32, 61, 32, 97, 99,111,115, 40,118, 97,108, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32,
+ 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95, 97,116, 97,110, 40,102,108,111, 97,116, 32,118,
+ 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32,
+ 61, 32, 97,116, 97,110, 40,118, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,112,111,119, 40,102,108,
+111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,
+111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 32, 40,118, 97,108, 49, 32, 62, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,
+116,118, 97,108, 32, 61, 32,112,111,119, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,
+111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,108,111,103, 40,102,
+108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116,
+ 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,105,102, 40,118, 97,108, 49, 32, 62, 32, 48, 46, 48, 32, 32, 38, 38, 32,118, 97,
+108, 50, 32, 62, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116,118, 97,108, 61, 32,108,111,103, 50, 40,118, 97,108, 49, 41, 32, 47,
+ 32,108,111,103, 50, 40,118, 97,108, 50, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 61, 32, 48, 46, 48,
+ 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,109, 97,120, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,
+108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,
+111,117,116,118, 97,108, 32, 61, 32,109, 97,120, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,
+100, 32,109, 97,116,104, 95,109,105,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,108,111, 97,116, 32,118, 97,108,
+ 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61,
+ 32,109,105,110, 40,118, 97,108, 49, 44, 32,118, 97,108, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109, 97,116,104, 95,114,
+111,117,110,100, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108,
+ 41, 10,123, 10, 9,111,117,116,118, 97,108, 61, 32,102,108,111,111,114, 40,118, 97,108, 32, 43, 32, 48, 46, 53, 41, 59, 10,125,
+ 10, 10,118,111,105,100, 32,109, 97,116,104, 95,108,101,115,115, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 49,
+ 44, 32,102,108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,
+123, 10, 9,105,102, 40,118, 97,108, 49, 32, 60, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46,
+ 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100,
+ 32,109, 97,116,104, 95,103,114,101, 97,116,101,114, 95,116,104, 97,110, 40,102,108,111, 97,116, 32,118, 97,108, 49, 44, 32,102,
+108,111, 97,116, 32,118, 97,108, 50, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,
+105,102, 40,118, 97,108, 49, 32, 62, 32,118, 97,108, 50, 41, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 59, 10,
+ 9,101,108,115,101, 10, 9, 9,111,117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,113,
+117,101,101,122,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,102,108,111, 97,116, 32,119,105,100,116,104, 44, 32,102,108,
+111, 97,116, 32, 99,101,110,116,101,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10,
+ 9,111,117,116,118, 97,108, 32, 61, 32, 49, 46, 48, 47, 40, 49, 46, 48, 32, 43, 32,112,111,119, 40, 50, 46, 55, 49, 56, 50, 56,
+ 49, 56, 51, 44, 32, 45, 40, 40,118, 97,108, 45, 99,101,110,116,101,114, 41, 42,119,105,100,116,104, 41, 41, 41, 59, 10,125, 10,
+ 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 97,100,100, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51,
+ 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,
+111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32,118, 50, 59, 10, 9,111,117,
+116,118, 97,108, 32, 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,
+118,101, 99, 91, 49, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, 51, 46, 48, 59, 10,125,
+ 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,115,117, 98, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99,
+ 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116,
+ 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 45, 32,118, 50, 59, 10, 9,111,
+117,116,118, 97,108, 32, 61, 32, 40, 97, 98,115, 40,111,117,116,118,101, 99, 91, 48, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,
+116,118,101, 99, 91, 49, 93, 41, 32, 43, 32, 97, 98,115, 40,111,117,116,118,101, 99, 91, 50, 93, 41, 41, 47, 51, 46, 48, 59, 10,
+125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95, 97,118,101,114, 97,103,101, 40,118,101, 99, 51, 32,118, 49,
+ 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,
+102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118, 49, 32, 43, 32,118,
+ 50, 59, 10, 9,111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, 59, 10, 9,111,117,
+116,118,101, 99, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,
+100, 32,118,101, 99, 95,109, 97,116,104, 95,100,111,116, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44,
+ 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,
+ 97,108, 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32,118,101, 99, 51, 40, 48, 44, 32, 48, 44, 32, 48, 41, 59, 10, 9,
+111,117,116,118, 97,108, 32, 61, 32,100,111,116, 40,118, 49, 44, 32,118, 50, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101,
+ 99, 95,109, 97,116,104, 95, 99,114,111,115,115, 40,118,101, 99, 51, 32,118, 49, 44, 32,118,101, 99, 51, 32,118, 50, 44, 32,111,
+117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108,
+ 41, 10,123, 10, 9,111,117,116,118,101, 99, 32, 61, 32, 99,114,111,115,115, 40,118, 49, 44, 32,118, 50, 41, 59, 10, 9,111,117,
+116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,111,117,116,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,
+101, 99, 95,109, 97,116,104, 95,110,111,114,109, 97,108,105,122,101, 40,118,101, 99, 51, 32,118, 44, 32,111,117,116, 32,118,101,
+ 99, 51, 32,111,117,116,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,
+111,117,116,118, 97,108, 32, 61, 32,108,101,110,103,116,104, 40,118, 41, 59, 10, 9,111,117,116,118,101, 99, 32, 61, 32,110,111,
+114,109, 97,108,105,122,101, 40,118, 41, 59, 10,125, 10, 10,118,111,105,100, 32,118,101, 99, 95,109, 97,116,104, 95,110,101,103,
+ 97,116,101, 40,118,101, 99, 51, 32,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 41, 10,123, 10, 9,111,117,
+116,118, 32, 61, 32, 45,118, 59, 10,125, 10, 10,118,111,105,100, 32,110,111,114,109, 97,108, 40,118,101, 99, 51, 32,100,105,114,
+ 44, 32,118,101, 99, 51, 32,110,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114, 44, 32,111,117,116,
+ 32,102,108,111, 97,116, 32,111,117,116,100,111,116, 41, 10,123, 10, 9,111,117,116,110,111,114, 32, 61, 32,100,105,114, 59, 10,
+ 9,111,117,116,100,111,116, 32, 61, 32, 45,100,111,116, 40,100,105,114, 44, 32,110,111,114, 41, 59, 10,125, 10, 10,118,111,105,
+100, 32, 99,117,114,118,101,115, 95,118,101, 99, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,115, 97,109,112,108,101,114, 49, 68,
+ 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,
+117,116,118,101, 99, 46,120, 32, 61, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32, 40,118,
+101, 99, 46,120, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, 53, 41, 46,120, 59, 10, 9,111,117,116,118,101, 99, 46,121, 32, 61, 32,
+116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32, 40,118,101, 99, 46,121, 32, 43, 32, 49, 46, 48,
+ 41, 42, 48, 46, 53, 41, 46,121, 59, 10, 9,111,117,116,118,101, 99, 46,122, 32, 61, 32,116,101,120,116,117,114,101, 49, 68, 40,
+ 99,117,114,118,101,109, 97,112, 44, 32, 40,118,101, 99, 46,122, 32, 43, 32, 49, 46, 48, 41, 42, 48, 46, 53, 41, 46,122, 59, 10,
+125, 10, 10,118,111,105,100, 32, 99,117,114,118,101,115, 95,114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,115, 97,109,
+112,108,101,114, 49, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108,
+ 41, 10,123, 10, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109,
+ 97,112, 44, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32, 99,111,108, 46,114, 41, 46, 97,
+ 41, 46,114, 59, 10, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,
+109, 97,112, 44, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32, 99,111,108, 46,103, 41, 46,
+ 97, 41, 46,103, 59, 10, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,
+101,109, 97,112, 44, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32, 99,111,108, 46, 98, 41,
+ 46, 97, 41, 46, 98, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,
+100, 32,115,101,116, 95,118, 97,108,117,101, 40,102,108,111, 97,116, 32,118, 97,108, 44, 32,111,117,116, 32,102,108,111, 97,116,
+ 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118, 97,108, 59, 10,125, 10, 10,118,111,105,
+100, 32,115,101,116, 95,114,103, 98, 40,118,101, 99, 51, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,
+ 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,
+116, 95,114,103, 98, 97, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108,
+ 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,118,
+ 97,108,117,101, 95,122,101,114,111, 40,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,
+117,116,118, 97,108, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 95,122,101,114,
+111, 40,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118,
+101, 99, 51, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,101,116, 95,114,103, 98, 97, 95,122,101,114,111, 40,
+111,117,116, 32,118,101, 99, 52, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32,118,101, 99,
+ 52, 40, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95, 98,108,101,110,100, 40,102,108,111, 97,116, 32,
+102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,
+101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32,
+ 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,
+111,108, 50, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125,
+ 10, 10,118,111,105,100, 32,109,105,120, 95, 97,100,100, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,
+111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41,
+ 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,
+ 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 43, 32, 99,111,108, 50, 44,
+ 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,
+105,100, 32,109,105,120, 95,109,117,108,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49,
+ 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10,
+ 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,
+116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 42, 32, 99,111,108, 50, 44, 32,102, 97,
+ 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,
+109,105,120, 95,115, 99,114,101,101,110, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44,
+ 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,
+102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111,
+ 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,
+118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 40,118,101, 99, 52, 40,102, 97, 99,109, 41, 32, 43, 32,102, 97, 99, 42, 40,118,
+101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 99,111,108, 50, 41, 41, 42, 40,118,101, 99, 52, 40, 49, 46, 48, 41, 32, 45, 32, 99,
+111,108, 49, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,
+100, 32,109,105,120, 95,111,118,101,114,108, 97,121, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,
+108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,
+123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,
+102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108,
+ 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,
+111,117,116, 99,111,108, 46,114, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 99,111,108, 50, 46,
+114, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,
+109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,114, 41, 41, 42, 40, 49, 46, 48,
+ 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 60, 32, 48, 46,
+ 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42,
+ 99,111,108, 50, 46,103, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45,
+ 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108, 50, 46,103, 41, 41,
+ 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98,
+ 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 42, 61, 32,102, 97, 99,109, 32, 43, 32, 50, 46, 48,
+ 42,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,
+ 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99, 42, 40, 49, 46, 48, 32, 45, 32, 99,111,108,
+ 50, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 59, 10,125, 10, 10,118,111,105,100, 32,
+109,105,120, 95,115,117, 98, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101,
+ 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99,
+ 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108,
+ 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 99,111,108, 49, 32, 45, 32, 99,111,108, 50, 44, 32,102, 97, 99, 41, 59, 10,
+ 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,
+100,105,118, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,
+111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,
+108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109,
+ 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10,
+ 9,105,102, 40, 99,111,108, 50, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,114, 32, 61, 32,102, 97,
+ 99,109, 42,111,117,116, 99,111,108, 46,114, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,114, 47, 99,111,108, 50, 46,
+114, 59, 10, 9,105,102, 40, 99,111,108, 50, 46,103, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,103, 32, 61,
+ 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,103, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46,103, 47, 99,111,
+108, 50, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 50, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,111,117,116, 99,111,108, 46,
+ 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46, 98, 32, 43, 32,102, 97, 99, 42,111,117,116, 99,111,108, 46, 98,
+ 47, 99,111,108, 50, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,105,102,102, 40,102,108,111, 97,116, 32,
+102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,
+101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32,
+ 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40, 99,111,108, 49, 44, 32, 97,
+ 98,115, 40, 99,111,108, 49, 32, 45, 32, 99,111,108, 50, 41, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46, 97,
+ 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100, 97,114,107, 40,102,108,111, 97,
+116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116,
+ 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99,
+ 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109,105,110, 40, 99,
+111,108, 49, 46,114,103, 98, 44, 32, 99,111,108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46,
+ 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,108,105,103,104,116, 40,102,108,
+111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,
+117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102,
+ 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 46,114,103, 98, 32, 61, 32,109, 97,120,
+ 40, 99,111,108, 49, 46,114,103, 98, 44, 32, 99,111,108, 50, 46,114,103, 98, 42,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,
+108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,100,111,100,103,101, 40,
+102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44,
+ 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112,
+ 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59,
+ 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116,
+ 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59, 10, 9, 9,105,102, 40,116,109,
+112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,
+108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46,114, 47,116,109,112, 41, 32, 62, 32, 49, 46,
+ 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,
+111,117,116, 99,111,108, 46,114, 32, 61, 32,116,109,112, 59, 10, 9,125, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32,
+ 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97,
+ 99, 42, 99,111,108, 50, 46,103, 59, 10, 9, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,
+116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,
+117,116, 99,111,108, 46,103, 47,116,109,112, 41, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32,
+ 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,116,109,112, 59,
+ 10, 9,125, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,102,108,111,
+ 97,116, 32,116,109,112, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 42, 99,111,108, 50, 46, 98, 59, 10, 9, 9,105,102, 40,
+116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9,
+ 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 47,116,109,112, 41, 32, 62, 32,
+ 49, 46, 48, 41, 10, 9, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 10, 9,
+ 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32,116,109,112, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120,
+ 95, 98,117,114,110, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52,
+ 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61,
+ 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,116,109,
+112, 44, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,
+ 99,111,108, 49, 59, 10, 10, 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,114, 59,
+ 10, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,114, 32, 61, 32, 48, 46,
+ 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 32, 45,
+ 32,111,117,116, 99,111,108, 46,114, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108,
+ 46,114, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10, 9, 9,
+111,117,116, 99,111,108, 46,114, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108, 46,114,
+ 32, 61, 32,116,109,112, 59, 10, 10, 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108, 50, 46,
+103, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32,
+ 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48,
+ 32, 45, 32,111,117,116, 99,111,108, 46,103, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,
+111,108, 46,103, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48, 41, 10,
+ 9, 9,111,117,116, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108,
+ 46,103, 32, 61, 32,116,109,112, 59, 10, 10, 9,116,109,112, 32, 61, 32,102, 97, 99,109, 32, 43, 32,102, 97, 99, 42, 99,111,108,
+ 50, 46, 98, 59, 10, 9,105,102, 40,116,109,112, 32, 60, 61, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32,
+ 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 40,116,109,112, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32, 40, 49,
+ 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46, 98, 41, 47,116,109,112, 41, 41, 32, 60, 32, 48, 46, 48, 41, 10, 9, 9,111,117,
+116, 99,111,108, 46, 98, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,116,109,112, 32, 62, 32, 49, 46, 48,
+ 41, 10, 9, 9,111,117,116, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,
+111,108, 46, 98, 32, 61, 32,116,109,112, 59, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,104,117,101, 40,102,108,111, 97,
+116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116,
+ 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99,
+ 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45,
+ 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,
+118, 44, 32,104,115,118, 50, 44, 32,116,109,112, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,
+104,115,118, 50, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 50, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,
+103, 98, 95,116,111, 95,104,115,118, 40,111,117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 9, 9,104,115,118, 46,120, 32,
+ 61, 32,104,115,118, 50, 46,120, 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,116,109,112, 41,
+ 59, 32, 10, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,108, 44, 32,116,109,112, 44, 32,
+102, 97, 99, 41, 59, 10, 9, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46, 97, 59, 10, 9,125, 10,125, 10,
+ 10,118,111,105,100, 32,109,105,120, 95,115, 97,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,
+108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,
+123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,
+102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,116, 99,111,108,
+ 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,
+116,111, 95,104,115,118, 40,111,117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 10, 9,105,102, 40,104,115,118, 46,121, 32,
+ 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118,
+ 50, 41, 59, 10, 10, 9, 9,104,115,118, 46,121, 32, 61, 32,102, 97, 99,109, 42,104,115,118, 46,121, 32, 43, 32,102, 97, 99, 42,
+104,115,118, 50, 46,121, 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108,
+ 41, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,105,120, 95,118, 97,108, 40,102,108,111, 97,116, 32,102, 97, 99, 44,
+ 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,
+111,117,116, 99,111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44,
+ 32, 49, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10,
+ 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,
+108, 49, 44, 32,104,115,118, 41, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50,
+ 41, 59, 10, 10, 9,104,115,118, 46,122, 32, 61, 32,102, 97, 99,109, 42,104,115,118, 46,122, 32, 43, 32,102, 97, 99, 42,104,115,
+118, 50, 46,122, 59, 10, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10,
+125, 10, 10,118,111,105,100, 32,109,105,120, 95, 99,111,108,111,114, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99,
+ 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,
+111,108, 41, 10,123, 10, 9,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48,
+ 41, 59, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99, 59, 10, 10, 9,111,117,
+116, 99,111,108, 32, 61, 32, 99,111,108, 49, 59, 10, 10, 9,118,101, 99, 52, 32,104,115,118, 44, 32,104,115,118, 50, 44, 32,116,
+109,112, 59, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 50, 44, 32,104,115,118, 50, 41, 59, 10, 10, 9,105,
+102, 40,104,115,118, 50, 46,121, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,103, 98, 95,116,111, 95,104,115,118, 40,
+111,117,116, 99,111,108, 44, 32,104,115,118, 41, 59, 10, 9, 9,104,115,118, 46,120, 32, 61, 32,104,115,118, 50, 46,120, 59, 10,
+ 9, 9,104,115,118, 46,121, 32, 61, 32,104,115,118, 50, 46,121, 59, 10, 9, 9,104,115,118, 95,116,111, 95,114,103, 98, 40,104,
+115,118, 44, 32,116,109,112, 41, 59, 32, 10, 10, 9, 9,111,117,116, 99,111,108, 32, 61, 32,109,105,120, 40,111,117,116, 99,111,
+108, 44, 32,116,109,112, 44, 32,102, 97, 99, 41, 59, 10, 9, 9,111,117,116, 99,111,108, 46, 97, 32, 61, 32, 99,111,108, 49, 46,
+ 97, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,118, 97,108,116,111,114,103, 98, 40,102,108,111, 97,116, 32,102, 97, 99,
+ 44, 32,115, 97,109,112,108,101,114, 49, 68, 32, 99,111,108,111,114,109, 97,112, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,
+117,116, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116, 97,108,112,104, 97, 41, 10,123, 10, 9,111,117,
+116, 99,111,108, 32, 61, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,111,108,111,114,109, 97,112, 44, 32,102, 97, 99, 41, 59,
+ 10, 9,111,117,116, 97,108,112,104, 97, 32, 61, 32,111,117,116, 99,111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,114,
+103, 98,116,111, 98,119, 40,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,
+118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, 42, 48, 46, 51, 53, 32, 43, 32,
+ 99,111,108,111,114, 46,103, 42, 48, 46, 52, 53, 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, 50, 59, 10,125, 10, 10,118,
+111,105,100, 32,105,110,118,101,114,116, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,
+111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 46,120,121,122, 32, 61,
+ 32,109,105,120, 40, 99,111,108, 46,120,121,122, 44, 32,118,101, 99, 51, 40, 49, 46, 48, 44, 32, 49, 46, 48, 44, 32, 49, 46, 48,
+ 41, 32, 45, 32, 99,111,108, 46,120,121,122, 44, 32,102, 97, 99, 41, 59, 10, 9,111,117,116, 99,111,108, 46,119, 32, 61, 32, 99,
+111,108, 46,119, 59, 10,125, 10, 10,118,111,105,100, 32,104,117,101, 95,115, 97,116, 40,102,108,111, 97,116, 32,104,117,101, 44,
+ 32,102,108,111, 97,116, 32,115, 97,116, 44, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,102,108,111, 97,116, 32,102,
+ 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123,
+ 10, 9,118,101, 99, 52, 32,104,115,118, 59, 10, 10, 9,114,103, 98, 95,116,111, 95,104,115,118, 40, 99,111,108, 44, 32,104,115,
+118, 41, 59, 10, 10, 9,104,115,118, 91, 48, 93, 32, 43, 61, 32, 40,104,117,101, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,105,102,
+ 40,104,115,118, 91, 48, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 48, 93, 45, 61, 49, 46, 48, 59, 32,101,108,115,101, 32,105,
+102, 40,104,115,118, 91, 48, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, 48, 93, 43, 61, 32, 49, 46, 48, 59, 10, 9,104,115,118,
+ 91, 49, 93, 32, 42, 61, 32,115, 97,116, 59, 10, 9,105,102, 40,104,115,118, 91, 49, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91,
+ 49, 93, 61, 32, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102, 40,104,115,118, 91, 49, 93, 60, 48, 46, 48, 41, 32,104,115,118,
+ 91, 49, 93, 61, 32, 48, 46, 48, 59, 10, 9,104,115,118, 91, 50, 93, 32, 42, 61, 32,118, 97,108,117,101, 59, 10, 9,105,102, 40,
+104,115,118, 91, 50, 93, 62, 49, 46, 48, 41, 32,104,115,118, 91, 50, 93, 61, 32, 49, 46, 48, 59, 32,101,108,115,101, 32,105,102,
+ 40,104,115,118, 91, 50, 93, 60, 48, 46, 48, 41, 32,104,115,118, 91, 50, 93, 61, 32, 48, 46, 48, 59, 10, 10, 9,104,115,118, 95,
+116,111, 95,114,103, 98, 40,104,115,118, 44, 32,111,117,116, 99,111,108, 41, 59, 10, 10, 9,111,117,116, 99,111,108, 32, 61, 32,
+109,105,120, 40, 99,111,108, 44, 32,111,117,116, 99,111,108, 44, 32,102, 97, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,
+101,112, 97,114, 97,116,101, 95,114,103, 98, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,
+114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 98, 41, 10,123, 10, 9,
+114, 32, 61, 32, 99,111,108, 46,114, 59, 10, 9,103, 32, 61, 32, 99,111,108, 46,103, 59, 10, 9, 98, 32, 61, 32, 99,111,108, 46,
+ 98, 59, 10,125, 10, 10,118,111,105,100, 32, 99,111,109, 98,105,110,101, 95,114,103, 98, 40,102,108,111, 97,116, 32,114, 44, 32,
+102,108,111, 97,116, 32,103, 44, 32,102,108,111, 97,116, 32, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108, 41, 10,
+123, 10, 9, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,114, 44, 32,103, 44, 32, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,
+118,111,105,100, 32,111,117,116,112,117,116, 95,110,111,100,101, 40,118,101, 99, 52, 32,114,103, 98, 44, 32,102,108,111, 97,116,
+ 32, 97,108,112,104, 97, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,111,117,116,114,
+103, 98, 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 46,114,103, 98, 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10, 47, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 84, 69, 88, 84, 85, 82, 69, 83, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 47, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95,102,108,105,112, 95, 98,108,101,110,100, 40,118,101,
+ 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,
+101, 99, 32, 61, 32,118,101, 99, 46,121,120,122, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95, 98,108,
+101,110,100, 95,108,105,110, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,
+ 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,108, 32, 61, 32, 40, 49, 46, 48, 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 59,
+ 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,101, 95, 98,108,101,110,100, 95,113,117, 97,100, 40,118,101, 99, 51,
+ 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,116,118, 97,
+108, 32, 61, 32,109, 97,120, 40, 40, 49, 46, 48, 43,118,101, 99, 46,120, 41, 47, 50, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10, 9,
+111,117,116,118, 97,108, 32, 42, 61, 32,111,117,116,118, 97,108, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,114,
+101, 95,119,111,111,100, 95,115,105,110, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,
+ 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,
+111,114,109, 97,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32, 97, 32, 61, 32,115,113,114,116, 40,118,101, 99, 46,120, 42,118,
+101, 99, 46,120, 32, 43, 32,118,101, 99, 46,121, 42,118,101, 99, 46,121, 32, 43, 32,118,101, 99, 46,122, 42,118,101, 99, 46,122,
+ 41, 42, 50, 48, 46, 48, 59, 10, 9,102,108,111, 97,116, 32,119,105, 32, 61, 32, 48, 46, 53, 32, 43, 32, 48, 46, 53, 42,115,105,
+110, 40, 97, 41, 59, 10, 10, 9,118, 97,108,117,101, 32, 61, 32,119,105, 59, 10, 9, 99,111,108,111,114, 32, 61, 32,118,101, 99,
+ 52, 40,119,105, 44, 32,119,105, 44, 32,119,105, 44, 32, 49, 46, 48, 41, 59, 10, 9,110,111,114,109, 97,108, 32, 61, 32,118,101,
+ 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120,116,117,
+114,101, 95,105,109, 97,103,101, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97,
+ 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,
+114, 44, 32,111,117,116, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,
+101,120,116,117,114,101, 50, 68, 40,105,109, 97, 44, 32, 40,118,101, 99, 46,120,121, 32, 43, 32,118,101, 99, 50, 40, 49, 46, 48,
+ 44, 32, 49, 46, 48, 41, 41, 42, 48, 46, 53, 41, 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10, 10, 9,110,111,
+114,109, 97,108, 46,120, 32, 61, 32, 50, 46, 48, 42, 40, 99,111,108,111,114, 46,114, 32, 45, 32, 48, 46, 53, 41, 59, 10, 9,110,
+111,114,109, 97,108, 46,121, 32, 61, 32, 50, 46, 48, 42, 40, 48, 46, 53, 32, 45, 32, 99,111,108,111,114, 46,103, 41, 59, 10, 9,
+110,111,114,109, 97,108, 46,122, 32, 61, 32, 50, 46, 48, 42, 40, 99,111,108,111,114, 46, 98, 32, 45, 32, 48, 46, 53, 41, 59, 10,
+125, 10, 10, 47, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 32, 77, 84, 69, 88, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,111,114, 99,111, 40,118,101, 99, 51, 32,
+ 97,116,116,111,114, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,114, 99,111, 41, 10,123, 10, 9,111,114, 99,111, 32,
+ 61, 32, 97,116,116,111,114, 99,111, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,117,118, 40,118,101, 99, 50,
+ 32, 97,116,116,117,118, 44, 32,111,117,116, 32,118,101, 99, 51, 32,117,118, 41, 10,123, 10, 9, 47, 42, 32,100,105,115, 97, 98,
+108,101,100, 32,102,111,114, 32,110,111,119, 44, 32,119,111,114,107,115, 32,116,111,103,101,116,104,101,114, 32,119,105,116,104,
+ 32,108,101, 97,118,105,110,103, 32,111,117,116, 32,109,116,101,120, 95, 50,100, 95,109, 97,112,112,105,110,103, 10, 9, 32, 32,
+ 32,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118, 42, 50, 46, 48, 32, 45, 32,118,101, 99, 50, 40, 49, 46, 48, 44,
+ 32, 49, 46, 48, 41, 44, 32, 48, 46, 48, 41, 59, 32, 42, 47, 10, 9,117,118, 32, 61, 32,118,101, 99, 51, 40, 97,116,116,117,118,
+ 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,110,111,114,109, 40,118,101, 99, 51, 32,
+110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47,
+ 42, 32, 99,111,114,114,101,115,112,111,110,100,115, 32,116,111, 32,115,104,105, 45, 62,111,114,110, 44, 32,119,104,105, 99,104,
+ 32,105,115, 32,110,101,103, 97,116,101,100, 32,115,111, 32, 99, 97,110, 99,101,108,115, 10, 9, 32, 32, 32,111,117,116, 32, 98,
+108,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,110,101,103, 97,116,105,111,110, 32, 42, 47, 10, 9,111,117,116,110,111,
+114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,
+100, 32,116,101,120, 99,111, 95,116, 97,110,103,101,110,116, 40,118,101, 99, 51, 32,116, 97,110,103,101,110,116, 44, 32,111,117,
+116, 32,118,101, 99, 51, 32,111,117,116,116, 97,110,103,101,110,116, 41, 10,123, 10, 9,111,117,116,116, 97,110,103,101,110,116,
+ 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,116, 97,110,103,101,110,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,
+101,120, 99,111, 95,103,108,111, 98, 97,108, 40,109, 97,116, 52, 32,118,105,101,119,105,110,118,109, 97,116, 44, 32,118,101, 99,
+ 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,103,108,111, 98, 97,108, 41, 10,123, 10, 9,103,108,111, 98, 97,108,
+ 32, 61, 32, 40,118,105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48, 41, 41, 46,120,121,
+122, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,111, 98,106,101, 99,116, 40,109, 97,116, 52, 32,118,105,101,
+119,105,110,118,109, 97,116, 44, 32,109, 97,116, 52, 32,111, 98,105,110,118,109, 97,116, 44, 32,118,101, 99, 51, 32, 99,111, 44,
+ 32,111,117,116, 32,118,101, 99, 51, 32,111, 98,106,101, 99,116, 41, 10,123, 10, 9,111, 98,106,101, 99,116, 32, 61, 32, 40,111,
+ 98,105,110,118,109, 97,116, 42, 40,118,105,101,119,105,110,118,109, 97,116, 42,118,101, 99, 52, 40, 99,111, 44, 32, 49, 46, 48,
+ 41, 41, 41, 46,120,121,122, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,120, 99,111, 95,114,101,102,108, 40,118,101, 99, 51,
+ 32,118,110, 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,111,117,116, 32,118,101, 99, 51, 32,114,101,102, 41, 10,123, 10,
+ 9,114,101,102, 32, 61, 32,118,105,101,119, 32, 45, 32, 50, 46, 48, 42,100,111,116, 40,118,110, 44, 32,118,105,101,119, 41, 42,
+118,110, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,110,111,114,109, 40,118,101, 99, 51, 32,110,111,114,109,
+ 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9, 47, 42, 32, 98,108,
+101,110,100,101,114, 32,114,101,110,100,101,114, 32,110,111,114,109, 97,108, 32,105,115, 32,110,101,103, 97,116,101,100, 32, 42,
+ 47, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32, 45,110,111,114,109, 97,108,105,122,101, 40,110,111,114,109, 97,108,
+ 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, 98,108,101,110,100, 40,118,101, 99, 51, 32,111,
+117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,
+102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,
+108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109,
+ 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,
+111,108, 32, 43, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,
+103, 98, 95,109,117,108, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44,
+ 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99,
+ 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42,
+ 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,110, 99,111,
+108, 32, 61, 32, 40,102, 97, 99,109, 32, 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59,
+ 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115, 99,114,101,101,110, 40,118,101, 99, 51, 32,111,117,
+116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,
+108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,
+111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32,
+ 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,118,101, 99, 51, 40, 49, 46, 48, 41, 32,
+ 45, 32, 40,118,101, 99, 51, 40,102, 97, 99,109, 41, 32, 43, 32,102, 97, 99,116, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32,
+ 45, 32,116,101,120, 99,111,108, 41, 41, 42, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,111,117,116, 99,111,108, 41, 59,
+ 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,111,118,101,114,108, 97,121, 40,118,101, 99, 51, 32,111,
+117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,
+102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,
+108,111, 97,116, 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109,
+ 32, 61, 32, 49, 46, 48, 45,102, 97, 99,103, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46,114, 32, 60, 32, 48, 46, 53,
+ 41, 10, 9, 9,105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 42, 40,102, 97, 99,109, 32, 43, 32, 50,
+ 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108,
+ 46,114, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48,
+ 32, 45, 32,116,101,120, 99,111,108, 46,114, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,114, 41, 59, 10,
+ 10, 9,105,102, 40,111,117,116, 99,111,108, 46,103, 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61,
+ 32,111,117,116, 99,111,108, 46,103, 42, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,
+108, 46,103, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 46,103, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102,
+ 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46,103, 41, 41,
+ 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,108, 46,103, 41, 59, 10, 10, 9,105,102, 40,111,117,116, 99,111,108, 46, 98,
+ 32, 60, 32, 48, 46, 53, 41, 10, 9, 9,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 42, 40,102, 97,
+ 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,116, 42,116,101,120, 99,111,108, 46, 98, 41, 59, 10, 9,101,108,115,101, 10, 9,
+ 9,105,110, 99,111,108, 46, 98, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,102, 97, 99,109, 32, 43, 32, 50, 46, 48, 42,102, 97, 99,
+116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 46, 98, 41, 41, 42, 40, 49, 46, 48, 32, 45, 32,111,117,116, 99,111,
+108, 46, 98, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115,117, 98, 40,118,101, 99, 51, 32,
+111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44,
+ 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,
+105,110, 99,111,108, 32, 61, 32, 45,102, 97, 99,116, 42,102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,
+111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95, 97,100,100, 40,118,101, 99, 51, 32,111,117,
+116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,
+108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,105,110,
+ 99,111,108, 32, 61, 32,102, 97, 99,116, 42,102, 97, 99,103, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59,
+ 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,100,105,118, 40,118,101, 99, 51, 32,111,117,116, 99,111,
+108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,
+116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116,
+ 32,102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49,
+ 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 46,114, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,
+110, 99,111,108, 46,114, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,114, 32, 43, 32,102, 97, 99,116, 42,111,117,
+116, 99,111,108, 46,114, 47,116,101,120, 99,111,108, 46,114, 59, 10, 9,105,102, 40,116,101,120, 99,111,108, 46,103, 32, 33, 61,
+ 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46,103, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 46,103, 32, 43, 32,
+102, 97, 99,116, 42,111,117,116, 99,111,108, 46,103, 47,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40,116,101,120, 99,
+111,108, 46, 98, 32, 33, 61, 32, 48, 46, 48, 41, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,
+111,108, 46, 98, 32, 43, 32,102, 97, 99,116, 42,111,117,116, 99,111,108, 46, 98, 47,116,101,120, 99,111,108, 46, 98, 59, 10,125,
+ 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,100,105,102,102, 40,118,101, 99, 51, 32,111,117,116, 99,111,108,
+ 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116,
+ 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,
+102, 97, 99,109, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49, 46,
+ 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,
+102, 97, 99,116, 42, 97, 98,115, 40,116,101,120, 99,111,108, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,
+105,100, 32,109,116,101,120, 95,114,103, 98, 95,100, 97,114,107, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101,
+ 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,
+103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109,
+ 44, 32, 99,111,108, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61, 32, 49,
+ 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,114, 59, 10,
+ 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,114, 32, 61, 32, 99,111,
+108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114, 59, 10, 9, 99,111,108,
+ 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,
+111,108, 46,103, 41, 32,105,110, 99,111,108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,
+103, 32, 61, 32,111,117,116, 99,111,108, 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108,
+ 46, 98, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110, 99,111,108, 46, 98, 32,
+ 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,111,108, 46, 98, 59, 10,
+125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,108,105,103,104,116, 40,118,101, 99, 51, 32,111,117,116, 99,
+111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111,
+ 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,
+116, 32,102, 97, 99,109, 44, 32, 99,111,108, 59, 10, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97,
+ 99,109, 32, 61, 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,
+111,108, 46,114, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46,114, 41, 32,105,110, 99,111,108, 46,
+114, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46,114, 32, 61, 32,111,117,116, 99,111,108, 46,114,
+ 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 46,103, 59, 10, 9,105,102, 40, 99,111,108, 32,
+ 62, 32,111,117,116, 99,111,108, 46,103, 41, 32,105,110, 99,111,108, 46,103, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,
+105,110, 99,111,108, 46,103, 32, 61, 32,111,117,116, 99,111,108, 46,103, 59, 10, 9, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,
+116,101,120, 99,111,108, 46, 98, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 46, 98, 41, 32,105,110,
+ 99,111,108, 46, 98, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 46, 98, 32, 61, 32,111,117,116, 99,
+111,108, 46, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,104,117,101, 40,118,101, 99, 51, 32,
+111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44,
+ 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,
+118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,105,120, 95,104,117,101, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,
+101, 99, 52, 40,111,117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49,
+ 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59,
+ 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,115, 97,116, 40,118,101, 99, 51, 32,111,117,116, 99,111,
+108, 44, 32,118,101, 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,
+116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32,
+ 99,111,108, 59, 10, 10, 9,109,105,120, 95,115, 97,116, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,
+117,116, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32,
+ 99,111,108, 41, 59, 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,
+111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,118, 97,108, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101,
+ 99, 51, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,
+103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10,
+ 10, 9,109,105,120, 95,118, 97,108, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108,
+ 44, 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59,
+ 10, 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,
+116,101,120, 95,114,103, 98, 95, 99,111,108,111,114, 40,118,101, 99, 51, 32,111,117,116, 99,111,108, 44, 32,118,101, 99, 51, 32,
+116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,
+111,117,116, 32,118,101, 99, 51, 32,105,110, 99,111,108, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111,108, 59, 10, 10, 9,109,
+105,120, 95, 99,111,108,111,114, 40,102, 97, 99,116, 42,102, 97, 99,103, 44, 32,118,101, 99, 52, 40,111,117,116, 99,111,108, 44,
+ 32, 49, 46, 48, 41, 44, 32,118,101, 99, 52, 40,116,101,120, 99,111,108, 44, 32, 49, 46, 48, 41, 44, 32, 99,111,108, 41, 59, 10,
+ 9,105,110, 99,111,108, 46,114,103, 98, 32, 61, 32, 99,111,108, 46,114,103, 98, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,
+101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,105,110,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,
+102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,102, 97, 99,109, 44, 32,102,108,111, 97,
+116, 32,102,108,105,112, 41, 10,123, 10, 9,102, 97, 99,116, 32, 42, 61, 32,102, 97, 99,103, 59, 10, 9,102, 97, 99,109, 32, 61,
+ 32, 49, 46, 48, 45,102, 97, 99,116, 59, 10, 10, 9,105,102, 40,102,108,105,112, 32, 33, 61, 32, 48, 46, 48, 41, 32,123, 10, 9,
+ 9,102,108,111, 97,116, 32,116,109,112, 32, 61, 32,102, 97, 99,116, 59, 10, 9, 9,102, 97, 99,116, 32, 61, 32,102, 97, 99,109,
+ 59, 10, 9, 9,102, 97, 99,109, 32, 61, 32,116,109,112, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,
+118, 97,108,117,101, 95, 98,108,101,110,100, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,
+116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,
+102,108,111, 97,116, 32,102,108,105,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,
+102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,
+116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 44, 32,102,108,105,112, 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,
+102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,
+105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,109,117,108, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,
+102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,
+102, 97, 99,103, 44, 32,102,108,111, 97,116, 32,102,108,105,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,
+108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,
+114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 44, 32,102,108,105,112, 41, 59, 10, 10, 9,102, 97,
+ 99,109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99,103, 59, 10, 9,105,110, 99,111,108, 32, 61, 32, 40,102, 97, 99,109, 32,
+ 43, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 41, 42,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,
+116,101,120, 95,118, 97,108,117,101, 95,115, 99,114,101,101,110, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,
+108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102,
+ 97, 99,103, 44, 32,102,108,111, 97,116, 32,102,108,105,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108,
+ 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,
+115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 44, 32,102,108,105,112, 41, 59, 10, 10, 9,102, 97, 99,
+109, 32, 61, 32, 49, 46, 48, 32, 45, 32,102, 97, 99,103, 59, 10, 9,105,110, 99,111,108, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40,
+102, 97, 99,109, 32, 43, 32,102, 97, 99,116, 42, 40, 49, 46, 48, 32, 45, 32,116,101,120, 99,111,108, 41, 41, 42, 40, 49, 46, 48,
+ 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,115,
+117, 98, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,
+108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,102,108,111, 97,116, 32,102,108,105,
+112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,
+109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,
+102, 97, 99,109, 44, 32,102,108,105,112, 41, 59, 10, 10, 9,102, 97, 99,116, 32, 61, 32, 45,102, 97, 99,116, 59, 10, 9,105,110,
+ 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,
+111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95, 97,100,100, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44,
+ 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116,
+ 32,102, 97, 99,103, 44, 32,102,108,111, 97,116, 32,102,108,105,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,
+111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118,
+ 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 44, 32,102,108,105,112, 41, 59, 10, 10, 9,102,
+ 97, 99,116, 32, 61, 32,102, 97, 99,116, 59, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108,
+ 32, 43, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,
+118, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,
+111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,102,108,111, 97,116, 32,102,108,105,112,
+ 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109,
+ 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102,
+ 97, 99,109, 44, 32,102,108,105,112, 41, 59, 10, 10, 9,105,102, 40,116,101,120, 99,111,108, 32, 33, 61, 32, 48, 46, 48, 41, 10,
+ 9, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42,111,117,116,
+ 99,111,108, 47,116,101,120, 99,111,108, 59, 10, 9,101,108,115,101, 10, 9, 9,105,110, 99,111,108, 32, 61, 32, 48, 46, 48, 59,
+ 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,100,105,102,102, 40,102,108,111, 97,116, 32,111,
+117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44,
+ 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,102,108,111, 97,116, 32,102,108,105,112, 44, 32,111,117,116, 32,102,108,111,
+ 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118,
+ 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 44, 32,102,108,105,112,
+ 41, 59, 10, 10, 9,105,110, 99,111,108, 32, 61, 32,102, 97, 99,109, 42,111,117,116, 99,111,108, 32, 43, 32,102, 97, 99,116, 42,
+ 97, 98,115, 40,116,101,120, 99,111,108, 32, 45, 32,111,117,116, 99,111,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,
+101,120, 95,118, 97,108,117,101, 95,100, 97,114,107, 40,102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,
+116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103,
+ 44, 32,102,108,111, 97,116, 32,102,108,105,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123,
+ 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10, 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102,
+ 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,109, 44, 32,102,108,105,112, 41, 59, 10, 10, 9,102,108,111, 97,116, 32,
+ 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120, 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 60, 32,111,117,116,
+ 99,111,108, 41, 32,105,110, 99,111,108, 32, 61, 32, 99,111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32,111,
+117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,118, 97,108,117,101, 95,108,105,103,104,116, 40,
+102,108,111, 97,116, 32,111,117,116, 99,111,108, 44, 32,102,108,111, 97,116, 32,116,101,120, 99,111,108, 44, 32,102,108,111, 97,
+116, 32,102, 97, 99,116, 44, 32,102,108,111, 97,116, 32,102, 97, 99,103, 44, 32,102,108,111, 97,116, 32,102,108,105,112, 44, 32,
+111,117,116, 32,102,108,111, 97,116, 32,105,110, 99,111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,109, 59, 10,
+ 9,109,116,101,120, 95,118, 97,108,117,101, 95,118, 97,114,115, 40,102, 97, 99,116, 44, 32,102, 97, 99,103, 44, 32,102, 97, 99,
+109, 44, 32,102,108,105,112, 41, 59, 10, 10, 9,102,108,111, 97,116, 32, 99,111,108, 32, 61, 32,102, 97, 99,116, 42,116,101,120,
+ 99,111,108, 59, 10, 9,105,102, 40, 99,111,108, 32, 62, 32,111,117,116, 99,111,108, 41, 32,105,110, 99,111,108, 32, 61, 32, 99,
+111,108, 59, 32,101,108,115,101, 32,105,110, 99,111,108, 32, 61, 32,111,117,116, 99,111,108, 59, 10,125, 10, 10,118,111,105,100,
+ 32,109,116,101,120, 95,118, 97,108,117,101, 95, 99,108, 97,109,112, 95,112,111,115,105,116,105,118,101, 40,102,108,111, 97,116,
+ 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,111,117,116,102, 97,
+ 99, 32, 61, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,
+118, 97,108,117,101, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116,
+ 32,111,117,116,102, 97, 99, 41, 10,123, 10, 9,111,117,116,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40,102, 97, 99, 44, 32,
+ 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,104, 97,114, 95,100,105,118,105,
+100,101, 40,102,108,111, 97,116, 32,104, 97,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,104, 97,114, 41, 10,
+123, 10, 9,111,117,116,104, 97,114, 32, 61, 32,104, 97,114, 47, 49, 50, 56, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,109,
+116,101,120, 95,104, 97,114, 95,109,117,108,116,105,112,108,121, 95, 99,108, 97,109,112, 40,102,108,111, 97,116, 32,104, 97,114,
+ 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,104, 97,114, 41, 10,123, 10, 9,104, 97,114, 32, 42, 61, 32, 49, 50,
+ 56, 46, 48, 59, 10, 10, 9,105,102, 40,104, 97,114, 32, 60, 32, 49, 46, 48, 41, 32,111,117,116,104, 97,114, 32, 61, 32, 49, 46,
+ 48, 59, 10, 9,101,108,115,101, 32,105,102, 40,104, 97,114, 32, 62, 32, 53, 49, 49, 46, 48, 41, 32,111,117,116,104, 97,114, 32,
+ 61, 32, 53, 49, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,111,117,116,104, 97,114, 32, 61, 32,104, 97,114, 59, 10,125, 10, 10,
+118,111,105,100, 32,109,116,101,120, 95, 97,108,112,104, 97, 95,102,114,111,109, 95, 99,111,108, 40,118,101, 99, 52, 32, 99,111,
+108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 41, 10,123, 10, 9, 97,108,112,104, 97, 32, 61, 32, 99,
+111,108, 46, 97, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 97,108,112,104, 97, 95,116,111, 95, 99,111,108, 40,
+118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111, 97,116, 32, 97,108,112,104, 97, 44, 32,111,117,116, 32,118,101, 99, 52, 32,
+111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98,
+ 44, 32, 97,108,112,104, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98,116,111,105,110,116, 40,
+118,101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,116,101,110,115,105,116,121, 41, 10,123,
+ 10, 9,105,110,116,101,110,115,105,116,121, 32, 61, 32,100,111,116, 40,118,101, 99, 51, 40, 48, 46, 51, 53, 44, 32, 48, 46, 52,
+ 53, 44, 32, 48, 46, 50, 41, 44, 32,114,103, 98, 46,114,103, 98, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,
+118, 97,108,117,101, 95,105,110,118,101,114,116, 40,102,108,111, 97,116, 32,105,110,118, 97,108,117,101, 44, 32,111,117,116, 32,
+102,108,111, 97,116, 32,111,117,116,118, 97,108,117,101, 41, 10,123, 10, 9,111,117,116,118, 97,108,117,101, 32, 61, 32, 49, 46,
+ 48, 32, 45, 32,105,110,118, 97,108,117,101, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,114,103, 98, 95,105,110,
+118,101,114,116, 40,118,101, 99, 52, 32,105,110,114,103, 98, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98,
+ 41, 10,123, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,118,101, 99, 51, 40, 49, 46, 48, 41, 32, 45, 32,105,
+110,114,103, 98, 46,114,103, 98, 44, 32,105,110,114,103, 98, 46, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120,
+ 95,118, 97,108,117,101, 95,115,116,101,110, 99,105,108, 40,102,108,111, 97,116, 32,115,116,101,110, 99,105,108, 44, 32,102,108,
+111, 97,116, 32,105,110,116,101,110,115,105,116,121, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,115,116,101,110,
+ 99,105,108, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105,110,116,101,110,115,105,116,121, 41, 10,123, 10, 9,
+102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,105,110,116,101,110,115,105,116,121, 59, 10, 9,111,117,116,105,110,116,101,
+110,115,105,116,121, 32, 61, 32,105,110,116,101,110,115,105,116,121, 42,115,116,101,110, 99,105,108, 59, 10, 9,111,117,116,115,
+116,101,110, 99,105,108, 32, 61, 32,115,116,101,110, 99,105,108, 42,102, 97, 99,116, 59, 10,125, 10, 10,118,111,105,100, 32,109,
+116,101,120, 95,114,103, 98, 95,115,116,101,110, 99,105,108, 40,102,108,111, 97,116, 32,115,116,101,110, 99,105,108, 44, 32,118,
+101, 99, 52, 32,114,103, 98, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,115,116,101,110, 99,105,108, 44, 32,111,
+117,116, 32,118,101, 99, 52, 32,111,117,116,114,103, 98, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99,116, 32, 61, 32,
+114,103, 98, 46, 97, 59, 10, 9,111,117,116,114,103, 98, 32, 61, 32,118,101, 99, 52, 40,114,103, 98, 46,114,103, 98, 44, 32,114,
+103, 98, 46, 97, 42,115,116,101,110, 99,105,108, 41, 59, 10, 9,111,117,116,115,116,101,110, 99,105,108, 32, 61, 32,115,116,101,
+110, 99,105,108, 42,102, 97, 99,116, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,109, 97,112,112,105,110,103, 95,
+111,102,115, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, 99, 51, 32,111,102,115, 44, 32,111,117,116, 32,118,101,
+ 99, 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117,116,116,101,120, 99,111, 32, 61, 32,116,101,120, 99,111,
+ 32, 43, 32,111,102,115, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,109, 97,112,112,105,110,103, 95,115,105,122,
+101, 40,118,101, 99, 51, 32,116,101,120, 99,111, 44, 32,118,101, 99, 51, 32,115,105,122,101, 44, 32,111,117,116, 32,118,101, 99,
+ 51, 32,111,117,116,116,101,120, 99,111, 41, 10,123, 10, 9,111,117,116,116,101,120, 99,111, 32, 61, 32,115,105,122,101, 42,116,
+101,120, 99,111, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 50,100, 95,109, 97,112,112,105,110,103, 40,118,101,
+ 99, 51, 32,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,118,101, 99, 41, 10,123, 10, 9,111,117,116,118,
+101, 99, 32, 61, 32,118,101, 99, 51, 40,118,101, 99, 46,120,121, 42, 48, 46, 53, 32, 43, 32,118,101, 99, 50, 40, 48, 46, 53, 44,
+ 32, 48, 46, 53, 41, 44, 32,118,101, 99, 46,122, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,105,109, 97,103,
+101, 40,118,101, 99, 51, 32,118,101, 99, 44, 32,115, 97,109,112,108,101,114, 50, 68, 32,105,109, 97, 44, 32,111,117,116, 32,102,
+108,111, 97,116, 32,118, 97,108,117,101, 44, 32,111,117,116, 32,118,101, 99, 52, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,
+118,101, 99, 51, 32,110,111,114,109, 97,108, 41, 10,123, 10, 9, 99,111,108,111,114, 32, 61, 32,116,101,120,116,117,114,101, 50,
+ 68, 40,105,109, 97, 44, 32,118,101, 99, 46,120,121, 41, 59, 10, 9,118, 97,108,117,101, 32, 61, 32, 49, 46, 48, 59, 10, 9, 10,
+ 9,110,111,114,109, 97,108, 32, 61, 32, 50, 46, 48, 42, 40,118,101, 99, 51, 40, 99,111,108,111,114, 46,114, 44, 32, 45, 99,111,
+108,111,114, 46,103, 44, 32, 99,111,108,111,114, 46, 98, 41, 32, 45, 32,118,101, 99, 51, 40, 48, 46, 53, 44, 32, 45, 48, 46, 53,
+ 44, 32, 48, 46, 53, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95,110,101,103, 97,116,101, 95,116,101,120,
+110,111,114,109, 97,108, 40,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,
+110,111,114,109, 97,108, 41, 10,123, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,118,101, 99, 51, 40, 45,110,111,114,
+109, 97,108, 46,120, 44, 32, 45,110,111,114,109, 97,108, 46,121, 44, 32,110,111,114,109, 97,108, 46,122, 41, 59, 10,125, 10, 10,
+118,111,105,100, 32,109,116,101,120, 95,110,115,112, 97, 99,101, 95,116, 97,110,103,101,110,116, 40,118,101, 99, 51, 32,116, 97,
+110,103,101,110,116, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, 51, 32,116,101,120,110,111,114,109,
+ 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123, 10, 9,116, 97,110,103,101,
+110,116, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,116, 97,110,103,101,110,116, 41, 59, 10, 9,118,101, 99, 51, 32, 66,
+ 32, 61, 32, 99,114,111,115,115, 40,110,111,114,109, 97,108, 44, 32,116, 97,110,103,101,110,116, 41, 59, 10, 10, 9,111,117,116,
+110,111,114,109, 97,108, 32, 61, 32,116,101,120,110,111,114,109, 97,108, 46,120, 42,116, 97,110,103,101,110,116, 32, 43, 32,116,
+101,120,110,111,114,109, 97,108, 46,121, 42, 66, 32, 43, 32,116,101,120,110,111,114,109, 97,108, 46,122, 42,110,111,114,109, 97,
+108, 59, 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,110,111,114,
+109, 97,108, 41, 59, 10,125, 10, 10,118,111,105,100, 32,109,116,101,120, 95, 98,108,101,110,100, 95,110,111,114,109, 97,108, 40,
+102,108,111, 97,116, 32,110,111,114,102, 97, 99, 44, 32,118,101, 99, 51, 32,110,111,114,109, 97,108, 44, 32,118,101, 99, 51, 32,
+110,101,119,110,111,114,109, 97,108, 44, 32,111,117,116, 32,118,101, 99, 51, 32,111,117,116,110,111,114,109, 97,108, 41, 10,123,
+ 10, 9,111,117,116,110,111,114,109, 97,108, 32, 61, 32, 40, 49, 46, 48, 32, 45, 32,110,111,114,102, 97, 99, 41, 42,110,111,114,
+109, 97,108, 32, 43, 32,110,111,114,102, 97, 99, 42,110,101,119,110,111,114,109, 97,108, 59, 10, 9,111,117,116,110,111,114,109,
+ 97,108, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,111,117,116,110,111,114,109, 97,108, 41, 59, 10,125, 10, 10, 47, 42,
+ 42, 42, 42, 42, 42, 42, 32, 77, 65, 84, 69, 82, 73, 65, 76, 32, 42, 42, 42, 42, 42, 42, 42, 42, 42, 47, 10, 10,118,111,105,100,
+ 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,115,117,110, 95,104,101,109,105, 40,118,101, 99, 51, 32,108,
+ 97,109,112,118,101, 99, 44, 32,111,117,116, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100,
+105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32,
+108, 97,109,112,118,101, 99, 59, 10, 9,100,105,115,116, 32, 61, 32, 49, 46, 48, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61,
+ 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,111,116,
+104,101,114, 40,118,101, 99, 51, 32, 99,111, 44, 32,118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,111,117,116, 32,118,101,
+ 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116,
+ 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,108,118, 32, 61, 32, 99,111, 32, 45, 32,108, 97,109,112, 99,111, 59, 10, 9,
+100,105,115,116, 32, 61, 32,108,101,110,103,116,104, 40,108,118, 41, 59, 10, 9,108,118, 32, 61, 32,110,111,114,109, 97,108,105,
+122,101, 40,108,118, 41, 59, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,
+108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,105,110,118,108,105,110,101, 97,114, 40,102,108,111, 97,116, 32,108, 97,109,
+112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,
+105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,
+112,100,105,115,116, 32, 43, 32,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,
+111,102,102, 95,105,110,118,115,113,117, 97,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,
+111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,
+118,105,115,105,102, 97, 99, 32, 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,100,
+105,115,116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,102, 97,108,108,111,102,102, 95,
+115,108,105,100,101,114,115, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,108,100,
+ 49, 44, 32,102,108,111, 97,116, 32,108,100, 50, 44, 32,102,108,111, 97,116, 32,100,105,115,116, 44, 32,111,117,116, 32,102,108,
+111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116,107,119,
+ 32, 61, 32,108, 97,109,112,100,105,115,116, 42,108, 97,109,112,100,105,115,116, 59, 10, 10, 9,118,105,115,105,102, 97, 99, 32,
+ 61, 32,108, 97,109,112,100,105,115,116, 47, 40,108, 97,109,112,100,105,115,116, 32, 43, 32,108,100, 49, 42,100,105,115,116, 41,
+ 59, 10, 9,118,105,115,105,102, 97, 99, 32, 42, 61, 32,108, 97,109,112,100,105,115,116,107,119, 47, 40,108, 97,109,112,100,105,
+115,116,107,119, 32, 43, 32,108,100, 50, 42,100,105,115,116, 42,100,105,115,116, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108,
+ 97,109,112, 95,102, 97,108,108,111,102,102, 95, 99,117,114,118,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116,
+ 44, 32,115, 97,109,112,108,101,114, 49, 68, 32, 99,117,114,118,101,109, 97,112, 44, 32,102,108,111, 97,116, 32,100,105,115,116,
+ 44, 32,111,117,116, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,118,105,115,105,102, 97, 99, 32,
+ 61, 32,116,101,120,116,117,114,101, 49, 68, 40, 99,117,114,118,101,109, 97,112, 44, 32,100,105,115,116, 47,108, 97,109,112,100,
+105,115,116, 41, 46,120, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95,
+115,112,104,101,114,101, 40,102,108,111, 97,116, 32,108, 97,109,112,100,105,115,116, 44, 32,102,108,111, 97,116, 32,100,105,115,
+116, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,
+105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, 61, 32,108, 97,109,112,100,105,115,116, 32, 45, 32,100,
+105,115,116, 59, 10, 10, 9,111,117,116,118,105,115,105,102, 97, 99, 61, 32,118,105,115,105,102, 97, 99, 42,109, 97,120, 40,116,
+ 44, 32, 48, 46, 48, 41, 47,108, 97,109,112,100,105,115,116, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,
+115,105, 98,105,108,105,116,121, 95,115,112,111,116, 95,115,113,117, 97,114,101, 40,118,101, 99, 51, 32,108, 97,109,112,118,101,
+ 99, 44, 32,109, 97,116, 52, 32,108, 97,109,112,105,109, 97,116, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,
+108,111, 97,116, 32,105,110,112,114, 41, 10,123, 10, 9,105,102, 40,100,111,116, 40,108,118, 44, 32,108, 97,109,112,118,101, 99,
+ 41, 32, 62, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,118,101, 99, 51, 32,108,118,114,111,116, 32, 61, 32, 40,108, 97,109,112,105,
+109, 97,116, 42,118,101, 99, 52, 40,108,118, 44, 32, 48, 46, 48, 41, 41, 46,120,121,122, 59, 10, 9, 9,102,108,111, 97,116, 32,
+120, 32, 61, 32,109, 97,120, 40, 97, 98,115, 40,108,118,114,111,116, 46,120, 47,108,118,114,111,116, 46,122, 41, 44, 32, 97, 98,
+115, 40,108,118,114,111,116, 46,121, 47,108,118,114,111,116, 46,122, 41, 41, 59, 10, 10, 9, 9,105,110,112,114, 32, 61, 32, 49,
+ 46, 48, 47,115,113,114,116, 40, 49, 46, 48, 32, 43, 32,120, 42,120, 41, 59, 10, 9,125, 10, 9,101,108,115,101, 10, 9, 9,105,
+110,112,114, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,
+116,121, 95,115,112,111,116, 95, 99,105,114, 99,108,101, 40,118,101, 99, 51, 32,108, 97,109,112,118,101, 99, 44, 32,118,101, 99,
+ 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112,114, 41, 10,123, 10, 9,105,110,112,114, 32, 61, 32,
+100,111,116, 40,108,118, 44, 32,108, 97,109,112,118,101, 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,
+105,115,105, 98,105,108,105,116,121, 95,115,112,111,116, 40,102,108,111, 97,116, 32,115,112,111,116,115,105, 44, 32,102,108,111,
+ 97,116, 32,115,112,111,116, 98,108, 44, 32,102,108,111, 97,116, 32,105,110,112,114, 44, 32,102,108,111, 97,116, 32,118,105,115,
+105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,105,115,105,102, 97, 99, 41, 10,123, 10, 9,102,
+108,111, 97,116, 32,116, 32, 61, 32,115,112,111,116,115,105, 59, 10, 10, 9,105,102, 40,105,110,112,114, 32, 60, 61, 32,116, 41,
+ 32,123, 10, 9, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,
+123, 10, 9, 9,116, 32, 61, 32,105,110,112,114, 32, 45, 32,116, 59, 10, 10, 9, 9, 47, 42, 32,115,111,102,116, 32, 97,114,101,
+ 97, 32, 42, 47, 10, 9, 9,105,102, 40,115,112,111,116, 98,108, 32, 33, 61, 32, 48, 46, 48, 41, 10, 9, 9, 9,105,110,112,114,
+ 32, 42, 61, 32,115,109,111,111,116,104,115,116,101,112, 40, 48, 46, 48, 44, 32, 49, 46, 48, 44, 32,116, 47,115,112,111,116, 98,
+108, 41, 59, 10, 10, 9, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32,118,105,115,105,102, 97, 99, 42,105,110,112,114,
+ 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,108, 97,109,112, 95,118,105,115,105, 98,105,108,105,116,121, 95, 99,108, 97,
+109,112, 40,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118,
+105,115,105,102, 97, 99, 41, 10,123, 10, 9,111,117,116,118,105,115,105,102, 97, 99, 32, 61, 32, 40,118,105,115,105,102, 97, 99,
+ 32, 60, 32, 48, 46, 48, 48, 49, 41, 63, 32, 48, 46, 48, 58, 32,118,105,115,105,102, 97, 99, 59, 10,125, 10, 10,118,111,105,100,
+ 32,115,104, 97,100,101, 95,118,105,101,119, 40,118,101, 99, 51, 32, 99,111, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,105,
+101,119, 41, 10,123, 10, 9, 47, 42, 32,104, 97,110,100,108,101, 32,112,101,114,115,112,101, 99,116,105,118,101, 47,111,114,116,
+104,111,103,114, 97,112,104,105, 99, 32, 42, 47, 10, 9,118,105,101,119, 32, 61, 32, 40,103,108, 95, 80,114,111,106,101, 99,116,
+105,111,110, 77, 97,116,114,105,120, 91, 51, 93, 91, 51, 93, 32, 61, 61, 32, 48, 46, 48, 41, 63, 32,110,111,114,109, 97,108,105,
+122,101, 40, 99,111, 41, 58, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 45, 49, 46, 48, 41, 59, 10,125, 10,
+ 10,118,111,105,100, 32,115,104, 97,100,101, 95,116, 97,110,103,101,110,116, 95,118, 40,118,101, 99, 51, 32,108,118, 44, 32,118,
+101, 99, 51, 32,116, 97,110,103, 44, 32,111,117,116, 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,101, 99, 51, 32, 99,
+ 32, 61, 32, 99,114,111,115,115, 40,108,118, 44, 32,116, 97,110,103, 41, 59, 10, 9,118,101, 99, 51, 32,118,110,111,114, 32, 61,
+ 32, 99,114,111,115,115, 40, 99, 44, 32,116, 97,110,103, 41, 59, 10, 10, 9,118,110, 32, 61, 32, 45,110,111,114,109, 97,108,105,
+122,101, 40,118,110,111,114, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,105,110,112, 40,118,101, 99, 51,
+ 32,118,110, 44, 32,118,101, 99, 51, 32,108,118, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112, 41, 10,123, 10, 9,
+105,110,112, 32, 61, 32,100,111,116, 40,118,110, 44, 32,108,118, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101,
+ 95,105,115, 95,110,111, 95,100,105,102,102,117,115,101, 40,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,
+105,115, 32, 61, 32, 48, 46, 48, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,105,115, 95,104,101,109,105, 40,
+102,108,111, 97,116, 32,105,110,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,105,115, 32, 61,
+ 32, 48, 46, 53, 42,105,110,112, 32, 43, 32, 48, 46, 53, 59, 10,125, 10, 10,102,108,111, 97,116, 32, 97,114,101, 97, 95,108, 97,
+109,112, 95,101,110,101,114,103,121, 40,109, 97,116, 52, 32, 97,114,101, 97, 44, 32,118,101, 99, 51, 32, 99,111, 44, 32,118,101,
+ 99, 51, 32,118,110, 41, 10,123, 10, 9,118,101, 99, 51, 32,118,101, 99, 91, 52, 93, 44, 32, 99, 91, 52, 93, 59, 10, 9,102,108,
+111, 97,116, 32,114, 97,100, 91, 52, 93, 44, 32,102, 97, 99, 59, 10, 9, 10, 9,118,101, 99, 91, 48, 93, 32, 61, 32,110,111,114,
+109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 48, 93, 46,120,121,122, 41, 59, 10, 9,118,101, 99, 91, 49,
+ 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 49, 93, 46,120,121,122, 41, 59,
+ 10, 9,118,101, 99, 91, 50, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45, 32, 97,114,101, 97, 91, 50,
+ 93, 46,120,121,122, 41, 59, 10, 9,118,101, 99, 91, 51, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,111, 32, 45,
+ 32, 97,114,101, 97, 91, 51, 93, 46,120,121,122, 41, 59, 10, 10, 9, 99, 91, 48, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,
+101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 48, 93, 44, 32,118,101, 99, 91, 49, 93, 41, 41, 59, 10, 9, 99, 91, 49, 93, 32,
+ 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91, 49, 93, 44, 32,118,101, 99, 91, 50, 93,
+ 41, 41, 59, 10, 9, 99, 91, 50, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40, 99,114,111,115,115, 40,118,101, 99, 91,
+ 50, 93, 44, 32,118,101, 99, 91, 51, 93, 41, 41, 59, 10, 9, 99, 91, 51, 93, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,
+ 99,114,111,115,115, 40,118,101, 99, 91, 51, 93, 44, 32,118,101, 99, 91, 48, 93, 41, 41, 59, 10, 10, 9,114, 97,100, 91, 48, 93,
+ 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 48, 93, 44, 32,118,101, 99, 91, 49, 93, 41, 41, 59, 10, 9,114,
+ 97,100, 91, 49, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 49, 93, 44, 32,118,101, 99, 91, 50, 93, 41,
+ 41, 59, 10, 9,114, 97,100, 91, 50, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 50, 93, 44, 32,118,101,
+ 99, 91, 51, 93, 41, 41, 59, 10, 9,114, 97,100, 91, 51, 93, 32, 61, 32, 97, 99,111,115, 40,100,111,116, 40,118,101, 99, 91, 51,
+ 93, 44, 32,118,101, 99, 91, 48, 93, 41, 41, 59, 10, 10, 9,102, 97, 99, 61, 32, 32,114, 97,100, 91, 48, 93, 42,100,111,116, 40,
+118,110, 44, 32, 99, 91, 48, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 49, 93, 42,100,111,116, 40,118,110, 44,
+ 32, 99, 91, 49, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 50, 93, 42,100,111,116, 40,118,110, 44, 32, 99, 91,
+ 50, 93, 41, 59, 10, 9,102, 97, 99, 43, 61, 32,114, 97,100, 91, 51, 93, 42,100,111,116, 40,118,110, 44, 32, 99, 91, 51, 93, 41,
+ 59, 10, 10, 9,114,101,116,117,114,110, 32,109, 97,120, 40,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,
+100, 32,115,104, 97,100,101, 95,105,110,112, 95, 97,114,101, 97, 40,118,101, 99, 51, 32,112,111,115,105,116,105,111,110, 44, 32,
+118,101, 99, 51, 32,108, 97,109,112, 99,111, 44, 32,118,101, 99, 51, 32,108, 97,109,112,118,101, 99, 44, 32,118,101, 99, 51, 32,
+118,110, 44, 32,109, 97,116, 52, 32, 97,114,101, 97, 44, 32,102,108,111, 97,116, 32, 97,114,101, 97,115,105,122,101, 44, 32,102,
+108,111, 97,116, 32,107, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,110,112, 41, 10,123, 10, 9,118,101, 99, 51, 32, 99,
+111, 32, 61, 32,112,111,115,105,116,105,111,110, 59, 10, 9,118,101, 99, 51, 32,118,101, 99, 32, 61, 32, 99,111, 32, 45, 32,108,
+ 97,109,112, 99,111, 59, 10, 10, 9,105,102, 40,100,111,116, 40,118,101, 99, 44, 32,108, 97,109,112,118,101, 99, 41, 32, 60, 32,
+ 48, 46, 48, 41, 32,123, 10, 9, 9,105,110,112, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9,
+ 9,102,108,111, 97,116, 32,105,110,116,101,110,115, 32, 61, 32, 97,114,101, 97, 95,108, 97,109,112, 95,101,110,101,114,103,121,
+ 40, 97,114,101, 97, 44, 32, 99,111, 44, 32,118,110, 41, 59, 10, 10, 9, 9,105,110,112, 32, 61, 32,112,111,119, 40,105,110,116,
+101,110,115, 42, 97,114,101, 97,115,105,122,101, 44, 32,107, 41, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,
+100,101, 95,100,105,102,102,117,115,101, 95,111,114,101,110, 95,110, 97,121,101,114, 40,102,108,111, 97,116, 32,110,108, 44, 32,
+118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,114,111,
+117,103,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,
+111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,109, 97,120,
+ 40,100,111,116, 40,110, 44, 32,104, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,
+120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9,102,108,111, 97,116, 32,114,101, 97,108,110,108,
+ 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 10, 9,105,102, 40,114,101, 97,108,110,108, 32, 60, 32, 48, 46, 48, 41,
+ 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,105,102, 40,110,108, 32, 60, 32,
+ 48, 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,
+102,108,111, 97,116, 32,118,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,118, 44, 32,104, 41, 44, 32, 48, 46, 48, 41, 59, 10,
+ 9, 9,102,108,111, 97,116, 32, 76,105,116, 95, 65, 32, 61, 32, 97, 99,111,115, 40,114,101, 97,108,110,108, 41, 59, 10, 9, 9,
+102,108,111, 97,116, 32, 86,105,101,119, 95, 65, 32, 61, 32, 97, 99,111,115, 40,110,118, 41, 59, 10, 10, 9, 9,118,101, 99, 51,
+ 32, 76,105,116, 95, 66, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 45, 32,114,101, 97,108,110,108, 42,110, 41,
+ 59, 10, 9, 9,118,101, 99, 51, 32, 86,105,101,119, 95, 66, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 45, 32,
+110,118, 42,110, 41, 59, 10, 10, 9, 9,102,108,111, 97,116, 32,116, 32, 61, 32,109, 97,120, 40,100,111,116, 40, 76,105,116, 95,
+ 66, 44, 32, 86,105,101,119, 95, 66, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9, 9,102,108,111, 97,116, 32, 97, 44, 32, 98, 59,
+ 10, 10, 9, 9,105,102, 40, 76,105,116, 95, 65, 32, 62, 32, 86,105,101,119, 95, 65, 41, 32,123, 10, 9, 9, 9, 97, 32, 61, 32,
+ 76,105,116, 95, 65, 59, 10, 9, 9, 9, 98, 32, 61, 32, 86,105,101,119, 95, 65, 59, 10, 9, 9,125, 10, 9, 9,101,108,115,101,
+ 32,123, 10, 9, 9, 9, 97, 32, 61, 32, 86,105,101,119, 95, 65, 59, 10, 9, 9, 9, 98, 32, 61, 32, 76,105,116, 95, 65, 59, 10,
+ 9, 9,125, 10, 10, 9, 9,102,108,111, 97,116, 32, 65, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 48, 46, 53, 42, 40, 40,114,111,
+117,103,104, 42,114,111,117,103,104, 41, 47, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 32, 43, 32, 48, 46, 51, 51,
+ 41, 41, 41, 59, 10, 9, 9,102,108,111, 97,116, 32, 66, 32, 61, 32, 48, 46, 52, 53, 42, 40, 40,114,111,117,103,104, 42,114,111,
+117,103,104, 41, 47, 40, 40,114,111,117,103,104, 42,114,111,117,103,104, 41, 32, 43, 32, 48, 46, 48, 57, 41, 41, 59, 10, 10, 9,
+ 9, 98, 32, 42, 61, 32, 48, 46, 57, 53, 59, 10, 9, 9,105,115, 32, 61, 32,110,108, 42, 40, 65, 32, 43, 32, 40, 66, 32, 42, 32,
+116, 32, 42, 32,115,105,110, 40, 97, 41, 32, 42, 32,116, 97,110, 40, 98, 41, 41, 41, 59, 10, 9,125, 10,125, 10, 10,118,111,105,
+100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,116,111,111,110, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99,
+ 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,115,105,122,101, 44, 32,102,108,111, 97,116, 32,116,
+115,109,111,111,116,104, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,102,108,111, 97,116, 32,114,
+115,108,116, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,110,103, 32, 61, 32, 97, 99,
+111,115, 40,114,115,108,116, 41, 59, 10, 10, 9,105,102, 40, 97,110,103, 32, 60, 32,115,105,122,101, 41, 32,105,115, 32, 61, 32,
+ 49, 46, 48, 59, 10, 9,101,108,115,101, 32,105,102, 40, 97,110,103, 32, 62, 32, 40,115,105,122,101, 32, 43, 32,116,115,109,111,
+111,116,104, 41, 32,124,124, 32,116,115,109,111,111,116,104, 32, 61, 61, 32, 48, 46, 48, 41, 32,105,115, 32, 61, 32, 48, 46, 48,
+ 59, 10, 9,101,108,115,101, 32,105,115, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 40, 97,110,103, 32, 45, 32,115,105,122,101, 41,
+ 47,116,115,109,111,111,116,104, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101,
+ 95,109,105,110,110, 97,101,114,116, 40,102,108,111, 97,116, 32,110,108, 44, 32,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51,
+ 32,118, 44, 32,102,108,111, 97,116, 32,100, 97,114,107,110,101,115,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115,
+ 41, 10,123, 10, 9,105,102, 40,110,108, 32, 60, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,105,115, 32, 61, 32, 48, 46, 48, 59,
+ 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116,
+ 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9, 9,105,102, 40,100, 97,114,107,110,101,115,115, 32, 60, 61, 32,
+ 49, 46, 48, 41, 10, 9, 9, 9,105,115, 32, 61, 32,110,108, 42,112,111,119, 40,109, 97,120, 40,110,118, 42,110,108, 44, 32, 48,
+ 46, 49, 41, 44, 32,100, 97,114,107,110,101,115,115, 32, 45, 32, 49, 46, 48, 41, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,
+105,115, 32, 61, 32,110,108, 42,112,111,119, 40, 49, 46, 48, 48, 48, 49, 32, 45, 32,110,118, 44, 32,100, 97,114,107,110,101,115,
+115, 32, 45, 32, 49, 46, 48, 41, 59, 10, 9,125, 10,125, 10, 10,102,108,111, 97,116, 32,102,114,101,115,110,101,108, 95,102, 97,
+ 99, 40,118,101, 99, 51, 32,118,105,101,119, 44, 32,118,101, 99, 51, 32,118,110, 44, 32,102,108,111, 97,116, 32,103,114, 97,100,
+ 44, 32,102,108,111, 97,116, 32,102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,116, 49, 44, 32,116, 50, 59, 10, 9,102,
+108,111, 97,116, 32,102,102, 97, 99, 59, 10, 10, 9,105,102, 40,102, 97, 99, 61, 61, 48, 46, 48, 41, 32,123, 10, 9, 9,102,102,
+ 97, 99, 32, 61, 32, 49, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,116, 49, 61, 32,100,111,116, 40,118,
+105,101,119, 44, 32,118,110, 41, 59, 10, 9, 9,105,102, 40,116, 49, 62, 48, 46, 48, 41, 32, 32,116, 50, 61, 32, 49, 46, 48, 43,
+116, 49, 59, 10, 9, 9,101,108,115,101, 32,116, 50, 61, 32, 49, 46, 48, 45,116, 49, 59, 10, 10, 9, 9,116, 50, 61, 32,103,114,
+ 97,100, 32, 43, 32, 40, 49, 46, 48, 45,103,114, 97,100, 41, 42,112,111,119, 40,116, 50, 44, 32,102, 97, 99, 41, 59, 10, 10, 9,
+ 9,105,102, 40,116, 50, 60, 48, 46, 48, 41, 32,102,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,105,
+102, 40,116, 50, 62, 49, 46, 48, 41, 32,102,102, 97, 99, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9,101,108,115,101, 32,102,102, 97,
+ 99, 32, 61, 32,116, 50, 59, 10, 9,125, 10, 10, 9,114,101,116,117,114,110, 32,102,102, 97, 99, 59, 10,125, 10, 10,118,111,105,
+100, 32,115,104, 97,100,101, 95,100,105,102,102,117,115,101, 95,102,114,101,115,110,101,108, 40,118,101, 99, 51, 32,118,110, 44,
+ 32,118,101, 99, 51, 32,108,118, 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,102,108,111, 97,116, 32,102, 97, 99, 95,105,
+ 44, 32,102,108,111, 97,116, 32,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,105,115, 41, 10,123, 10, 9,105,115,
+ 32, 61, 32,102,114,101,115,110,101,108, 95,102, 97, 99, 40,108,118, 44, 32,118,110, 44, 32,102, 97, 99, 95,105, 44, 32,102, 97,
+ 99, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 99,117, 98,105, 99, 40,102,108,111, 97,116, 32,105,115,
+ 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,105,115, 41, 10,123, 10, 9,105,102, 40,105,115, 62, 48, 46, 48, 32,
+ 38, 38, 32,105,115, 60, 49, 46, 48, 41, 10, 9, 9,111,117,116,105,115, 61, 32,115,109,111,111,116,104,115,116,101,112, 40, 48,
+ 46, 48, 44, 32, 49, 46, 48, 44, 32,105,115, 41, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,105,115, 61, 32,105,115, 59,
+ 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,118,105,115,105,102, 97, 99, 40,102,108,111, 97,116, 32,105, 44, 32,
+102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,102,108,111, 97,116, 32,114,101,102,108, 44, 32,111,117,116, 32,102,
+108,111, 97,116, 32,111,117,116,105, 41, 10,123, 10, 9, 47, 42,105,102, 40,105, 32, 62, 32, 48, 46, 48, 41, 42, 47, 10, 9, 9,
+111,117,116,105, 32, 61, 32,109, 97,120, 40,105, 42,118,105,115,105,102, 97, 99, 42,114,101,102,108, 44, 32, 48, 46, 48, 41, 59,
+ 10, 9, 47, 42,101,108,115,101, 10, 9, 9,111,117,116,105, 32, 61, 32,105, 59, 42, 47, 10,125, 10, 10,118,111,105,100, 32,115,
+104, 97,100,101, 95,116, 97,110,103,101,110,116, 95,118, 95,115,112,101, 99, 40,118,101, 99, 51, 32,116, 97,110,103, 44, 32,111,
+117,116, 32,118,101, 99, 51, 32,118,110, 41, 10,123, 10, 9,118,110, 32, 61, 32,116, 97,110,103, 59, 10,125, 10, 10,118,111,105,
+100, 32,115,104, 97,100,101, 95, 97,100,100, 95,116,111, 95,100,105,102,102,117,115,101, 40,102,108,111, 97,116, 32,105, 44, 32,
+118,101, 99, 51, 32,108, 97,109,112, 99,111,108, 44, 32,118,101, 99, 51, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 51,
+ 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,105,102, 40,105, 32, 62, 32, 48, 46, 48, 41, 10, 9, 9,111,117,116, 99,111,108,
+ 32, 61, 32,105, 42,108, 97,109,112, 99,111,108, 42, 99,111,108, 59, 10, 9,101,108,115,101, 10, 9, 9,111,117,116, 99,111,108,
+ 32, 61, 32,118,101, 99, 51, 40, 48, 46, 48, 44, 32, 48, 46, 48, 44, 32, 48, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,
+115,104, 97,100,101, 95,104,101,109,105, 95,115,112,101, 99, 40,118,101, 99, 51, 32,118,110, 44, 32,118,101, 99, 51, 32,108,118,
+ 44, 32,118,101, 99, 51, 32,118,105,101,119, 44, 32,102,108,111, 97,116, 32,115,112,101, 99, 44, 32,102,108,111, 97,116, 32,104,
+ 97,114,100, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,116, 41,
+ 10,123, 10, 9,108,118, 32, 43, 61, 32,118,105,101,119, 59, 10, 9,108,118, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,
+108,118, 41, 59, 10, 10, 9,116, 32, 61, 32,100,111,116, 40,118,110, 44, 32,108,118, 41, 59, 10, 9,116, 32, 61, 32, 48, 46, 53,
+ 42,116, 32, 43, 32, 48, 46, 53, 59, 10, 10, 9,116, 32, 61, 32,118,105,115,105,102, 97, 99, 42,115,112,101, 99, 42,112,111,119,
+ 40,116, 44, 32,104, 97,114,100, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,112,104,111,110,103, 95,115,
+112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,
+116, 32,104, 97,114,100, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101,
+ 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, 59, 10, 9,102,108,111, 97,116, 32,
+114,115,108,116, 32, 61, 32,109, 97,120, 40,100,111,116, 40,104, 44, 32,110, 41, 44, 32, 48, 46, 48, 41, 59, 10, 10, 9,115,112,
+101, 99,102, 97, 99, 32, 61, 32,112,111,119, 40,114,115,108,116, 44, 32,104, 97,114,100, 41, 59, 10,125, 10, 10,118,111,105,100,
+ 32,115,104, 97,100,101, 95, 99,111,111,107,116,111,114,114, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99,
+ 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,108,111, 97,116, 32,104, 97,114,100, 44, 32,111,117,116, 32,102,108,111,
+ 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,
+101, 40,118, 32, 43, 32,108, 41, 59, 10, 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,100,111,116, 40,110, 44, 32,104, 41, 59,
+ 10, 10, 9,105,102, 40,110,104, 32, 60, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46,
+ 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,
+111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46, 48, 41, 59, 10, 9, 9,102,108,111, 97,116, 32,105, 32, 61, 32,112,111,119, 40,
+110,104, 44, 32,104, 97,114,100, 41, 59, 10, 10, 9, 9,105, 32, 61, 32,105, 47, 40, 48, 46, 49, 43,110,118, 41, 59, 10, 9, 9,
+115,112,101, 99,102, 97, 99, 32, 61, 32,105, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 98,108,
+105,110,110, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44,
+ 32,102,108,111, 97,116, 32,114,101,102,114, 97, 99, 44, 32,102,108,111, 97,116, 32,115,112,101, 99, 95,112,111,119,101,114, 44,
+ 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,105,102, 40,114,101,102,114, 97, 99,
+ 32, 60, 32, 49, 46, 48, 41, 32,123, 10, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,
+108,115,101, 32,105,102, 40,115,112,101, 99, 95,112,111,119,101,114, 32, 61, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,115,112,
+101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,105,102, 40,115,112,101,
+ 99, 95,112,111,119,101,114, 60, 49, 48, 48, 46, 48, 41, 10, 9, 9, 9,115,112,101, 99, 95,112,111,119,101,114, 61, 32,115,113,
+114,116, 40, 49, 46, 48, 47,115,112,101, 99, 95,112,111,119,101,114, 41, 59, 10, 9, 9,101,108,115,101, 10, 9, 9, 9,115,112,
+101, 99, 95,112,111,119,101,114, 61, 32, 49, 48, 46, 48, 47,115,112,101, 99, 95,112,111,119,101,114, 59, 10, 10, 9, 9,118,101,
+ 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,118, 32, 43, 32,108, 41, 59, 10, 9, 9,102,108,111, 97,116,
+ 32,110,104, 32, 61, 32,100,111,116, 40,110, 44, 32,104, 41, 59, 10, 9, 9,105,102, 40,110,104, 32, 60, 32, 48, 46, 48, 41, 32,
+123, 10, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32, 48, 46, 48, 59, 10, 9, 9,125, 10, 9, 9,101,108,115,101, 32,123,
+ 10, 9, 9, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46,
+ 48, 49, 41, 59, 10, 9, 9, 9,102,108,111, 97,116, 32,110,108, 32, 61, 32,100,111,116, 40,110, 44, 32,108, 41, 59, 10, 9, 9,
+ 9,105,102, 40,110,108, 32, 60, 61, 32, 48, 46, 48, 49, 41, 32,123, 10, 9, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,
+ 48, 46, 48, 59, 10, 9, 9, 9,125, 10, 9, 9, 9,101,108,115,101, 32,123, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,118,104,
+ 32, 61, 32,109, 97,120, 40,100,111,116, 40,118, 44, 32,104, 41, 44, 32, 48, 46, 48, 49, 41, 59, 10, 10, 9, 9, 9, 9,102,108,
+111, 97,116, 32, 97, 32, 61, 32, 49, 46, 48, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 98, 32, 61, 32, 40, 50, 46, 48, 42,
+110,104, 42,110,118, 41, 47,118,104, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32, 99, 32, 61, 32, 40, 50, 46, 48, 42,110,104,
+ 42,110,108, 41, 47,118,104, 59, 10, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,103, 59, 10, 10, 9, 9, 9, 9,105,102, 40, 97,
+ 32, 60, 32, 98, 32, 38, 38, 32, 97, 32, 60, 32, 99, 41, 32,103, 32, 61, 32, 97, 59, 10, 9, 9, 9, 9,101,108,115,101, 32,105,
+102, 40, 98, 32, 60, 32, 97, 32, 38, 38, 32, 98, 32, 60, 32, 99, 41, 32,103, 32, 61, 32, 98, 59, 10, 9, 9, 9, 9,101,108,115,
+101, 32,105,102, 40, 99, 32, 60, 32, 97, 32, 38, 38, 32, 99, 32, 60, 32, 98, 41, 32,103, 32, 61, 32, 99, 59, 10, 10, 9, 9, 9,
+ 9,102,108,111, 97,116, 32,112, 32, 61, 32,115,113,114,116, 40, 40, 40,114,101,102,114, 97, 99, 32, 42, 32,114,101,102,114, 97,
+ 99, 41, 43, 40,118,104, 42,118,104, 41, 45, 49, 46, 48, 41, 41, 59, 10, 9, 9, 9, 9,102,108,111, 97,116, 32,102, 32, 61, 32,
+ 40, 40, 40,112, 45,118,104, 41, 42, 40,112, 45,118,104, 41, 41, 47, 40, 40,112, 43,118,104, 41, 42, 40,112, 43,118,104, 41, 41,
+ 41, 42, 40, 49, 46, 48, 43, 40, 40, 40, 40,118,104, 42, 40,112, 43,118,104, 41, 41, 45, 49, 46, 48, 41, 42, 40, 40,118,104, 42,
+ 40,112, 43,118,104, 41, 41, 45, 49, 46, 48, 41, 41, 47, 40, 40, 40,118,104, 42, 40,112, 45,118,104, 41, 41, 43, 49, 46, 48, 41,
+ 42, 40, 40,118,104, 42, 40,112, 45,118,104, 41, 41, 43, 49, 46, 48, 41, 41, 41, 41, 59, 10, 9, 9, 9, 9,102,108,111, 97,116,
+ 32, 97,110,103, 32, 61, 32, 97, 99,111,115, 40,110,104, 41, 59, 10, 10, 9, 9, 9, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,
+109, 97,120, 40,102, 42,103, 42,101,120,112, 95, 98,108,101,110,100,101,114, 40, 40, 45, 40, 97,110,103, 42, 97,110,103, 41, 47,
+ 40, 50, 46, 48, 42,115,112,101, 99, 95,112,111,119,101,114, 42,115,112,101, 99, 95,112,111,119,101,114, 41, 41, 41, 44, 32, 48,
+ 46, 48, 41, 59, 10, 9, 9, 9,125, 10, 9, 9,125, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,119,
+ 97,114,100,105,115,111, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51,
+ 32,118, 44, 32,102,108,111, 97,116, 32,114,109,115, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99,
+ 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,122,101, 40,108, 32, 43, 32,118, 41, 59, 10,
+ 9,102,108,111, 97,116, 32,110,104, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,104, 41, 44, 32, 48, 46, 48, 48, 49,
+ 41, 59, 10, 9,102,108,111, 97,116, 32,110,118, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,118, 41, 44, 32, 48, 46,
+ 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32,110,108, 32, 61, 32,109, 97,120, 40,100,111,116, 40,110, 44, 32,108, 41, 44,
+ 32, 48, 46, 48, 48, 49, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,110,103,108,101, 32, 61, 32,116, 97,110, 40, 97, 99,111,115,
+ 40,110,104, 41, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,108,112,104, 97, 32, 61, 32,109, 97,120, 40,114,109,115, 44, 32, 48,
+ 46, 48, 48, 49, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, 99, 61, 32,110,108, 32, 42, 32, 40, 49, 46, 48, 47, 40, 52, 46, 48,
+ 42, 77, 95, 80, 73, 42, 97,108,112,104, 97, 42, 97,108,112,104, 97, 41, 41, 42, 40,101,120,112, 95, 98,108,101,110,100,101,114,
+ 40, 45, 40, 97,110,103,108,101, 42, 97,110,103,108,101, 41, 47, 40, 97,108,112,104, 97, 42, 97,108,112,104, 97, 41, 41, 47, 40,
+115,113,114,116, 40,110,118, 42,110,108, 41, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,116,111,111,
+110, 95,115,112,101, 99, 40,118,101, 99, 51, 32,110, 44, 32,118,101, 99, 51, 32,108, 44, 32,118,101, 99, 51, 32,118, 44, 32,102,
+108,111, 97,116, 32,115,105,122,101, 44, 32,102,108,111, 97,116, 32,116,115,109,111,111,116,104, 44, 32,111,117,116, 32,102,108,
+111, 97,116, 32,115,112,101, 99,102, 97, 99, 41, 10,123, 10, 9,118,101, 99, 51, 32,104, 32, 61, 32,110,111,114,109, 97,108,105,
+122,101, 40,108, 32, 43, 32,118, 41, 59, 10, 9,102,108,111, 97,116, 32,114,115,108,116, 32, 61, 32,100,111,116, 40,104, 44, 32,
+110, 41, 59, 10, 9,102,108,111, 97,116, 32, 97,110,103, 32, 61, 32, 97, 99,111,115, 40,114,115,108,116, 41, 59, 10, 10, 9,105,
+102, 40, 97,110,103, 32, 60, 32,115,105,122,101, 41, 32,114,115,108,116, 32, 61, 32, 49, 46, 48, 59, 10, 9,101,108,115,101, 32,
+105,102, 40, 97,110,103, 32, 62, 61, 32, 40,115,105,122,101, 32, 43, 32,116,115,109,111,111,116,104, 41, 32,124,124, 32,116,115,
+109,111,111,116,104, 32, 61, 61, 32, 48, 46, 48, 41, 32,114,115,108,116, 32, 61, 32, 48, 46, 48, 59, 10, 9,101,108,115,101, 32,
+114,115,108,116, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 40, 97,110,103, 32, 45, 32,115,105,122,101, 41, 47,116,115,109,111,111,
+116,104, 41, 59, 10, 10, 9,115,112,101, 99,102, 97, 99, 32, 61, 32,114,115,108,116, 59, 10,125, 10, 10,118,111,105,100, 32,115,
+104, 97,100,101, 95,115,112,101, 99, 95, 97,114,101, 97, 95,105,110,112, 40,102,108,111, 97,116, 32,115,112,101, 99,102, 97, 99,
+ 44, 32,102,108,111, 97,116, 32,105,110,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,115,112,101, 99,102, 97,
+ 99, 41, 10,123, 10, 9,111,117,116,115,112,101, 99,102, 97, 99, 32, 61, 32,115,112,101, 99,102, 97, 99, 42,105,110,112, 59, 10,
+125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,115,112,101, 99, 95,116, 40,102,108,111, 97,116, 32,115,104, 97,100,102,
+ 97, 99, 44, 32,102,108,111, 97,116, 32,115,112,101, 99, 44, 32,102,108,111, 97,116, 32,118,105,115,105,102, 97, 99, 44, 32,102,
+108,111, 97,116, 32,115,112,101, 99,102, 97, 99, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,116, 41, 10,123, 10, 9,116, 32,
+ 61, 32,115,104, 97,100,102, 97, 99, 42,115,112,101, 99, 42,118,105,115,105,102, 97, 99, 42,115,112,101, 99,102, 97, 99, 59, 10,
+125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 95,115,112,101, 99, 40,102,108,111, 97,116, 32,116, 44, 32,
+118,101, 99, 51, 32,108, 97,109,112, 99,111,108, 44, 32,118,101, 99, 51, 32,115,112,101, 99, 99,111,108, 44, 32,111,117,116, 32,
+118,101, 99, 51, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,116, 42,108, 97,109,112, 99,
+111,108, 42,115,112,101, 99, 99,111,108, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,100,100, 40,118,101,
+ 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,
+ 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 49, 32, 43, 32, 99,111,108, 50, 59, 10,125, 10,
+ 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100,100, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32,
+ 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108,
+ 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 32, 43, 32, 99,111,108, 49, 42, 99,111,108, 50, 59, 10,125,
+ 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109, 97,100,100,102, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,102,108,111,
+ 97,116, 32,102, 44, 32,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108,
+ 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 32, 43, 32,102, 42, 99,111,108, 49, 59, 10,125, 10, 10,118,
+111,105,100, 32,115,104, 97,100,101, 95,109,117,108, 40,118,101, 99, 52, 32, 99,111,108, 49, 44, 32,118,101, 99, 52, 32, 99,111,
+108, 50, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61,
+ 32, 99,111,108, 49, 42, 99,111,108, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,109,117,108, 95,118, 97,
+108,117,101, 40,102,108,111, 97,116, 32,102, 97, 99, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99,
+ 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32, 99,111,108, 42,102, 97, 99, 59, 10,125,
+ 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,111, 98, 99,111,108,111,114, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118,
+101, 99, 52, 32,111, 98, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,
+117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40, 99,111,108, 46,114,103, 98, 42,111, 98, 99,111,108, 46,114,103, 98, 44, 32,
+ 99,111,108, 46, 97, 41, 59, 10,125, 10, 10,118,111,105,100, 32,114, 97,109,112, 95,114,103, 98,116,111, 98,119, 40,118,101, 99,
+ 51, 32, 99,111,108,111,114, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,118, 97,108, 41, 10,123, 10, 9,111,117,
+116,118, 97,108, 32, 61, 32, 99,111,108,111,114, 46,114, 42, 48, 46, 51, 32, 43, 32, 99,111,108,111,114, 46,103, 42, 48, 46, 53,
+ 56, 32, 43, 32, 99,111,108,111,114, 46, 98, 42, 48, 46, 49, 50, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,
+111,110,108,121, 95,115,104, 97,100,111,119, 40,102,108,111, 97,116, 32,105, 44, 32,102,108,111, 97,116, 32,115,104, 97,100,102,
+ 97, 99, 44, 32,102,108,111, 97,116, 32,101,110,101,114,103,121, 44, 32,118,101, 99, 51, 32,114,103, 98, 44, 32,118,101, 99, 51,
+ 32,115,112,101, 99,114,103, 98, 44, 32,118,101, 99, 52, 32,100,105,102,102, 44, 32,118,101, 99, 52, 32,115,112,101, 99, 44, 32,
+111,117,116, 32,118,101, 99, 52, 32,111,117,116,100,105,102,102, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116,115,112,
+101, 99, 41, 10,123, 10, 9,115,104, 97,100,102, 97, 99, 32, 61, 32,105, 42,101,110,101,114,103,121, 42, 40, 49, 46, 48, 32, 45,
+ 32,115,104, 97,100,102, 97, 99, 41, 59, 10, 10, 9,111,117,116,100,105,102,102, 32, 61, 32,100,105,102,102, 32, 45, 32,118,101,
+ 99, 52, 40,114,103, 98, 42,115,104, 97,100,102, 97, 99, 44, 32, 48, 46, 48, 41, 59, 10, 9,111,117,116,115,112,101, 99, 32, 61,
+ 32,115,112,101, 99, 32, 45, 32,118,101, 99, 52, 40,115,112,101, 99,114,103, 98, 42,115,104, 97,100,102, 97, 99, 44, 32, 48, 46,
+ 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,116,101,115,116, 95,115,104, 97,100,111,119, 98,117,102, 40,118,101, 99, 51, 32,
+114, 99,111, 44, 32,115, 97,109,112,108,101,114, 50, 68, 83,104, 97,100,111,119, 32,115,104, 97,100,111,119,109, 97,112, 44, 32,
+109, 97,116, 52, 32,115,104, 97,100,111,119,112,101,114,115,109, 97,116, 44, 32,102,108,111, 97,116, 32,115,104, 97,100,111,119,
+ 98,105, 97,115, 44, 32,102,108,111, 97,116, 32,105,110,112, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,114,101,115,117,108,
+116, 41, 10,123, 10, 9,105,102, 40,105,110,112, 32, 60, 61, 32, 48, 46, 48, 41, 32,123, 10, 9, 9,114,101,115,117,108,116, 32,
+ 61, 32, 48, 46, 48, 59, 10, 9,125, 10, 9,101,108,115,101, 32,123, 10, 9, 9,118,101, 99, 52, 32, 99,111, 32, 61, 32,115,104,
+ 97,100,111,119,112,101,114,115,109, 97,116, 42,118,101, 99, 52, 40,114, 99,111, 44, 32, 49, 46, 48, 41, 59, 10, 10, 9, 9, 47,
+ 47,102,108,111, 97,116, 32, 98,105, 97,115, 32, 61, 32, 40, 49, 46, 53, 32, 45, 32,105,110,112, 42,105,110,112, 41, 42,115,104,
+ 97,100,111,119, 98,105, 97,115, 59, 10, 9, 9, 99,111, 46,122, 32, 45, 61, 32,115,104, 97,100,111,119, 98,105, 97,115, 42, 99,
+111, 46,119, 59, 10, 10, 9, 9,114,101,115,117,108,116, 32, 61, 32,115,104, 97,100,111,119, 50, 68, 80,114,111,106, 40,115,104,
+ 97,100,111,119,109, 97,112, 44, 32, 99,111, 41, 46,120, 59, 10, 9,125, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101,
+ 95,101,120,112,111,115,117,114,101, 95, 99,111,114,114,101, 99,116, 40,118,101, 99, 51, 32, 99,111,108, 44, 32,102,108,111, 97,
+116, 32,108,105,110,102, 97, 99, 44, 32,102,108,111, 97,116, 32,108,111,103,102, 97, 99, 44, 32,111,117,116, 32,118,101, 99, 51,
+ 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,108,105,110,102, 97, 99, 42, 40, 49, 46, 48,
+ 32, 45, 32,101,120,112, 40, 99,111,108, 42,108,111,103,102, 97, 99, 41, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,
+100,101, 95,109,105,115,116, 95,102, 97, 99,116,111,114, 40,118,101, 99, 51, 32, 99,111, 44, 32,102,108,111, 97,116, 32,109,105,
+115,116,115,116, 97, 44, 32,102,108,111, 97,116, 32,109,105,115,116,100,105,115,116, 44, 32,102,108,111, 97,116, 32,109,105,115,
+116,116,121,112,101, 44, 32,102,108,111, 97,116, 32,109,105,115,105, 44, 32,111,117,116, 32,102,108,111, 97,116, 32,111,117,116,
+102, 97, 99, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99, 44, 32,122, 99,111,114, 59, 10, 10, 9,122, 99,111,114, 32,
+ 61, 32, 40,103,108, 95, 80,114,111,106,101, 99,116,105,111,110, 77, 97,116,114,105,120, 91, 51, 93, 91, 51, 93, 32, 61, 61, 32,
+ 48, 46, 48, 41, 63, 32,108,101,110,103,116,104, 40, 99,111, 41, 58, 32, 45, 99,111, 91, 50, 93, 59, 10, 9, 10, 9,102, 97, 99,
+ 32, 61, 32, 99,108, 97,109,112, 40, 40,122, 99,111,114, 45,109,105,115,116,115,116, 97, 41, 47,109,105,115,116,100,105,115,116,
+ 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,105,102, 40,109,105,115,116,116,121,112,101, 32, 61, 61, 32, 48, 46, 48,
+ 41, 32,102, 97, 99, 32, 42, 61, 32,102, 97, 99, 59, 10, 9,101,108,115,101, 32,105,102, 40,109,105,115,116,116,121,112,101, 32,
+ 61, 61, 32, 49, 46, 48, 41, 59, 10, 9,101,108,115,101, 32,102, 97, 99, 32, 61, 32,115,113,114,116, 40,102, 97, 99, 41, 59, 10,
+ 10, 9,111,117,116,102, 97, 99, 32, 61, 32, 49, 46, 48, 32, 45, 32, 40, 49, 46, 48, 45,102, 97, 99, 41, 42, 40, 49, 46, 48, 45,
+109,105,115,105, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95,119,111,114,108,100, 95,109,105,120, 40,118,
+101, 99, 51, 32,104,111,114, 44, 32,118,101, 99, 52, 32, 99,111,108, 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,
+111,108, 41, 10,123, 10, 9,102,108,111, 97,116, 32,102, 97, 99, 32, 61, 32, 99,108, 97,109,112, 40, 99,111,108, 46, 97, 44, 32,
+ 48, 46, 48, 44, 32, 49, 46, 48, 41, 59, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52, 40,109,105,120, 40,104,111,
+114, 44, 32, 99,111,108, 46,114,103, 98, 44, 32,102, 97, 99, 41, 44, 32, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10,118,111,105,
+100, 32,115,104, 97,100,101, 95, 97,108,112,104, 97, 95,111,112, 97,113,117,101, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,111,
+117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,101, 99, 52,
+ 40, 99,111,108, 46,114,103, 98, 44, 32, 49, 46, 48, 41, 59, 10,125, 10, 10,118,111,105,100, 32,115,104, 97,100,101, 95, 97,108,
+112,104, 97, 95,111, 98, 99,111,108,111,114, 40,118,101, 99, 52, 32, 99,111,108, 44, 32,118,101, 99, 52, 32,111, 98, 99,111,108,
+ 44, 32,111,117,116, 32,118,101, 99, 52, 32,111,117,116, 99,111,108, 41, 10,123, 10, 9,111,117,116, 99,111,108, 32, 61, 32,118,
+101, 99, 52, 40, 99,111,108, 46,114,103, 98, 44, 32, 99,111,108, 46, 97, 42,111, 98, 99,111,108, 46, 97, 41, 59, 10,125, 10, 10,
+ 0};
+
diff --git a/source/blender/gpu/intern/gpu_shader_vertex.glsl b/source/blender/gpu/intern/gpu_shader_vertex.glsl
new file mode 100644
index 00000000000..ba9ef7dead6
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_shader_vertex.glsl
@@ -0,0 +1,12 @@
+
+varying vec3 varposition;
+varying vec3 varnormal;
+
+void main()
+{
+ vec4 co = gl_ModelViewMatrix * gl_Vertex;
+
+ varposition = co.xyz;
+ varnormal = gl_NormalMatrix * gl_Normal;
+ gl_Position = gl_ProjectionMatrix * co;
+
diff --git a/source/blender/gpu/intern/gpu_shader_vertex.glsl.c b/source/blender/gpu/intern/gpu_shader_vertex.glsl.c
new file mode 100644
index 00000000000..a89de776864
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_shader_vertex.glsl.c
@@ -0,0 +1,13 @@
+/* DataToC output of file <gpu_shader_vertex_glsl> */
+
+int datatoc_gpu_shader_vertex_glsl_size= 217;
+char datatoc_gpu_shader_vertex_glsl[]= {
+ 10,118, 97,114,121,105,110,103, 32,118,101, 99, 51, 32,118, 97,114,112,111,115,105,116,105,111,110,
+ 59, 10,118, 97,114,121,105,110,103, 32,118,101, 99, 51, 32,118, 97,114,110,111,114,109, 97,108, 59, 10, 10,118,111,105,100, 32,
+109, 97,105,110, 40, 41, 10,123, 10, 9,118,101, 99, 52, 32, 99,111, 32, 61, 32,103,108, 95, 77,111,100,101,108, 86,105,101,119,
+ 77, 97,116,114,105,120, 32, 42, 32,103,108, 95, 86,101,114,116,101,120, 59, 10, 10, 9,118, 97,114,112,111,115,105,116,105,111,
+110, 32, 61, 32, 99,111, 46,120,121,122, 59, 10, 9,118, 97,114,110,111,114,109, 97,108, 32, 61, 32,103,108, 95, 78,111,114,109,
+ 97,108, 77, 97,116,114,105,120, 32, 42, 32,103,108, 95, 78,111,114,109, 97,108, 59, 10, 9,103,108, 95, 80,111,115,105,116,105,
+111,110, 32, 61, 32,103,108, 95, 80,114,111,106,101, 99,116,105,111,110, 77, 97,116,114,105,120, 32, 42, 32, 99,111, 59, 10, 10,
+};
+