aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/freetype/demo/engine-test.dpr
diff options
context:
space:
mode:
authortobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2008-10-26 11:54:33 +0000
committertobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2008-10-26 11:54:33 +0000
commitd6770dd47dcb871f021868dec2b333527ffb8ee8 (patch)
tree7357a6c430fc75761ca4ecb7df0f249efba6438e /src/lib/freetype/demo/engine-test.dpr
parent831c09280154452be3520b0d0d2987a2e405e419 (diff)
downloadusdx-d6770dd47dcb871f021868dec2b333527ffb8ee8.tar.gz
usdx-d6770dd47dcb871f021868dec2b333527ffb8ee8.tar.xz
usdx-d6770dd47dcb871f021868dec2b333527ffb8ee8.zip
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1479 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to '')
-rw-r--r--src/lib/freetype/demo/engine-test.dpr (renamed from src/lib/freetype/demo/lesson43.dpr)702
1 files changed, 336 insertions, 366 deletions
diff --git a/src/lib/freetype/demo/lesson43.dpr b/src/lib/freetype/demo/engine-test.dpr
index 8a470a2e..80177735 100644
--- a/src/lib/freetype/demo/lesson43.dpr
+++ b/src/lib/freetype/demo/engine-test.dpr
@@ -1,366 +1,336 @@
-program lesson43;
-(*
- * This code was created by Jeff Molofee '99
- * (ported to Linux/SDL by Ti Leggett '01)
- *
- * If you've found this code useful, please let me know.
- *
- * Visit Jeff at http://nehe.gamedev.net/
- *
- * or for port-specific comments, questions, bugreports etc.
- * email to leggett@eecs.tulane.edu
- *)
-
-{$IFDEF FPC}
- {$mode delphi}{$H+}
-{$ENDIF}
-
-{$APPTYPE Console}
-
-{.$DEFINE FONT2}
-
-uses
- moduleloader in '../../JEDI-SDL/SDL/Pas/moduleloader.pas',
- SDL in '../../JEDI-SDL/SDL/Pas/sdl.pas',
- gl in '../../JEDI-SDL/OpenGL/Pas/gl.pas',
- glext in '../../JEDI-SDL/OpenGL/Pas/glext.pas',
- glu in '../../JEDI-SDL/OpenGL/Pas/glu.pas',
- ctypes in '../../ctypes/ctypes.pas',
- FreeType in '../freetype.pas',
- {$IFNDEF FONT2}
- UFont in 'UFont.pas',
- {$ELSE}
- UFont2 in 'UFont2.pas',
- {$ENDIF}
- math,
- sysutils;
-
-const
- // screen width, height, and bit depth
- SCREEN_WIDTH = 640;
- SCREEN_HEIGHT = 480;
- SCREEN_BPP = 16;
-
- //FONT_FILE = 'Test.ttf';
- //FONT_FILE = 'C:/Windows/Fonts/Arial.ttf';
- //FONT_FILE = 'C:/Windows/Fonts/SimSun.ttf';
- //FONT_FILE = 'C:/Windows/Fonts/SimSun.ttf';
- FONT_FILE = 'eurostarregularextended.ttf';
-
-var
- OurFont: TScalableFont;
- // This is our SDL surface
- surface: PSDL_Surface;
- cnt1, cnt2: GLfloat;
-
-(* function to release/destroy our resources and restoring the old desktop *)
-procedure Quit(returnCode: integer);
-begin
- OurFont.Free;
-
- // clean up the window
- SDL_Quit( );
-
- // and exit appropriately
- Halt( returnCode );
-end;
-
-(* function to reset our viewport after a window resize *)
-function resizeWindow(width: integer; height: integer): boolean;
-begin
- // Protect against a divide by zero
- if ( height = 0 ) then
- height := 1;
-
- // Setup our viewport.
- glViewport( 0, 0, GLsizei(width), GLsizei(height) );
-
- // change to the projection matrix and set our viewing volume.
- glMatrixMode( GL_PROJECTION );
- glLoadIdentity( );
-
- // Set our perspective
- //gluOrtho2D(0, width, 0, height);
- gluOrtho2D(0, 800, 0, 600);
-
- // Make sure we're chaning the model view and not the projection
- glMatrixMode( GL_MODELVIEW );
-
- // Reset The View
- glLoadIdentity( );
-
- Result := true;
-end;
-
-(* function to handle key press events *)
-procedure handleKeyPress(keysym: PSDL_keysym);
-begin
- case ( keysym^.sym ) of
- SDLK_ESCAPE:
- begin
- // ESC key was pressed
- Quit( 0 );
- end;
- SDLK_F1:
- begin
- // F1 key was pressed
- // this toggles fullscreen mode
- SDL_WM_ToggleFullScreen( surface );
- end;
- end;
-end;
-
-(* general OpenGL initialization function *)
-function initGL(): boolean;
-begin
- // Enable smooth shading
- glShadeModel( GL_SMOOTH );
-
- // Set the background black
- //glClearColor( 1, 1, 1.0, 1.0 );
- //glClearColor( 0.3, 0.7, 1.0, 1.0 );
- glClearColor( 0.0, 0.0, 0.0, 1.0 );
-
- // Depth buffer setup
- glClearDepth( 1.0 );
-
- // Enables Depth Testing
- glEnable( GL_DEPTH_TEST );
-
- // The Type Of Depth Test To Do
- glDepthFunc( GL_LEQUAL );
-
- // Really Nice Perspective Calculations
- glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
-
- //OurFont := TFTScalableFont.Create(FONT_FILE, 64);
- //OurFont := TFTFont.Create(FONT_FILE, 128);
- OurFont := TFTScalableOutlineFont.Create(FONT_FILE, 64, 0.05);
- //OurFont.UseKerning := false;
- TFTScalableOutlineFont(OurFont).SetOutlineColor(1, 0, 0);
- //OurFont := TOutlineFont.Create(FONT_FILE, 32, 2);
- //OurFont.LineSpacing := OurFont.LineSpacing * 0.5;
-
- Result := true;
-end;
-
-var
- NextTime: cardinal;
- Counter: integer;
-
-type
- TVector4d = array[0..3] of GLdouble;
-
-function NewVector4d(a, b, c, d: GLdouble): TVector4d;
-begin
- Result[0] := a;
- Result[1] := b;
- Result[2] := c;
- Result[3] := d;
-end;
-
-(* Here goes our drawing code *)
-function drawGLScene(): boolean;
-var
- msg: WideString;
- bounds: TBoundsDbl;
- ClipPlaneEq: TVector4d;
-begin
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
-
- //msg := 'Here'#13'there'#13'be'#13#13'newlines'#13'.';
- //msg := 'Here'#13'newlines';
- msg := 'Hallo Du';//Active FreeType Text - ' + FloatToStr(cnt1);
- //msg := 'Hören'#13'其自诞生至今'#13'спецификация';
-
- // Red text
- glLoadIdentity();
- glTranslatef(cnt2, 240, 0);
- if (cnt2 > 800) then
- cnt2 := 0;
- glTranslatef(30, 40, 0);
- //glTranslatef(320, 240, 0);
- //glRotatef(cnt1, 0, 0, 1);
- //glScalef(1, 0.8 + 0.3*cos(cnt1/5), 1);
-
- OurFont.Style := [Italic, Underline, Reflect];
- //OurFont.GlyphSpacing := 10;
- //OurFont.SetOutlineColor(0.5, 0.5, 0.5);
- //OurFont.ReflectionSpacing := -4;
- //OurFont.UseKerning := false;
- OurFont.Height := 32;//cnt2;
- //OurFont.Reset;
- //OurFont.Aspect := 2;
-
- {
- glColor3f(1, 1, 0);
- bounds := OurFont.BBox(msg);
- glRectf(bounds.Left, bounds.Top, bounds.Right, bounds.Bottom);
- }
-
- {
- glEnable(GL_CLIP_PLANE0);
- ClipPlaneEq := NewVector4d(-1, 0, 0, bounds.Right/5);
- glClipPlane(GL_CLIP_PLANE0, @ClipPlaneEq);
- }
- //glColor3f(1, 0, 0);
- glColor3f(1, 1, 1);
- //OurFont.ReflectionSpacing := 0;
- OurFont.Print(msg);
-
- glTranslatef(0, 50, 0);
- glColor3f(1, 1, 0);
- bounds := OurFont.BBox('Hallo ');
- glRectf(bounds.Left, bounds.Top, bounds.Right, bounds.Bottom);
- OurFont.Print('Hallo ');
-
- {
- ClipPlaneEq := NewVector4d(1, 0, 0, -bounds.Right/5);
- glClipPlane(GL_CLIP_PLANE0, @ClipPlaneEq);
- glColor3f(0, 0, 1);
- OurFont.Print(msg);
- glDisable(GL_CLIP_PLANE0);
- //glColor3f(0, 1, 0);
- //OurFont.Style := OurFont.Style - [Italic];
- //OurFont.Print(msg);
- }
-
- cnt1 := cnt1 + 0.051; // Increase The First Counter
- cnt2 := cnt2 + 0.005; // Increase The First Counter
-
- SDL_GL_SwapBuffers( );
-
- Inc(Counter);
-
- if (NextTime < SDL_GetTicks()) then
- begin
- NextTime := SDL_GetTicks() + 2000;
- writeln('FPS: ' + floattostr(Counter / 2.0));
- Counter := 0;
- end;
-
- Result := true;
-end;
-
-var
- // Flags to pass to SDL_SetVideoMode
- videoFlags: integer;
- // main loop variable
- done: boolean = false;
- // used to collect events
- event: TSDL_Event;
- // this holds some info about our display
- videoInfo: PSDL_VideoInfo;
- // whether or not the window is active
- isActive: boolean = true;
-
-begin
- // initialize SDL
- if ( SDL_Init( SDL_INIT_VIDEO or SDL_INIT_TIMER ) < 0 ) then
- begin
- writeln( ErrOutput, 'Video initialization failed: ' + SDL_GetError() );
- Quit( 1 );
- end;
-
- // Fetch the video info
- videoInfo := SDL_GetVideoInfo( );
-
- if ( videoInfo = nil ) then
- begin
- writeln( ErrOutput, 'Video query failed: ' + SDL_GetError() );
- Quit( 1 );
- end;
-
- SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // Enable double buffering
-
- // the flags to pass to SDL_SetVideoMode
- videoFlags := SDL_OPENGL; // Enable OpenGL in SDL
- videoFlags := videoFlags or SDL_HWPALETTE; // Store the palette in hardware
- videoFlags := videoFlags or SDL_RESIZABLE; // Enable window resizing
-
- // This checks to see if surfaces can be stored in memory
- if ( videoInfo^.hw_available <> 0 ) then
- videoFlags := videoFlags or SDL_HWSURFACE
- else
- videoFlags := videoFlags or SDL_SWSURFACE;
-
- // This checks if hardware blits can be done
- if ( videoInfo^.blit_hw <> 0 ) then
- videoFlags := videoFlags or SDL_HWACCEL;
-
- // Sets up OpenGL double buffering
- SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
-
- // get a SDL surface
- surface := SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,
- videoFlags );
-
- // Verify there is a surface
- if ( surface = nil ) then
- begin
- writeln( ErrOutput, 'Video mode set failed: ' + SDL_GetError() );
- Quit( 1 );
- end;
-
- // initialize OpenGL
- initGL();
-
- // resize the initial window
- resizeWindow( SCREEN_WIDTH, SCREEN_HEIGHT );
-
- // wait for events
- while ( not done ) do
- begin
- { handle the events in the queue }
-
- while ( SDL_PollEvent( @event ) <> 0 ) do
- begin
- case( event.type_ ) of
- SDL_ACTIVEEVENT:
- begin
- // Something's happend with our focus
- // If we are iconified, we shouldn't draw the screen
- if ( (event.active.state and SDL_APPACTIVE) <> 0 ) then
- begin
- if ( event.active.gain = 0 ) then
- isActive := false
- else
- isActive := true;
- end;
- end;
- SDL_VIDEORESIZE:
- begin
- // handle resize event
- {$IFDEF UNIX}
- surface := SDL_SetVideoMode( event.resize.w,
- event.resize.h,
- 16, videoFlags );
- if ( surface = nil ) then
- begin
- writeln( ErrOutput, 'Could not get a surface after resize: ' + SDL_GetError( ) );
- Quit( 1 );
- end;
- {$ENDIF}
- resizeWindow( event.resize.w, event.resize.h );
- end;
- SDL_KEYDOWN:
- begin
- // handle key presses
- handleKeyPress( @event.key.keysym );
- end;
- SDL_QUITEV:
- begin
- // handle quit requests
- done := true;
- end;
- end;
- end;
-
- // draw the scene
- if ( isActive ) then
- drawGLScene( );
- end;
-
- // clean ourselves up and exit
- Quit( 0 );
-end.
+program engine_test;
+(*
+ * This code was created by Jeff Molofee '99
+ * (ported to Linux/SDL by Ti Leggett '01)
+ *
+ * If you've found this code useful, please let me know.
+ *
+ * Visit Jeff at http://nehe.gamedev.net/
+ *
+ * or for port-specific comments, questions, bugreports etc.
+ * email to leggett@eecs.tulane.edu
+ *)
+
+{$IFDEF FPC}
+ {$mode delphi}{$H+}
+{$ENDIF}
+
+{$APPTYPE Console}
+
+uses
+ moduleloader in '../../JEDI-SDL/SDL/Pas/moduleloader.pas',
+ SDL in '../../JEDI-SDL/SDL/Pas/sdl.pas',
+ gl in '../../JEDI-SDL/OpenGL/Pas/gl.pas',
+ glext in '../../JEDI-SDL/OpenGL/Pas/glext.pas',
+ glu in '../../JEDI-SDL/OpenGL/Pas/glu.pas',
+ {$IFNDEF FPC}
+ ctypes in '../../ctypes/ctypes.pas',
+ {$ENDIF}
+ FreeType in '../freetype.pas',
+ UFont in '../../../base/UFont.pas',
+ math,
+ sysutils;
+
+const
+ // screen width, height, and bit depth
+ SCREEN_WIDTH = 640;
+ SCREEN_HEIGHT = 480;
+ SCREEN_BPP = 16;
+
+ //FONT_FILE = 'Test.ttf';
+ //FONT_FILE = 'C:/Windows/Fonts/Arial.ttf';
+ //FONT_FILE = 'C:/Windows/Fonts/SimSun.ttf';
+ //FONT_FILE = 'eurostarregularextended.ttf';
+ FONT_FILE = 'FreeSans.ttf';
+
+var
+ OurFont: TScalableFont;
+ // This is our SDL surface
+ surface: PSDL_Surface;
+ cnt1, cnt2: GLfloat;
+
+(* function to release/destroy our resources and restoring the old desktop *)
+procedure Quit(returnCode: integer);
+begin
+ OurFont.Free;
+
+ // clean up the window
+ SDL_Quit( );
+
+ // and exit appropriately
+ Halt( returnCode );
+end;
+
+(* function to reset our viewport after a window resize *)
+function resizeWindow(width: integer; height: integer): boolean;
+begin
+ // Protect against a divide by zero
+ if ( height = 0 ) then
+ height := 1;
+
+ // Setup our viewport.
+ glViewport( 0, 0, GLsizei(width), GLsizei(height) );
+
+ // change to the projection matrix and set our viewing volume.
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity( );
+
+ // Set our perspective
+ //gluOrtho2D(0, width, 0, height);
+ gluOrtho2D(0, 800, 0, 600);
+
+ // Make sure we're chaning the model view and not the projection
+ glMatrixMode( GL_MODELVIEW );
+
+ // Reset The View
+ glLoadIdentity( );
+
+ Result := true;
+end;
+
+(* function to handle key press events *)
+procedure handleKeyPress(keysym: PSDL_keysym);
+begin
+ case ( keysym^.sym ) of
+ SDLK_ESCAPE:
+ begin
+ // ESC key was pressed
+ Quit( 0 );
+ end;
+ SDLK_F1:
+ begin
+ // F1 key was pressed
+ // this toggles fullscreen mode
+ SDL_WM_ToggleFullScreen( surface );
+ end;
+ end;
+end;
+
+(* general OpenGL initialization function *)
+function initGL(): boolean;
+begin
+ // Enable smooth shading
+ glShadeModel( GL_SMOOTH );
+
+ // Set the background black
+ //glClearColor( 1, 1, 1.0, 1.0 );
+ //glClearColor( 0.3, 0.7, 1.0, 1.0 );
+ glClearColor( 0.0, 0.0, 0.0, 1.0 );
+
+ // Depth buffer setup
+ glClearDepth( 1.0 );
+
+ // Enables Depth Testing
+ glEnable( GL_DEPTH_TEST );
+
+ // The Type Of Depth Test To Do
+ glDepthFunc( GL_LEQUAL );
+
+ // Really Nice Perspective Calculations
+ glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
+
+ //OurFont := TFTScalableFont.Create(FONT_FILE, 64);
+ //OurFont := TFTFont.Create(FONT_FILE, 128);
+ OurFont := TFTScalableOutlineFont.Create(FONT_FILE, 64, 0.05);
+ //OurFont.UseKerning := false;
+ TFTScalableOutlineFont(OurFont).SetOutlineColor(1, 0, 0);
+ //OurFont := TOutlineFont.Create(FONT_FILE, 32, 2);
+ //OurFont.LineSpacing := OurFont.LineSpacing * 0.5;
+
+ Result := true;
+end;
+
+var
+ NextTime: cardinal;
+ Counter: integer;
+
+type
+ TVector4d = array[0..3] of GLdouble;
+
+function NewVector4d(a, b, c, d: GLdouble): TVector4d;
+begin
+ Result[0] := a;
+ Result[1] := b;
+ Result[2] := c;
+ Result[3] := d;
+end;
+
+(* Here goes our drawing code *)
+function drawGLScene(): boolean;
+var
+ msg: WideString;
+ bounds: TBoundsDbl;
+begin
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
+
+ //msg := 'Here'#13'there'#13'be'#13#13'newlines'#13'.';
+ //msg := 'Here'#13'newlines';
+ msg := 'Active FreeType Text - ' + FloatToStr(cnt1);
+ //msg := 'Hören'#13'其自诞生至今'#13'спецификация';
+
+ // Red text
+ glLoadIdentity();
+ glTranslatef(cnt2, 240, 0);
+ if (cnt2 > 800) then
+ cnt2 := 0;
+ glTranslatef(30, 40, 0);
+ //glTranslatef(320, 240, 0);
+ //glRotatef(cnt1, 0, 0, 1);
+ //glScalef(1, 0.8 + 0.3*cos(cnt1/5), 1);
+
+ OurFont.Style := [Italic, {Underline,} Reflect];
+ //OurFont.GlyphSpacing := 10;
+ //OurFont.SetOutlineColor(0.5, 0.5, 0.5);
+ //OurFont.ReflectionSpacing := -4;
+ //OurFont.UseKerning := false;
+ OurFont.Height := 64;//cnt2;
+ //OurFont.Reset;
+ //OurFont.Aspect := 2;
+
+ glColor3f(1, 1, 0);
+ bounds := OurFont.BBox(msg);
+ //glRectf(bounds.Left, OurFont.Ascender, bounds.Right, OurFont.Ascender-OurFont.Height);
+
+ glColor3f(1, 1, 1);
+ //OurFont.ReflectionSpacing := 0;
+ OurFont.Print(msg);
+
+ cnt1 := cnt1 + 0.051; // Increase The First Counter
+ cnt2 := cnt2 + 0.005; // Increase The First Counter
+
+ SDL_GL_SwapBuffers( );
+
+ Inc(Counter);
+
+ if (NextTime < SDL_GetTicks()) then
+ begin
+ NextTime := SDL_GetTicks() + 2000;
+ writeln('FPS: ' + floattostr(Counter / 2.0));
+ Counter := 0;
+ end;
+
+ Result := true;
+end;
+
+var
+ // Flags to pass to SDL_SetVideoMode
+ videoFlags: integer;
+ // main loop variable
+ done: boolean = false;
+ // used to collect events
+ event: TSDL_Event;
+ // this holds some info about our display
+ videoInfo: PSDL_VideoInfo;
+ // whether or not the window is active
+ isActive: boolean = true;
+
+begin
+ // initialize SDL
+ if ( SDL_Init( SDL_INIT_VIDEO or SDL_INIT_TIMER ) < 0 ) then
+ begin
+ writeln( ErrOutput, 'Video initialization failed: ' + SDL_GetError() );
+ Quit( 1 );
+ end;
+
+ // Fetch the video info
+ videoInfo := SDL_GetVideoInfo( );
+
+ if ( videoInfo = nil ) then
+ begin
+ writeln( ErrOutput, 'Video query failed: ' + SDL_GetError() );
+ Quit( 1 );
+ end;
+
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // Enable double buffering
+
+ // the flags to pass to SDL_SetVideoMode
+ videoFlags := SDL_OPENGL; // Enable OpenGL in SDL
+ videoFlags := videoFlags or SDL_HWPALETTE; // Store the palette in hardware
+ videoFlags := videoFlags or SDL_RESIZABLE; // Enable window resizing
+
+ // This checks to see if surfaces can be stored in memory
+ if ( videoInfo^.hw_available <> 0 ) then
+ videoFlags := videoFlags or SDL_HWSURFACE
+ else
+ videoFlags := videoFlags or SDL_SWSURFACE;
+
+ // This checks if hardware blits can be done
+ if ( videoInfo^.blit_hw <> 0 ) then
+ videoFlags := videoFlags or SDL_HWACCEL;
+
+ // Sets up OpenGL double buffering
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+ // get a SDL surface
+ surface := SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,
+ videoFlags );
+
+ // Verify there is a surface
+ if ( surface = nil ) then
+ begin
+ writeln( ErrOutput, 'Video mode set failed: ' + SDL_GetError() );
+ Quit( 1 );
+ end;
+
+ // initialize OpenGL
+ initGL();
+
+ // resize the initial window
+ resizeWindow( SCREEN_WIDTH, SCREEN_HEIGHT );
+
+ // wait for events
+ while ( not done ) do
+ begin
+ { handle the events in the queue }
+
+ while ( SDL_PollEvent( @event ) <> 0 ) do
+ begin
+ case( event.type_ ) of
+ SDL_ACTIVEEVENT:
+ begin
+ // Something's happend with our focus
+ // If we are iconified, we shouldn't draw the screen
+ if ( (event.active.state and SDL_APPACTIVE) <> 0 ) then
+ begin
+ if ( event.active.gain = 0 ) then
+ isActive := false
+ else
+ isActive := true;
+ end;
+ end;
+ SDL_VIDEORESIZE:
+ begin
+ // handle resize event
+ {$IFDEF UNIX}
+ surface := SDL_SetVideoMode( event.resize.w,
+ event.resize.h,
+ 16, videoFlags );
+ if ( surface = nil ) then
+ begin
+ writeln( ErrOutput, 'Could not get a surface after resize: ' + SDL_GetError( ) );
+ Quit( 1 );
+ end;
+ {$ENDIF}
+ resizeWindow( event.resize.w, event.resize.h );
+ end;
+ SDL_KEYDOWN:
+ begin
+ // handle key presses
+ handleKeyPress( @event.key.keysym );
+ end;
+ SDL_QUITEV:
+ begin
+ // handle quit requests
+ done := true;
+ end;
+ end;
+ end;
+
+ // draw the scene
+ if ( isActive ) then
+ drawGLScene( );
+ end;
+
+ // clean ourselves up and exit
+ Quit( 0 );
+end.